ソースを参照

qcacmn: Add API to set channel parameters for 802.11be station

Extract new channel parameter generating including puncture from
wlan_cm_sta_update_bw_puncture as a new API, so that other module
can use the new API.

Change-Id: I20190168c9228fa97e32583bc8db79c98b3b7918
CRs-Fixed: 3326723
Bing Sun 2 年 前
コミット
062186ff39

+ 4 - 0
umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h

@@ -3940,6 +3940,7 @@ enum mlme_csa_event_ies_present_flag {
  * @switch_mode: switch mode
  * @sec_chan_offset: secondary channel offset
  * @new_ch_width: new channel width
+ * @new_punct_bitmap: new puncture bitmap based on new channel width
  * @new_ch_freq_seg1: channel center freq 1
  * @new_ch_freq_seg2: channel center freq 2
  * @ies_present_flag: BIT MAP of MLME_CSA_EVENT_IES_PRESENT_FLAG
@@ -3951,6 +3952,9 @@ struct csa_offload_params {
 	uint8_t switch_mode;
 	uint8_t sec_chan_offset;
 	enum phy_ch_width new_ch_width;
+#ifdef WLAN_FEATURE_11BE
+	uint16_t new_punct_bitmap;
+#endif
 	uint8_t new_op_class;
 	uint8_t new_ch_freq_seg1;
 	uint8_t new_ch_freq_seg2;

+ 25 - 0
umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_api.h

@@ -477,6 +477,31 @@ wlan_cm_disc_cont_after_rso_stop(struct wlan_objmgr_vdev *vdev,
 				 struct wlan_cm_vdev_discon_req *req);
 
 #ifdef WLAN_FEATURE_11BE
+/**
+ * wlan_cm_sta_set_chan_param() - set channel parameters for 802.11be sta
+ *
+ * @vdev: vdev
+ * @ch_freq: operating channel frequency
+ * @ori_bw: bandwidth information according to EHT operation IE
+ * @ori_punc: original puncture bitmap from EHT operation IE
+ * @ccfs0: EHT channel center frequency segment0 information
+ * @ccfs1: EHT channel center frequency segment1 information
+ * @chan_param: chan_param to be set
+ *
+ * ori_bw, ori_punc, ccfs0, ccfs1 are information from AP EHT operation IE
+ * chan_param->ch_width is the intersected channel width based on STA's
+ * capability. Complete chan_param including puncture will be set if
+ * it returns success.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_cm_sta_set_chan_param(struct wlan_objmgr_vdev *vdev,
+				      qdf_freq_t ch_freq,
+				      enum phy_ch_width ori_bw,
+				      uint16_t ori_punc,
+				      uint8_t ccfs0, uint8_t ccfs1,
+				      struct ch_params *chan_param);
+
 /**
  * wlan_cm_sta_update_puncture() - update puncture and channel width for sta
  * @vdev: vdev

+ 74 - 50
umac/mlme/connection_mgr/dispatcher/src/wlan_cm_api.c

@@ -381,17 +381,13 @@ wlan_cm_disc_cont_after_rso_stop(struct wlan_objmgr_vdev *vdev,
 }
 
 #ifdef WLAN_FEATURE_11BE
-QDF_STATUS wlan_cm_sta_update_bw_puncture(struct wlan_objmgr_vdev *vdev,
-					  uint8_t *peer_mac,
-					  uint16_t ori_punc,
-					  enum phy_ch_width ori_bw,
-					  uint8_t ccfs0, uint8_t ccfs1,
-					  enum phy_ch_width new_bw)
+QDF_STATUS wlan_cm_sta_set_chan_param(struct wlan_objmgr_vdev *vdev,
+				      qdf_freq_t ch_freq,
+				      enum phy_ch_width ori_bw,
+				      uint16_t ori_punc,
+				      uint8_t ccfs0, uint8_t ccfs1,
+				      struct ch_params *chan_param)
 {
-	struct wlan_channel *des_chan;
-	uint16_t curr_punc = 0;
-	uint16_t new_punc = 0;
-	enum phy_ch_width curr_bw;
 	uint16_t primary_puncture_bitmap = 0;
 	struct wlan_objmgr_pdev *pdev;
 	struct reg_channel_list chan_list;
@@ -399,80 +395,108 @@ QDF_STATUS wlan_cm_sta_update_bw_puncture(struct wlan_objmgr_vdev *vdev,
 	qdf_freq_t center_freq_320 = 0;
 	qdf_freq_t center_freq_40 = 0;
 	uint8_t band_mask;
-	uint32_t bw_puncture = 0;
+	uint16_t new_punc;
 
-	if (!vdev || !peer_mac) {
+	if (!vdev || !chan_param) {
 		mlme_err("invalid input parameters");
 		return QDF_STATUS_E_INVAL;
 	}
 	pdev = wlan_vdev_get_pdev(vdev);
-	des_chan = wlan_vdev_mlme_get_des_chan(vdev);
-	if (!des_chan || !pdev) {
-		mlme_err("invalid des chan");
+	if (!pdev) {
+		mlme_err("invalid pdev");
 		return QDF_STATUS_E_INVAL;
 	}
 	if (ori_bw == CH_WIDTH_320MHZ) {
-		if (WLAN_REG_IS_6GHZ_CHAN_FREQ(des_chan->ch_freq))
+		if (WLAN_REG_IS_6GHZ_CHAN_FREQ(ch_freq))
 			band_mask = BIT(REG_BAND_6G);
 		else
 			band_mask = BIT(REG_BAND_5G);
 		center_freq_320 = wlan_reg_chan_band_to_freq(pdev, ccfs1,
 							     band_mask);
 	} else if (ori_bw == CH_WIDTH_40MHZ) {
-		if (WLAN_REG_IS_24GHZ_CH_FREQ(des_chan->ch_freq)) {
+		if (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq)) {
 			band_mask = BIT(REG_BAND_2G);
 			center_freq_40 = wlan_reg_chan_band_to_freq(pdev,
 								    ccfs0,
 								    band_mask);
-			if (center_freq_40 ==  des_chan->ch_freq + BW_10_MHZ)
-				sec_ch_2g_freq = des_chan->ch_freq + BW_20_MHZ;
-			if (center_freq_40 ==  des_chan->ch_freq - BW_10_MHZ)
-				sec_ch_2g_freq = des_chan->ch_freq - BW_20_MHZ;
+			if (center_freq_40 == ch_freq + BW_10_MHZ)
+				sec_ch_2g_freq = ch_freq + BW_20_MHZ;
+			if (center_freq_40 == ch_freq - BW_10_MHZ)
+				sec_ch_2g_freq = ch_freq - BW_20_MHZ;
 		}
 	}
-	qdf_mem_zero(&chan_list, sizeof(chan_list));
-	curr_punc = des_chan->puncture_bitmap;
-	curr_bw = des_chan->ch_width;
 	wlan_reg_extract_puncture_by_bw(ori_bw, ori_punc,
-					des_chan->ch_freq,
+					ch_freq,
 					center_freq_320,
 					CH_WIDTH_20MHZ,
 					&primary_puncture_bitmap);
 	if (primary_puncture_bitmap) {
 		mlme_err("sta vdev %d freq %d RX bw %d puncture 0x%x primary chan is punctured",
-			 wlan_vdev_get_id(vdev), des_chan->ch_freq,
+			 wlan_vdev_get_id(vdev), ch_freq,
 			 ori_bw, ori_punc);
 		return QDF_STATUS_E_FAULT;
 	}
-	if (new_bw == ori_bw)
+	if (chan_param->ch_width != CH_WIDTH_320MHZ)
+		center_freq_320 = 0;
+	qdf_mem_zero(&chan_list, sizeof(chan_list));
+	wlan_reg_fill_channel_list(pdev, ch_freq,
+				   sec_ch_2g_freq, chan_param->ch_width,
+				   center_freq_320, &chan_list,
+				   true);
+	*chan_param = chan_list.chan_param[0];
+	if (chan_param->ch_width == ori_bw)
 		new_punc = ori_punc;
 	else
 		wlan_reg_extract_puncture_by_bw(ori_bw, ori_punc,
-						des_chan->ch_freq,
-						center_freq_320,
-						new_bw,
+						ch_freq,
+						chan_param->mhz_freq_seg1,
+						chan_param->ch_width,
 						&new_punc);
-	if (curr_bw == new_bw) {
-		if (curr_punc != new_punc)
-			des_chan->puncture_bitmap = new_punc;
-		else
-			return QDF_STATUS_SUCCESS;
-	} else {
-		if (new_bw != CH_WIDTH_320MHZ)
-			center_freq_320 = 0;
-		wlan_reg_fill_channel_list(pdev, des_chan->ch_freq,
-					   sec_ch_2g_freq, new_bw,
-					   center_freq_320, &chan_list,
-					   true);
-		des_chan->ch_freq_seg1 =
-				chan_list.chan_param[0].center_freq_seg0;
-		des_chan->ch_freq_seg2 =
-				chan_list.chan_param[0].center_freq_seg1;
-		des_chan->ch_cfreq1 = chan_list.chan_param[0].mhz_freq_seg0;
-		des_chan->ch_cfreq2 = chan_list.chan_param[1].mhz_freq_seg1;
-		des_chan->puncture_bitmap = new_punc;
-		des_chan->ch_width = new_bw;
+
+	chan_param->reg_punc_bitmap = new_punc;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_cm_sta_update_bw_puncture(struct wlan_objmgr_vdev *vdev,
+					  uint8_t *peer_mac,
+					  uint16_t ori_punc,
+					  enum phy_ch_width ori_bw,
+					  uint8_t ccfs0, uint8_t ccfs1,
+					  enum phy_ch_width new_bw)
+{
+	struct wlan_channel *des_chan;
+	struct ch_params ch_param;
+	uint32_t bw_puncture = 0;
+	QDF_STATUS status = QDF_STATUS_E_INVAL;
+
+	if (!vdev || !peer_mac) {
+		mlme_err("invalid input parameters");
+		return status;
+	}
+	des_chan = wlan_vdev_mlme_get_des_chan(vdev);
+	if (!des_chan) {
+		mlme_err("invalid des chan");
+		return status;
 	}
+	qdf_mem_zero(&ch_param, sizeof(ch_param));
+	ch_param.ch_width = new_bw;
+	status = wlan_cm_sta_set_chan_param(vdev, des_chan->ch_freq,
+					    ori_bw, ori_punc, ccfs0,
+					    ccfs1, &ch_param);
+	if (QDF_IS_STATUS_ERROR(status))
+		return status;
+
+	if (des_chan->puncture_bitmap == ch_param.reg_punc_bitmap &&
+	    des_chan->ch_width == ch_param.ch_width)
+		return status;
+
+	des_chan->ch_freq_seg1 = ch_param.center_freq_seg0;
+	des_chan->ch_freq_seg2 = ch_param.center_freq_seg1;
+	des_chan->ch_cfreq1 = ch_param.mhz_freq_seg0;
+	des_chan->ch_cfreq2 = ch_param.mhz_freq_seg1;
+	des_chan->puncture_bitmap = ch_param.reg_punc_bitmap;
+	des_chan->ch_width = ch_param.ch_width;
 	mlme_debug("sta vdev %d freq %d bw %d puncture 0x%x ch_cfreq1 %d ch_cfreq2 %d",
 		   wlan_vdev_get_id(vdev), des_chan->ch_freq,
 		   des_chan->ch_width, des_chan->puncture_bitmap,