Kaynağa Gözat

qcacld-3.0: Accommodate channel bandwidth as input during channel switch

Add support to include channel bandwidth as one of the inputs to
decide the channel switch parameters. Currently only the target channel
is used as the input to decide the channel switch parameters. With this
fix, user specified channel bandwidth is also taken into consideration.

Change-Id: Ic49b24edde6cabc52aa2b38110763da82da6790d
CRs-Fixed: 955368
Chandrasekaran, Manishekar 9 yıl önce
ebeveyn
işleme
a74bb024b1

+ 1 - 1
core/hdd/inc/wlan_hdd_main.h

@@ -1545,7 +1545,7 @@ const char *hdd_get_fwpath(void);
 void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind);
 hdd_adapter_t *hdd_get_adapter_by_sme_session_id(hdd_context_t *hdd_ctx,
 						uint32_t sme_session_id);
-
+phy_ch_width hdd_map_nl_chan_width(enum nl80211_chan_width ch_width);
 uint8_t wlan_hdd_find_opclass(tHalHandle hal, uint8_t channel,
 			uint8_t bw_offset);
 

+ 4 - 1
core/hdd/src/wlan_hdd_cfg80211.c

@@ -11115,6 +11115,7 @@ static int __wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
 	uint8_t channel;
 	uint16_t freq;
 	int ret;
+	phy_ch_width ch_width;
 
 	hddLog(LOG1, FL("Set Freq %d"),
 		  csa_params->chandef.chan->center_freq);
@@ -11132,7 +11133,9 @@ static int __wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
 	freq = csa_params->chandef.chan->center_freq;
 	channel = cds_freq_to_chan(freq);
 
-	ret = hdd_softap_set_channel_change(dev, channel);
+	ch_width = hdd_map_nl_chan_width(csa_params->chandef.width);
+
+	ret = hdd_softap_set_channel_change(dev, channel, ch_width);
 	return ret;
 }
 

+ 12 - 6
core/hdd/src/wlan_hdd_hostapd.c

@@ -1701,7 +1701,8 @@ CDF_STATUS hdd_hostapd_sap_event_cb(tpSap_Event pSapEvent,
 		  FL("Channel change indication from peer for channel %d"),
 				pSapEvent->sapevt.sap_chan_cng_ind.new_chan);
 		if (hdd_softap_set_channel_change(dev,
-			 pSapEvent->sapevt.sap_chan_cng_ind.new_chan))
+			 pSapEvent->sapevt.sap_chan_cng_ind.new_chan,
+			 CH_WIDTH_MAX))
 			return CDF_STATUS_E_FAILURE;
 		else
 			return CDF_STATUS_SUCCESS;
@@ -1893,10 +1894,13 @@ int hdd_softap_unpack_ie(tHalHandle halHandle,
  *
  * @dev: pointer to the net device.
  * @target_channel: target channel number.
+ * @target_bw: Target bandwidth to move.
+ * If no bandwidth is specified, the value is CH_WIDTH_MAX
  *
  * Return: 0 for success, non zero for failure
  */
-int hdd_softap_set_channel_change(struct net_device *dev, int target_channel)
+int hdd_softap_set_channel_change(struct net_device *dev, int target_channel,
+				 phy_ch_width target_bw)
 {
 	CDF_STATUS status;
 	int ret = 0;
@@ -1960,12 +1964,13 @@ int hdd_softap_set_channel_change(struct net_device *dev, int target_channel)
 		p_cds_context,
 #endif
 		(uint32_t)
-		target_channel);
+		target_channel,
+		target_bw);
 
 	if (CDF_STATUS_SUCCESS != status) {
 		hddLog(LOGE,
-		       FL("SAP set channel failed for channel = %d"),
-		       target_channel);
+		       FL("SAP set channel failed for channel = %d, bw:%d"),
+		       target_channel, target_bw);
 		/*
 		 * If channel change command fails then clear the
 		 * radar found flag and also restart the netif
@@ -2287,7 +2292,8 @@ static __iw_softap_setparam(struct net_device *dev,
 			hddLog(LOG1,
 			       "SET Channel Change to new channel= %d",
 			       set_value);
-			ret = hdd_softap_set_channel_change(dev, set_value);
+			ret = hdd_softap_set_channel_change(dev, set_value,
+								CH_WIDTH_MAX);
 		} else {
 			hddLog(LOGE,
 			       FL("Channel Change Failed, Device in test mode"));

+ 3 - 2
core/hdd/src/wlan_hdd_hostapd.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -58,7 +58,8 @@ eCsrAuthType
 hdd_translate_rsn_to_csr_auth_type(uint8_t auth_suite[4]);
 
 int hdd_softap_set_channel_change(struct net_device *dev,
-					  int target_channel);
+				int target_channel,
+				phy_ch_width target_bw);
 
 eCsrEncryptionType
 hdd_translate_rsn_to_csr_encryption_type(uint8_t cipher_suite[4]);

+ 33 - 0
core/hdd/src/wlan_hdd_main.c

@@ -349,6 +349,39 @@ static int con_mode;
 /* Variable to hold connection mode including module parameter con_mode */
 static int curr_con_mode;
 
+/**
+ * hdd_map_nl_chan_width() - Map NL channel width to internal representation
+ * @ch_width: NL channel width
+ *
+ * Converts the NL channel width to the driver's internal representation
+ *
+ * Return: Converted channel width. In case of non matching NL channel width,
+ * CH_WIDTH_MAX will be returned.
+ */
+phy_ch_width hdd_map_nl_chan_width(enum nl80211_chan_width ch_width)
+{
+	switch (ch_width) {
+	case NL80211_CHAN_WIDTH_20_NOHT:
+	case NL80211_CHAN_WIDTH_20:
+		return CH_WIDTH_20MHZ;
+	case NL80211_CHAN_WIDTH_40:
+		return CH_WIDTH_40MHZ;
+		break;
+	case NL80211_CHAN_WIDTH_80:
+		return CH_WIDTH_80MHZ;
+	case NL80211_CHAN_WIDTH_80P80:
+		return CH_WIDTH_80P80MHZ;
+	case NL80211_CHAN_WIDTH_160:
+		return CH_WIDTH_160MHZ;
+	case NL80211_CHAN_WIDTH_5:
+	case NL80211_CHAN_WIDTH_10:
+	default:
+		hdd_err("Invalid channel width %d, setting to default",
+				ch_width);
+		return CH_WIDTH_MAX;
+	}
+}
+
 /* wlan_hdd_find_opclass() - Find operating class for a channel
  * @hal: handler to HAL
  * @channel: channel id

+ 2 - 1
core/mac/inc/sir_api.h

@@ -300,7 +300,8 @@ typedef enum ch_width {
 	CH_WIDTH_40MHZ = 1,
 	CH_WIDTH_80MHZ = 2,
 	CH_WIDTH_160MHZ = 3,
-	CH_WIDTH_80P80MHZ = 4
+	CH_WIDTH_80P80MHZ = 4,
+	CH_WIDTH_MAX
 } phy_ch_width;
 
 /**

+ 1 - 1
core/sap/inc/sap_api.h

@@ -841,7 +841,7 @@ CDF_STATUS wlansap_disassoc_sta(void *p_cds_gctx,
 CDF_STATUS wlansap_deauth_sta(void *p_cds_gctx,
 			struct tagCsrDelStaParams *pDelStaParams);
 CDF_STATUS wlansap_set_channel_change_with_csa(void *p_cds_gctx,
-			uint32_t targetChannel);
+			uint32_t targetChannel, phy_ch_width target_bw);
 CDF_STATUS wlansap_set_key_sta(void *p_cds_gctx,
 	tCsrRoamSetKey *pSetKeyInfo);
 CDF_STATUS wlansap_get_assoc_stations(void *p_cds_gctx,

+ 44 - 26
core/sap/src/sap_module.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -1483,32 +1483,20 @@ static CDF_STATUS wlansap_update_csa_channel_params(ptSapContext sap_context,
 	return CDF_STATUS_SUCCESS;
 }
 
-/*==========================================================================
-   FUNCTION    wlansap_set_channel_change_with_csa
-
-   DESCRIPTION
-      This api function does a channel change to the target channel specified
-      through an iwpriv. CSA IE is included in the beacons before doing a
-      channel change.
-
-   DEPENDENCIES
-    NA.
-
-   PARAMETERS
-
-    IN
-    p_cds_gctx             : Pointer to cds global context structure
-    targetChannel        : New target channel to change to.
-
-   RETURN VALUE
-    The CDF_STATUS code associated with performing the operation
-
-    CDF_STATUS_SUCCESS:  Success
-
-   SIDE EFFECTS
-   ============================================================================*/
+/**
+ * wlansap_set_channel_change_with_csa() - Set channel change with CSA
+ * @p_cds_gctx: Pointer to cds global context structure
+ * @targetChannel: Target channel
+ * @target_bw: Target bandwidth
+ *
+ * This api function does a channel change to the target channel specified.
+ * CSA IE is included in the beacons before doing a channel change.
+ *
+ * Return: CDF_STATUS
+ */
 CDF_STATUS
-wlansap_set_channel_change_with_csa(void *p_cds_gctx, uint32_t targetChannel)
+wlansap_set_channel_change_with_csa(void *p_cds_gctx, uint32_t targetChannel,
+					phy_ch_width target_bw)
 {
 
 	ptSapContext sapContext = NULL;
@@ -1575,11 +1563,41 @@ wlansap_set_channel_change_with_csa(void *p_cds_gctx, uint32_t targetChannel)
 			pMac->sap.SapDfsInfo.target_channel = targetChannel;
 			pMac->sap.SapDfsInfo.new_ch_params.ch_width =
 				pMac->sap.SapDfsInfo.new_chanWidth;
+
+			/* By this time, the best bandwidth is calculated for
+			 * the given target channel. Now, if there was a
+			 * request from user to move to a selected bandwidth,
+			 * we can see if it can be honored.
+			 *
+			 * Ex1: BW80 was selected for the target channel and
+			 * user wants BW40, it can be allowed
+			 * Ex2: BW40 was selected for the target channel and
+			 * user wants BW80, it cannot be allowed for the given
+			 * target channel.
+			 *
+			 * So, the MIN of the selected channel bandwidth and
+			 * user input is used for the bandwidth
+			 */
+			if (target_bw != CH_WIDTH_MAX) {
+				CDF_TRACE(CDF_MODULE_ID_SAP,
+					CDF_TRACE_LEVEL_INFO,
+					"%s: target bw:%d new width:%d",
+					__func__, target_bw,
+					pMac->sap.SapDfsInfo.
+					new_ch_params.ch_width);
+				pMac->sap.SapDfsInfo.new_ch_params.ch_width =
+					pMac->sap.SapDfsInfo.new_chanWidth =
+					CDF_MIN(pMac->sap.SapDfsInfo.
+							new_ch_params.ch_width,
+							target_bw);
+			}
+
 			sme_set_ch_params(hHal,
 					sapContext->csr_roamProfile.phyMode,
 					targetChannel,
 					0,
 					&pMac->sap.SapDfsInfo.new_ch_params);
+
 			/*
 			 * Set the CSA IE required flag.
 			 */