Ver código fonte

qcacld-3.0: Add support for new cfg80211 connect api

qcacld-2.0 to qcacld-3.0 propagation

The new cfg80211 connect api 'cfg80211_connect_bss' takes
a new input parameter, the connected bss. This is required
for the kernel to map its current_bss to the bss on the
correct channel when more than one bssid, ssid pair is
present on different channels with the kernel. Without this
the kernel might report a wrong channel as the associated
channel. Hence add support in driver to use the new connect
api.

Change-Id: I1e5ded1b40ca324469917acebf17a03cc1e1c679
CRs-Fixed: 1008794
(cherry picked from commit fc06d173ce8155c1ee470f0a135490d42237d66e)
Anurag Chouhan 8 anos atrás
pai
commit
c40929266c

+ 5 - 0
core/hdd/inc/wlan_hdd_main.h

@@ -1825,6 +1825,11 @@ int hdd_wlan_start_modules(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter,
 			   bool reinit);
 int hdd_wlan_stop_modules(hdd_context_t *hdd_ctx, bool shutdown);
 int hdd_start_adapter(hdd_adapter_t *adapter);
+void hdd_connect_result(struct net_device *dev, const u8 *bssid,
+			tCsrRoamInfo *roam_info, const u8 *req_ie,
+			size_t req_ie_len, const u8 *resp_ie,
+			size_t resp_ie_len, u16 status, gfp_t gfp);
+
 #ifdef WLAN_FEATURE_FASTPATH
 void hdd_enable_fastpath(struct hdd_config *hdd_cfg,
 			 void *context);

+ 13 - 11
core/hdd/src/wlan_hdd_assoc.c

@@ -2649,9 +2649,10 @@ static QDF_STATUS hdd_association_completion_handler(hdd_adapter_t *pAdapter,
 					hddLog(LOG1,
 					       FL("ft_carrier_on is %d, sending connect indication"),
 					       ft_carrier_on);
-					cfg80211_connect_result(dev,
+					hdd_connect_result(dev,
 								pRoamInfo->
 								bssid.bytes,
+								pRoamInfo,
 								pFTAssocReq,
 								assocReqlen,
 								pFTAssocRsp,
@@ -2692,9 +2693,10 @@ static QDF_STATUS hdd_association_completion_handler(hdd_adapter_t *pAdapter,
 						       roamResult, roamStatus);
 
 						/* inform connect result to nl80211 */
-						cfg80211_connect_result(dev,
+						hdd_connect_result(dev,
 									pRoamInfo->
 									bssid.bytes,
+									pRoamInfo,
 									reqRsnIe,
 									reqRsnLength,
 									rspRsnIe,
@@ -2854,15 +2856,15 @@ static QDF_STATUS hdd_association_completion_handler(hdd_adapter_t *pAdapter,
 			if (eCSR_ROAM_RESULT_ASSOC_FAIL_CON_CHANNEL ==
 			    roamResult) {
 				if (pRoamInfo)
-					cfg80211_connect_result(dev,
+					hdd_connect_result(dev,
 						pRoamInfo->bssid.bytes,
-						NULL, 0, NULL, 0,
+						NULL, NULL, 0, NULL, 0,
 						WLAN_STATUS_ASSOC_DENIED_UNSPEC,
 						GFP_KERNEL);
 				else
-					cfg80211_connect_result(dev,
+					hdd_connect_result(dev,
 						pWextState->req_bssId.bytes,
-						NULL, 0, NULL, 0,
+						NULL, NULL, 0, NULL, 0,
 						WLAN_STATUS_ASSOC_DENIED_UNSPEC,
 						GFP_KERNEL);
 			} else {
@@ -2893,18 +2895,18 @@ static QDF_STATUS hdd_association_completion_handler(hdd_adapter_t *pAdapter,
 					 * applications to reconnect the station
 					 * with correct configuration.
 					 */
-					cfg80211_connect_result(dev,
-						pRoamInfo->bssid.bytes, NULL, 0,
-						NULL, 0,
+					hdd_connect_result(dev,
+						pRoamInfo->bssid.bytes,
+						NULL, NULL, 0, NULL, 0,
 						(isWep &&
 						 pRoamInfo->reasonCode) ?
 						pRoamInfo->reasonCode :
 						WLAN_STATUS_UNSPECIFIED_FAILURE,
 						GFP_KERNEL);
 				} else
-					cfg80211_connect_result(dev,
+					hdd_connect_result(dev,
 						pWextState->req_bssId.bytes,
-						NULL, 0, NULL, 0,
+						NULL, NULL, 0, NULL, 0,
 						WLAN_STATUS_UNSPECIFIED_FAILURE,
 						GFP_KERNEL);
 			}

+ 87 - 1
core/hdd/src/wlan_hdd_main.c

@@ -3649,6 +3649,92 @@ static bool hdd_is_interface_up(hdd_adapter_t *adapter)
 		return false;
 }
 
+#if defined CFG80211_CONNECT_BSS
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)) \
+	&& !defined(WITH_BACKPORTS) && !defined(IEEE80211_PRIVACY)
+struct cfg80211_bss *hdd_cfg80211_get_bss(struct wiphy *wiphy,
+					  struct ieee80211_channel *channel,
+					  const u8 *bssid, const u8 *ssid,
+					  size_t ssid_len)
+{
+	return cfg80211_get_bss(wiphy, channel, bssid,
+				ssid, ssid_len,
+				WLAN_CAPABILITY_ESS,
+				WLAN_CAPABILITY_ESS);
+}
+#else
+struct cfg80211_bss *hdd_cfg80211_get_bss(struct wiphy *wiphy,
+					  struct ieee80211_channel *channel,
+					  const u8 *bssid, const u8 *ssid,
+					  size_t ssid_len)
+{
+	return cfg80211_get_bss(wiphy, channel, bssid,
+				ssid, ssid_len,
+				IEEE80211_BSS_TYPE_ESS,
+				IEEE80211_PRIVACY_ANY);
+}
+#endif
+#endif
+
+
+/**
+ * hdd_connect_result() - API to send connection status to supplicant
+ * @dev: network device
+ * @bssid: bssid to which we want to associate
+ * @roam_info: information about connected bss
+ * @req_ie: Request Information Element
+ * @req_ie_len: len of the req IE
+ * @resp_ie: Response IE
+ * @resp_ie_len: len of ht response IE
+ * @status: status
+ * @gfp: Kernel Flag
+ *
+ * The API is a wrapper to send connection status to supplicant
+ * and allow runtime suspend
+ *
+ * Return: Void
+ */
+#if defined CFG80211_CONNECT_BSS
+void hdd_connect_result(struct net_device *dev, const u8 *bssid,
+			tCsrRoamInfo *roam_info, const u8 *req_ie,
+			size_t req_ie_len, const u8 *resp_ie,
+			size_t resp_ie_len, u16 status, gfp_t gfp)
+{
+	hdd_adapter_t *padapter = (hdd_adapter_t *) netdev_priv(dev);
+	struct cfg80211_bss *bss = NULL;
+
+	if (WLAN_STATUS_SUCCESS == status) {
+		struct ieee80211_channel *chan;
+		int freq;
+		int chan_no = roam_info->pBssDesc->channelId;
+
+		if (chan_no <= 14)
+			freq = ieee80211_channel_to_frequency(chan_no,
+			IEEE80211_BAND_2GHZ);
+		else
+			freq = ieee80211_channel_to_frequency(chan_no,
+			IEEE80211_BAND_5GHZ);
+
+		chan = ieee80211_get_channel(padapter->wdev.wiphy, freq);
+		bss = hdd_cfg80211_get_bss(padapter->wdev.wiphy, chan, bssid,
+			roam_info->u.pConnectedProfile->SSID.ssId,
+			roam_info->u.pConnectedProfile->SSID.length);
+	}
+	cfg80211_connect_bss(dev, bssid, bss, req_ie, req_ie_len,
+		resp_ie, resp_ie_len, status, gfp);
+}
+#else
+void hdd_connect_result(struct net_device *dev, const u8 *bssid,
+			tCsrRoamInfo *roam_info, const u8 *req_ie,
+			size_t req_ie_len, const u8 *resp_ie,
+			size_t resp_ie_len, u16 status, gfp_t gfp)
+{
+	cfg80211_connect_result(dev, bssid, req_ie, req_ie_len,
+				resp_ie, resp_ie_len, status, gfp);
+}
+#endif
+
+
 QDF_STATUS hdd_start_all_adapters(hdd_context_t *hdd_ctx)
 {
 	hdd_adapter_list_node_t *adapterNode = NULL, *pNext = NULL;
@@ -3707,7 +3793,7 @@ QDF_STATUS hdd_start_all_adapters(hdd_context_t *hdd_ctx)
 				 * Indicate connect failure to supplicant if we were in the
 				 * process of connecting
 				 */
-				cfg80211_connect_result(adapter->dev, NULL,
+				hdd_connect_result(adapter->dev, NULL, NULL,
 							NULL, 0, NULL, 0,
 							WLAN_STATUS_ASSOC_DENIED_UNSPEC,
 							GFP_KERNEL);