1 /******************************************************************************
2 * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
4 * This program is distributed in the hope that it will be useful, but WITHOUT
5 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
6 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
9 * The full GNU General Public License is included in this distribution in the
10 * file called LICENSE.
12 * Contact Information:
13 * wlanfae <wlanfae@realtek.com>
14 ******************************************************************************/
16 #include "rtl819x_HT.h"
17 u8 MCS_FILTER_ALL
[16] = {
18 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
19 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
22 u8 MCS_FILTER_1SS
[16] = {
23 0xff, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
24 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
27 u16 MCS_DATA_RATE
[2][2][77] = {
28 {{13, 26, 39, 52, 78, 104, 117, 130, 26, 52, 78, 104, 156, 208, 234,
29 260, 39, 78, 117, 234, 312, 351, 390, 52, 104, 156, 208, 312, 416,
30 468, 520, 0, 78, 104, 130, 117, 156, 195, 104, 130, 130, 156, 182,
31 182, 208, 156, 195, 195, 234, 273, 273, 312, 130, 156, 181, 156,
32 181, 208, 234, 208, 234, 260, 260, 286, 195, 234, 273, 234, 273,
33 312, 351, 312, 351, 390, 390, 429},
34 {14, 29, 43, 58, 87, 116, 130, 144, 29, 58, 87, 116, 173, 231, 260, 289,
35 43, 87, 130, 173, 260, 347, 390, 433, 58, 116, 173, 231, 347, 462, 520,
36 578, 0, 87, 116, 144, 130, 173, 217, 116, 144, 144, 173, 202, 202, 231,
37 173, 217, 217, 260, 303, 303, 347, 144, 173, 202, 173, 202, 231, 260,
38 231, 260, 289, 289, 318, 217, 260, 303, 260, 303, 347, 390, 347, 390,
40 {{27, 54, 81, 108, 162, 216, 243, 270, 54, 108, 162, 216, 324, 432, 486,
41 540, 81, 162, 243, 324, 486, 648, 729, 810, 108, 216, 324, 432, 648,
42 864, 972, 1080, 12, 162, 216, 270, 243, 324, 405, 216, 270, 270, 324,
43 378, 378, 432, 324, 405, 405, 486, 567, 567, 648, 270, 324, 378, 324,
44 378, 432, 486, 432, 486, 540, 540, 594, 405, 486, 567, 486, 567, 648,
45 729, 648, 729, 810, 810, 891},
46 {30, 60, 90, 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540,
47 600, 90, 180, 270, 360, 540, 720, 810, 900, 120, 240, 360, 480, 720,
48 960, 1080, 1200, 13, 180, 240, 300, 270, 360, 450, 240, 300, 300, 360,
49 420, 420, 480, 360, 450, 450, 540, 630, 630, 720, 300, 360, 420, 360,
50 420, 480, 540, 480, 540, 600, 600, 660, 450, 540, 630, 540, 630, 720,
51 810, 720, 810, 900, 900, 990} }
54 static u8 UNKNOWN_BORADCOM
[3] = {0x00, 0x14, 0xbf};
56 static u8 LINKSYSWRT330_LINKSYSWRT300_BROADCOM
[3] = {0x00, 0x1a, 0x70};
58 static u8 LINKSYSWRT350_LINKSYSWRT150_BROADCOM
[3] = {0x00, 0x1d, 0x7e};
60 static u8 BELKINF5D8233V1_RALINK
[3] = {0x00, 0x17, 0x3f};
62 static u8 BELKINF5D82334V3_RALINK
[3] = {0x00, 0x1c, 0xdf};
64 static u8 PCI_RALINK
[3] = {0x00, 0x90, 0xcc};
66 static u8 EDIMAX_RALINK
[3] = {0x00, 0x0e, 0x2e};
68 static u8 AIRLINK_RALINK
[3] = {0x00, 0x18, 0x02};
70 static u8 DLINK_ATHEROS_1
[3] = {0x00, 0x1c, 0xf0};
72 static u8 DLINK_ATHEROS_2
[3] = {0x00, 0x21, 0x91};
74 static u8 CISCO_BROADCOM
[3] = {0x00, 0x17, 0x94};
76 static u8 LINKSYS_MARVELL_4400N
[3] = {0x00, 0x14, 0xa4};
78 void HTUpdateDefaultSetting(struct rtllib_device
*ieee
)
80 struct rt_hi_throughput
*pHTInfo
= ieee
->pHTInfo
;
82 pHTInfo
->bAcceptAddbaReq
= 1;
84 pHTInfo
->bRegShortGI20MHz
= 1;
85 pHTInfo
->bRegShortGI40MHz
= 1;
87 pHTInfo
->bRegBW40MHz
= 1;
89 if (pHTInfo
->bRegBW40MHz
)
90 pHTInfo
->bRegSuppCCK
= 1;
92 pHTInfo
->bRegSuppCCK
= true;
94 pHTInfo
->nAMSDU_MaxSize
= 7935UL;
95 pHTInfo
->bAMSDU_Support
= 0;
97 pHTInfo
->bAMPDUEnable
= 1;
98 pHTInfo
->AMPDU_Factor
= 2;
99 pHTInfo
->MPDU_Density
= 0;
101 pHTInfo
->SelfMimoPs
= 3;
102 if (pHTInfo
->SelfMimoPs
== 2)
103 pHTInfo
->SelfMimoPs
= 3;
104 ieee
->bTxDisableRateFallBack
= 0;
105 ieee
->bTxUseDriverAssingedRate
= 0;
107 ieee
->bTxEnableFwCalcDur
= 1;
109 pHTInfo
->bRegRT2RTAggregation
= 1;
111 pHTInfo
->bRegRxReorderEnable
= 1;
112 pHTInfo
->RxReorderWinSize
= 64;
113 pHTInfo
->RxReorderPendingTime
= 30;
116 static u16
HTMcsToDataRate(struct rtllib_device
*ieee
, u8 nMcsRate
)
118 struct rt_hi_throughput
*pHTInfo
= ieee
->pHTInfo
;
120 u8 is40MHz
= (pHTInfo
->bCurBW40MHz
) ? 1 : 0;
121 u8 isShortGI
= (pHTInfo
->bCurBW40MHz
) ?
122 ((pHTInfo
->bCurShortGI40MHz
) ? 1 : 0) :
123 ((pHTInfo
->bCurShortGI20MHz
) ? 1 : 0);
124 return MCS_DATA_RATE
[is40MHz
][isShortGI
][(nMcsRate
& 0x7f)];
127 u16
TxCountToDataRate(struct rtllib_device
*ieee
, u8 nDataRate
)
129 u16 CCKOFDMRate
[12] = {0x02, 0x04, 0x0b, 0x16, 0x0c, 0x12, 0x18,
130 0x24, 0x30, 0x48, 0x60, 0x6c};
135 return CCKOFDMRate
[nDataRate
];
136 if (nDataRate
>= 0x10 && nDataRate
<= 0x1f) {
139 } else if (nDataRate
>= 0x20 && nDataRate
<= 0x2f) {
142 } else if (nDataRate
>= 0x30 && nDataRate
<= 0x3f) {
145 } else if (nDataRate
>= 0x40 && nDataRate
<= 0x4f) {
149 return MCS_DATA_RATE
[is40MHz
][isShortGI
][nDataRate
&0xf];
152 bool IsHTHalfNmodeAPs(struct rtllib_device
*ieee
)
154 bool retValue
= false;
155 struct rtllib_network
*net
= &ieee
->current_network
;
157 if ((memcmp(net
->bssid
, BELKINF5D8233V1_RALINK
, 3) == 0) ||
158 (memcmp(net
->bssid
, BELKINF5D82334V3_RALINK
, 3) == 0) ||
159 (memcmp(net
->bssid
, PCI_RALINK
, 3) == 0) ||
160 (memcmp(net
->bssid
, EDIMAX_RALINK
, 3) == 0) ||
161 (memcmp(net
->bssid
, AIRLINK_RALINK
, 3) == 0) ||
162 (net
->ralink_cap_exist
))
164 else if (!memcmp(net
->bssid
, UNKNOWN_BORADCOM
, 3) ||
165 !memcmp(net
->bssid
, LINKSYSWRT330_LINKSYSWRT300_BROADCOM
, 3) ||
166 !memcmp(net
->bssid
, LINKSYSWRT350_LINKSYSWRT150_BROADCOM
, 3) ||
167 (net
->broadcom_cap_exist
))
169 else if (net
->bssht
.bdRT2RTAggregation
)
177 static void HTIOTPeerDetermine(struct rtllib_device
*ieee
)
179 struct rt_hi_throughput
*pHTInfo
= ieee
->pHTInfo
;
180 struct rtllib_network
*net
= &ieee
->current_network
;
182 if (net
->bssht
.bdRT2RTAggregation
) {
183 pHTInfo
->IOTPeer
= HT_IOT_PEER_REALTEK
;
184 if (net
->bssht
.RT2RT_HT_Mode
& RT_HT_CAP_USE_92SE
)
185 pHTInfo
->IOTPeer
= HT_IOT_PEER_REALTEK_92SE
;
186 if (net
->bssht
.RT2RT_HT_Mode
& RT_HT_CAP_USE_SOFTAP
)
187 pHTInfo
->IOTPeer
= HT_IOT_PEER_92U_SOFTAP
;
188 } else if (net
->broadcom_cap_exist
)
189 pHTInfo
->IOTPeer
= HT_IOT_PEER_BROADCOM
;
190 else if (!memcmp(net
->bssid
, UNKNOWN_BORADCOM
, 3) ||
191 !memcmp(net
->bssid
, LINKSYSWRT330_LINKSYSWRT300_BROADCOM
, 3) ||
192 !memcmp(net
->bssid
, LINKSYSWRT350_LINKSYSWRT150_BROADCOM
, 3))
193 pHTInfo
->IOTPeer
= HT_IOT_PEER_BROADCOM
;
194 else if ((memcmp(net
->bssid
, BELKINF5D8233V1_RALINK
, 3) == 0) ||
195 (memcmp(net
->bssid
, BELKINF5D82334V3_RALINK
, 3) == 0) ||
196 (memcmp(net
->bssid
, PCI_RALINK
, 3) == 0) ||
197 (memcmp(net
->bssid
, EDIMAX_RALINK
, 3) == 0) ||
198 (memcmp(net
->bssid
, AIRLINK_RALINK
, 3) == 0) ||
199 net
->ralink_cap_exist
)
200 pHTInfo
->IOTPeer
= HT_IOT_PEER_RALINK
;
201 else if ((net
->atheros_cap_exist
) ||
202 (memcmp(net
->bssid
, DLINK_ATHEROS_1
, 3) == 0) ||
203 (memcmp(net
->bssid
, DLINK_ATHEROS_2
, 3) == 0))
204 pHTInfo
->IOTPeer
= HT_IOT_PEER_ATHEROS
;
205 else if ((memcmp(net
->bssid
, CISCO_BROADCOM
, 3) == 0) ||
206 net
->cisco_cap_exist
)
207 pHTInfo
->IOTPeer
= HT_IOT_PEER_CISCO
;
208 else if ((memcmp(net
->bssid
, LINKSYS_MARVELL_4400N
, 3) == 0) ||
209 net
->marvell_cap_exist
)
210 pHTInfo
->IOTPeer
= HT_IOT_PEER_MARVELL
;
211 else if (net
->airgo_cap_exist
)
212 pHTInfo
->IOTPeer
= HT_IOT_PEER_AIRGO
;
214 pHTInfo
->IOTPeer
= HT_IOT_PEER_UNKNOWN
;
216 netdev_dbg(ieee
->dev
, "IOTPEER: %x\n", pHTInfo
->IOTPeer
);
219 static u8
HTIOTActIsDisableMCS14(struct rtllib_device
*ieee
, u8
*PeerMacAddr
)
225 static bool HTIOTActIsDisableMCS15(struct rtllib_device
*ieee
)
230 static bool HTIOTActIsDisableMCSTwoSpatialStream(struct rtllib_device
*ieee
)
235 static u8
HTIOTActIsDisableEDCATurbo(struct rtllib_device
*ieee
,
241 static u8
HTIOTActIsMgntUseCCK6M(struct rtllib_device
*ieee
,
242 struct rtllib_network
*network
)
247 if (ieee
->pHTInfo
->IOTPeer
== HT_IOT_PEER_BROADCOM
)
253 static u8
HTIOTActIsCCDFsync(struct rtllib_device
*ieee
)
257 if (ieee
->pHTInfo
->IOTPeer
== HT_IOT_PEER_BROADCOM
)
262 static void HTIOTActDetermineRaFunc(struct rtllib_device
*ieee
, bool bPeerRx2ss
)
264 struct rt_hi_throughput
*pHTInfo
= ieee
->pHTInfo
;
266 pHTInfo
->IOTRaFunc
&= HT_IOT_RAFUNC_DISABLE_ALL
;
268 if (pHTInfo
->IOTPeer
== HT_IOT_PEER_RALINK
&& !bPeerRx2ss
)
269 pHTInfo
->IOTRaFunc
|= HT_IOT_RAFUNC_PEER_1R
;
271 if (pHTInfo
->IOTAction
& HT_IOT_ACT_AMSDU_ENABLE
)
272 pHTInfo
->IOTRaFunc
|= HT_IOT_RAFUNC_TX_AMSDU
;
276 void HTResetIOTSetting(struct rt_hi_throughput
*pHTInfo
)
278 pHTInfo
->IOTAction
= 0;
279 pHTInfo
->IOTPeer
= HT_IOT_PEER_UNKNOWN
;
280 pHTInfo
->IOTRaFunc
= 0;
283 void HTConstructCapabilityElement(struct rtllib_device
*ieee
, u8
*posHTCap
,
284 u8
*len
, u8 IsEncrypt
, bool bAssoc
)
286 struct rt_hi_throughput
*pHT
= ieee
->pHTInfo
;
287 struct ht_capab_ele
*pCapELE
= NULL
;
289 if ((posHTCap
== NULL
) || (pHT
== NULL
)) {
290 netdev_warn(ieee
->dev
,
291 "%s(): posHTCap and pHTInfo are null\n", __func__
);
294 memset(posHTCap
, 0, *len
);
296 if ((bAssoc
) && (pHT
->ePeerHTSpecVer
== HT_SPEC_VER_EWC
)) {
297 u8 EWC11NHTCap
[] = {0x00, 0x90, 0x4c, 0x33};
299 memcpy(posHTCap
, EWC11NHTCap
, sizeof(EWC11NHTCap
));
300 pCapELE
= (struct ht_capab_ele
*)&(posHTCap
[4]);
303 pCapELE
= (struct ht_capab_ele
*)posHTCap
;
307 pCapELE
->AdvCoding
= 0;
308 if (ieee
->GetHalfNmodeSupportByAPsHandler(ieee
->dev
))
309 pCapELE
->ChlWidth
= 0;
311 pCapELE
->ChlWidth
= (pHT
->bRegBW40MHz
? 1 : 0);
313 pCapELE
->MimoPwrSave
= pHT
->SelfMimoPs
;
314 pCapELE
->GreenField
= 0;
315 pCapELE
->ShortGI20Mhz
= 1;
316 pCapELE
->ShortGI40Mhz
= 1;
320 pCapELE
->DelayBA
= 0;
321 pCapELE
->MaxAMSDUSize
= (MAX_RECEIVE_BUFFER_SIZE
>= 7935) ? 1 : 0;
322 pCapELE
->DssCCk
= ((pHT
->bRegBW40MHz
) ? (pHT
->bRegSuppCCK
? 1 : 0) : 0);
324 pCapELE
->LSigTxopProtect
= 0;
327 netdev_dbg(ieee
->dev
,
328 "TX HT cap/info ele BW=%d MaxAMSDUSize:%d DssCCk:%d\n",
329 pCapELE
->ChlWidth
, pCapELE
->MaxAMSDUSize
, pCapELE
->DssCCk
);
332 pCapELE
->MPDUDensity
= 7;
333 pCapELE
->MaxRxAMPDUFactor
= 2;
335 pCapELE
->MaxRxAMPDUFactor
= 3;
336 pCapELE
->MPDUDensity
= 0;
339 memcpy(pCapELE
->MCS
, ieee
->Regdot11HTOperationalRateSet
, 16);
340 memset(&pCapELE
->ExtHTCapInfo
, 0, 2);
341 memset(pCapELE
->TxBFCap
, 0, 4);
346 if (pHT
->IOTAction
& HT_IOT_ACT_DISABLE_MCS15
)
347 pCapELE
->MCS
[1] &= 0x7f;
349 if (pHT
->IOTAction
& HT_IOT_ACT_DISABLE_MCS14
)
350 pCapELE
->MCS
[1] &= 0xbf;
352 if (pHT
->IOTAction
& HT_IOT_ACT_DISABLE_ALL_2SS
)
353 pCapELE
->MCS
[1] &= 0x00;
355 if (pHT
->IOTAction
& HT_IOT_ACT_DISABLE_RX_40MHZ_SHORT_GI
)
356 pCapELE
->ShortGI40Mhz
= 0;
358 if (ieee
->GetHalfNmodeSupportByAPsHandler(ieee
->dev
)) {
359 pCapELE
->ChlWidth
= 0;
365 void HTConstructInfoElement(struct rtllib_device
*ieee
, u8
*posHTInfo
,
366 u8
*len
, u8 IsEncrypt
)
368 struct rt_hi_throughput
*pHT
= ieee
->pHTInfo
;
369 struct ht_info_ele
*pHTInfoEle
= (struct ht_info_ele
*)posHTInfo
;
371 if ((posHTInfo
== NULL
) || (pHTInfoEle
== NULL
)) {
372 netdev_warn(ieee
->dev
,
373 "%s(): posHTInfo and pHTInfoEle are null\n",
378 memset(posHTInfo
, 0, *len
);
379 if ((ieee
->iw_mode
== IW_MODE_ADHOC
) ||
380 (ieee
->iw_mode
== IW_MODE_MASTER
)) {
381 pHTInfoEle
->ControlChl
= ieee
->current_network
.channel
;
382 pHTInfoEle
->ExtChlOffset
= ((pHT
->bRegBW40MHz
== false) ?
383 HT_EXTCHNL_OFFSET_NO_EXT
:
384 (ieee
->current_network
.channel
<= 6)
385 ? HT_EXTCHNL_OFFSET_UPPER
:
386 HT_EXTCHNL_OFFSET_LOWER
);
387 pHTInfoEle
->RecommemdedTxWidth
= pHT
->bRegBW40MHz
;
388 pHTInfoEle
->RIFS
= 0;
389 pHTInfoEle
->PSMPAccessOnly
= 0;
390 pHTInfoEle
->SrvIntGranularity
= 0;
391 pHTInfoEle
->OptMode
= pHT
->CurrentOpMode
;
392 pHTInfoEle
->NonGFDevPresent
= 0;
393 pHTInfoEle
->DualBeacon
= 0;
394 pHTInfoEle
->SecondaryBeacon
= 0;
395 pHTInfoEle
->LSigTxopProtectFull
= 0;
396 pHTInfoEle
->PcoActive
= 0;
397 pHTInfoEle
->PcoPhase
= 0;
399 memset(pHTInfoEle
->BasicMSC
, 0, 16);
409 void HTConstructRT2RTAggElement(struct rtllib_device
*ieee
, u8
*posRT2RTAgg
,
412 if (posRT2RTAgg
== NULL
) {
413 netdev_warn(ieee
->dev
, "%s(): posRT2RTAgg is null\n", __func__
);
416 memset(posRT2RTAgg
, 0, *len
);
417 *posRT2RTAgg
++ = 0x00;
418 *posRT2RTAgg
++ = 0xe0;
419 *posRT2RTAgg
++ = 0x4c;
420 *posRT2RTAgg
++ = 0x02;
421 *posRT2RTAgg
++ = 0x01;
425 if (ieee
->bSupportRemoteWakeUp
)
426 *posRT2RTAgg
|= RT_HT_CAP_USE_WOW
;
431 static u8
HT_PickMCSRate(struct rtllib_device
*ieee
, u8
*pOperateMCS
)
435 if (pOperateMCS
== NULL
) {
436 netdev_warn(ieee
->dev
, "%s(): pOperateMCS is null\n", __func__
);
440 switch (ieee
->mode
) {
444 for (i
= 0; i
<= 15; i
++)
449 pOperateMCS
[0] &= RATE_ADPT_1SS_MASK
;
450 pOperateMCS
[1] &= RATE_ADPT_2SS_MASK
;
451 pOperateMCS
[3] &= RATE_ADPT_MCS32_MASK
;
461 u8
HTGetHighestMCSRate(struct rtllib_device
*ieee
, u8
*pMCSRateSet
,
467 u8 availableMcsRate
[16];
469 if (pMCSRateSet
== NULL
|| pMCSFilter
== NULL
) {
470 netdev_warn(ieee
->dev
,
471 "%s(): pMCSRateSet and pMCSFilter are null\n",
475 for (i
= 0; i
< 16; i
++)
476 availableMcsRate
[i
] = pMCSRateSet
[i
] & pMCSFilter
[i
];
478 for (i
= 0; i
< 16; i
++) {
479 if (availableMcsRate
[i
] != 0)
485 for (i
= 0; i
< 16; i
++) {
486 if (availableMcsRate
[i
] != 0) {
487 bitMap
= availableMcsRate
[i
];
488 for (j
= 0; j
< 8; j
++) {
489 if ((bitMap
%2) != 0) {
490 if (HTMcsToDataRate(ieee
, (8*i
+j
)) >
491 HTMcsToDataRate(ieee
, mcsRate
))
498 return mcsRate
| 0x80;
501 static u8
HTFilterMCSRate(struct rtllib_device
*ieee
, u8
*pSupportMCS
,
507 for (i
= 0; i
<= 15; i
++)
508 pOperateMCS
[i
] = ieee
->Regdot11TxHTOperationalRateSet
[i
] &
511 HT_PickMCSRate(ieee
, pOperateMCS
);
513 if (ieee
->GetHalfNmodeSupportByAPsHandler(ieee
->dev
))
516 for (i
= 2; i
<= 15; i
++)
522 void HTSetConnectBwMode(struct rtllib_device
*ieee
,
523 enum ht_channel_width Bandwidth
,
524 enum ht_extchnl_offset Offset
);
526 void HTOnAssocRsp(struct rtllib_device
*ieee
)
528 struct rt_hi_throughput
*pHTInfo
= ieee
->pHTInfo
;
529 struct ht_capab_ele
*pPeerHTCap
= NULL
;
530 struct ht_info_ele
*pPeerHTInfo
= NULL
;
531 u16 nMaxAMSDUSize
= 0;
532 u8
*pMcsFilter
= NULL
;
534 static u8 EWC11NHTCap
[] = {0x00, 0x90, 0x4c, 0x33};
535 static u8 EWC11NHTInfo
[] = {0x00, 0x90, 0x4c, 0x34};
537 if (pHTInfo
->bCurrentHTSupport
== false) {
538 netdev_warn(ieee
->dev
, "%s(): HT_DISABLE\n", __func__
);
541 netdev_dbg(ieee
->dev
, "%s(): HT_ENABLE\n", __func__
);
543 if (!memcmp(pHTInfo
->PeerHTCapBuf
, EWC11NHTCap
, sizeof(EWC11NHTCap
)))
544 pPeerHTCap
= (struct ht_capab_ele
*)(&pHTInfo
->PeerHTCapBuf
[4]);
546 pPeerHTCap
= (struct ht_capab_ele
*)(pHTInfo
->PeerHTCapBuf
);
548 if (!memcmp(pHTInfo
->PeerHTInfoBuf
, EWC11NHTInfo
, sizeof(EWC11NHTInfo
)))
549 pPeerHTInfo
= (struct ht_info_ele
*)
550 (&pHTInfo
->PeerHTInfoBuf
[4]);
552 pPeerHTInfo
= (struct ht_info_ele
*)(pHTInfo
->PeerHTInfoBuf
);
556 print_hex_dump_bytes("HTOnAssocRsp(): ", DUMP_PREFIX_NONE
,
557 pPeerHTCap
, sizeof(struct ht_capab_ele
));
559 HTSetConnectBwMode(ieee
, (enum ht_channel_width
)(pPeerHTCap
->ChlWidth
),
560 (enum ht_extchnl_offset
)(pPeerHTInfo
->ExtChlOffset
));
561 pHTInfo
->bCurTxBW40MHz
= ((pPeerHTInfo
->RecommemdedTxWidth
== 1) ?
564 pHTInfo
->bCurShortGI20MHz
= ((pHTInfo
->bRegShortGI20MHz
) ?
565 ((pPeerHTCap
->ShortGI20Mhz
== 1) ?
566 true : false) : false);
567 pHTInfo
->bCurShortGI40MHz
= ((pHTInfo
->bRegShortGI40MHz
) ?
568 ((pPeerHTCap
->ShortGI40Mhz
== 1) ?
569 true : false) : false);
571 pHTInfo
->bCurSuppCCK
= ((pHTInfo
->bRegSuppCCK
) ?
572 ((pPeerHTCap
->DssCCk
== 1) ? true :
576 pHTInfo
->bCurrent_AMSDU_Support
= pHTInfo
->bAMSDU_Support
;
578 nMaxAMSDUSize
= (pPeerHTCap
->MaxAMSDUSize
== 0) ? 3839 : 7935;
580 if (pHTInfo
->nAMSDU_MaxSize
> nMaxAMSDUSize
)
581 pHTInfo
->nCurrent_AMSDU_MaxSize
= nMaxAMSDUSize
;
583 pHTInfo
->nCurrent_AMSDU_MaxSize
= pHTInfo
->nAMSDU_MaxSize
;
585 pHTInfo
->bCurrentAMPDUEnable
= pHTInfo
->bAMPDUEnable
;
586 if (ieee
->rtllib_ap_sec_type
&&
587 (ieee
->rtllib_ap_sec_type(ieee
)&(SEC_ALG_WEP
|SEC_ALG_TKIP
))) {
588 if ((pHTInfo
->IOTPeer
== HT_IOT_PEER_ATHEROS
) ||
589 (pHTInfo
->IOTPeer
== HT_IOT_PEER_UNKNOWN
))
590 pHTInfo
->bCurrentAMPDUEnable
= false;
593 if (!pHTInfo
->bRegRT2RTAggregation
) {
594 if (pHTInfo
->AMPDU_Factor
> pPeerHTCap
->MaxRxAMPDUFactor
)
595 pHTInfo
->CurrentAMPDUFactor
=
596 pPeerHTCap
->MaxRxAMPDUFactor
;
598 pHTInfo
->CurrentAMPDUFactor
= pHTInfo
->AMPDU_Factor
;
601 if (ieee
->current_network
.bssht
.bdRT2RTAggregation
) {
602 if (ieee
->pairwise_key_type
!= KEY_TYPE_NA
)
603 pHTInfo
->CurrentAMPDUFactor
=
604 pPeerHTCap
->MaxRxAMPDUFactor
;
606 pHTInfo
->CurrentAMPDUFactor
= HT_AGG_SIZE_64K
;
608 if (pPeerHTCap
->MaxRxAMPDUFactor
< HT_AGG_SIZE_32K
)
609 pHTInfo
->CurrentAMPDUFactor
=
610 pPeerHTCap
->MaxRxAMPDUFactor
;
612 pHTInfo
->CurrentAMPDUFactor
= HT_AGG_SIZE_32K
;
615 if (pHTInfo
->MPDU_Density
> pPeerHTCap
->MPDUDensity
)
616 pHTInfo
->CurrentMPDUDensity
= pHTInfo
->MPDU_Density
;
618 pHTInfo
->CurrentMPDUDensity
= pPeerHTCap
->MPDUDensity
;
619 if (pHTInfo
->IOTAction
& HT_IOT_ACT_TX_USE_AMSDU_8K
) {
620 pHTInfo
->bCurrentAMPDUEnable
= false;
621 pHTInfo
->ForcedAMSDUMode
= HT_AGG_FORCE_ENABLE
;
622 pHTInfo
->ForcedAMSDUMaxSize
= 7935;
624 pHTInfo
->bCurRxReorderEnable
= pHTInfo
->bRegRxReorderEnable
;
626 if (pPeerHTCap
->MCS
[0] == 0)
627 pPeerHTCap
->MCS
[0] = 0xff;
629 HTIOTActDetermineRaFunc(ieee
, ((pPeerHTCap
->MCS
[1]) != 0));
631 HTFilterMCSRate(ieee
, pPeerHTCap
->MCS
, ieee
->dot11HTOperationalRateSet
);
633 pHTInfo
->PeerMimoPs
= pPeerHTCap
->MimoPwrSave
;
634 if (pHTInfo
->PeerMimoPs
== MIMO_PS_STATIC
)
635 pMcsFilter
= MCS_FILTER_1SS
;
637 pMcsFilter
= MCS_FILTER_ALL
;
638 ieee
->HTHighestOperaRate
= HTGetHighestMCSRate(ieee
,
639 ieee
->dot11HTOperationalRateSet
, pMcsFilter
);
640 ieee
->HTCurrentOperaRate
= ieee
->HTHighestOperaRate
;
642 pHTInfo
->CurrentOpMode
= pPeerHTInfo
->OptMode
;
645 void HTInitializeHTInfo(struct rtllib_device
*ieee
)
647 struct rt_hi_throughput
*pHTInfo
= ieee
->pHTInfo
;
649 netdev_vdbg(ieee
->dev
, "%s()\n", __func__
);
650 pHTInfo
->bCurrentHTSupport
= false;
652 pHTInfo
->bCurBW40MHz
= false;
653 pHTInfo
->bCurTxBW40MHz
= false;
655 pHTInfo
->bCurShortGI20MHz
= false;
656 pHTInfo
->bCurShortGI40MHz
= false;
657 pHTInfo
->bForcedShortGI
= false;
659 pHTInfo
->bCurSuppCCK
= true;
661 pHTInfo
->bCurrent_AMSDU_Support
= false;
662 pHTInfo
->nCurrent_AMSDU_MaxSize
= pHTInfo
->nAMSDU_MaxSize
;
663 pHTInfo
->CurrentMPDUDensity
= pHTInfo
->MPDU_Density
;
664 pHTInfo
->CurrentAMPDUFactor
= pHTInfo
->AMPDU_Factor
;
666 memset((void *)(&(pHTInfo
->SelfHTCap
)), 0,
667 sizeof(pHTInfo
->SelfHTCap
));
668 memset((void *)(&(pHTInfo
->SelfHTInfo
)), 0,
669 sizeof(pHTInfo
->SelfHTInfo
));
670 memset((void *)(&(pHTInfo
->PeerHTCapBuf
)), 0,
671 sizeof(pHTInfo
->PeerHTCapBuf
));
672 memset((void *)(&(pHTInfo
->PeerHTInfoBuf
)), 0,
673 sizeof(pHTInfo
->PeerHTInfoBuf
));
675 pHTInfo
->bSwBwInProgress
= false;
677 pHTInfo
->ePeerHTSpecVer
= HT_SPEC_VER_IEEE
;
679 pHTInfo
->bCurrentRT2RTAggregation
= false;
680 pHTInfo
->bCurrentRT2RTLongSlotTime
= false;
681 pHTInfo
->RT2RT_HT_Mode
= (enum rt_ht_capability
)0;
683 pHTInfo
->IOTPeer
= 0;
684 pHTInfo
->IOTAction
= 0;
685 pHTInfo
->IOTRaFunc
= 0;
688 u8
*RegHTSuppRateSets
= &(ieee
->RegHTSuppRateSet
[0]);
690 RegHTSuppRateSets
[0] = 0xFF;
691 RegHTSuppRateSets
[1] = 0xFF;
692 RegHTSuppRateSets
[4] = 0x01;
696 void HTInitializeBssDesc(struct bss_ht
*pBssHT
)
699 pBssHT
->bdSupportHT
= false;
700 memset(pBssHT
->bdHTCapBuf
, 0, sizeof(pBssHT
->bdHTCapBuf
));
701 pBssHT
->bdHTCapLen
= 0;
702 memset(pBssHT
->bdHTInfoBuf
, 0, sizeof(pBssHT
->bdHTInfoBuf
));
703 pBssHT
->bdHTInfoLen
= 0;
705 pBssHT
->bdHTSpecVer
= HT_SPEC_VER_IEEE
;
707 pBssHT
->bdRT2RTAggregation
= false;
708 pBssHT
->bdRT2RTLongSlotTime
= false;
709 pBssHT
->RT2RT_HT_Mode
= (enum rt_ht_capability
)0;
712 void HTResetSelfAndSavePeerSetting(struct rtllib_device
*ieee
,
713 struct rtllib_network
*pNetwork
)
715 struct rt_hi_throughput
*pHTInfo
= ieee
->pHTInfo
;
718 netdev_vdbg(ieee
->dev
, "%s()\n", __func__
);
719 /* unmark bEnableHT flag here is the same reason why unmarked in
720 * function rtllib_softmac_new_net. WB 2008.09.10
722 if (pNetwork
->bssht
.bdSupportHT
) {
723 pHTInfo
->bCurrentHTSupport
= true;
724 pHTInfo
->ePeerHTSpecVer
= pNetwork
->bssht
.bdHTSpecVer
;
726 if (pNetwork
->bssht
.bdHTCapLen
> 0 &&
727 pNetwork
->bssht
.bdHTCapLen
<= sizeof(pHTInfo
->PeerHTCapBuf
))
728 memcpy(pHTInfo
->PeerHTCapBuf
,
729 pNetwork
->bssht
.bdHTCapBuf
,
730 pNetwork
->bssht
.bdHTCapLen
);
732 if (pNetwork
->bssht
.bdHTInfoLen
> 0 &&
733 pNetwork
->bssht
.bdHTInfoLen
<=
734 sizeof(pHTInfo
->PeerHTInfoBuf
))
735 memcpy(pHTInfo
->PeerHTInfoBuf
,
736 pNetwork
->bssht
.bdHTInfoBuf
,
737 pNetwork
->bssht
.bdHTInfoLen
);
739 if (pHTInfo
->bRegRT2RTAggregation
) {
740 pHTInfo
->bCurrentRT2RTAggregation
=
741 pNetwork
->bssht
.bdRT2RTAggregation
;
742 pHTInfo
->bCurrentRT2RTLongSlotTime
=
743 pNetwork
->bssht
.bdRT2RTLongSlotTime
;
744 pHTInfo
->RT2RT_HT_Mode
= pNetwork
->bssht
.RT2RT_HT_Mode
;
746 pHTInfo
->bCurrentRT2RTAggregation
= false;
747 pHTInfo
->bCurrentRT2RTLongSlotTime
= false;
748 pHTInfo
->RT2RT_HT_Mode
= (enum rt_ht_capability
)0;
751 HTIOTPeerDetermine(ieee
);
753 pHTInfo
->IOTAction
= 0;
754 bIOTAction
= HTIOTActIsDisableMCS14(ieee
, pNetwork
->bssid
);
756 pHTInfo
->IOTAction
|= HT_IOT_ACT_DISABLE_MCS14
;
758 bIOTAction
= HTIOTActIsDisableMCS15(ieee
);
760 pHTInfo
->IOTAction
|= HT_IOT_ACT_DISABLE_MCS15
;
762 bIOTAction
= HTIOTActIsDisableMCSTwoSpatialStream(ieee
);
764 pHTInfo
->IOTAction
|= HT_IOT_ACT_DISABLE_ALL_2SS
;
767 bIOTAction
= HTIOTActIsDisableEDCATurbo(ieee
, pNetwork
->bssid
);
769 pHTInfo
->IOTAction
|= HT_IOT_ACT_DISABLE_EDCA_TURBO
;
771 bIOTAction
= HTIOTActIsMgntUseCCK6M(ieee
, pNetwork
);
773 pHTInfo
->IOTAction
|= HT_IOT_ACT_MGNT_USE_CCK_6M
;
774 bIOTAction
= HTIOTActIsCCDFsync(ieee
);
776 pHTInfo
->IOTAction
|= HT_IOT_ACT_CDD_FSYNC
;
778 pHTInfo
->bCurrentHTSupport
= false;
779 pHTInfo
->bCurrentRT2RTAggregation
= false;
780 pHTInfo
->bCurrentRT2RTLongSlotTime
= false;
781 pHTInfo
->RT2RT_HT_Mode
= (enum rt_ht_capability
)0;
783 pHTInfo
->IOTAction
= 0;
784 pHTInfo
->IOTRaFunc
= 0;
788 void HT_update_self_and_peer_setting(struct rtllib_device
*ieee
,
789 struct rtllib_network
*pNetwork
)
791 struct rt_hi_throughput
*pHTInfo
= ieee
->pHTInfo
;
792 struct ht_info_ele
*pPeerHTInfo
=
793 (struct ht_info_ele
*)pNetwork
->bssht
.bdHTInfoBuf
;
795 if (pHTInfo
->bCurrentHTSupport
) {
796 if (pNetwork
->bssht
.bdHTInfoLen
!= 0)
797 pHTInfo
->CurrentOpMode
= pPeerHTInfo
->OptMode
;
800 EXPORT_SYMBOL(HT_update_self_and_peer_setting
);
802 void HTUseDefaultSetting(struct rtllib_device
*ieee
)
804 struct rt_hi_throughput
*pHTInfo
= ieee
->pHTInfo
;
806 if (pHTInfo
->bEnableHT
) {
807 pHTInfo
->bCurrentHTSupport
= true;
808 pHTInfo
->bCurSuppCCK
= pHTInfo
->bRegSuppCCK
;
810 pHTInfo
->bCurBW40MHz
= pHTInfo
->bRegBW40MHz
;
811 pHTInfo
->bCurShortGI20MHz
= pHTInfo
->bRegShortGI20MHz
;
813 pHTInfo
->bCurShortGI40MHz
= pHTInfo
->bRegShortGI40MHz
;
815 if (ieee
->iw_mode
== IW_MODE_ADHOC
)
816 ieee
->current_network
.qos_data
.active
=
817 ieee
->current_network
.qos_data
.supported
;
818 pHTInfo
->bCurrent_AMSDU_Support
= pHTInfo
->bAMSDU_Support
;
819 pHTInfo
->nCurrent_AMSDU_MaxSize
= pHTInfo
->nAMSDU_MaxSize
;
821 pHTInfo
->bCurrentAMPDUEnable
= pHTInfo
->bAMPDUEnable
;
822 pHTInfo
->CurrentAMPDUFactor
= pHTInfo
->AMPDU_Factor
;
824 pHTInfo
->CurrentMPDUDensity
= pHTInfo
->CurrentMPDUDensity
;
826 HTFilterMCSRate(ieee
, ieee
->Regdot11TxHTOperationalRateSet
,
827 ieee
->dot11HTOperationalRateSet
);
828 ieee
->HTHighestOperaRate
= HTGetHighestMCSRate(ieee
,
829 ieee
->dot11HTOperationalRateSet
,
831 ieee
->HTCurrentOperaRate
= ieee
->HTHighestOperaRate
;
834 pHTInfo
->bCurrentHTSupport
= false;
838 u8
HTCCheck(struct rtllib_device
*ieee
, u8
*pFrame
)
840 if (ieee
->pHTInfo
->bCurrentHTSupport
) {
841 if ((IsQoSDataFrame(pFrame
) && Frame_Order(pFrame
)) == 1) {
842 netdev_dbg(ieee
->dev
, "HT CONTROL FILED EXIST!!\n");
849 static void HTSetConnectBwModeCallback(struct rtllib_device
*ieee
)
851 struct rt_hi_throughput
*pHTInfo
= ieee
->pHTInfo
;
853 netdev_vdbg(ieee
->dev
, "%s()\n", __func__
);
855 if (pHTInfo
->bCurBW40MHz
) {
856 if (pHTInfo
->CurSTAExtChnlOffset
== HT_EXTCHNL_OFFSET_UPPER
)
857 ieee
->set_chan(ieee
->dev
,
858 ieee
->current_network
.channel
+ 2);
859 else if (pHTInfo
->CurSTAExtChnlOffset
==
860 HT_EXTCHNL_OFFSET_LOWER
)
861 ieee
->set_chan(ieee
->dev
,
862 ieee
->current_network
.channel
- 2);
864 ieee
->set_chan(ieee
->dev
,
865 ieee
->current_network
.channel
);
867 ieee
->SetBWModeHandler(ieee
->dev
, HT_CHANNEL_WIDTH_20_40
,
868 pHTInfo
->CurSTAExtChnlOffset
);
870 ieee
->set_chan(ieee
->dev
, ieee
->current_network
.channel
);
871 ieee
->SetBWModeHandler(ieee
->dev
, HT_CHANNEL_WIDTH_20
,
872 HT_EXTCHNL_OFFSET_NO_EXT
);
875 pHTInfo
->bSwBwInProgress
= false;
878 void HTSetConnectBwMode(struct rtllib_device
*ieee
,
879 enum ht_channel_width Bandwidth
,
880 enum ht_extchnl_offset Offset
)
882 struct rt_hi_throughput
*pHTInfo
= ieee
->pHTInfo
;
884 if (pHTInfo
->bRegBW40MHz
== false)
887 if (ieee
->GetHalfNmodeSupportByAPsHandler(ieee
->dev
))
888 Bandwidth
= HT_CHANNEL_WIDTH_20
;
890 if (pHTInfo
->bSwBwInProgress
) {
891 pr_info("%s: bSwBwInProgress!!\n", __func__
);
894 if (Bandwidth
== HT_CHANNEL_WIDTH_20_40
) {
895 if (ieee
->current_network
.channel
< 2 &&
896 Offset
== HT_EXTCHNL_OFFSET_LOWER
)
897 Offset
= HT_EXTCHNL_OFFSET_NO_EXT
;
898 if (Offset
== HT_EXTCHNL_OFFSET_UPPER
||
899 Offset
== HT_EXTCHNL_OFFSET_LOWER
) {
900 pHTInfo
->bCurBW40MHz
= true;
901 pHTInfo
->CurSTAExtChnlOffset
= Offset
;
903 pHTInfo
->bCurBW40MHz
= false;
904 pHTInfo
->CurSTAExtChnlOffset
= HT_EXTCHNL_OFFSET_NO_EXT
;
907 pHTInfo
->bCurBW40MHz
= false;
908 pHTInfo
->CurSTAExtChnlOffset
= HT_EXTCHNL_OFFSET_NO_EXT
;
911 pr_info("%s():pHTInfo->bCurBW40MHz:%x\n", __func__
,
912 pHTInfo
->bCurBW40MHz
);
914 pHTInfo
->bSwBwInProgress
= true;
916 HTSetConnectBwModeCallback(ieee
);