qcacmn: RNR IE parsing support

Add RNR IE parsing support on scan module.

Change-Id: I7a0685f16a61a45910212b2d8fe5cbc12b5bd92e
CRs-Fixed: 2557271
This commit is contained in:
Sandeep Puligilla 2019-10-30 00:38:16 -07:00 • committed by nshrivas
commit aba2b0c42b
3 changed files with 204 additions and 0 deletions

View file

@ -121,6 +121,7 @@
#define WLAN_IBSS_IE_MAX_LEN 2
#define WLAN_REQUEST_IE_MAX_LEN 255
#define WLAN_RM_CAPABILITY_IE_MAX_LEN 5
#define WLAN_RNR_IE_MIN_LEN 5
/* HT capability flags */
#define WLAN_HTCAP_C_ADVCODING 0x0001
@ -392,6 +393,7 @@ enum element_ie {
WLAN_ELEMID_AID = 197,
WLAN_ELEMID_QUIET_CHANNEL = 198,
WLAN_ELEMID_OP_MODE_NOTIFY = 199,
WLAN_ELEMID_REDUCED_NEIGHBOR_REPORT = 201,
WLAN_ELEMID_VENDOR = 221,
WLAN_ELEMID_FILS_INDICATION = 240,
WLAN_ELEMID_EXTN_ELEM = 255,

View file

@ -35,6 +35,7 @@ typedef uint32_t wlan_scan_id;
#define WLAN_SCAN_MAX_NUM_SSID 16
#define WLAN_SCAN_MAX_NUM_BSSID 4
#define MAX_RNR_BSS 5
#define SCM_CANCEL_SCAN_WAIT_TIME 50
#define SCM_CANCEL_SCAN_WAIT_ITERATION 600
@ -154,6 +155,7 @@ struct element_info {
* @fils_indication: pointer to FILS indication ie
* @esp: pointer to ESP indication ie
* @mbo_oce: pointer to mbo/oce indication ie
* @rnrie: reduced neighbor report IE
* @adaptive_11r: pointer to adaptive 11r IE
*/
struct ie_list {
@ -203,6 +205,7 @@ struct ie_list {
uint8_t *esp;
uint8_t *mbo_oce;
uint8_t *muedca;
uint8_t *rnrie;
uint8_t *extender;
uint8_t *adaptive_11r;
};
@ -278,6 +281,82 @@ struct scan_mbssid_info {
uint8_t trans_bssid[QDF_MAC_ADDR_SIZE];
};
/**
* struct rnr_bss_info - Reduced Neighbor Report BSS information
* @neighbor_ap_tbtt_offset: Neighbor AP TBTT offset
* @channel_number: channel number
* @operating_class: operting class
* @bssid: BSS MAC address
* @short_ssid: short ssid
* @bss_params: BSS parameters
*/
struct rnr_bss_info {
uint8_t neighbor_ap_tbtt_offset;
uint32_t channel_number;
uint32_t operating_class;
struct qdf_mac_addr bssid;
uint32_t short_ssid;
uint8_t bss_params;
};
/**
* struct tbtt_information_header - TBTT information header
* @tbbt_info_fieldtype: TBTT information field type
* @filter_neighbor_ap: filtered neighbor ap
* @tbbt_info_count: TBTT information count
* @tbtt_info_length: TBTT informaiton length
*/
struct tbtt_information_header {
uint16_t tbbt_info_fieldtype:2;
uint16_t filtered_neighbor_ap:1;
uint16_t reserved:1;
uint16_t tbtt_info_count:4;
uint16_t tbtt_info_length:8;
};
/**
* struct neighbor_ap_info_field - Neighbor information field
* @tbtt_info_header: TBTT information header
* @operting_class: operating class
* @channel_number: channel number
*/
struct neighbor_ap_info_field {
struct tbtt_information_header tbtt_header;
uint8_t operting_class;
uint8_t channel_number;
};
/**
* enum tbtt_information_field - TBTT information field
* @TBTT_NEIGHBOR_AP_OFFSET_ONLY: TBTT information field type
* @TBTT_NEIGHBOR_AP_BSS_PARAM: neighbor AP and bss param
* @TBTT_NEIGHBOR_AP_SHORTSSID: neighbor AP and Short ssid
* @TBTT_NEIGHBOR_AP_S_SSID_BSS_PARAM: neighbor AP, short ssid and bss param
* @TBTT_NEIGHBOR_AP_BSSID: neighbor AP and bssid
* @TBTT_NEIGHBOR_AP_BSSID_BSS_PARAM: neighbor AP, bssid and bss param
* @TBTT_NEIGHBOR_AP_BSSSID_S_SSID: neighbor AP, bssid and short ssid
* @TBTT_NEIGHBOR_AP_BSSID_S_SSID_BSS_PARAM: neighbor AP, bssid, short ssid
* and bss params
*/
enum tbtt_information_field {
TBTT_NEIGHBOR_AP_OFFSET_ONLY = 1,
TBTT_NEIGHBOR_AP_BSS_PARAM = 2,
TBTT_NEIGHBOR_AP_SHORTSSID = 5,
TBTT_NEIGHBOR_AP_S_SSID_BSS_PARAM = 6,
TBTT_NEIGHBOR_AP_BSSID = 7,
TBTT_NEIGHBOR_AP_BSSID_BSS_PARAM = 8,
TBTT_NEIGHBOR_AP_BSSSID_S_SSID = 11,
TBTT_NEIGHBOR_AP_BSSID_S_SSID_BSS_PARAM = 12
};
/**
* struct reduced_neighbor_report - Reduced Neighbor Report
* @bss_info: RNR BSS Information
*/
struct reduced_neighbor_report {
struct rnr_bss_info bss_info[MAX_RNR_BSS];
};
/**
* struct scan_cache_entry: structure containing scan entry
* @frm_subtype: updated from beacon/probe
@ -306,6 +385,7 @@ struct scan_mbssid_info {
* @hidden_ssid_timestamp: boottime in microsec when hidden
* ssid was received
* @mbssid_info: Multi bssid information
* @rnr: Reduced neighbor report information
* @channel: channel info on which AP is present
* @channel_mismatch: if channel received in metadata
* doesnot match the one in beacon
@ -350,6 +430,7 @@ struct scan_cache_entry {
qdf_time_t rssi_timestamp;
qdf_time_t hidden_ssid_timestamp;
struct scan_mbssid_info mbssid_info;
struct reduced_neighbor_report rnr;
struct channel_info channel;
bool channel_mismatch;
struct mlme_info mlme_info;

View file

@ -28,6 +28,9 @@
#include <wlan_reg_services_api.h>
#define MAX_IE_LEN 1024
#define SHORT_SSID_LEN 4
#define NEIGHBOR_AP_LEN 1
#define BSS_PARAMS_LEN 1
const char*
util_scan_get_ev_type_name(enum scan_event_type type)
@ -559,6 +562,116 @@ util_scan_is_hidden_ssid(struct ie_ssid *ssid)
return true;
}
static QDF_STATUS
util_scan_update_rnr(struct rnr_bss_info *rnr,
struct neighbor_ap_info_field *ap_info,
uint8_t **data)
{
uint16_t fieldtype;
uint8_t *tmp = *data;
fieldtype = ap_info->tbtt_header.tbbt_info_fieldtype;
switch (fieldtype) {
case TBTT_NEIGHBOR_AP_OFFSET_ONLY:
/* Dont store it skip*/
*data = tmp + NEIGHBOR_AP_LEN;
break;
case TBTT_NEIGHBOR_AP_BSS_PARAM:
/* Dont store it skip*/
break;
case TBTT_NEIGHBOR_AP_SHORTSSID:
rnr->channel_number = ap_info->channel_number;
rnr->operating_class = ap_info->operting_class;
qdf_mem_copy(&rnr->short_ssid, &tmp[1], SHORT_SSID_LEN);
*data = tmp + NEIGHBOR_AP_LEN + SHORT_SSID_LEN;
break;
case TBTT_NEIGHBOR_AP_S_SSID_BSS_PARAM:
rnr->channel_number = ap_info->channel_number;
rnr->operating_class = ap_info->operting_class;
qdf_mem_copy(&rnr->short_ssid, &tmp[1], SHORT_SSID_LEN);
rnr->bss_params = tmp[5];
*data = tmp + NEIGHBOR_AP_LEN + SHORT_SSID_LEN + BSS_PARAMS_LEN;
break;
case TBTT_NEIGHBOR_AP_BSSID:
rnr->channel_number = ap_info->channel_number;
rnr->operating_class = ap_info->operting_class;
qdf_mem_copy(&rnr->bssid, &tmp[1], QDF_MAC_ADDR_SIZE);
*data = tmp + NEIGHBOR_AP_LEN + QDF_MAC_ADDR_SIZE;
break;
case TBTT_NEIGHBOR_AP_BSSID_BSS_PARAM:
rnr->channel_number = ap_info->channel_number;
rnr->operating_class = ap_info->operting_class;
qdf_mem_copy(&rnr->bssid, &tmp[1], QDF_MAC_ADDR_SIZE);
rnr->bss_params = tmp[7];
*data = tmp + NEIGHBOR_AP_LEN + QDF_MAC_ADDR_SIZE
+ BSS_PARAMS_LEN;
break;
case TBTT_NEIGHBOR_AP_BSSSID_S_SSID:
rnr->channel_number = ap_info->channel_number;
rnr->operating_class = ap_info->operting_class;
qdf_mem_copy(&rnr->bssid, &tmp[1], QDF_MAC_ADDR_SIZE);
qdf_mem_copy(&rnr->short_ssid, &tmp[7], SHORT_SSID_LEN);
*data = tmp + NEIGHBOR_AP_LEN + QDF_MAC_ADDR_SIZE
+ SHORT_SSID_LEN;
break;
case TBTT_NEIGHBOR_AP_BSSID_S_SSID_BSS_PARAM:
rnr->channel_number = ap_info->channel_number;
rnr->operating_class = ap_info->operting_class;
qdf_mem_copy(&rnr->bssid, &tmp[1], QDF_MAC_ADDR_SIZE);
qdf_mem_copy(&rnr->short_ssid, &tmp[7], SHORT_SSID_LEN);
rnr->bss_params = tmp[11];
*data = tmp + NEIGHBOR_AP_LEN + QDF_MAC_ADDR_SIZE
+ SHORT_SSID_LEN + BSS_PARAMS_LEN;
break;
default:
scm_debug("Wrong fieldtype");
}
return QDF_STATUS_SUCCESS;
}
static QDF_STATUS
util_scan_parse_rnr_ie(struct scan_cache_entry *scan_entry,
struct ie_header *ie)
{
uint32_t rnr_ie_len;
uint16_t tbtt_count, tbtt_length, i, fieldtype;
uint8_t *data;
struct neighbor_ap_info_field *neighbor_ap_info;
rnr_ie_len = ie->ie_len;
data = (uint8_t *)ie + sizeof(struct ie_header);
while (data < (uint8_t *)ie + rnr_ie_len + 2) {
neighbor_ap_info = (struct neighbor_ap_info_field *)data;
tbtt_count = neighbor_ap_info->tbtt_header.tbtt_info_count;
tbtt_length = neighbor_ap_info->tbtt_header.tbtt_info_length;
fieldtype = neighbor_ap_info->tbtt_header.tbbt_info_fieldtype;
scm_debug("channel number %d, op class %d",
neighbor_ap_info->channel_number,
neighbor_ap_info->operting_class);
scm_debug("tbtt_count %d, tbtt_length %d, fieldtype %d",
tbtt_count, tbtt_length, fieldtype);
for (i = 0; i < tbtt_count && i < MAX_RNR_BSS; i++) {
data = data + sizeof(struct neighbor_ap_info_field);
util_scan_update_rnr(&scan_entry->rnr.bss_info[i],
neighbor_ap_info,
&data);
}
}
return QDF_STATUS_SUCCESS;
}
static QDF_STATUS
util_scan_parse_extn_ie(struct scan_cache_entry *scan_params,
struct ie_header *ie)
@ -877,6 +990,14 @@ util_scan_populate_bcn_ie_list(struct scan_cache_entry *scan_params,
if (QDF_IS_STATUS_ERROR(status))
goto err_status;
break;
case WLAN_ELEMID_REDUCED_NEIGHBOR_REPORT:
if (ie->ie_len < WLAN_RNR_IE_MIN_LEN)
goto err;
scan_params->ie_list.rnrie = (uint8_t *)ie;
status = util_scan_parse_rnr_ie(scan_params, ie);
if (QDF_IS_STATUS_ERROR(status))
goto err_status;
break;
default:
break;
}