1 /******************************************************************************
3 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 ******************************************************************************/
22 #include <drv_types.h>
24 #ifdef CONFIG_80211AC_VHT
25 // 20/40/80, ShortGI, MCS Rate
26 const u16 VHT_MCS_DATA_RATE[3][2][30] =
27 { { {13, 26, 39, 52, 78, 104, 117, 130, 156, 156,
28 26, 52, 78, 104, 156, 208, 234, 260, 312, 312,
29 39, 78, 117, 156, 234, 312, 351, 390, 468, 520}, // Long GI, 20MHz
30 {14, 29, 43, 58, 87, 116, 130, 144, 173, 173,
31 29, 58, 87, 116, 173, 231, 260, 289, 347, 347,
32 43, 87, 130, 173, 260, 347,390, 433, 520, 578} }, // Short GI, 20MHz
33 { {27, 54, 81, 108, 162, 216, 243, 270, 324, 360,
34 54, 108, 162, 216, 324, 432, 486, 540, 648, 720,
35 81, 162, 243, 324, 486, 648, 729, 810, 972, 1080}, // Long GI, 40MHz
36 {30, 60, 90, 120, 180, 240, 270, 300,360, 400,
37 60, 120, 180, 240, 360, 480, 540, 600, 720, 800,
38 90, 180, 270, 360, 540, 720, 810, 900, 1080, 1200}}, // Short GI, 40MHz
39 { {59, 117, 176, 234, 351, 468, 527, 585, 702, 780,
40 117, 234, 351, 468, 702, 936, 1053, 1170, 1404, 1560,
41 176, 351, 527, 702, 1053, 1404, 1580, 1755, 2106, 2340}, /* Long GI, 80MHz */
42 {65, 130, 195, 260, 390, 520, 585, 650, 780, 867,
43 130, 260, 390, 520, 780, 1040, 1170, 1300, 1560,1734,
44 195, 390, 585, 780, 1170, 1560, 1755, 1950, 2340, 2600} } /* Short GI, 80MHz */
47 u8 rtw_get_vht_highest_rate(u8 *pvht_mcs_map)
53 for(i = 0; i < 2; i++)
55 if(pvht_mcs_map[i] != 0xff)
57 for(j = 0; j < 8; j += 2)
59 bit_map = (pvht_mcs_map[i] >> j) & 3;
62 vht_mcs_rate = MGN_VHT1SS_MCS7 + 10*j/2 + i*40 + bit_map; //VHT rate indications begin from 0x90
67 /* DBG_871X("HighestVHTMCSRate is %x\n", vht_mcs_rate); */
71 u8 rtw_vht_mcsmap_to_nss(u8 *pvht_mcs_map)
77 for(i = 0; i < 2; i++)
79 if(pvht_mcs_map[i] != 0xff)
81 for(j = 0; j < 8; j += 2)
83 bit_map = (pvht_mcs_map[i] >> j) & 3;
91 /* DBG_871X("%s : %dSS\n", __FUNCTION__, nss); */
95 void rtw_vht_nss_to_mcsmap(u8 nss, u8 *target_mcs_map, u8 *cur_mcs_map)
98 u8 cur_rate, target_rate;
100 for(i = 0; i < 2; i++)
102 target_mcs_map[i] = 0;
103 for(j = 0; j < 8; j+=2)
105 cur_rate = (cur_mcs_map[i] >> j) & 3;
106 if(cur_rate == 3) //0x3 indicates not supported that num of SS
108 else if(nss <= ((j/2)+i*4))
111 target_rate = cur_rate;
113 target_mcs_map[i] |= (target_rate << j);
117 //DBG_871X("%s : %dSS\n", __FUNCTION__, nss);
120 u16 rtw_vht_mcs_to_data_rate(u8 bw, u8 short_GI, u8 vht_mcs_rate)
122 if(vht_mcs_rate > MGN_VHT3SS_MCS9)
123 vht_mcs_rate = MGN_VHT3SS_MCS9;
124 /* DBG_871X("bw=%d, short_GI=%d, ((vht_mcs_rate - MGN_VHT1SS_MCS0)&0x3f)=%d\n", bw, short_GI, ((vht_mcs_rate - MGN_VHT1SS_MCS0)&0x3f)); */
125 return VHT_MCS_DATA_RATE[bw][short_GI][((vht_mcs_rate - MGN_VHT1SS_MCS0)&0x3f)];
128 void rtw_vht_use_default_setting(_adapter *padapter)
130 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
131 struct vht_priv *pvhtpriv = &pmlmepriv->vhtpriv;
132 struct registry_priv *pregistrypriv = &padapter->registrypriv;
133 BOOLEAN bHwLDPCSupport = _FALSE, bHwSTBCSupport = _FALSE;
134 BOOLEAN bHwSupportBeamformer = _FALSE, bHwSupportBeamformee = _FALSE;
136 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
137 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
138 pvhtpriv->sgi_80m = TEST_FLAG(pregistrypriv->short_gi, BIT2) ? _TRUE : _FALSE;
141 rtw_hal_get_def_var(padapter, HAL_DEF_RX_LDPC, (u8 *)&bHwLDPCSupport);
142 CLEAR_FLAGS(pvhtpriv->ldpc_cap);
145 if(TEST_FLAG(pregistrypriv->ldpc_cap, BIT0))
146 SET_FLAG(pvhtpriv->ldpc_cap, LDPC_VHT_ENABLE_RX);
148 rtw_hal_get_def_var(padapter, HAL_DEF_TX_LDPC, (u8 *)&bHwLDPCSupport);
151 if(TEST_FLAG(pregistrypriv->ldpc_cap, BIT1))
152 SET_FLAG(pvhtpriv->ldpc_cap, LDPC_VHT_ENABLE_TX);
154 if (pvhtpriv->ldpc_cap)
155 DBG_871X("[VHT] Support LDPC = 0x%02X\n", pvhtpriv->ldpc_cap);
158 rtw_hal_get_def_var(padapter, HAL_DEF_TX_STBC, (u8 *)&bHwSTBCSupport);
159 CLEAR_FLAGS(pvhtpriv->stbc_cap);
162 if(TEST_FLAG(pregistrypriv->stbc_cap, BIT1))
163 SET_FLAG(pvhtpriv->stbc_cap, STBC_VHT_ENABLE_TX);
165 rtw_hal_get_def_var(padapter, HAL_DEF_RX_STBC, (u8 *)&bHwSTBCSupport);
168 if(TEST_FLAG(pregistrypriv->stbc_cap, BIT0))
169 SET_FLAG(pvhtpriv->stbc_cap, STBC_VHT_ENABLE_RX);
171 if (pvhtpriv->stbc_cap)
172 DBG_871X("[VHT] Support STBC = 0x%02X\n", pvhtpriv->stbc_cap);
174 // Beamforming setting
175 rtw_hal_get_def_var(padapter, HAL_DEF_EXPLICIT_BEAMFORMER, (u8 *)&bHwSupportBeamformer);
176 rtw_hal_get_def_var(padapter, HAL_DEF_EXPLICIT_BEAMFORMEE, (u8 *)&bHwSupportBeamformee);
177 CLEAR_FLAGS(pvhtpriv->beamform_cap);
178 if (TEST_FLAG(pregistrypriv->beamform_cap, BIT0) && bHwSupportBeamformer) {
179 #ifdef CONFIG_CONCURRENT_MODE
180 if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) {
181 SET_FLAG(pvhtpriv->beamform_cap, BEAMFORMING_VHT_BEAMFORMER_ENABLE);
182 DBG_871X("[VHT] CONCURRENT AP Support Beamformer\n");
184 DBG_871X("[VHT] CONCURRENT not AP ;not allow Support Beamformer\n");
186 SET_FLAG(pvhtpriv->beamform_cap, BEAMFORMING_VHT_BEAMFORMER_ENABLE);
187 DBG_871X("[VHT] Support Beamformer\n");
190 if(TEST_FLAG(pregistrypriv->beamform_cap, BIT1) && bHwSupportBeamformee)
192 SET_FLAG(pvhtpriv->beamform_cap, BEAMFORMING_VHT_BEAMFORMEE_ENABLE);
193 DBG_871X("[VHT] Support Beamformee\n");
196 pvhtpriv->ampdu_len = pregistrypriv->ampdu_factor;
198 rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
200 if (rf_type == RF_3T3R)
201 pvhtpriv->vht_mcs_map[0] = 0xea; /* support 1SS MCS 0~9 2SS MCS 0~9 3SS MCS 0~9 */
202 else if(rf_type == RF_2T2R)
203 pvhtpriv->vht_mcs_map[0] = 0xfa; /* support 1SS MCS 0~9 2SS MCS 0~9 */
205 pvhtpriv->vht_mcs_map[0] = 0xfe; /* Only support 1SS MCS 0~9; */
206 pvhtpriv->vht_mcs_map[1] = 0xff;
208 if(pregistrypriv->vht_rate_sel == 1)
210 pvhtpriv->vht_mcs_map[0] = 0xfc; // support 1SS MCS 0~7
212 else if(pregistrypriv->vht_rate_sel == 2)
214 pvhtpriv->vht_mcs_map[0] = 0xfd; // Support 1SS MCS 0~8
216 else if(pregistrypriv->vht_rate_sel == 3)
218 pvhtpriv->vht_mcs_map[0] = 0xfe; // Support 1SS MCS 0~9
220 else if(pregistrypriv->vht_rate_sel == 4)
222 pvhtpriv->vht_mcs_map[0] = 0xf0; // support 1SS MCS 0~7 2SS MCS 0~7
224 else if(pregistrypriv->vht_rate_sel == 5)
226 pvhtpriv->vht_mcs_map[0] = 0xf5; // support 1SS MCS 0~8 2SS MCS 0~8
228 else if(pregistrypriv->vht_rate_sel == 6)
230 pvhtpriv->vht_mcs_map[0] = 0xfa; // support 1SS MCS 0~9 2SS MCS 0~9
232 else if(pregistrypriv->vht_rate_sel == 7)
234 pvhtpriv->vht_mcs_map[0] = 0xf8; // support 1SS MCS 0-7 2SS MCS 0~9
236 else if(pregistrypriv->vht_rate_sel == 8)
238 pvhtpriv->vht_mcs_map[0] = 0xf9; // support 1SS MCS 0-8 2SS MCS 0~9
240 else if(pregistrypriv->vht_rate_sel == 9)
242 pvhtpriv->vht_mcs_map[0] = 0xf4; // support 1SS MCS 0-7 2SS MCS 0~8
245 pvhtpriv->vht_highest_rate = rtw_get_vht_highest_rate(pvhtpriv->vht_mcs_map);
248 u64 rtw_vht_rate_to_bitmap(u8 *pVHTRate)
255 for(i = j= 0; i < Bits_3ss; i+=2, j+=10)
257 /* every two bits means single sptial stream */
258 tmpRate = (pVHTRate[0] >> i) & 3;
262 RateBitmap = RateBitmap | (0x03ff << j);
265 RateBitmap = RateBitmap | (0x01ff << j);
269 RateBitmap = RateBitmap | (0x00ff << j);
276 DBG_871X("RateBitmap=%016llx , pVHTRate[0]=%02x, pVHTRate[1]=%02x\n", RateBitmap, pVHTRate[0], pVHTRate[1]);
280 void update_sta_vht_info_apmode(_adapter *padapter, PVOID sta)
282 struct sta_info *psta = (struct sta_info *)sta;
283 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
284 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
285 struct vht_priv *pvhtpriv_ap = &pmlmepriv->vhtpriv;
286 struct vht_priv *pvhtpriv_sta = &psta->vhtpriv;
287 struct ht_priv *phtpriv_sta = &psta->htpriv;
288 u8 cur_ldpc_cap = 0, cur_stbc_cap = 0, bw_mode = 0;
289 u16 cur_beamform_cap = 0;
292 if (pvhtpriv_sta->vht_option == _FALSE) {
296 bw_mode = GET_VHT_OPERATING_MODE_FIELD_CHNL_WIDTH(&pvhtpriv_sta->vht_op_mode_notify);
298 //if (bw_mode > psta->bw_mode)
299 psta->bw_mode = bw_mode;
302 if (TEST_FLAG(pvhtpriv_ap->ldpc_cap, LDPC_VHT_ENABLE_TX) &&
303 GET_VHT_CAPABILITY_ELE_RX_LDPC(pvhtpriv_sta->vht_cap))
305 SET_FLAG(cur_ldpc_cap, (LDPC_VHT_ENABLE_TX | LDPC_VHT_CAP_TX));
306 DBG_871X("Current STA(%d) VHT LDPC = %02X\n", psta->aid, cur_ldpc_cap);
308 pvhtpriv_sta->ldpc_cap = cur_ldpc_cap;
310 if (psta->bw_mode > pmlmeext->cur_bwmode)
311 psta->bw_mode = pmlmeext->cur_bwmode;
313 if (psta->bw_mode == CHANNEL_WIDTH_80) {
314 // B5 Short GI for 80 MHz
315 pvhtpriv_sta->sgi_80m = (GET_VHT_CAPABILITY_ELE_SHORT_GI80M(pvhtpriv_sta->vht_cap) & pvhtpriv_ap->sgi_80m) ? _TRUE : _FALSE;
316 //DBG_871X("Current STA ShortGI80MHz = %d\n", pvhtpriv_sta->sgi_80m);
317 } else if (psta->bw_mode >= CHANNEL_WIDTH_160) {
318 // B5 Short GI for 80 MHz
319 pvhtpriv_sta->sgi_80m = (GET_VHT_CAPABILITY_ELE_SHORT_GI160M(pvhtpriv_sta->vht_cap) & pvhtpriv_ap->sgi_80m) ? _TRUE : _FALSE;
320 //DBG_871X("Current STA ShortGI160MHz = %d\n", pvhtpriv_sta->sgi_80m);
324 if (TEST_FLAG(pvhtpriv_ap->stbc_cap, STBC_VHT_ENABLE_TX) &&
325 GET_VHT_CAPABILITY_ELE_RX_STBC(pvhtpriv_sta->vht_cap))
327 SET_FLAG(cur_stbc_cap, (STBC_VHT_ENABLE_TX | STBC_VHT_CAP_TX));
328 DBG_871X("Current STA(%d) VHT STBC = %02X\n", psta->aid, cur_stbc_cap);
330 pvhtpriv_sta->stbc_cap = cur_stbc_cap;
332 #ifdef CONFIG_BEAMFORMING
333 // B11 SU Beamformer Capable, the target supports Beamformer and we are Beamformee
334 if (TEST_FLAG(pvhtpriv_ap->beamform_cap, BEAMFORMING_VHT_BEAMFORMER_ENABLE) &&
335 GET_VHT_CAPABILITY_ELE_SU_BFEE(pvhtpriv_sta->vht_cap))
337 SET_FLAG(cur_beamform_cap, BEAMFORMING_VHT_BEAMFORMEE_ENABLE);
338 /*Shift to BEAMFORMING_VHT_BEAMFORMER_STS_CAP*/
339 SET_FLAG(cur_beamform_cap, GET_VHT_CAPABILITY_ELE_SU_BFEE_STS_CAP(pvhtpriv_sta->vht_cap)<<8);
342 // B12 SU Beamformee Capable, the target supports Beamformee and we are Beamformer
343 if (TEST_FLAG(pvhtpriv_ap->beamform_cap, BEAMFORMING_VHT_BEAMFORMEE_ENABLE) &&
344 GET_VHT_CAPABILITY_ELE_SU_BFER(pvhtpriv_sta->vht_cap))
346 SET_FLAG(cur_beamform_cap, BEAMFORMING_VHT_BEAMFORMER_ENABLE);
347 /*Shit to BEAMFORMING_VHT_BEAMFORMEE_SOUND_DIM*/
348 SET_FLAG(cur_beamform_cap, GET_VHT_CAPABILITY_ELE_SU_BFER_SOUND_DIM_NUM(pvhtpriv_sta->vht_cap)<<12);
350 pvhtpriv_sta->beamform_cap = cur_beamform_cap;
351 if (cur_beamform_cap) {
352 DBG_871X("Current STA(%d) VHT Beamforming Setting = %02X\n", psta->aid, cur_beamform_cap);
356 // B23 B24 B25 Maximum A-MPDU Length Exponent
357 pvhtpriv_sta->ampdu_len = GET_VHT_CAPABILITY_ELE_MAX_RXAMPDU_FACTOR(pvhtpriv_sta->vht_cap);
359 pcap_mcs = GET_VHT_CAPABILITY_ELE_RX_MCS(pvhtpriv_sta->vht_cap);
360 _rtw_memcpy(pvhtpriv_sta->vht_mcs_map, pcap_mcs, 2);
362 pvhtpriv_sta->vht_highest_rate = rtw_get_vht_highest_rate(pvhtpriv_sta->vht_mcs_map);
366 void update_hw_vht_param(_adapter *padapter)
368 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
369 struct vht_priv *pvhtpriv = &pmlmepriv->vhtpriv;
370 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
371 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
374 ht_AMPDU_len = pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x03;
376 if(pvhtpriv->ampdu_len > ht_AMPDU_len)
377 rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_FACTOR, (u8 *)(&pvhtpriv->ampdu_len));
380 void VHT_caps_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE)
382 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
383 struct vht_priv *pvhtpriv = &pmlmepriv->vhtpriv;
384 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
385 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
386 u8 cur_ldpc_cap = 0, cur_stbc_cap = 0, rf_type = RF_1T1R;
387 u16 cur_beamform_cap = 0;
391 if(pIE==NULL) return;
393 if(pvhtpriv->vht_option == _FALSE) return;
395 pmlmeinfo->VHT_enable = 1;
398 if (TEST_FLAG(pvhtpriv->ldpc_cap, LDPC_VHT_ENABLE_TX) &&
399 GET_VHT_CAPABILITY_ELE_RX_LDPC(pIE->data))
401 SET_FLAG(cur_ldpc_cap, (LDPC_VHT_ENABLE_TX | LDPC_VHT_CAP_TX));
402 DBG_871X("Current VHT LDPC Setting = %02X\n", cur_ldpc_cap);
404 pvhtpriv->ldpc_cap = cur_ldpc_cap;
406 // B5 Short GI for 80 MHz
407 pvhtpriv->sgi_80m = (GET_VHT_CAPABILITY_ELE_SHORT_GI80M(pIE->data) & pvhtpriv->sgi_80m) ? _TRUE : _FALSE;
408 //DBG_871X("Current ShortGI80MHz = %d\n", pvhtpriv->sgi_80m);
411 if (TEST_FLAG(pvhtpriv->stbc_cap, STBC_VHT_ENABLE_TX) &&
412 GET_VHT_CAPABILITY_ELE_RX_STBC(pIE->data))
414 SET_FLAG(cur_stbc_cap, (STBC_VHT_ENABLE_TX | STBC_VHT_CAP_TX));
415 DBG_871X("Current VHT STBC Setting = %02X\n", cur_stbc_cap);
417 pvhtpriv->stbc_cap = cur_stbc_cap;
418 #ifdef CONFIG_BEAMFORMING
419 // B11 SU Beamformer Capable, the target supports Beamformer and we are Beamformee
420 if (TEST_FLAG(pvhtpriv->beamform_cap, BEAMFORMING_VHT_BEAMFORMER_ENABLE) &&
421 GET_VHT_CAPABILITY_ELE_SU_BFEE(pIE->data))
423 SET_FLAG(cur_beamform_cap, BEAMFORMING_VHT_BEAMFORMEE_ENABLE);
424 /*Shift to BEAMFORMING_VHT_BEAMFORMER_STS_CAP*/
425 SET_FLAG(cur_beamform_cap, GET_VHT_CAPABILITY_ELE_SU_BFEE_STS_CAP(pIE->data)<<8);
428 // B12 SU Beamformee Capable, the target supports Beamformee and we are Beamformer
429 if (TEST_FLAG(pvhtpriv->beamform_cap, BEAMFORMING_VHT_BEAMFORMEE_ENABLE) &&
430 GET_VHT_CAPABILITY_ELE_SU_BFER(pIE->data))
432 SET_FLAG(cur_beamform_cap, BEAMFORMING_VHT_BEAMFORMER_ENABLE);
433 /*Shit to BEAMFORMING_VHT_BEAMFORMEE_SOUND_DIM*/
434 SET_FLAG(cur_beamform_cap, GET_VHT_CAPABILITY_ELE_SU_BFER_SOUND_DIM_NUM(pIE->data)<<12);
437 pvhtpriv->beamform_cap = cur_beamform_cap;
438 if (cur_beamform_cap) {
439 DBG_871X("Current VHT Beamforming Setting = %02X\n", cur_beamform_cap);
442 // B23 B24 B25 Maximum A-MPDU Length Exponent
443 pvhtpriv->ampdu_len = GET_VHT_CAPABILITY_ELE_MAX_RXAMPDU_FACTOR(pIE->data);
445 pcap_mcs = GET_VHT_CAPABILITY_ELE_RX_MCS(pIE->data);
446 _rtw_memcpy(vht_mcs, pcap_mcs, 2);
448 rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
449 if ((rf_type == RF_1T1R) || (rf_type == RF_1T2R))
451 else if (rf_type == RF_2T2R)
453 else if (rf_type == RF_3T3R)
456 _rtw_memcpy(pvhtpriv->vht_mcs_map, vht_mcs, 2);
458 pvhtpriv->vht_highest_rate = rtw_get_vht_highest_rate(pvhtpriv->vht_mcs_map);
461 void VHT_operation_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE)
463 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
464 struct vht_priv *pvhtpriv = &pmlmepriv->vhtpriv;
466 if(pIE==NULL) return;
468 if(pvhtpriv->vht_option == _FALSE) return;
471 void rtw_process_vht_op_mode_notify(_adapter *padapter, u8 *pframe, PVOID sta)
473 struct sta_info *psta = (struct sta_info *)sta;
474 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
475 struct vht_priv *pvhtpriv = &pmlmepriv->vhtpriv;
476 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
477 struct registry_priv *regsty = adapter_to_regsty(padapter);
479 u8 target_rxss, current_rxss;
480 u8 update_ra = _FALSE;
481 u8 vht_mcs_map[2] = {};
483 if(pvhtpriv->vht_option == _FALSE)
486 target_bw = GET_VHT_OPERATING_MODE_FIELD_CHNL_WIDTH(pframe);
487 target_rxss = (GET_VHT_OPERATING_MODE_FIELD_RX_NSS(pframe)+1);
489 if (target_bw != psta->bw_mode) {
490 if (hal_is_bw_support(padapter, target_bw)
491 && REGSTY_IS_BW_5G_SUPPORT(regsty, target_bw)
494 psta->bw_mode = target_bw;
498 current_rxss = rtw_vht_mcsmap_to_nss(psta->vhtpriv.vht_mcs_map);
499 if (target_rxss != current_rxss) {
502 rtw_vht_nss_to_mcsmap(target_rxss, vht_mcs_map, psta->vhtpriv.vht_mcs_map);
503 _rtw_memcpy(psta->vhtpriv.vht_mcs_map, vht_mcs_map, 2);
505 rtw_hal_update_sta_rate_mask(padapter, psta);
509 rtw_dm_ra_mask_wk_cmd(padapter, (u8 *)psta);
513 u32 rtw_build_vht_operation_ie(_adapter *padapter, u8 *pbuf, u8 channel)
515 struct registry_priv *pregistrypriv = &padapter->registrypriv;
516 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
517 struct vht_priv *pvhtpriv = &pmlmepriv->vhtpriv;
518 //struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
519 u8 ChnlWidth, center_freq, bw_mode, rf_type = 0;
523 rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
525 _rtw_memset(operation, 0, 5);
527 bw_mode = REGSTY_BW_5G(pregistrypriv); /* TODO: control op bw with other info */
529 if (hal_chk_bw_cap(padapter, BW_CAP_80M | BW_CAP_160M)
530 && REGSTY_BW_5G(pregistrypriv) >= CHANNEL_WIDTH_80
532 center_freq = rtw_get_center_ch(channel, bw_mode, HAL_PRIME_CHNL_OFFSET_LOWER);
540 SET_VHT_OPERATION_ELE_CHL_WIDTH(operation, ChnlWidth);
542 SET_VHT_OPERATION_ELE_CHL_CENTER_FREQ1(operation, center_freq);//Todo: need to set correct center channel
543 SET_VHT_OPERATION_ELE_CHL_CENTER_FREQ2(operation,0);
545 if (padapter->registrypriv.rf_config != RF_MAX_TYPE)
546 rf_type = padapter->registrypriv.rf_config;
571 DBG_871X("%s, %d, unknown rf type\n", __func__, __LINE__);
574 rtw_set_ie(pbuf, EID_VHTOperation, 5, operation, &len);
579 u32 rtw_build_vht_op_mode_notify_ie(_adapter *padapter, u8 *pbuf, u8 bw)
581 //struct registry_priv *pregistrypriv = &padapter->registrypriv;
582 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
583 struct vht_priv *pvhtpriv = &pmlmepriv->vhtpriv;
585 u8 opmode = 0, rf_type = 0;
586 u8 chnl_width, rx_nss;
590 rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
591 if(rf_type == RF_3T3R)
593 else if(rf_type == RF_2T2R)
598 SET_VHT_OPERATING_MODE_FIELD_CHNL_WIDTH(&opmode, chnl_width);
599 SET_VHT_OPERATING_MODE_FIELD_RX_NSS(&opmode, (rx_nss-1));
600 SET_VHT_OPERATING_MODE_FIELD_RX_NSS_TYPE(&opmode, 0); //Todo
602 pvhtpriv->vht_op_mode_notify = opmode;
604 pbuf = rtw_set_ie(pbuf, EID_OpModeNotification, 1, &opmode, &len);
609 u32 rtw_build_vht_cap_ie(_adapter *padapter, u8 *pbuf)
611 u8 bw, rf_type, rf_num, rx_stbc_nss = 0;
615 struct registry_priv *pregistrypriv = &padapter->registrypriv;
616 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
617 struct vht_priv *pvhtpriv = &pmlmepriv->vhtpriv;
619 pcap = pvhtpriv->vht_cap;
620 _rtw_memset(pcap, 0, 32);
622 /* B0 B1 Maximum MPDU Length */
623 SET_VHT_CAPABILITY_ELE_MAX_MPDU_LENGTH(pcap, 2);
625 /* B2 B3 Supported Channel Width Set */
626 if (hal_chk_bw_cap(padapter, BW_CAP_160M) && REGSTY_IS_BW_5G_SUPPORT(pregistrypriv, CHANNEL_WIDTH_160)) {
627 if (hal_chk_bw_cap(padapter, BW_CAP_80_80M) && REGSTY_IS_BW_5G_SUPPORT(pregistrypriv, CHANNEL_WIDTH_80_80))
628 SET_VHT_CAPABILITY_ELE_CHL_WIDTH(pcap, 2);
630 SET_VHT_CAPABILITY_ELE_CHL_WIDTH(pcap, 1);
632 SET_VHT_CAPABILITY_ELE_CHL_WIDTH(pcap, 0);
636 if(TEST_FLAG(pvhtpriv->ldpc_cap, LDPC_VHT_ENABLE_RX))
638 SET_VHT_CAPABILITY_ELE_RX_LDPC(pcap, 1);
641 // B5 ShortGI for 80MHz
642 SET_VHT_CAPABILITY_ELE_SHORT_GI80M(pcap, pvhtpriv->sgi_80m? 1 : 0); // We can receive Short GI of 80M
644 // B6 ShortGI for 160MHz
645 //SET_VHT_CAPABILITY_ELE_SHORT_GI160M(pcap, pvhtpriv->sgi_80m? 1 : 0);
648 if(TEST_FLAG(pvhtpriv->stbc_cap, STBC_VHT_ENABLE_TX))
650 SET_VHT_CAPABILITY_ELE_TX_STBC(pcap, 1);
654 if(TEST_FLAG(pvhtpriv->stbc_cap, STBC_VHT_ENABLE_RX))
656 rtw_hal_get_def_var(padapter, HAL_DEF_RX_STBC, (u8 *)(&rx_stbc_nss));
658 SET_VHT_CAPABILITY_ELE_RX_STBC(pcap, rx_stbc_nss);
661 // B11 SU Beamformer Capable
662 if (TEST_FLAG(pvhtpriv->beamform_cap, BEAMFORMING_VHT_BEAMFORMER_ENABLE)) {
663 SET_VHT_CAPABILITY_ELE_SU_BFER(pcap, 1);
664 // B16 17 18 Number of Sounding Dimensions
665 rtw_hal_get_def_var(padapter, HAL_DEF_BEAMFORMER_CAP, (u8 *)&rf_num);
666 SET_VHT_CAPABILITY_ELE_SOUNDING_DIMENSIONS(pcap, rf_num);
669 // B12 SU Beamformee Capable
670 if (TEST_FLAG(pvhtpriv->beamform_cap, BEAMFORMING_VHT_BEAMFORMEE_ENABLE)) {
671 SET_VHT_CAPABILITY_ELE_SU_BFEE(pcap, 1);
672 // B13 14 15 Compressed Steering Number of Beamformer Antennas Supported
673 rtw_hal_get_def_var(padapter, HAL_DEF_BEAMFORMEE_CAP, (u8 *)&rf_num);
674 SET_VHT_CAPABILITY_ELE_BFER_ANT_SUPP(pcap, rf_num);
677 // B19 MU Beamformer Capable
678 SET_VHT_CAPABILITY_ELE_MU_BFER(pcap, 0); //HW don't support mu bfee/bfer
679 // B20 MU Beamformee Capable
680 SET_VHT_CAPABILITY_ELE_MU_BFEE(pcap, 0);
682 SET_VHT_CAPABILITY_ELE_TXOP_PS(pcap, 0);
683 // B22 +HTC-VHT Capable
684 SET_VHT_CAPABILITY_ELE_HTC_VHT(pcap, 1);
685 // B23 24 25 Maximum A-MPDU Length Exponent
686 if (pregistrypriv->ampdu_factor != 0xFE)
688 SET_VHT_CAPABILITY_ELE_MAX_RXAMPDU_FACTOR(pcap, pregistrypriv->ampdu_factor);
692 SET_VHT_CAPABILITY_ELE_MAX_RXAMPDU_FACTOR(pcap, 7);
694 // B26 27 VHT Link Adaptation Capable
695 SET_VHT_CAPABILITY_ELE_LINK_ADAPTION(pcap, 0);
697 pcap_mcs = GET_VHT_CAPABILITY_ELE_RX_MCS(pcap);
698 _rtw_memcpy(pcap_mcs, pvhtpriv->vht_mcs_map, 2);
700 pcap_mcs = GET_VHT_CAPABILITY_ELE_TX_MCS(pcap);
701 _rtw_memcpy(pcap_mcs, pvhtpriv->vht_mcs_map, 2);
703 /* find the largest bw supported by both registry and hal */
704 bw = hal_largest_bw(padapter, REGSTY_BW_5G(pregistrypriv));
706 HighestRate = VHT_MCS_DATA_RATE[bw][pvhtpriv->sgi_80m][((pvhtpriv->vht_highest_rate - MGN_VHT1SS_MCS0)&0x3f)];
707 HighestRate = (HighestRate+1) >> 1;
709 SET_VHT_CAPABILITY_ELE_MCS_RX_HIGHEST_RATE(pcap, HighestRate); //indicate we support highest rx rate is 600Mbps.
710 SET_VHT_CAPABILITY_ELE_MCS_TX_HIGHEST_RATE(pcap, HighestRate); //indicate we support highest tx rate is 600Mbps.
712 pbuf = rtw_set_ie(pbuf, EID_VHTCapability, 12, pcap, &len);
717 u32 rtw_restructure_vht_ie(_adapter *padapter, u8 *in_ie, u8 *out_ie, uint in_len, uint *pout_len)
719 u32 ielen=0, out_len=0;
720 u8 cap_len=0, notify_len=0, notify_bw=0, operation_bw=0, supported_chnl_width=0;
722 struct registry_priv *pregistrypriv = &padapter->registrypriv;
723 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
724 struct vht_priv *pvhtpriv = &pmlmepriv->vhtpriv;
726 rtw_vht_use_default_setting(padapter);
728 p = rtw_get_ie(in_ie+12, EID_VHTCapability, &ielen, in_len-12);
730 supported_chnl_width = GET_VHT_CAPABILITY_ELE_CHL_WIDTH(p+2);
732 // VHT Capabilities element
733 cap_len = rtw_build_vht_cap_ie(padapter, out_ie+*pout_len);
734 *pout_len += cap_len;
737 p = rtw_get_ie(in_ie+12, _HT_EXTRA_INFO_IE_, &ielen, in_len-12);
739 struct HT_info_element *pht_info = (struct HT_info_element *)(p+2);
740 if (pht_info->infos[0] & BIT(2))
741 operation_bw = CHANNEL_WIDTH_40;
743 operation_bw = CHANNEL_WIDTH_20;
746 // VHT Operation element
747 p = rtw_get_ie(in_ie+12, EID_VHTOperation, &ielen, in_len-12);
750 if (GET_VHT_OPERATION_ELE_CHL_WIDTH(p+2) >= 1) {
751 if (supported_chnl_width == 2)
752 operation_bw = CHANNEL_WIDTH_80_80;
753 else if (supported_chnl_width == 1)
754 operation_bw = CHANNEL_WIDTH_160;
756 operation_bw = CHANNEL_WIDTH_80;
758 pframe = rtw_set_ie(out_ie+out_len, EID_VHTOperation, ielen, p+2 , pout_len);
761 /* find the largest bw supported by both registry and hal */
762 notify_bw = hal_largest_bw(padapter, REGSTY_BW_5G(pregistrypriv));
764 if (notify_bw > operation_bw)
765 notify_bw = operation_bw;
767 // Operating Mode Notification element
768 notify_len = rtw_build_vht_op_mode_notify_ie(padapter, out_ie+*pout_len, notify_bw);
769 *pout_len += notify_len;
771 pvhtpriv->vht_option = _TRUE;
774 return (pvhtpriv->vht_option);
778 void VHTOnAssocRsp(_adapter *padapter)
780 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
781 struct vht_priv *pvhtpriv = &pmlmepriv->vhtpriv;
782 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
783 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
786 DBG_871X("%s\n", __FUNCTION__);
788 if (!pmlmeinfo->HT_enable)
791 if (!pmlmeinfo->VHT_enable)
794 ht_AMPDU_len = pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x03;
796 if(pvhtpriv->ampdu_len > ht_AMPDU_len)
797 rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_FACTOR, (u8 *)(&pvhtpriv->ampdu_len));
799 rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_MAX_TIME, (u8 *)(&pvhtpriv->vht_highest_rate));
802 #endif //CONFIG_80211AC_VHT