net: wireless: rockchip_wlan: add rtl8188eu support
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / rtl8188eu / core / rtw_vht.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
4  *                                        
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.
8  *
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
12  * more details.
13  *
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
17  *
18  *
19  ******************************************************************************/
20 #define _RTW_VHT_C
21
22 #include <drv_types.h>
23
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 */
45         };
46
47 u8      rtw_get_vht_highest_rate(u8 *pvht_mcs_map)
48 {
49         u8      i, j;
50         u8      bit_map;
51         u8      vht_mcs_rate = 0;
52         
53         for(i = 0; i < 2; i++)
54         {
55                 if(pvht_mcs_map[i] != 0xff)
56                 {
57                         for(j = 0; j < 8; j += 2)
58                         {
59                                 bit_map = (pvht_mcs_map[i] >> j) & 3;
60                                 
61                                 if(bit_map != 3)
62                                         vht_mcs_rate = MGN_VHT1SS_MCS7 + 10*j/2 + i*40 + bit_map;  //VHT rate indications begin from 0x90
63                         }
64                 }
65         }
66         
67         /* DBG_871X("HighestVHTMCSRate is %x\n", vht_mcs_rate); */
68         return vht_mcs_rate;
69 }
70
71 u8      rtw_vht_mcsmap_to_nss(u8 *pvht_mcs_map)
72 {
73         u8      i, j;
74         u8      bit_map;
75         u8      nss = 0;
76         
77         for(i = 0; i < 2; i++)
78         {
79                 if(pvht_mcs_map[i] != 0xff)
80                 {
81                         for(j = 0; j < 8; j += 2)
82                         {
83                                 bit_map = (pvht_mcs_map[i] >> j) & 3;
84                                 
85                                 if(bit_map != 3)
86                                         nss++;
87                         }
88                 }
89         }
90         
91         /* DBG_871X("%s : %dSS\n", __FUNCTION__, nss); */
92         return nss;
93 }
94
95 void    rtw_vht_nss_to_mcsmap(u8 nss, u8 *target_mcs_map, u8 *cur_mcs_map)
96 {
97         u8      i, j;
98         u8      cur_rate, target_rate;
99         
100         for(i = 0; i < 2; i++)
101         {
102                 target_mcs_map[i] = 0;
103                 for(j = 0; j < 8; j+=2)
104                 {
105                         cur_rate = (cur_mcs_map[i] >> j) & 3;
106                         if(cur_rate == 3)  //0x3 indicates not supported that num of SS
107                                 target_rate = 3;
108                         else if(nss <= ((j/2)+i*4))
109                                 target_rate = 3;
110                         else    
111                                 target_rate = cur_rate;
112
113                         target_mcs_map[i] |= (target_rate << j);
114                 }
115         }
116         
117         //DBG_871X("%s : %dSS\n", __FUNCTION__, nss);
118 }
119
120 u16     rtw_vht_mcs_to_data_rate(u8 bw, u8 short_GI, u8 vht_mcs_rate)
121 {
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)];
126 }
127
128 void    rtw_vht_use_default_setting(_adapter *padapter)
129 {
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;
135         u8      rf_type = 0;
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;
139
140         // LDPC support
141         rtw_hal_get_def_var(padapter, HAL_DEF_RX_LDPC, (u8 *)&bHwLDPCSupport);
142         CLEAR_FLAGS(pvhtpriv->ldpc_cap);
143         if(bHwLDPCSupport)
144         {
145                 if(TEST_FLAG(pregistrypriv->ldpc_cap, BIT0))
146                         SET_FLAG(pvhtpriv->ldpc_cap, LDPC_VHT_ENABLE_RX);
147         }
148         rtw_hal_get_def_var(padapter, HAL_DEF_TX_LDPC, (u8 *)&bHwLDPCSupport);
149         if(bHwLDPCSupport)
150         {
151                 if(TEST_FLAG(pregistrypriv->ldpc_cap, BIT1))
152                         SET_FLAG(pvhtpriv->ldpc_cap, LDPC_VHT_ENABLE_TX);
153         }
154         if (pvhtpriv->ldpc_cap)
155                 DBG_871X("[VHT] Support LDPC = 0x%02X\n", pvhtpriv->ldpc_cap);
156
157         // STBC
158         rtw_hal_get_def_var(padapter, HAL_DEF_TX_STBC, (u8 *)&bHwSTBCSupport);
159         CLEAR_FLAGS(pvhtpriv->stbc_cap);
160         if(bHwSTBCSupport)
161         {
162                 if(TEST_FLAG(pregistrypriv->stbc_cap, BIT1))
163                         SET_FLAG(pvhtpriv->stbc_cap, STBC_VHT_ENABLE_TX);
164         }
165         rtw_hal_get_def_var(padapter, HAL_DEF_RX_STBC, (u8 *)&bHwSTBCSupport);
166         if(bHwSTBCSupport)
167         {
168                 if(TEST_FLAG(pregistrypriv->stbc_cap, BIT0))
169                         SET_FLAG(pvhtpriv->stbc_cap, STBC_VHT_ENABLE_RX);
170         }
171         if (pvhtpriv->stbc_cap)
172                 DBG_871X("[VHT] Support STBC = 0x%02X\n", pvhtpriv->stbc_cap);
173
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");
183                         } else
184                         DBG_871X("[VHT] CONCURRENT not AP ;not allow  Support Beamformer\n");
185                 #else
186                         SET_FLAG(pvhtpriv->beamform_cap, BEAMFORMING_VHT_BEAMFORMER_ENABLE);
187                         DBG_871X("[VHT] Support Beamformer\n");
188                 #endif
189         }
190         if(TEST_FLAG(pregistrypriv->beamform_cap, BIT1) && bHwSupportBeamformee)
191         {
192                 SET_FLAG(pvhtpriv->beamform_cap, BEAMFORMING_VHT_BEAMFORMEE_ENABLE);
193                 DBG_871X("[VHT] Support Beamformee\n");
194         }
195
196         pvhtpriv->ampdu_len = pregistrypriv->ampdu_factor;
197
198         rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
199
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 */
204         else
205                 pvhtpriv->vht_mcs_map[0] = 0xfe;        /* Only support 1SS MCS 0~9; */
206         pvhtpriv->vht_mcs_map[1] = 0xff;
207
208         if(pregistrypriv->vht_rate_sel == 1)
209         {                       
210                 pvhtpriv->vht_mcs_map[0] = 0xfc;        // support 1SS MCS 0~7
211         }
212         else if(pregistrypriv->vht_rate_sel == 2)
213         {
214                 pvhtpriv->vht_mcs_map[0] = 0xfd;        // Support 1SS MCS 0~8
215         }
216         else if(pregistrypriv->vht_rate_sel == 3)
217         {
218                 pvhtpriv->vht_mcs_map[0] = 0xfe;        // Support 1SS MCS 0~9
219         }
220         else if(pregistrypriv->vht_rate_sel == 4)
221         {
222                 pvhtpriv->vht_mcs_map[0] = 0xf0;        // support 1SS MCS 0~7 2SS MCS 0~7
223         }
224         else if(pregistrypriv->vht_rate_sel == 5)
225         {
226                 pvhtpriv->vht_mcs_map[0] = 0xf5;        // support 1SS MCS 0~8 2SS MCS 0~8
227         }
228         else if(pregistrypriv->vht_rate_sel == 6)
229         {
230                 pvhtpriv->vht_mcs_map[0] = 0xfa;        // support 1SS MCS 0~9 2SS MCS 0~9
231         }
232         else if(pregistrypriv->vht_rate_sel == 7)
233         {
234                 pvhtpriv->vht_mcs_map[0] = 0xf8;        // support 1SS MCS 0-7 2SS MCS 0~9
235         }
236         else if(pregistrypriv->vht_rate_sel == 8)
237         {
238                 pvhtpriv->vht_mcs_map[0] = 0xf9;        // support 1SS MCS 0-8 2SS MCS 0~9
239         }
240         else if(pregistrypriv->vht_rate_sel == 9)
241         {
242                 pvhtpriv->vht_mcs_map[0] = 0xf4;        // support 1SS MCS 0-7 2SS MCS 0~8
243         }
244
245         pvhtpriv->vht_highest_rate = rtw_get_vht_highest_rate(pvhtpriv->vht_mcs_map);
246 }
247
248 u64     rtw_vht_rate_to_bitmap(u8 *pVHTRate)
249 {
250
251         u8      i,j , tmpRate;
252         u64     RateBitmap = 0;
253         u8 Bits_3ss = 6;
254                 
255         for(i = j= 0; i < Bits_3ss; i+=2, j+=10)
256         {
257                 /* every two bits means single sptial stream */
258                 tmpRate = (pVHTRate[0] >> i) & 3;
259
260                 switch(tmpRate){
261                 case 2:
262                         RateBitmap = RateBitmap | (0x03ff << j);
263                         break;
264                 case 1:
265                         RateBitmap = RateBitmap | (0x01ff << j);
266                 break;
267
268                 case 0:
269                         RateBitmap = RateBitmap | (0x00ff << j);
270                 break;
271
272                 default:
273                         break;
274                 }
275         }
276         DBG_871X("RateBitmap=%016llx , pVHTRate[0]=%02x, pVHTRate[1]=%02x\n", RateBitmap, pVHTRate[0], pVHTRate[1]);
277         return RateBitmap;
278 }
279
280 void    update_sta_vht_info_apmode(_adapter *padapter, PVOID sta)
281 {
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;
290         u8      *pcap_mcs;
291
292         if (pvhtpriv_sta->vht_option == _FALSE) {
293                 return;
294         }
295
296         bw_mode = GET_VHT_OPERATING_MODE_FIELD_CHNL_WIDTH(&pvhtpriv_sta->vht_op_mode_notify);
297         
298         //if (bw_mode > psta->bw_mode)
299         psta->bw_mode = bw_mode;
300
301         // B4 Rx LDPC
302         if (TEST_FLAG(pvhtpriv_ap->ldpc_cap, LDPC_VHT_ENABLE_TX) && 
303                 GET_VHT_CAPABILITY_ELE_RX_LDPC(pvhtpriv_sta->vht_cap))
304         {
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);
307         }
308         pvhtpriv_sta->ldpc_cap = cur_ldpc_cap;
309
310         if (psta->bw_mode > pmlmeext->cur_bwmode)
311                 psta->bw_mode = pmlmeext->cur_bwmode;
312
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);
321         }
322
323         // B8 B9 B10 Rx STBC
324         if (TEST_FLAG(pvhtpriv_ap->stbc_cap, STBC_VHT_ENABLE_TX) && 
325                 GET_VHT_CAPABILITY_ELE_RX_STBC(pvhtpriv_sta->vht_cap))
326         {
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);
329         }
330         pvhtpriv_sta->stbc_cap = cur_stbc_cap;
331
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))
336         {
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);
340         }
341
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))
345         {
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);
349         }
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);
353         }
354  #endif
355
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);
358
359         pcap_mcs = GET_VHT_CAPABILITY_ELE_RX_MCS(pvhtpriv_sta->vht_cap);
360         _rtw_memcpy(pvhtpriv_sta->vht_mcs_map, pcap_mcs, 2);
361
362         pvhtpriv_sta->vht_highest_rate = rtw_get_vht_highest_rate(pvhtpriv_sta->vht_mcs_map);
363
364 }
365
366 void    update_hw_vht_param(_adapter *padapter)
367 {
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);
372         u8      ht_AMPDU_len;
373
374         ht_AMPDU_len = pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x03;
375
376         if(pvhtpriv->ampdu_len > ht_AMPDU_len)
377                 rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_FACTOR, (u8 *)(&pvhtpriv->ampdu_len));
378 }
379
380 void VHT_caps_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE)
381 {
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;
388         u8      *pcap_mcs;
389         u8      vht_mcs[2];
390
391         if(pIE==NULL) return;
392
393         if(pvhtpriv->vht_option == _FALSE)      return;
394
395         pmlmeinfo->VHT_enable = 1;
396
397         // B4 Rx LDPC
398         if (TEST_FLAG(pvhtpriv->ldpc_cap, LDPC_VHT_ENABLE_TX) && 
399                 GET_VHT_CAPABILITY_ELE_RX_LDPC(pIE->data))
400         {
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);
403         }
404         pvhtpriv->ldpc_cap = cur_ldpc_cap;
405
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);
409
410         // B8 B9 B10 Rx STBC
411         if (TEST_FLAG(pvhtpriv->stbc_cap, STBC_VHT_ENABLE_TX) && 
412                 GET_VHT_CAPABILITY_ELE_RX_STBC(pIE->data))
413         {
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);
416         }
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))
422         {
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);
426         }
427
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))
431         {
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);
435                 
436         }
437         pvhtpriv->beamform_cap = cur_beamform_cap;
438         if (cur_beamform_cap) {
439                 DBG_871X("Current VHT Beamforming Setting = %02X\n", cur_beamform_cap);
440         }
441  #endif
442         // B23 B24 B25 Maximum A-MPDU Length Exponent
443         pvhtpriv->ampdu_len = GET_VHT_CAPABILITY_ELE_MAX_RXAMPDU_FACTOR(pIE->data);
444
445         pcap_mcs = GET_VHT_CAPABILITY_ELE_RX_MCS(pIE->data);
446         _rtw_memcpy(vht_mcs, pcap_mcs, 2);
447
448         rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
449         if ((rf_type == RF_1T1R) || (rf_type == RF_1T2R))
450                 vht_mcs[0] |= 0xfc;
451         else if (rf_type == RF_2T2R)
452                 vht_mcs[0] |= 0xf0;
453         else if (rf_type == RF_3T3R)
454                 vht_mcs[0] |= 0xc0;
455
456         _rtw_memcpy(pvhtpriv->vht_mcs_map, vht_mcs, 2);
457
458         pvhtpriv->vht_highest_rate = rtw_get_vht_highest_rate(pvhtpriv->vht_mcs_map);
459 }
460
461 void VHT_operation_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE)
462 {
463         struct mlme_priv                *pmlmepriv = &padapter->mlmepriv;
464         struct vht_priv         *pvhtpriv = &pmlmepriv->vhtpriv;
465
466         if(pIE==NULL) return;
467
468         if(pvhtpriv->vht_option == _FALSE)      return;
469 }
470
471 void rtw_process_vht_op_mode_notify(_adapter *padapter, u8 *pframe, PVOID sta)
472 {
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);
478         u8      target_bw;
479         u8      target_rxss, current_rxss;
480         u8      update_ra = _FALSE;
481         u8      vht_mcs_map[2] = {};
482
483         if(pvhtpriv->vht_option == _FALSE)
484                 return;
485
486         target_bw = GET_VHT_OPERATING_MODE_FIELD_CHNL_WIDTH(pframe);
487         target_rxss = (GET_VHT_OPERATING_MODE_FIELD_RX_NSS(pframe)+1);
488
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)
492                 ) {
493                         update_ra = _TRUE;
494                         psta->bw_mode = target_bw;
495                 }
496         }
497
498         current_rxss = rtw_vht_mcsmap_to_nss(psta->vhtpriv.vht_mcs_map);
499         if (target_rxss != current_rxss) {
500                 update_ra = _TRUE;
501
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);
504                 
505                 rtw_hal_update_sta_rate_mask(padapter, psta);
506         }
507
508         if (update_ra) {
509                 rtw_dm_ra_mask_wk_cmd(padapter, (u8 *)psta);
510         }
511 }
512
513 u32     rtw_build_vht_operation_ie(_adapter *padapter, u8 *pbuf, u8 channel)
514 {
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;
520         u32     len = 0;
521         u8      operation[5];
522         
523         rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
524         
525         _rtw_memset(operation, 0, 5);
526
527         bw_mode = REGSTY_BW_5G(pregistrypriv); /* TODO: control op bw with other info */
528
529         if (hal_chk_bw_cap(padapter, BW_CAP_80M | BW_CAP_160M)
530                 && REGSTY_BW_5G(pregistrypriv) >= CHANNEL_WIDTH_80
531         ) {
532                 center_freq = rtw_get_center_ch(channel, bw_mode, HAL_PRIME_CHNL_OFFSET_LOWER);
533                 ChnlWidth = 1;
534         } else {
535                 center_freq = 0;
536                 ChnlWidth = 0;
537         }
538
539         
540         SET_VHT_OPERATION_ELE_CHL_WIDTH(operation, ChnlWidth);
541         //center frequency
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);
544         
545         if (padapter->registrypriv.rf_config != RF_MAX_TYPE)
546                 rf_type = padapter->registrypriv.rf_config;
547         
548         switch (rf_type) {
549         case RF_1T1R:
550         operation[3] = 0xfe;
551         operation[4] = 0xff;
552         break;
553         case RF_1T2R:
554         case RF_2T2R:
555         case RF_2T2R_GREEN:
556         operation[3] = 0xfa;
557         operation[4] = 0xff;
558         break;
559         case RF_2T3R:
560         case RF_2T4R:
561         case RF_3T3R:
562         case RF_3T4R:
563         operation[3] = 0xea;
564         operation[4] = 0xff;
565         break;
566         case RF_4T4R:
567         operation[3] = 0xaa;
568         operation[4] = 0xff;
569         break;
570         default:
571         DBG_871X("%s, %d, unknown rf type\n", __func__, __LINE__);
572         }
573
574         rtw_set_ie(pbuf, EID_VHTOperation, 5, operation, &len);
575
576         return len;
577 }
578
579 u32     rtw_build_vht_op_mode_notify_ie(_adapter *padapter, u8 *pbuf, u8 bw)
580 {
581         //struct registry_priv *pregistrypriv = &padapter->registrypriv;
582         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
583         struct vht_priv *pvhtpriv = &pmlmepriv->vhtpriv;
584         u32     len = 0;
585         u8      opmode = 0, rf_type = 0;
586         u8      chnl_width, rx_nss;
587
588         chnl_width = bw;
589
590         rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
591         if(rf_type == RF_3T3R)
592                 rx_nss = 3;
593         else if(rf_type == RF_2T2R)
594                 rx_nss = 2;
595         else
596                 rx_nss = 1;
597
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
601
602         pvhtpriv->vht_op_mode_notify = opmode;
603
604         pbuf = rtw_set_ie(pbuf, EID_OpModeNotification, 1, &opmode, &len);
605
606         return len;
607 }
608
609 u32     rtw_build_vht_cap_ie(_adapter *padapter, u8 *pbuf)
610 {
611         u8      bw, rf_type, rf_num, rx_stbc_nss = 0;
612         u16     HighestRate;
613         u8      *pcap, *pcap_mcs;
614         u32     len = 0;
615         struct registry_priv *pregistrypriv = &padapter->registrypriv;
616         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
617         struct vht_priv *pvhtpriv = &pmlmepriv->vhtpriv;
618
619         pcap = pvhtpriv->vht_cap;
620         _rtw_memset(pcap, 0, 32);
621         
622         /* B0 B1 Maximum MPDU Length */
623         SET_VHT_CAPABILITY_ELE_MAX_MPDU_LENGTH(pcap, 2); 
624         
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);
629                 else
630                         SET_VHT_CAPABILITY_ELE_CHL_WIDTH(pcap, 1);
631         } else {
632                 SET_VHT_CAPABILITY_ELE_CHL_WIDTH(pcap, 0);
633         }
634
635         // B4 Rx LDPC
636         if(TEST_FLAG(pvhtpriv->ldpc_cap, LDPC_VHT_ENABLE_RX))
637         {
638                 SET_VHT_CAPABILITY_ELE_RX_LDPC(pcap, 1);
639         }
640
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
643
644         // B6 ShortGI for 160MHz
645         //SET_VHT_CAPABILITY_ELE_SHORT_GI160M(pcap, pvhtpriv->sgi_80m? 1 : 0);
646
647         // B7 Tx STBC
648         if(TEST_FLAG(pvhtpriv->stbc_cap, STBC_VHT_ENABLE_TX))
649         {
650                 SET_VHT_CAPABILITY_ELE_TX_STBC(pcap, 1);
651         }
652
653         // B8 B9 B10 Rx STBC
654         if(TEST_FLAG(pvhtpriv->stbc_cap, STBC_VHT_ENABLE_RX))
655         {
656                 rtw_hal_get_def_var(padapter, HAL_DEF_RX_STBC, (u8 *)(&rx_stbc_nss));
657                 
658                 SET_VHT_CAPABILITY_ELE_RX_STBC(pcap, rx_stbc_nss);
659         }
660
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);
667         }
668
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);
675         }
676
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);
681         // B21 VHT TXOP PS
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)
687         {
688                 SET_VHT_CAPABILITY_ELE_MAX_RXAMPDU_FACTOR(pcap, pregistrypriv->ampdu_factor);
689         }
690         else
691         {
692                 SET_VHT_CAPABILITY_ELE_MAX_RXAMPDU_FACTOR(pcap, 7);
693         }
694         // B26 27 VHT Link Adaptation Capable
695         SET_VHT_CAPABILITY_ELE_LINK_ADAPTION(pcap, 0);
696
697         pcap_mcs = GET_VHT_CAPABILITY_ELE_RX_MCS(pcap);
698         _rtw_memcpy(pcap_mcs, pvhtpriv->vht_mcs_map, 2);
699
700         pcap_mcs = GET_VHT_CAPABILITY_ELE_TX_MCS(pcap);
701         _rtw_memcpy(pcap_mcs, pvhtpriv->vht_mcs_map, 2);
702
703         /* find the largest bw supported by both registry and hal */
704         bw = hal_largest_bw(padapter, REGSTY_BW_5G(pregistrypriv));
705
706         HighestRate = VHT_MCS_DATA_RATE[bw][pvhtpriv->sgi_80m][((pvhtpriv->vht_highest_rate - MGN_VHT1SS_MCS0)&0x3f)];
707         HighestRate = (HighestRate+1) >> 1;
708
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.
711
712         pbuf = rtw_set_ie(pbuf, EID_VHTCapability, 12, pcap, &len);
713
714         return len;
715 }
716
717 u32 rtw_restructure_vht_ie(_adapter *padapter, u8 *in_ie, u8 *out_ie, uint in_len, uint *pout_len)
718 {
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;
721         u8      *p, *pframe;
722         struct registry_priv *pregistrypriv = &padapter->registrypriv;
723         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
724         struct vht_priv *pvhtpriv = &pmlmepriv->vhtpriv;
725
726         rtw_vht_use_default_setting(padapter);
727
728         p = rtw_get_ie(in_ie+12, EID_VHTCapability, &ielen, in_len-12);
729         if (p && ielen>0) {
730                 supported_chnl_width = GET_VHT_CAPABILITY_ELE_CHL_WIDTH(p+2);
731                 
732                 // VHT Capabilities element
733                 cap_len = rtw_build_vht_cap_ie(padapter, out_ie+*pout_len);
734                 *pout_len += cap_len;
735
736                 // Get HT BW
737                 p = rtw_get_ie(in_ie+12, _HT_EXTRA_INFO_IE_, &ielen, in_len-12);
738                 if (p && ielen>0) {
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;
742                         else
743                                 operation_bw = CHANNEL_WIDTH_20;
744                 }
745
746                 // VHT Operation element
747                 p = rtw_get_ie(in_ie+12, EID_VHTOperation, &ielen, in_len-12);
748                 if (p && ielen>0) {
749                         out_len = *pout_len;
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;
755                                 else
756                                         operation_bw = CHANNEL_WIDTH_80;
757                         }
758                         pframe = rtw_set_ie(out_ie+out_len, EID_VHTOperation, ielen, p+2 , pout_len);
759                 }
760
761                 /* find the largest bw supported by both registry and hal */
762                 notify_bw = hal_largest_bw(padapter, REGSTY_BW_5G(pregistrypriv));
763
764                 if (notify_bw > operation_bw)
765                         notify_bw = operation_bw;
766
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;
770
771                 pvhtpriv->vht_option = _TRUE;
772         }
773         
774         return (pvhtpriv->vht_option);
775         
776 }
777
778 void VHTOnAssocRsp(_adapter *padapter)
779 {
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);
784         u8      ht_AMPDU_len;
785         
786         DBG_871X("%s\n", __FUNCTION__);
787
788         if (!pmlmeinfo->HT_enable)
789                 return;
790
791         if (!pmlmeinfo->VHT_enable)
792                 return;
793
794         ht_AMPDU_len = pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x03;
795
796         if(pvhtpriv->ampdu_len > ht_AMPDU_len)
797                 rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_FACTOR, (u8 *)(&pvhtpriv->ampdu_len));
798
799         rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_MAX_TIME, (u8 *)(&pvhtpriv->vht_highest_rate));
800 }
801
802 #endif //CONFIG_80211AC_VHT
803