Jelajahi Sumber

qcacld-3.0: Fix VHT 160 rate report

1. Update pAddBssParams->ch_width to 160Mhz ch width value
based on VHT operation IE's ch width, channel segment 0
and channel segment 1 fields.

2. Report link rate information to OS for 160Mhz based on
rate flag TX_RATE_VHT160.

The change will fix the incorrect bandwdith reported by
IW commmand (iw wlan0 link) when STA is connected to AP
in VHT160 mode.

Change-Id: I698b12da825619e8e8f28f0cf4ea1ccf2e7072e6
CRs-Fixed: 2585986
Liangwei Dong 5 tahun lalu
induk
melakukan
73fdb0d319

+ 6 - 4
core/hdd/src/wlan_hdd_stats.c

@@ -4049,9 +4049,11 @@ static void wlan_hdd_fill_os_rate_info(enum tx_rate_info rate_flags,
 
 	wlan_hdd_fill_os_he_rateflags(os_rate, rate_flags, dcm, guard_interval);
 
-	if (rate_flags & (TX_RATE_VHT80 | TX_RATE_VHT40 |
+	if (rate_flags & (TX_RATE_VHT160 | TX_RATE_VHT80 | TX_RATE_VHT40 |
 	    TX_RATE_VHT20)) {
-		if (rate_flags & TX_RATE_VHT80)
+		if (rate_flags & TX_RATE_VHT160)
+			hdd_set_rate_bw(os_rate, HDD_RATE_BW_160);
+		else if (rate_flags & TX_RATE_VHT80)
 			hdd_set_rate_bw(os_rate, HDD_RATE_BW_80);
 		else if (rate_flags & TX_RATE_VHT40)
 			hdd_set_rate_bw(os_rate, HDD_RATE_BW_40);
@@ -4200,7 +4202,7 @@ bool hdd_report_max_rate(mac_handle_t mac_handle,
 		rate_flag = 0;
 
 		if (rate_flags & (TX_RATE_VHT80 | TX_RATE_HE80 |
-				TX_RATE_HE160))
+				TX_RATE_HE160 | TX_RATE_VHT160))
 			mode = 2;
 		else if (rate_flags & (TX_RATE_HT40 |
 			 TX_RATE_VHT40 | TX_RATE_HE40))
@@ -4210,7 +4212,7 @@ bool hdd_report_max_rate(mac_handle_t mac_handle,
 
 		if (rate_flags & (TX_RATE_VHT20 | TX_RATE_VHT40 |
 		    TX_RATE_VHT80 | TX_RATE_HE20 | TX_RATE_HE40 |
-		    TX_RATE_HE80 | TX_RATE_HE160)) {
+		    TX_RATE_HE80 | TX_RATE_HE160 | TX_RATE_VHT160)) {
 			stat = ucfg_mlme_cfg_get_vht_tx_mcs_map(hdd_ctx->psoc,
 								&vht_mcs_map);
 			if (QDF_IS_STATUS_ERROR(stat))

+ 24 - 4
core/mac/src/pe/lim/lim_assoc_utils.c

@@ -3581,8 +3581,25 @@ static void lim_update_vht_oper_assoc_resp(struct mac_context *mac_ctx,
 		struct bss_params *pAddBssParams,
 		tDot11fIEVHTOperation *vht_oper, struct pe_session *pe_session)
 {
-	if (vht_oper->chanWidth && pe_session->ch_width)
-		pAddBssParams->ch_width = vht_oper->chanWidth + 1;
+	int16_t ccfs0 = vht_oper->chan_center_freq_seg0;
+	int16_t ccfs1 = vht_oper->chan_center_freq_seg1;
+	int16_t offset = abs((ccfs0 -  ccfs1));
+	uint8_t ch_width;
+
+	ch_width = pAddBssParams->ch_width;
+	if (vht_oper->chanWidth && pe_session->ch_width) {
+		ch_width = CH_WIDTH_80MHZ;
+		if (ccfs1 && offset == 8)
+			ch_width = CH_WIDTH_160MHZ;
+		else if (ccfs1 && offset > 16)
+			ch_width = CH_WIDTH_80P80MHZ;
+	}
+	if (ch_width > pe_session->ch_width)
+		ch_width = pe_session->ch_width;
+	pAddBssParams->ch_width = ch_width;
+	pAddBssParams->staContext.ch_width = ch_width;
+	pe_debug("ch_width %d, pe chanWidth %d ccfs0 %d, ccfs1 %d",
+		 pAddBssParams->ch_width, pe_session->ch_width, ccfs0, ccfs1);
 }
 
 #ifdef WLAN_SUPPORT_TWT
@@ -3838,18 +3855,21 @@ QDF_STATUS lim_sta_send_add_bss(struct mac_context *mac, tpSirAssocRsp pAssocRsp
 		if (chan_width_support &&
 		    ((pAssocRsp->HTCaps.supportedChannelWidthSet) ||
 		    (pBeaconStruct->HTCaps.supportedChannelWidthSet))) {
+			pAddBssParams->ch_width =
+					pe_session->ch_width;
 			pAddBssParams->staContext.ch_width =
 					pe_session->ch_width;
 		} else {
+			pAddBssParams->ch_width = CH_WIDTH_20MHZ;
 			sta_context->ch_width =	CH_WIDTH_20MHZ;
 			if (!vht_cap_info->enable_txbf_20mhz)
 				sta_context->vhtTxBFCapable = 0;
 		}
 
-		pe_debug("StaCtx: vhtCap %d ChBW %d TxBF %d",
+		pe_debug("StaCtx: vhtCap %d ChBW %d TxBF %d ch_width %d",
 			 pAddBssParams->staContext.vhtCapable,
 			 pAddBssParams->staContext.ch_width,
-			 sta_context->vhtTxBFCapable);
+			 sta_context->vhtTxBFCapable, pAddBssParams->ch_width);
 		pe_debug("StaContext su_tx_bfer %d, vht_mcs11 %d",
 			 sta_context->enable_su_tx_bformer,
 			 pAddBssParams->staContext.vht_mcs_10_11_supp);

+ 2 - 0
core/wma/inc/wma_internal.h

@@ -95,12 +95,14 @@ struct index_data_rate_type {
  * @ht20_rate: VHT20 supported rate table
  * @ht40_rate: VHT40 supported rate table
  * @ht80_rate: VHT80 supported rate table
+ * @ht160_rate: VHT160 supported rate table
  */
 struct index_vht_data_rate_type {
 	uint8_t mcs_index;
 	uint16_t ht20_rate[2];
 	uint16_t ht40_rate[2];
 	uint16_t ht80_rate[2];
+	uint16_t ht160_rate[2];
 };
 
 #ifdef WLAN_FEATURE_11AX

+ 2 - 2
core/wma/src/wma_data.c

@@ -829,9 +829,9 @@ void wma_set_bss_rate_flags(tp_wma_handle wma, uint8_t vdev_id,
 		wma_set_bss_rate_flags_he(rate_flags, add_bss)) {
 		if (add_bss->vhtCapable) {
 			if (add_bss->ch_width == CH_WIDTH_80P80MHZ)
-				*rate_flags |= TX_RATE_VHT80;
+				*rate_flags |= TX_RATE_VHT160;
 			if (add_bss->ch_width == CH_WIDTH_160MHZ)
-				*rate_flags |= TX_RATE_VHT80;
+				*rate_flags |= TX_RATE_VHT160;
 			if (add_bss->ch_width == CH_WIDTH_80MHZ)
 				*rate_flags |= TX_RATE_VHT80;
 			else if (add_bss->ch_width)

+ 40 - 26
core/wma/src/wma_utils.c

@@ -95,32 +95,32 @@ static struct index_data_rate_type mcs_nss2[] = {
 /* MCS Based VHT rate table */
 /* MCS parameters with Nss = 1*/
 static struct index_vht_data_rate_type vht_mcs_nss1[] = {
-	/* MCS L20  S20    L40   S40    L80   S80 */
-	{0,  {65,   72 }, {135,  150},  {293,  325} },
-	{1,  {130,  144}, {270,  300},  {585,  650} },
-	{2,  {195,  217}, {405,  450},  {878,  975} },
-	{3,  {260,  289}, {540,  600},  {1170, 1300} },
-	{4,  {390,  433}, {810,  900},  {1755, 1950} },
-	{5,  {520,  578}, {1080, 1200}, {2340, 2600} },
-	{6,  {585,  650}, {1215, 1350}, {2633, 2925} },
-	{7,  {650,  722}, {1350, 1500}, {2925, 3250} },
-	{8,  {780,  867}, {1620, 1800}, {3510, 3900} },
-	{9,  {865,  960}, {1800, 2000}, {3900, 4333} }
+	/* MCS L20  S20    L40   S40    L80   S80    L160  S160*/
+	{0,  {65,   72 }, {135,  150},  {293,  325}, {585, 650} },
+	{1,  {130,  144}, {270,  300},  {585,  650}, {1170, 1300} },
+	{2,  {195,  217}, {405,  450},  {878,  975}, {1755, 1950} },
+	{3,  {260,  289}, {540,  600},  {1170, 1300}, {2340, 2600} },
+	{4,  {390,  433}, {810,  900},  {1755, 1950}, {3510, 3900} },
+	{5,  {520,  578}, {1080, 1200}, {2340, 2600}, {4680, 5200} },
+	{6,  {585,  650}, {1215, 1350}, {2633, 2925}, {5265, 5850} },
+	{7,  {650,  722}, {1350, 1500}, {2925, 3250}, {5850, 6500} },
+	{8,  {780,  867}, {1620, 1800}, {3510, 3900}, {7020, 7800} },
+	{9,  {865,  960}, {1800, 2000}, {3900, 4333}, {7800, 8667} }
 };
 
 /*MCS parameters with Nss = 2*/
 static struct index_vht_data_rate_type vht_mcs_nss2[] = {
-	/* MCS L20  S20    L40    S40    L80    S80 */
-	{0,  {130,  144},  {270,  300},  { 585,  650} },
-	{1,  {260,  289},  {540,  600},  {1170, 1300} },
-	{2,  {390,  433},  {810,  900},  {1755, 1950} },
-	{3,  {520,  578},  {1080, 1200}, {2340, 2600} },
-	{4,  {780,  867},  {1620, 1800}, {3510, 3900} },
-	{5,  {1040, 1156}, {2160, 2400}, {4680, 5200} },
-	{6,  {1170, 1300}, {2430, 2700}, {5265, 5850} },
-	{7,  {1300, 1444}, {2700, 3000}, {5850, 6500} },
-	{8,  {1560, 1733}, {3240, 3600}, {7020, 7800} },
-	{9,  {1730, 1920}, {3600, 4000}, {7800, 8667} }
+	/* MCS L20  S20    L40    S40    L80    S80    L160   S160*/
+	{0,  {130,  144},  {270,  300},  { 585,  650}, {1170, 1300} },
+	{1,  {260,  289},  {540,  600},  {1170, 1300}, {2340, 2600} },
+	{2,  {390,  433},  {810,  900},  {1755, 1950}, {3510, 3900} },
+	{3,  {520,  578},  {1080, 1200}, {2340, 2600}, {4680, 5200} },
+	{4,  {780,  867},  {1620, 1800}, {3510, 3900}, {7020, 7800} },
+	{5,  {1040, 1156}, {2160, 2400}, {4680, 5200}, {9360, 10400} },
+	{6,  {1170, 1300}, {2430, 2700}, {5265, 5850}, {10530, 11700} },
+	{7,  {1300, 1444}, {2700, 3000}, {5850, 6500}, {11700, 13000} },
+	{8,  {1560, 1733}, {3240, 3600}, {7020, 7800}, {14040, 15600} },
+	{9,  {1730, 1920}, {3600, 4000}, {7800, 8667}, {15600, 17333} }
 };
 
 #ifdef WLAN_FEATURE_11AX
@@ -472,7 +472,18 @@ uint8_t wma_get_mcs_idx(uint16_t raw_rate, enum tx_rate_info rate_flags,
 		goto rate_found;
 
 	for (index = 0; index < MAX_VHT_MCS_IDX; index++) {
-		if (rate_flags & TX_RATE_VHT80) {
+		if (rate_flags & TX_RATE_VHT160) {
+			nss1_rate = &vht_mcs_nss1[index].ht160_rate[0];
+			nss2_rate = &vht_mcs_nss2[index].ht160_rate[0];
+			/* check for vht160 nss1/2 rate set */
+			match_rate = wma_mcs_rate_match(raw_rate, 0,
+							nss1_rate,
+							nss2_rate,
+							nss, guard_interval);
+			if (match_rate)
+				goto rate_found;
+		}
+		if (rate_flags & (TX_RATE_VHT80 | TX_RATE_VHT160)) {
 			nss1_rate = &vht_mcs_nss1[index].ht80_rate[0];
 			nss2_rate = &vht_mcs_nss2[index].ht80_rate[0];
 			/* check for vht80 nss1/2 rate set */
@@ -480,10 +491,13 @@ uint8_t wma_get_mcs_idx(uint16_t raw_rate, enum tx_rate_info rate_flags,
 							nss1_rate,
 							nss2_rate,
 							nss, guard_interval);
-			if (match_rate)
+			if (match_rate) {
+				*mcs_rate_flag &= ~TX_RATE_VHT160;
 				goto rate_found;
+			}
 		}
-		if (rate_flags & (TX_RATE_VHT40 | TX_RATE_VHT80)) {
+		if (rate_flags & (TX_RATE_VHT40 | TX_RATE_VHT80 |
+				TX_RATE_VHT160)) {
 			nss1_rate = &vht_mcs_nss1[index].ht40_rate[0];
 			nss2_rate = &vht_mcs_nss2[index].ht40_rate[0];
 			/* check for vht40 nss1/2 rate set */
@@ -497,7 +511,7 @@ uint8_t wma_get_mcs_idx(uint16_t raw_rate, enum tx_rate_info rate_flags,
 			}
 		}
 		if (rate_flags & (TX_RATE_VHT20 | TX_RATE_VHT40 |
-			TX_RATE_VHT80)) {
+			TX_RATE_VHT80 | TX_RATE_VHT160)) {
 			nss1_rate = &vht_mcs_nss1[index].ht20_rate[0];
 			nss2_rate = &vht_mcs_nss2[index].ht20_rate[0];
 			/* check for vht20 nss1/2 rate set */