Browse Source

qcacld-3.0: Add logic to use common API to inform beacon

Duplicate API's are present in HDD and common code to inform the
beacon to kernel. This change removes the duplicate API from HDD
and use common API to inform beacon.

Change-Id: I1916ebd6d3c153f47533cde6a1e2e78ebaae55dc
CRs-Fixed: 2199760
Abhishek Singh 7 years ago
parent
commit
f05b0cb604

+ 2 - 2
core/hdd/src/wlan_hdd_assoc.c

@@ -4711,8 +4711,8 @@ hdd_sme_roam_callback(void *pContext, struct csr_roam_info *roam_info,
 
 	case eCSR_ROAM_UPDATE_SCAN_RESULT:
 		if ((NULL != roam_info) && (NULL != roam_info->pBssDesc)) {
-			bss_status = wlan_hdd_cfg80211_inform_bss_frame(
-					adapter, roam_info->pBssDesc);
+			bss_status = wlan_hdd_inform_bss_frame(adapter,
+							roam_info->pBssDesc);
 			if (NULL == bss_status)
 				hdd_debug("UPDATE_SCAN_RESULT returned NULL");
 			else

+ 91 - 149
core/hdd/src/wlan_hdd_cfg80211.c

@@ -16207,91 +16207,74 @@ struct cfg80211_bss *wlan_hdd_cfg80211_update_bss_list(
 	return bss;
 }
 
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 3, 0)) || \
-	defined(CFG80211_INFORM_BSS_FRAME_DATA)
-static struct cfg80211_bss *
-wlan_hdd_cfg80211_inform_bss_frame_data(struct wiphy *wiphy,
-		struct ieee80211_channel *chan,
-		struct ieee80211_mgmt *mgmt,
-		size_t frame_len,
-		int rssi, gfp_t gfp,
-		uint64_t boottime_ns)
-{
-	struct cfg80211_bss *bss_status  = NULL;
-	struct cfg80211_inform_bss data  = {0};
-
-	data.chan = chan;
-	data.boottime_ns = boottime_ns;
-	data.signal = rssi;
-	bss_status = cfg80211_inform_bss_frame_data(wiphy, &data, mgmt,
-						    frame_len, gfp);
-	return bss_status;
+#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
+static inline int
+wlan_hdd_get_frame_len(struct bss_description *bss_desc)
+{
+	return GET_IE_LEN_IN_BSS(bss_desc->length) + sizeof(qcom_ie_age);
 }
-#else
-static struct cfg80211_bss *
-wlan_hdd_cfg80211_inform_bss_frame_data(struct wiphy *wiphy,
-		struct ieee80211_channel *chan,
-		struct ieee80211_mgmt *mgmt,
-		size_t frame_len,
-		int rssi, gfp_t gfp,
-		uint64_t boottime_ns)
+
+static inline void wlan_hdd_add_age_ie(struct ieee80211_mgmt *mgmt,
+	uint32_t ie_length, struct bss_description *bss_desc)
 {
-	struct cfg80211_bss *bss_status = NULL;
+	qcom_ie_age *qie_age = NULL;
 
-	bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt, frame_len,
-					       rssi, gfp);
-	return bss_status;
+	/*
+	 * GPS Requirement: need age ie per entry. Using vendor specific.
+	 * Assuming this is the last IE, copy at the end
+	 */
+	ie_length -= sizeof(qcom_ie_age);
+	qie_age = (qcom_ie_age *)mgmt->u.probe_resp.variable + ie_length;
+	qie_age->element_id = QCOM_VENDOR_IE_ID;
+	qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
+	qie_age->oui_1 = QCOM_OUI1;
+	qie_age->oui_2 = QCOM_OUI2;
+	qie_age->oui_3 = QCOM_OUI3;
+	qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
+	/*
+	 * Lowi expects the timestamp of bss in units of 1/10 ms. In driver
+	 * all bss related timestamp is in units of ms. Due to this when scan
+	 * results are sent to lowi the scan age is high.To address this,
+	 * send age in units of 1/10 ms.
+	 */
+	qie_age->age = (uint32_t)(qdf_mc_timer_get_system_time() -
+				  bss_desc->received_time)/10;
+	qie_age->tsf_delta = bss_desc->tsf_delta;
+	memcpy(&qie_age->beacon_tsf, bss_desc->timeStamp,
+	       sizeof(qie_age->beacon_tsf));
+	memcpy(&qie_age->seq_ctrl, &bss_desc->seq_ctrl,
+	       sizeof(qie_age->seq_ctrl));
 }
-#endif
+#else
+static inline int
+wlan_hdd_get_frame_len(struct bss_description *bss_desc)
+{
+	return GET_IE_LEN_IN_BSS(bss_desc->length);
+}
+static inline void wlan_hdd_add_age_ie(struct ieee80211_mgmt *mgmt,
+	uint32_t ie_length, struct bss_description *bss_desc)
+{
+}
+#endif /* WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS */
+
 
-/**
- * wlan_hdd_cfg80211_inform_bss_frame() - inform bss details to NL80211
- * @adapter: Pointer to adapter
- * @bss_desc: Pointer to bss descriptor
- *
- * This function is used to inform the BSS details to nl80211 interface.
- *
- * Return: struct cfg80211_bss pointer
- */
 struct cfg80211_bss *
-wlan_hdd_cfg80211_inform_bss_frame(struct hdd_adapter *adapter,
-				   struct bss_description *bss_desc)
+wlan_hdd_inform_bss_frame(struct hdd_adapter *adapter,
+				     struct bss_description *bss_desc)
 {
-	/*
-	 * cfg80211_inform_bss() is not updating ie field of bss entry, if entry
-	 * already exists in bss data base of cfg80211 for that particular BSS
-	 * ID. Using cfg80211_inform_bss_frame to update the bss entry instead
-	 * of cfg80211_inform_bss, But this call expects mgmt packet as input.
-	 * As of now there is no possibility to get the mgmt(probe response)
-	 * frame from PE, converting bss_desc to ieee80211_mgmt(probe response)
-	 * and passing to cfg80211_inform_bss_frame.
-	 */
-	struct net_device *dev = adapter->dev;
-	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct wireless_dev *wdev = adapter->dev->ieee80211_ptr;
 	struct wiphy *wiphy = wdev->wiphy;
-	int chan_no = bss_desc->channelId;
-#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
-	qcom_ie_age *qie_age = NULL;
-	int ie_length =
-		GET_IE_LEN_IN_BSS(bss_desc->length) + sizeof(qcom_ie_age);
-#else
-	int ie_length = GET_IE_LEN_IN_BSS(bss_desc->length);
-#endif
+	int ie_length = wlan_hdd_get_frame_len(bss_desc);
 	const char *ie =
 		((ie_length != 0) ? (const char *)&bss_desc->ieFields : NULL);
-	unsigned int freq;
-	struct ieee80211_channel *chan;
-	struct ieee80211_mgmt *mgmt = NULL;
+	uint32_t freq, i;
 	struct cfg80211_bss *bss_status = NULL;
-	size_t frame_len = ie_length + offsetof(struct ieee80211_mgmt,
-						u.probe_resp.variable);
-	int rssi = 0;
 	struct hdd_context *hdd_ctx;
 	struct timespec ts;
 	struct hdd_config *cfg_param;
+	struct wlan_cfg80211_inform_bss bss_data = {0};
 
 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
-
 	/*
 	 * wlan_hdd_validate_context should not be used here, In validate ctx
 	 * start_modules_in_progress or stop_modules_in_progress is validated,
@@ -16301,7 +16284,7 @@ wlan_hdd_cfg80211_inform_bss_frame(struct hdd_adapter *adapter,
 	 * informing bss to kernel. Hence removing the validate context.
 	 */
 
-	if (NULL == hdd_ctx || NULL == hdd_ctx->config) {
+	if (!hdd_ctx || !hdd_ctx->config) {
 		hdd_debug("HDD context is Null");
 		return NULL;
 	}
@@ -16314,125 +16297,85 @@ wlan_hdd_cfg80211_inform_bss_frame(struct hdd_adapter *adapter,
 	}
 
 	cfg_param = hdd_ctx->config;
-	mgmt = qdf_mem_malloc((sizeof(struct ieee80211_mgmt) + ie_length));
-	if (!mgmt) {
+	bss_data.frame_len = ie_length + offsetof(struct ieee80211_mgmt,
+						  u.probe_resp.variable);
+	bss_data.mgmt = qdf_mem_malloc(bss_data.frame_len);
+	if (!bss_data.mgmt) {
 		hdd_err("memory allocation failed");
 		return NULL;
 	}
 
-	memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
+	memcpy(bss_data.mgmt->bssid, bss_desc->bssId, ETH_ALEN);
 
 	/* Android does not want the timestamp from the frame.
 	 * Instead it wants a monotonic increasing value
 	 */
 	get_monotonic_boottime(&ts);
-	mgmt->u.probe_resp.timestamp =
+	bss_data.mgmt->u.probe_resp.timestamp =
 		((u64) ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
 
-	mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
-	mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
+	bss_data.mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
+	bss_data.mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
 
-#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
-	/* GPS Requirement: need age ie per entry. Using vendor specific. */
-	/* Assuming this is the last IE, copy at the end */
-	ie_length -= sizeof(qcom_ie_age);
-	qie_age = (qcom_ie_age *) (mgmt->u.probe_resp.variable + ie_length);
-	qie_age->element_id = QCOM_VENDOR_IE_ID;
-	qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
-	qie_age->oui_1 = QCOM_OUI1;
-	qie_age->oui_2 = QCOM_OUI2;
-	qie_age->oui_3 = QCOM_OUI3;
-	qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
-	/*
-	 * Lowi expects the timestamp of bss in units of 1/10 ms. In driver
-	 * all bss related timestamp is in units of ms. Due to this when scan
-	 * results are sent to lowi the scan age is high.To address this,
-	 * send age in units of 1/10 ms.
-	 */
-	qie_age->age =
-		(uint32_t)(qdf_mc_timer_get_system_time() - bss_desc->received_time)/10;
-	qie_age->tsf_delta = bss_desc->tsf_delta;
-	memcpy(&qie_age->beacon_tsf, bss_desc->timeStamp,
-	       sizeof(qie_age->beacon_tsf));
-	memcpy(&qie_age->seq_ctrl, &bss_desc->seq_ctrl,
-	       sizeof(qie_age->seq_ctrl));
-#endif
+	wlan_hdd_add_age_ie(bss_data.mgmt, ie_length, bss_desc);
 
-	memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
+	memcpy(bss_data.mgmt->u.probe_resp.variable, ie, ie_length);
 	if (bss_desc->fProbeRsp) {
-		mgmt->frame_control |=
+		bss_data.mgmt->frame_control |=
 			(u16) (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
 	} else {
-		mgmt->frame_control |=
+		bss_data.mgmt->frame_control |=
 			(u16) (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
 	}
 
-	if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_ghz) &&
+	if (bss_desc->channelId <= ARRAY_SIZE(hdd_channels_2_4_ghz) &&
 	    (wiphy->bands[HDD_NL80211_BAND_2GHZ] != NULL)) {
 		freq =
-			ieee80211_channel_to_frequency(chan_no,
+			ieee80211_channel_to_frequency(bss_desc->channelId,
 						       HDD_NL80211_BAND_2GHZ);
-	} else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_ghz))
+	} else if ((bss_desc->channelId > ARRAY_SIZE(hdd_channels_2_4_ghz))
 		   && (wiphy->bands[HDD_NL80211_BAND_5GHZ] != NULL)) {
 		freq =
-			ieee80211_channel_to_frequency(chan_no,
+			ieee80211_channel_to_frequency(bss_desc->channelId,
 						       HDD_NL80211_BAND_5GHZ);
 	} else {
-		hdd_err("Invalid channel: %d", chan_no);
-		qdf_mem_free(mgmt);
+		hdd_err("Invalid channel: %d", bss_desc->channelId);
+		qdf_mem_free(bss_data.mgmt);
 		return NULL;
 	}
 
-	chan = ieee80211_get_channel(wiphy, freq);
-	/* When the band is changed on the fly using the GUI, three things are done
-	 * 1. scan abort
-	 * 2. flush scan results from cache
-	 * 3. update the band with the new band user specified (refer to the
-	 * hdd_set_band_helper function) as part of the scan abort, message will be
-	 * queued to PE and we proceed with flushing and changinh the band.
-	 * PE will stop the scanning further and report back the results what ever
-	 * it had till now by calling the call back function.
-	 * if the time between update band and scandone call back is sufficient
-	 * enough the band change reflects in SME, SME validates the channels
-	 * and discards the channels correponding to previous band and calls back
-	 * with zero bss results. but if the time between band update and scan done
-	 * callback is very small then band change will not reflect in SME and SME
-	 * reports to HDD all the channels correponding to previous band.this is due
-	 * to race condition.but those channels are invalid to the new band and so
-	 * this function ieee80211_get_channel will return NULL.Each time we
-	 * report scan result with this pointer null warning kernel trace is printed.
-	 * if the scan results contain large number of APs continuosly kernel
-	 * warning trace is printed and it will lead to apps watch dog bark.
-	 * So drop the bss and continue to next bss.
-	 */
-	if (chan == NULL) {
+	bss_data.chan = ieee80211_get_channel(wiphy, freq);
+	if (!bss_data.chan) {
 		hdd_err("chan pointer is NULL, chan_no: %d freq: %d",
-			chan_no, freq);
-		qdf_mem_free(mgmt);
+			bss_desc->channelId, freq);
+		qdf_mem_free(bss_data.mgmt);
 		return NULL;
 	}
 
-	/* Based on .ini configuration, raw rssi can be reported for bss.
+	/*
+	 * Based on .ini configuration, raw rssi can be reported for bss.
 	 * Raw rssi is typically used for estimating power.
 	 */
-
-	rssi = (cfg_param->inform_bss_rssi_raw) ? bss_desc->rssi_raw :
+	bss_data.rssi = (cfg_param->inform_bss_rssi_raw) ? bss_desc->rssi_raw :
 			bss_desc->rssi;
 
 	/* Supplicant takes the signal strength in terms of mBm(100*dBm) */
-	rssi = QDF_MIN(rssi, 0) * 100;
+	bss_data.rssi = QDF_MIN(bss_data.rssi, 0) * 100;
+
+	bss_data.boottime_ns = bss_desc->scansystimensec;
+
+	/* Set all per chain rssi as invalid */
+	for (i = 0; i < WLAN_MGMT_TXRX_HOST_MAX_ANTENNA; i++)
+		bss_data.per_chain_snr[i] = WLAN_INVALID_PER_CHAIN_RSSI;
 
 	hdd_debug("BSSID: " MAC_ADDRESS_STR " Channel:%d RSSI:%d TSF %u",
-	       MAC_ADDR_ARRAY(mgmt->bssid), chan->center_freq,
-	       (int)(rssi / 100),
+	       MAC_ADDR_ARRAY(bss_data.mgmt->bssid), bss_data.chan->center_freq,
+	       (int)(bss_data.rssi / 100),
 	       bss_desc->timeStamp[0]);
 
-	bss_status = wlan_hdd_cfg80211_inform_bss_frame_data(wiphy, chan, mgmt,
-							     frame_len, rssi,
-							     GFP_KERNEL,
-							     bss_desc->scansystimensec);
+	bss_status = wlan_cfg80211_inform_bss_frame_data(wiphy, &bss_data);
 	hdd_ctx->beacon_probe_rsp_cnt_per_scan++;
-	qdf_mem_free(mgmt);
+	qdf_mem_free(bss_data.mgmt);
 	return bss_status;
 }
 
@@ -16457,11 +16400,10 @@ wlan_hdd_cfg80211_update_bss_db(struct hdd_adapter *adapter,
 	sme_roam_get_connect_profile(hHal, adapter->session_id, &roamProfile);
 
 	if (NULL != roamProfile.pBssDesc) {
-		bss = wlan_hdd_cfg80211_inform_bss_frame(adapter,
-							 roamProfile.pBssDesc);
+		bss = wlan_hdd_inform_bss_frame(adapter, roamProfile.pBssDesc);
 
 		if (NULL == bss)
-			hdd_debug("wlan_hdd_cfg80211_inform_bss_frame returned NULL");
+			hdd_debug("wlan_hdd_inform_bss_frame returned NULL");
 
 		sme_roam_free_connect_profile(&roamProfile);
 	} else {

+ 3 - 3
core/hdd/src/wlan_hdd_cfg80211.h

@@ -434,7 +434,7 @@ static inline void wlan_hdd_cfg80211_indicate_disconnect(struct net_device *dev,
 #endif
 
 /**
- * wlan_hdd_cfg80211_inform_bss_frame() - inform bss details to NL80211
+ * wlan_hdd_inform_bss_frame() - inform bss details to NL80211
  * @adapter: Pointer to adapter
  * @bss_desc: Pointer to bss descriptor
  *
@@ -443,8 +443,8 @@ static inline void wlan_hdd_cfg80211_indicate_disconnect(struct net_device *dev,
  * Return: struct cfg80211_bss pointer
  */
 struct cfg80211_bss *
-wlan_hdd_cfg80211_inform_bss_frame(struct hdd_adapter *adapter,
-				   struct bss_description *bss_desc);
+wlan_hdd_inform_bss_frame(struct hdd_adapter *adapter,
+				     struct bss_description *bss_desc);
 
 /**
  * wlan_hdd_change_hw_mode_for_given_chnl() - change HW mode for given channel

+ 5 - 1
core/sme/src/csr/csr_api_scan.c

@@ -1176,7 +1176,7 @@ static void csr_scan_add_result(tpAniSirGlobal mac_ctx,
 	struct mgmt_rx_event_params rx_param = {0};
 	struct wlan_frame_hdr *hdr;
 	struct wlan_bcn_frame *fixed_frame;
-	uint32_t buf_len;
+	uint32_t buf_len, i;
 	tSirBssDescription *bss_desc;
 	enum mgmt_frame_type frm_type = MGMT_BEACON;
 
@@ -1194,6 +1194,10 @@ static void csr_scan_add_result(tpAniSirGlobal mac_ctx,
 	rx_param.rssi = bss_desc->rssi;
 	rx_param.tsf_delta = bss_desc->tsf_delta;
 
+	/* Set all per chain rssi as invalid */
+	for (i = 0; i < WLAN_MGMT_TXRX_HOST_MAX_ANTENNA; i++)
+		rx_param.rssi_ctl[i] = WLAN_INVALID_PER_CHAIN_RSSI;
+
 	buf_len = GET_IE_LEN_IN_BSS(bss_desc->length) +
 		+ offsetof(struct wlan_bcn_frame, ie) + sizeof(*hdr);