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, 2106}, // 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, 2340} } // 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;
137 pvhtpriv->sgi_80m = TEST_FLAG(pregistrypriv->short_gi, BIT2) ? _TRUE : _FALSE;
140 rtw_hal_get_def_var(padapter, HAL_DEF_RX_LDPC, (u8 *)&bHwLDPCSupport);
141 CLEAR_FLAGS(pvhtpriv->ldpc_cap);
144 if(TEST_FLAG(pregistrypriv->ldpc_cap, BIT0))
145 SET_FLAG(pvhtpriv->ldpc_cap, LDPC_VHT_ENABLE_RX);
147 rtw_hal_get_def_var(padapter, HAL_DEF_TX_LDPC, (u8 *)&bHwLDPCSupport);
150 if(TEST_FLAG(pregistrypriv->ldpc_cap, BIT1))
151 SET_FLAG(pvhtpriv->ldpc_cap, LDPC_VHT_ENABLE_TX);
153 if (pvhtpriv->ldpc_cap)
154 DBG_871X("[VHT] Support LDPC = 0x%02X\n", pvhtpriv->ldpc_cap);
157 rtw_hal_get_def_var(padapter, HAL_DEF_TX_STBC, (u8 *)&bHwSTBCSupport);
158 CLEAR_FLAGS(pvhtpriv->stbc_cap);
161 if(TEST_FLAG(pregistrypriv->stbc_cap, BIT1))
162 SET_FLAG(pvhtpriv->stbc_cap, STBC_VHT_ENABLE_TX);
164 rtw_hal_get_def_var(padapter, HAL_DEF_RX_STBC, (u8 *)&bHwSTBCSupport);
167 if(TEST_FLAG(pregistrypriv->stbc_cap, BIT0))
168 SET_FLAG(pvhtpriv->stbc_cap, STBC_VHT_ENABLE_RX);
170 if (pvhtpriv->stbc_cap)
171 DBG_871X("[VHT] Support STBC = 0x%02X\n", pvhtpriv->stbc_cap);
173 // Beamforming setting
174 rtw_hal_get_def_var(padapter, HAL_DEF_EXPLICIT_BEAMFORMER, (u8 *)&bHwSupportBeamformer);
175 rtw_hal_get_def_var(padapter, HAL_DEF_EXPLICIT_BEAMFORMEE, (u8 *)&bHwSupportBeamformee);
176 CLEAR_FLAGS(pvhtpriv->beamform_cap);
177 if(TEST_FLAG(pregistrypriv->beamform_cap, BIT0) && bHwSupportBeamformer)
179 SET_FLAG(pvhtpriv->beamform_cap, BEAMFORMING_VHT_BEAMFORMER_ENABLE);
180 DBG_871X("[VHT] Support Beamformer\n");
182 if(TEST_FLAG(pregistrypriv->beamform_cap, BIT1) && bHwSupportBeamformee)
184 SET_FLAG(pvhtpriv->beamform_cap, BEAMFORMING_VHT_BEAMFORMEE_ENABLE);
185 DBG_871X("[VHT] Support Beamformee\n");
188 pvhtpriv->ampdu_len = pregistrypriv->ampdu_factor;
190 rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
192 if (rf_type == RF_3T3R)
193 pvhtpriv->vht_mcs_map[0] = 0xea; /* support 1SS MCS 0~9 2SS MCS 0~9 3SS MCS 0~9 */
194 else if(rf_type == RF_2T2R)
195 pvhtpriv->vht_mcs_map[0] = 0xfa; /* support 1SS MCS 0~9 2SS MCS 0~9 */
197 pvhtpriv->vht_mcs_map[0] = 0xfe; /* Only support 1SS MCS 0~9; */
198 pvhtpriv->vht_mcs_map[1] = 0xff;
200 if(pregistrypriv->vht_rate_sel == 1)
202 pvhtpriv->vht_mcs_map[0] = 0xfc; // support 1SS MCS 0~7
204 else if(pregistrypriv->vht_rate_sel == 2)
206 pvhtpriv->vht_mcs_map[0] = 0xfd; // Support 1SS MCS 0~8
208 else if(pregistrypriv->vht_rate_sel == 3)
210 pvhtpriv->vht_mcs_map[0] = 0xfe; // Support 1SS MCS 0~9
212 else if(pregistrypriv->vht_rate_sel == 4)
214 pvhtpriv->vht_mcs_map[0] = 0xf0; // support 1SS MCS 0~7 2SS MCS 0~7
216 else if(pregistrypriv->vht_rate_sel == 5)
218 pvhtpriv->vht_mcs_map[0] = 0xf5; // support 1SS MCS 0~8 2SS MCS 0~8
220 else if(pregistrypriv->vht_rate_sel == 6)
222 pvhtpriv->vht_mcs_map[0] = 0xfa; // support 1SS MCS 0~9 2SS MCS 0~9
224 else if(pregistrypriv->vht_rate_sel == 7)
226 pvhtpriv->vht_mcs_map[0] = 0xf8; // support 1SS MCS 0-7 2SS MCS 0~9
228 else if(pregistrypriv->vht_rate_sel == 8)
230 pvhtpriv->vht_mcs_map[0] = 0xf9; // support 1SS MCS 0-8 2SS MCS 0~9
232 else if(pregistrypriv->vht_rate_sel == 9)
234 pvhtpriv->vht_mcs_map[0] = 0xf4; // support 1SS MCS 0-7 2SS MCS 0~8
237 pvhtpriv->vht_highest_rate = rtw_get_vht_highest_rate(pvhtpriv->vht_mcs_map);
240 u64 rtw_vht_rate_to_bitmap(u8 *pVHTRate)
247 for(i = j= 0; i < Bits_3ss; i+=2, j+=10)
249 /* every two bits means single sptial stream */
250 tmpRate = (pVHTRate[0] >> i) & 3;
254 RateBitmap = RateBitmap | (0x03ff << j);
257 RateBitmap = RateBitmap | (0x01ff << j);
261 RateBitmap = RateBitmap | (0x00ff << j);
268 DBG_871X("RateBitmap=%016llx , pVHTRate[0]=%02x\n", RateBitmap, pVHTRate[0]);
272 void update_sta_vht_info_apmode(_adapter *padapter, PVOID sta)
274 struct sta_info *psta = (struct sta_info *)sta;
275 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
276 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
277 struct vht_priv *pvhtpriv_ap = &pmlmepriv->vhtpriv;
278 struct vht_priv *pvhtpriv_sta = &psta->vhtpriv;
279 struct ht_priv *phtpriv_sta = &psta->htpriv;
280 u8 cur_ldpc_cap=0, cur_stbc_cap=0, cur_beamform_cap=0, bw_mode = 0;
283 if (pvhtpriv_sta->vht_option == _FALSE) {
287 bw_mode = GET_VHT_OPERATING_MODE_FIELD_CHNL_WIDTH(&pvhtpriv_sta->vht_op_mode_notify);
289 //if (bw_mode > psta->bw_mode)
290 psta->bw_mode = bw_mode;
293 if (TEST_FLAG(pvhtpriv_ap->ldpc_cap, LDPC_VHT_ENABLE_TX) &&
294 GET_VHT_CAPABILITY_ELE_RX_LDPC(pvhtpriv_sta->vht_cap))
296 SET_FLAG(cur_ldpc_cap, (LDPC_VHT_ENABLE_TX | LDPC_VHT_CAP_TX));
297 DBG_871X("Current STA(%d) VHT LDPC = %02X\n", psta->aid, cur_ldpc_cap);
299 pvhtpriv_sta->ldpc_cap = cur_ldpc_cap;
301 if (psta->bw_mode > pmlmeext->cur_bwmode)
302 psta->bw_mode = pmlmeext->cur_bwmode;
304 if (psta->bw_mode == CHANNEL_WIDTH_80) {
305 // B5 Short GI for 80 MHz
306 pvhtpriv_sta->sgi_80m = (GET_VHT_CAPABILITY_ELE_SHORT_GI80M(pvhtpriv_sta->vht_cap) & pvhtpriv_ap->sgi_80m) ? _TRUE : _FALSE;
307 //DBG_871X("Current STA ShortGI80MHz = %d\n", pvhtpriv_sta->sgi_80m);
308 } else if (psta->bw_mode >= CHANNEL_WIDTH_160) {
309 // B5 Short GI for 80 MHz
310 pvhtpriv_sta->sgi_80m = (GET_VHT_CAPABILITY_ELE_SHORT_GI160M(pvhtpriv_sta->vht_cap) & pvhtpriv_ap->sgi_80m) ? _TRUE : _FALSE;
311 //DBG_871X("Current STA ShortGI160MHz = %d\n", pvhtpriv_sta->sgi_80m);
315 if (TEST_FLAG(pvhtpriv_ap->stbc_cap, STBC_VHT_ENABLE_TX) &&
316 GET_VHT_CAPABILITY_ELE_RX_STBC(pvhtpriv_sta->vht_cap))
318 SET_FLAG(cur_stbc_cap, (STBC_VHT_ENABLE_TX | STBC_VHT_CAP_TX));
319 DBG_871X("Current STA(%d) VHT STBC = %02X\n", psta->aid, cur_stbc_cap);
321 pvhtpriv_sta->stbc_cap = cur_stbc_cap;
323 // B11 SU Beamformer Capable, the target supports Beamformer and we are Beamformee
324 if (TEST_FLAG(pvhtpriv_ap->beamform_cap, BEAMFORMING_VHT_BEAMFORMER_ENABLE) &&
325 GET_VHT_CAPABILITY_ELE_SU_BFEE(pvhtpriv_sta->vht_cap))
327 SET_FLAG(cur_beamform_cap, BEAMFORMING_VHT_BEAMFORMEE_ENABLE);
330 // B12 SU Beamformee Capable, the target supports Beamformee and we are Beamformer
331 if (TEST_FLAG(pvhtpriv_ap->beamform_cap, BEAMFORMING_VHT_BEAMFORMEE_ENABLE) &&
332 GET_VHT_CAPABILITY_ELE_SU_BFER(pvhtpriv_sta->vht_cap))
334 SET_FLAG(cur_beamform_cap, BEAMFORMING_VHT_BEAMFORMER_ENABLE);
336 pvhtpriv_sta->beamform_cap = cur_beamform_cap;
337 if (cur_beamform_cap) {
338 DBG_871X("Current STA(%d) VHT Beamforming Setting = %02X\n", psta->aid, cur_beamform_cap);
341 // B23 B24 B25 Maximum A-MPDU Length Exponent
342 pvhtpriv_sta->ampdu_len = GET_VHT_CAPABILITY_ELE_MAX_RXAMPDU_FACTOR(pvhtpriv_sta->vht_cap);
344 pcap_mcs = GET_VHT_CAPABILITY_ELE_RX_MCS(pvhtpriv_sta->vht_cap);
345 _rtw_memcpy(pvhtpriv_sta->vht_mcs_map, pcap_mcs, 2);
347 pvhtpriv_sta->vht_highest_rate = rtw_get_vht_highest_rate(pvhtpriv_sta->vht_mcs_map);
351 void update_hw_vht_param(_adapter *padapter)
353 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
354 struct vht_priv *pvhtpriv = &pmlmepriv->vhtpriv;
355 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
356 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
359 ht_AMPDU_len = pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x03;
361 if(pvhtpriv->ampdu_len > ht_AMPDU_len)
362 rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_FACTOR, (u8 *)(&pvhtpriv->ampdu_len));
365 void VHT_caps_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE)
367 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
368 struct vht_priv *pvhtpriv = &pmlmepriv->vhtpriv;
369 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
370 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
371 u8 cur_ldpc_cap=0, cur_stbc_cap=0, cur_beamform_cap=0, rf_type = RF_1T1R;
375 if(pIE==NULL) return;
377 if(pvhtpriv->vht_option == _FALSE) return;
379 pmlmeinfo->VHT_enable = 1;
382 if (TEST_FLAG(pvhtpriv->ldpc_cap, LDPC_VHT_ENABLE_TX) &&
383 GET_VHT_CAPABILITY_ELE_RX_LDPC(pIE->data))
385 SET_FLAG(cur_ldpc_cap, (LDPC_VHT_ENABLE_TX | LDPC_VHT_CAP_TX));
386 DBG_871X("Current VHT LDPC Setting = %02X\n", cur_ldpc_cap);
388 pvhtpriv->ldpc_cap = cur_ldpc_cap;
390 // B5 Short GI for 80 MHz
391 pvhtpriv->sgi_80m = (GET_VHT_CAPABILITY_ELE_SHORT_GI80M(pIE->data) & pvhtpriv->sgi_80m) ? _TRUE : _FALSE;
392 //DBG_871X("Current ShortGI80MHz = %d\n", pvhtpriv->sgi_80m);
395 if (TEST_FLAG(pvhtpriv->stbc_cap, STBC_VHT_ENABLE_TX) &&
396 GET_VHT_CAPABILITY_ELE_RX_STBC(pIE->data))
398 SET_FLAG(cur_stbc_cap, (STBC_VHT_ENABLE_TX | STBC_VHT_CAP_TX));
399 DBG_871X("Current VHT STBC Setting = %02X\n", cur_stbc_cap);
401 pvhtpriv->stbc_cap = cur_stbc_cap;
403 // B11 SU Beamformer Capable, the target supports Beamformer and we are Beamformee
404 if (TEST_FLAG(pvhtpriv->beamform_cap, BEAMFORMING_VHT_BEAMFORMER_ENABLE) &&
405 GET_VHT_CAPABILITY_ELE_SU_BFEE(pIE->data))
407 SET_FLAG(cur_beamform_cap, BEAMFORMING_VHT_BEAMFORMEE_ENABLE);
410 // B12 SU Beamformee Capable, the target supports Beamformee and we are Beamformer
411 if (TEST_FLAG(pvhtpriv->beamform_cap, BEAMFORMING_VHT_BEAMFORMEE_ENABLE) &&
412 GET_VHT_CAPABILITY_ELE_SU_BFER(pIE->data))
414 SET_FLAG(cur_beamform_cap, BEAMFORMING_VHT_BEAMFORMER_ENABLE);
416 pvhtpriv->beamform_cap = cur_beamform_cap;
417 if (cur_beamform_cap) {
418 DBG_871X("Current VHT Beamforming Setting = %02X\n", cur_beamform_cap);
421 // B23 B24 B25 Maximum A-MPDU Length Exponent
422 pvhtpriv->ampdu_len = GET_VHT_CAPABILITY_ELE_MAX_RXAMPDU_FACTOR(pIE->data);
424 pcap_mcs = GET_VHT_CAPABILITY_ELE_RX_MCS(pIE->data);
425 _rtw_memcpy(vht_mcs, pcap_mcs, 2);
427 rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
428 if ((rf_type == RF_1T1R) || (rf_type == RF_1T2R))
430 else if (rf_type == RF_2T2R)
432 else if (rf_type == RF_3T3R)
435 _rtw_memcpy(pvhtpriv->vht_mcs_map, vht_mcs, 2);
437 pvhtpriv->vht_highest_rate = rtw_get_vht_highest_rate(pvhtpriv->vht_mcs_map);
440 void VHT_operation_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE)
442 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
443 struct vht_priv *pvhtpriv = &pmlmepriv->vhtpriv;
445 if(pIE==NULL) return;
447 if(pvhtpriv->vht_option == _FALSE) return;
450 void rtw_process_vht_op_mode_notify(_adapter *padapter, u8 *pframe, PVOID sta)
452 struct sta_info *psta = (struct sta_info *)sta;
453 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
454 struct vht_priv *pvhtpriv = &pmlmepriv->vhtpriv;
455 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
457 u8 target_rxss, current_rxss;
458 u8 update_ra = _FALSE;
459 u8 vht_mcs_map[2] = {};
461 if(pvhtpriv->vht_option == _FALSE)
464 target_bw = GET_VHT_OPERATING_MODE_FIELD_CHNL_WIDTH(pframe);
465 target_rxss = (GET_VHT_OPERATING_MODE_FIELD_RX_NSS(pframe)+1);
467 if (target_bw != psta->bw_mode) {
468 if (target_bw <= (padapter->registrypriv.bw_mode >> 4)) {
470 psta->bw_mode = target_bw;
474 current_rxss = rtw_vht_mcsmap_to_nss(psta->vhtpriv.vht_mcs_map);
475 if (target_rxss != current_rxss) {
478 rtw_vht_nss_to_mcsmap(target_rxss, vht_mcs_map, psta->vhtpriv.vht_mcs_map);
479 _rtw_memcpy(psta->vhtpriv.vht_mcs_map, vht_mcs_map, 2);
481 rtw_hal_update_sta_rate_mask(padapter, psta);
485 rtw_dm_ra_mask_wk_cmd(padapter, (u8 *)psta);
489 u32 rtw_build_vht_operation_ie(_adapter *padapter, u8 *pbuf, u8 channel)
491 struct registry_priv *pregistrypriv = &padapter->registrypriv;
492 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
493 struct vht_priv *pvhtpriv = &pmlmepriv->vhtpriv;
494 //struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
495 u8 ChnlWidth, center_freq, bw_mode;
499 _rtw_memset(operation, 0, 5);
501 bw_mode = pregistrypriv->bw_mode >> 4;
503 if (bw_mode >= CHANNEL_WIDTH_80)
505 center_freq = rtw_get_center_ch(channel, bw_mode, HAL_PRIME_CHNL_OFFSET_LOWER);
515 SET_VHT_OPERATION_ELE_CHL_WIDTH(operation, ChnlWidth);
517 SET_VHT_OPERATION_ELE_CHL_CENTER_FREQ1(operation, center_freq);//Todo: need to set correct center channel
518 SET_VHT_OPERATION_ELE_CHL_CENTER_FREQ2(operation,0);
522 rtw_set_ie(pbuf, EID_VHTOperation, 5, operation, &len);
527 u32 rtw_build_vht_op_mode_notify_ie(_adapter *padapter, u8 *pbuf, u8 bw)
529 //struct registry_priv *pregistrypriv = &padapter->registrypriv;
530 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
531 struct vht_priv *pvhtpriv = &pmlmepriv->vhtpriv;
533 u8 opmode = 0, rf_type = 0;
534 u8 chnl_width, rx_nss;
538 rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
539 if(rf_type == RF_3T3R)
541 else if(rf_type == RF_2T2R)
546 SET_VHT_OPERATING_MODE_FIELD_CHNL_WIDTH(&opmode, chnl_width);
547 SET_VHT_OPERATING_MODE_FIELD_RX_NSS(&opmode, (rx_nss-1));
548 SET_VHT_OPERATING_MODE_FIELD_RX_NSS_TYPE(&opmode, 0); //Todo
550 pvhtpriv->vht_op_mode_notify = opmode;
552 pbuf = rtw_set_ie(pbuf, EID_OpModeNotification, 1, &opmode, &len);
557 u32 rtw_build_vht_cap_ie(_adapter *padapter, u8 *pbuf)
563 struct registry_priv *pregistrypriv = &padapter->registrypriv;
564 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
565 struct vht_priv *pvhtpriv = &pmlmepriv->vhtpriv;
567 pcap = pvhtpriv->vht_cap;
568 _rtw_memset(pcap, 0, 32);
570 /* B0 B1 Maximum MPDU Length */
571 SET_VHT_CAPABILITY_ELE_MAX_MPDU_LENGTH(pcap, 2);
573 // B2 B3 Supported Channel Width Set
574 SET_VHT_CAPABILITY_ELE_CHL_WIDTH(pcap, 0); //indicate we don't support neither 160M nor 80+80M bandwidth.
577 if(TEST_FLAG(pvhtpriv->ldpc_cap, LDPC_VHT_ENABLE_RX))
579 SET_VHT_CAPABILITY_ELE_RX_LDPC(pcap, 1);
582 // B5 ShortGI for 80MHz
583 SET_VHT_CAPABILITY_ELE_SHORT_GI80M(pcap, pvhtpriv->sgi_80m? 1 : 0); // We can receive Short GI of 80M
585 // B6 ShortGI for 160MHz
586 //SET_VHT_CAPABILITY_ELE_SHORT_GI160M(pcap, pvhtpriv->sgi_80m? 1 : 0);
589 if(TEST_FLAG(pvhtpriv->stbc_cap, STBC_VHT_ENABLE_TX))
591 SET_VHT_CAPABILITY_ELE_TX_STBC(pcap, 1);
595 if(TEST_FLAG(pvhtpriv->stbc_cap, STBC_VHT_ENABLE_RX))
597 rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
598 if ((rf_type == RF_2T2R) || (rf_type == RF_1T2R)) {
599 SET_VHT_CAPABILITY_ELE_RX_STBC(pcap, 2);
601 else if (rf_type == RF_1T1R) {
602 SET_VHT_CAPABILITY_ELE_RX_STBC(pcap, 1);
606 // B11 SU Beamformer Capable
607 if(TEST_FLAG(pvhtpriv->beamform_cap, BEAMFORMING_VHT_BEAMFORMER_ENABLE))
609 SET_VHT_CAPABILITY_ELE_SU_BFER(pcap, 1);
610 // B16 17 18 Number of Sounding Dimensions
611 SET_VHT_CAPABILITY_ELE_SOUNDING_DIMENSIONS(pcap, 1);
614 // B12 SU Beamformee Capable
615 if(TEST_FLAG(pvhtpriv->beamform_cap, BEAMFORMING_VHT_BEAMFORMEE_ENABLE))
617 SET_VHT_CAPABILITY_ELE_SU_BFEE(pcap, 1);
618 // B13 14 15 Compressed Steering Number of Beamformer Antennas Supported
619 SET_VHT_CAPABILITY_ELE_BFER_ANT_SUPP(pcap, 1);
622 // B19 MU Beamformer Capable
623 SET_VHT_CAPABILITY_ELE_MU_BFER(pcap, 0); //HW don't support mu bfee/bfer
624 // B20 MU Beamformee Capable
625 SET_VHT_CAPABILITY_ELE_MU_BFEE(pcap, 0);
627 SET_VHT_CAPABILITY_ELE_TXOP_PS(pcap, 0);
628 // B22 +HTC-VHT Capable
629 SET_VHT_CAPABILITY_ELE_HTC_VHT(pcap, 1);
630 // B23 24 25 Maximum A-MPDU Length Exponent
631 if (pregistrypriv->ampdu_factor != 0xFE)
633 SET_VHT_CAPABILITY_ELE_MAX_RXAMPDU_FACTOR(pcap, pregistrypriv->ampdu_factor);
637 SET_VHT_CAPABILITY_ELE_MAX_RXAMPDU_FACTOR(pcap, 7);
639 // B26 27 VHT Link Adaptation Capable
640 SET_VHT_CAPABILITY_ELE_LINK_ADAPTION(pcap, 0);
642 pcap_mcs = GET_VHT_CAPABILITY_ELE_RX_MCS(pcap);
643 _rtw_memcpy(pcap_mcs, pvhtpriv->vht_mcs_map, 2);
645 pcap_mcs = GET_VHT_CAPABILITY_ELE_TX_MCS(pcap);
646 _rtw_memcpy(pcap_mcs, pvhtpriv->vht_mcs_map, 2);
648 bw = (pregistrypriv->bw_mode >> 4);
649 HighestRate = VHT_MCS_DATA_RATE[bw][pvhtpriv->sgi_80m][((pvhtpriv->vht_highest_rate - MGN_VHT1SS_MCS0)&0x3f)];
650 HighestRate = (HighestRate+1) >> 1;
652 SET_VHT_CAPABILITY_ELE_MCS_RX_HIGHEST_RATE(pcap, HighestRate); //indicate we support highest rx rate is 600Mbps.
653 SET_VHT_CAPABILITY_ELE_MCS_TX_HIGHEST_RATE(pcap, HighestRate); //indicate we support highest tx rate is 600Mbps.
655 pbuf = rtw_set_ie(pbuf, EID_VHTCapability, 12, pcap, &len);
660 u32 rtw_restructure_vht_ie(_adapter *padapter, u8 *in_ie, u8 *out_ie, uint in_len, uint *pout_len)
662 u32 ielen=0, out_len=0;
663 u8 cap_len=0, notify_len=0, notify_bw=0, operation_bw=0, supported_chnl_width=0;
665 struct registry_priv *pregistrypriv = &padapter->registrypriv;
666 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
667 struct vht_priv *pvhtpriv = &pmlmepriv->vhtpriv;
669 rtw_vht_use_default_setting(padapter);
671 p = rtw_get_ie(in_ie+12, EID_VHTCapability, &ielen, in_len-12);
673 supported_chnl_width = GET_VHT_CAPABILITY_ELE_CHL_WIDTH(p+2);
675 // VHT Capabilities element
676 cap_len = rtw_build_vht_cap_ie(padapter, out_ie+*pout_len);
677 *pout_len += cap_len;
680 p = rtw_get_ie(in_ie+12, _HT_EXTRA_INFO_IE_, &ielen, in_len-12);
682 struct HT_info_element *pht_info = (struct HT_info_element *)(p+2);
683 if (pht_info->infos[0] & BIT(2))
684 operation_bw = CHANNEL_WIDTH_40;
686 operation_bw = CHANNEL_WIDTH_20;
689 // VHT Operation element
690 p = rtw_get_ie(in_ie+12, EID_VHTOperation, &ielen, in_len-12);
693 if (GET_VHT_OPERATION_ELE_CHL_WIDTH(p+2) >= 1) {
694 if (supported_chnl_width == 2)
695 operation_bw = CHANNEL_WIDTH_80_80;
696 else if (supported_chnl_width == 1)
697 operation_bw = CHANNEL_WIDTH_160;
699 operation_bw = CHANNEL_WIDTH_80;
701 pframe = rtw_set_ie(out_ie+out_len, EID_VHTOperation, ielen, p+2 , pout_len);
704 notify_bw = pregistrypriv->bw_mode >> 4;
706 if (notify_bw > operation_bw)
707 notify_bw = operation_bw;
709 // Operating Mode Notification element
710 notify_len = rtw_build_vht_op_mode_notify_ie(padapter, out_ie+*pout_len, notify_bw);
711 *pout_len += notify_len;
713 pvhtpriv->vht_option = _TRUE;
716 return (pvhtpriv->vht_option);
720 void VHTOnAssocRsp(_adapter *padapter)
722 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
723 struct vht_priv *pvhtpriv = &pmlmepriv->vhtpriv;
724 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
725 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
728 DBG_871X("%s\n", __FUNCTION__);
730 if (!pmlmeinfo->HT_enable)
733 if (!pmlmeinfo->VHT_enable)
736 ht_AMPDU_len = pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x03;
738 if(pvhtpriv->ampdu_len > ht_AMPDU_len)
739 rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_FACTOR, (u8 *)(&pvhtpriv->ampdu_len));
741 rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_MAX_TIME, (u8 *)(&pvhtpriv->vht_highest_rate));
744 #endif //CONFIG_80211AC_VHT