ソースを参照

qcacmn: Add support to include selective scan IEs only

qcacld-2.0 to qcacmn propagation

Add support to include only selective IEs in probe requests in
order to improve user's privacy.

Change-Id: I59cf4181f60f5b4cd87a32fbcf29160d87ca59c8
CRs-Fixed: 1105495
Rajeev Kumar Sirasanagandla 7 年 前
コミット
a3f4a29130

+ 8 - 1
os_if/linux/scan/src/wlan_cfg80211_scan.c

@@ -549,6 +549,8 @@ int wlan_cfg80211_sched_scan_start(struct wlan_objmgr_pdev *pdev,
 	ucfg_scan_register_pno_cb(psoc,
 		wlan_cfg80211_pno_callback, NULL);
 	ucfg_scan_get_pno_def_params(vdev, req);
+	if (ucfg_ie_whitelist_enabled(psoc, vdev))
+		ucfg_copy_ie_whitelist_attrs(psoc, &req->ie_whitelist);
 	status = ucfg_scan_pno_start(vdev, req);
 	if (QDF_IS_STATUS_ERROR(status)) {
 		cfg80211_err("Failed to enable PNO");
@@ -1281,8 +1283,13 @@ int wlan_cfg80211_scan(struct wlan_objmgr_pdev *pdev,
 				request->ie_len);
 	}
 
-	if (!is_p2p_scan)
+	if (!is_p2p_scan) {
 		wlan_scan_rand_attrs(vdev, request, req);
+		if (ucfg_ie_whitelist_enabled(psoc, vdev) &&
+		    ucfg_copy_ie_whitelist_attrs(psoc,
+					&req->scan_req.ie_whitelist))
+			req->scan_req.scan_f_en_ie_whitelist_in_probe = true;
+	}
 
 	if (request->flags & NL80211_SCAN_FLAG_FLUSH)
 		ucfg_scan_flush_results(pdev, NULL);

+ 4 - 0
umac/scan/core/src/wlan_scan_main.h

@@ -365,6 +365,9 @@ struct scan_cb {
  * @requesters: requester allocation pool
  * @scan_ids:   last allocated scan id
  * @global_evhandlers:  registered scan event handlers
+ * @pdev_info: pointer to pdev info
+ * @pno_cfg: default pno configuration
+ * @ie_whitelist: default ie whitelist attrs
  */
 struct wlan_scan_obj {
 	qdf_spinlock_t lock;
@@ -376,6 +379,7 @@ struct wlan_scan_obj {
 	struct global_scan_ev_handlers global_evhandlers;
 	struct pdev_scan_info pdev_info[WLAN_UMAC_MAX_PDEVS];
 	struct pno_def_config pno_cfg;
+	struct probe_req_whitelist_attr ie_whitelist;
 };
 
 /**

+ 23 - 0
umac/scan/dispatcher/inc/wlan_scan_public_structs.h

@@ -58,6 +58,9 @@ typedef uint32_t wlan_scan_id;
 /* Increase dwell time for P2P search in ms */
 #define P2P_SEARCH_DWELL_TIME_INC 20
 
+#define PROBE_REQ_BITMAP_LEN 8
+#define MAX_PROBE_REQ_OUIS 16
+
 /* forward declaration */
 struct wlan_objmgr_vdev;
 struct wlan_objmgr_pdev;
@@ -479,6 +482,20 @@ struct scan_random_attr {
 	uint8_t mac_mask[QDF_MAC_ADDR_SIZE];
 };
 
+/**
+ * struct probe_req_whitelist_attr - holds probe req ie whitelist attrs
+ * @white_list: enable/disable whitelist
+ * @ie_bitmap: bitmap of IEs to be enabled
+ * @num_vendor_oui: number of vendor OUIs
+ * @voui: vendor oui buffer
+ */
+struct probe_req_whitelist_attr {
+	bool white_list;
+	uint32_t ie_bitmap[PROBE_REQ_BITMAP_LEN];
+	uint32_t num_vendor_oui;
+	uint32_t voui[MAX_PROBE_REQ_OUIS];
+};
+
 /**
  * struct scan_req_params - start scan request parameter
  * @scan_id: scan id
@@ -546,6 +563,7 @@ struct scan_random_attr {
  * @ssid: ssid list
  * @bssid_list: Lisst of bssid to scan
  * @scan_random: scan randomization params
+ * @ie_whitelist: probe req IE whitelist attrs
  * @extraie: list of optional/vendor specific ie's to be added in probe requests
  * @htcap: htcap ie
  * @vhtcap: vhtcap ie
@@ -625,6 +643,7 @@ struct scan_req_params {
 	struct wlan_ssid ssid[WLAN_SCAN_MAX_NUM_SSID];
 	struct qdf_mac_addr bssid_list[WLAN_SCAN_MAX_NUM_BSSID];
 	struct scan_random_attr scan_random;
+	struct probe_req_whitelist_attr ie_whitelist;
 	struct element_info extraie;
 	struct element_info htcap;
 	struct element_info vhtcap;
@@ -897,6 +916,7 @@ struct pno_nw_type {
  * to be triggered.
  * @networks_list: Preferred network list
  * @scan_random: scan randomization params
+ * @ie_whitelist: probe req IE whitelist attrs
  *
  * E.g.
  *	{ fast_scan_period=120, fast_scan_max_cycles=2,
@@ -920,6 +940,7 @@ struct pno_scan_req_params {
 	uint32_t channel_prediction_full_scan;
 	struct pno_nw_type networks_list[SCAN_PNO_MAX_SUPP_NETWORKS];
 	struct scan_random_attr scan_random;
+	struct probe_req_whitelist_attr ie_whitelist;
 };
 
 /**
@@ -962,6 +983,7 @@ struct pno_user_cfg {
  * @rssi_cat_gap: set rssi category gap
  * @scan_dwell_time_mode: Adaptive dweltime mode
  * @pno_cfg: Pno related config params
+ * @ie_whitelist: probe req IE whitelist attrs
  */
 struct scan_user_cfg {
 	uint32_t active_dwell;
@@ -979,6 +1001,7 @@ struct scan_user_cfg {
 	uint32_t rssi_cat_gap;
 	enum scan_dwelltime_adaptive_mode scan_dwell_time_mode;
 	struct pno_user_cfg pno_cfg;
+	struct probe_req_whitelist_attr ie_whitelist;
 };
 
 /**

+ 25 - 0
umac/scan/dispatcher/inc/wlan_scan_ucfg_api.h

@@ -465,4 +465,29 @@ QDF_STATUS ucfg_scan_psoc_close(struct wlan_objmgr_psoc *psoc);
  */
 uint32_t ucfg_scan_get_max_active_scans(struct wlan_objmgr_psoc *psoc);
 
+/**
+ * ucfg_ie_whitelist_enabled() - Checks for IE whitelisting enable
+ * @psoc: pointer to psoc object
+ * @vdev: pointer to vdev
+ *
+ * This function is used to check whether IE whitelisting is enabled or not
+ *
+ * Return: If enabled returns true else returns false
+ */
+bool ucfg_ie_whitelist_enabled(struct wlan_objmgr_psoc *psoc,
+			       struct wlan_objmgr_vdev *vdev);
+
+/**
+ * ucfg_copy_ie_whitelist_attrs() - Populate probe req IE whitelist attrs
+ * @psoc: pointer to psoc object
+ * @ie_whitelist: output parameter to hold ie whitelist attrs
+ *
+ * If IE whitelisting is enabled then invoke this function to copy
+ * IE whitelisting attrs from wlan scan object
+ *
+ * Return: true - successful copy
+ *         false - copy failed
+ */
+bool ucfg_copy_ie_whitelist_attrs(struct wlan_objmgr_psoc *psoc,
+				struct probe_req_whitelist_attr *ie_whitelist);
 #endif

+ 35 - 0
umac/scan/dispatcher/src/wlan_scan_ucfg_api.c

@@ -1116,6 +1116,7 @@ QDF_STATUS ucfg_scan_update_user_config(struct wlan_objmgr_psoc *psoc,
 	scan_def->select_5ghz_margin = scan_cfg->select_5ghz_margin;
 	scan_def->adaptive_dwell_time_mode = scan_cfg->scan_dwell_time_mode;
 	scan_def->scan_f_chan_stat_evnt = scan_cfg->is_snr_monitoring_enabled;
+	scan_obj->ie_whitelist = scan_cfg->ie_whitelist;
 
 	ucfg_scan_assign_rssi_category(scan_def,
 			scan_cfg->scan_bucket_threshold,
@@ -1364,3 +1365,37 @@ ucfg_scan_get_max_active_scans(struct wlan_objmgr_psoc *psoc)
 
 	return scan_params->max_active_scans_allowed;
 }
+
+bool ucfg_copy_ie_whitelist_attrs(struct wlan_objmgr_psoc *psoc,
+				  struct probe_req_whitelist_attr *ie_whitelist)
+{
+	struct wlan_scan_obj *scan_obj = NULL;
+
+	scan_obj = wlan_psoc_get_scan_obj(psoc);
+	if (!scan_obj)
+		return false;
+
+	qdf_mem_copy(ie_whitelist, &scan_obj->ie_whitelist,
+		     sizeof(*ie_whitelist));
+
+	return true;
+}
+
+bool ucfg_ie_whitelist_enabled(struct wlan_objmgr_psoc *psoc,
+			       struct wlan_objmgr_vdev *vdev)
+{
+	struct wlan_scan_obj *scan_obj = NULL;
+
+	scan_obj = wlan_psoc_get_scan_obj(psoc);
+	if (!scan_obj)
+		return false;
+
+	if ((wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE) ||
+	    wlan_vdev_is_connected(vdev))
+		return false;
+
+	if (!scan_obj->ie_whitelist.white_list)
+		return false;
+
+	return true;
+}

+ 2 - 0
wmi/inc/wmi_unified_param.h

@@ -1816,11 +1816,13 @@ struct rssi_monitor_param {
  * @oui: oui parameters
  * @vdev_id: interface id
  * @enb_probe_req_sno_randomization: control probe req sequence no randomization
+ * @ie_whitelist: probe req IE whitelist attrs
  */
 struct scan_mac_oui {
 	uint8_t oui[WMI_WIFI_SCANNING_MAC_OUI_LENGTH];
 	uint32_t vdev_id;
 	bool enb_probe_req_sno_randomization;
+	struct probe_req_whitelist_attr ie_whitelist;
 };
 
 #define WMI_PASSPOINT_REALM_LEN 256

+ 125 - 3
wmi/src/wmi_unified_tlv.c

@@ -2176,6 +2176,58 @@ void wmi_copy_scan_random_mac(uint8_t *mac, uint8_t *mask,
 	WMI_CHAR_ARRAY_TO_MAC_ADDR(mask, mac_mask);
 }
 
+/*
+ * wmi_fill_vendor_oui() - fill vendor OUIs
+ * @buf_ptr: pointer to wmi tlv buffer
+ * @num_vendor_oui: number of vendor OUIs to be filled
+ * @param_voui: pointer to OUI buffer
+ *
+ * This function populates the wmi tlv buffer when vendor specific OUIs are
+ * present.
+ *
+ * Return: None
+ */
+static inline
+void wmi_fill_vendor_oui(uint8_t *buf_ptr, uint32_t num_vendor_oui,
+			 uint32_t *pvoui)
+{
+	wmi_vendor_oui *voui = NULL;
+	uint32_t i;
+
+	voui = (wmi_vendor_oui *)buf_ptr;
+
+	for (i = 0; i < num_vendor_oui; i++) {
+		WMITLV_SET_HDR(&voui[i].tlv_header,
+			       WMITLV_TAG_STRUC_wmi_vendor_oui,
+			       WMITLV_GET_STRUCT_TLVLEN(wmi_vendor_oui));
+		voui[i].oui_type_subtype = pvoui[i];
+	}
+}
+
+/*
+ * wmi_fill_ie_whitelist_attrs() - fill IE whitelist attrs
+ * @ie_bitmap: output pointer to ie bit map in cmd
+ * @num_vendor_oui: output pointer to num vendor OUIs
+ * @ie_whitelist: input parameter
+ *
+ * This function populates the IE whitelist attrs of scan, pno and
+ * scan oui commands for ie_whitelist parameter.
+ *
+ * Return: None
+ */
+static inline
+void wmi_fill_ie_whitelist_attrs(uint32_t *ie_bitmap,
+				 uint32_t *num_vendor_oui,
+				 struct probe_req_whitelist_attr *ie_whitelist)
+{
+	uint32_t i = 0;
+
+	for (i = 0; i < PROBE_REQ_BITMAP_LEN; i++)
+		ie_bitmap[i] = ie_whitelist->ie_bitmap[i];
+
+	*num_vendor_oui = ie_whitelist->num_vendor_oui;
+}
+
 /**
  *  send_scan_start_cmd_tlv() - WMI scan start function
  *  @param wmi_handle      : handle to WMI.
@@ -2196,6 +2248,7 @@ static QDF_STATUS send_scan_start_cmd_tlv(wmi_unified_t wmi_handle,
 	wmi_mac_addr *bssid;
 	int len = sizeof(*cmd);
 	uint8_t extraie_len_with_pad = 0;
+	struct probe_req_whitelist_attr *ie_whitelist = &params->ie_whitelist;
 
 	/* Length TLV placeholder for array of uint32_t */
 	len += WMI_TLV_HDR_SIZE;
@@ -2220,6 +2273,10 @@ static QDF_STATUS send_scan_start_cmd_tlv(wmi_unified_t wmi_handle,
 		roundup(params->extraie.len, sizeof(uint32_t));
 		len += extraie_len_with_pad;
 
+	len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of wmi_vendor_oui */
+	if (ie_whitelist->num_vendor_oui)
+		len += ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui);
+
 	/* Allocate the memory */
 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
 	if (!wmi_buf) {
@@ -2266,6 +2323,11 @@ static QDF_STATUS send_scan_start_cmd_tlv(wmi_unified_t wmi_handle,
 					 &cmd->mac_addr,
 					 &cmd->mac_mask);
 
+	if (ie_whitelist->white_list)
+		wmi_fill_ie_whitelist_attrs(cmd->ie_bitmap,
+					    &cmd->num_vendor_oui,
+					    ie_whitelist);
+
 	buf_ptr += sizeof(*cmd);
 	tmp_ptr = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE);
 	for (i = 0; i < params->num_chan; ++i)
@@ -2316,6 +2378,18 @@ static QDF_STATUS send_scan_start_cmd_tlv(wmi_unified_t wmi_handle,
 
 	buf_ptr += WMI_TLV_HDR_SIZE + extraie_len_with_pad;
 
+	/* probe req ie whitelisting */
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+		       ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui));
+
+	buf_ptr += WMI_TLV_HDR_SIZE;
+
+	if (cmd->num_vendor_oui) {
+		wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui,
+				    ie_whitelist->voui);
+		buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui);
+	}
+
 	ret = wmi_unified_cmd_send(
 			get_pdev_wmi_handle(wmi_handle, cmd->vdev_id), wmi_buf,
 				      len, WMI_START_SCAN_CMDID);
@@ -5216,8 +5290,11 @@ static QDF_STATUS send_scan_probe_setoui_cmd_tlv(wmi_unified_t wmi_handle,
 	uint32_t len;
 	uint8_t *buf_ptr;
 	uint32_t *oui_buf;
+	struct probe_req_whitelist_attr *ie_whitelist = &psetoui->ie_whitelist;
+
+	len = sizeof(*cmd) + WMI_TLV_HDR_SIZE +
+		ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui);
 
-	len = sizeof(*cmd);
 	wmi_buf = wmi_buf_alloc(wmi_handle, len);
 	if (!wmi_buf) {
 		WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
@@ -5242,6 +5319,25 @@ static QDF_STATUS send_scan_probe_setoui_cmd_tlv(wmi_unified_t wmi_handle,
 	if (psetoui->enb_probe_req_sno_randomization)
 		cmd->flags |= WMI_SCAN_PROBE_OUI_RANDOM_SEQ_NO_IN_PROBE_REQ;
 
+	if (ie_whitelist->white_list) {
+		wmi_fill_ie_whitelist_attrs(cmd->ie_bitmap,
+					    &cmd->num_vendor_oui,
+					    ie_whitelist);
+		cmd->flags |=
+			WMI_SCAN_PROBE_OUI_ENABLE_IE_WHITELIST_IN_PROBE_REQ;
+	}
+
+	buf_ptr += sizeof(*cmd);
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+		       ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui));
+	buf_ptr += WMI_TLV_HDR_SIZE;
+
+	if (cmd->num_vendor_oui != 0) {
+		wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui,
+				    ie_whitelist->voui);
+		buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui);
+	}
+
 	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
 				 WMI_SCAN_PROB_REQ_OUI_CMDID)) {
 		WMI_LOGE("%s: failed to send command", __func__);
@@ -7236,20 +7332,25 @@ static QDF_STATUS send_pno_start_cmd_tlv(wmi_unified_t wmi_handle,
 	uint8_t *buf_ptr;
 	uint8_t i;
 	int ret;
+	struct probe_req_whitelist_attr *ie_whitelist = &pno->ie_whitelist;
 
 	/*
 	 * TLV place holder for array nlo_configured_parameters(nlo_list)
 	 * TLV place holder for array of uint32_t channel_list
 	 * TLV place holder for chnnl prediction cfg
+	 * TLV place holder for array of wmi_vendor_oui
 	 */
 	len = sizeof(*cmd) +
-		WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE;
+		WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE +
+		WMI_TLV_HDR_SIZE;
 
 	len += sizeof(uint32_t) * QDF_MIN(pno->networks_list[0].channel_cnt,
 					  WMI_NLO_MAX_CHAN);
 	len += sizeof(nlo_configured_parameters) *
 	       QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS);
 	len += sizeof(nlo_channel_prediction_cfg);
+	len += sizeof(enlo_candidate_score_params);
+	len += sizeof(wmi_vendor_oui) * ie_whitelist->num_vendor_oui;
 
 	buf = wmi_buf_alloc(wmi_handle, len);
 	if (!buf) {
@@ -7363,10 +7464,31 @@ static QDF_STATUS send_pno_start_cmd_tlv(wmi_unified_t wmi_handle,
 			sizeof(nlo_channel_prediction_cfg));
 	buf_ptr += WMI_TLV_HDR_SIZE;
 	wmi_set_pno_channel_prediction(buf_ptr, pno);
-	buf_ptr += WMI_TLV_HDR_SIZE;
+	buf_ptr += sizeof(nlo_channel_prediction_cfg);
 	/** TODO: Discrete firmware doesn't have command/option to configure
 	 * App IE which comes from wpa_supplicant as of part PNO start request.
 	 */
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_enlo_candidate_score_param,
+		       WMITLV_GET_STRUCT_TLVLEN(enlo_candidate_score_params));
+	buf_ptr += sizeof(enlo_candidate_score_params);
+
+	if (ie_whitelist->white_list) {
+		cmd->flags |= WMI_NLO_CONFIG_ENABLE_IE_WHITELIST_IN_PROBE_REQ;
+		wmi_fill_ie_whitelist_attrs(cmd->ie_bitmap,
+					    &cmd->num_vendor_oui,
+					    ie_whitelist);
+	}
+
+	/* ie white list */
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+		       ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui));
+	buf_ptr += WMI_TLV_HDR_SIZE;
+	if (cmd->num_vendor_oui != 0) {
+		wmi_fill_vendor_oui(buf_ptr, cmd->num_vendor_oui,
+				    ie_whitelist->voui);
+		buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui);
+	}
+
 	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
 				   WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID);
 	if (ret) {