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 * You should have received a copy of the GNU General Public License along with
10 * this program; if not, write to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
13 * The full GNU General Public License is included in this distribution in the
14 * file called LICENSE.
16 * Contact Information:
17 * wlanfae <wlanfae@realtek.com>
18 ******************************************************************************/
20 #include "rtl819x_HT.h"
21 u8 MCS_FILTER_ALL
[16] = {
22 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
23 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
26 u8 MCS_FILTER_1SS
[16] = {
27 0xff, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
28 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
31 u16 MCS_DATA_RATE
[2][2][77] = {
32 {{13, 26, 39, 52, 78, 104, 117, 130, 26, 52, 78, 104, 156, 208, 234,
33 260, 39, 78, 117, 234, 312, 351, 390, 52, 104, 156, 208, 312, 416,
34 468, 520, 0, 78, 104, 130, 117, 156, 195, 104, 130, 130, 156, 182,
35 182, 208, 156, 195, 195, 234, 273, 273, 312, 130, 156, 181, 156,
36 181, 208, 234, 208, 234, 260, 260, 286, 195, 234, 273, 234, 273,
37 312, 351, 312, 351, 390, 390, 429},
38 {14, 29, 43, 58, 87, 116, 130, 144, 29, 58, 87, 116, 173, 231, 260, 289,
39 43, 87, 130, 173, 260, 347, 390, 433, 58, 116, 173, 231, 347, 462, 520,
40 578, 0, 87, 116, 144, 130, 173, 217, 116, 144, 144, 173, 202, 202, 231,
41 173, 217, 217, 260, 303, 303, 347, 144, 173, 202, 173, 202, 231, 260,
42 231, 260, 289, 289, 318, 217, 260, 303, 260, 303, 347, 390, 347, 390,
44 {{27, 54, 81, 108, 162, 216, 243, 270, 54, 108, 162, 216, 324, 432, 486,
45 540, 81, 162, 243, 324, 486, 648, 729, 810, 108, 216, 324, 432, 648,
46 864, 972, 1080, 12, 162, 216, 270, 243, 324, 405, 216, 270, 270, 324,
47 378, 378, 432, 324, 405, 405, 486, 567, 567, 648, 270, 324, 378, 324,
48 378, 432, 486, 432, 486, 540, 540, 594, 405, 486, 567, 486, 567, 648,
49 729, 648, 729, 810, 810, 891},
50 {30, 60, 90, 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540,
51 600, 90, 180, 270, 360, 540, 720, 810, 900, 120, 240, 360, 480, 720,
52 960, 1080, 1200, 13, 180, 240, 300, 270, 360, 450, 240, 300, 300, 360,
53 420, 420, 480, 360, 450, 450, 540, 630, 630, 720, 300, 360, 420, 360,
54 420, 480, 540, 480, 540, 600, 600, 660, 450, 540, 630, 540, 630, 720,
55 810, 720, 810, 900, 900, 990} }
58 static u8 UNKNOWN_BORADCOM
[3] = {0x00, 0x14, 0xbf};
60 static u8 LINKSYSWRT330_LINKSYSWRT300_BROADCOM
[3] = {0x00, 0x1a, 0x70};
62 static u8 LINKSYSWRT350_LINKSYSWRT150_BROADCOM
[3] = {0x00, 0x1d, 0x7e};
64 static u8 BELKINF5D8233V1_RALINK
[3] = {0x00, 0x17, 0x3f};
66 static u8 BELKINF5D82334V3_RALINK
[3] = {0x00, 0x1c, 0xdf};
68 static u8 PCI_RALINK
[3] = {0x00, 0x90, 0xcc};
70 static u8 EDIMAX_RALINK
[3] = {0x00, 0x0e, 0x2e};
72 static u8 AIRLINK_RALINK
[3] = {0x00, 0x18, 0x02};
74 static u8 DLINK_ATHEROS_1
[3] = {0x00, 0x1c, 0xf0};
76 static u8 DLINK_ATHEROS_2
[3] = {0x00, 0x21, 0x91};
78 static u8 CISCO_BROADCOM
[3] = {0x00, 0x17, 0x94};
80 static u8 LINKSYS_MARVELL_4400N
[3] = {0x00, 0x14, 0xa4};
82 void HTUpdateDefaultSetting(struct rtllib_device
*ieee
)
84 struct rt_hi_throughput
*pHTInfo
= ieee
->pHTInfo
;
86 pHTInfo
->bAcceptAddbaReq
= 1;
88 pHTInfo
->bRegShortGI20MHz
= 1;
89 pHTInfo
->bRegShortGI40MHz
= 1;
91 pHTInfo
->bRegBW40MHz
= 1;
93 if (pHTInfo
->bRegBW40MHz
)
94 pHTInfo
->bRegSuppCCK
= 1;
96 pHTInfo
->bRegSuppCCK
= true;
98 pHTInfo
->nAMSDU_MaxSize
= 7935UL;
99 pHTInfo
->bAMSDU_Support
= 0;
101 pHTInfo
->bAMPDUEnable
= 1;
102 pHTInfo
->AMPDU_Factor
= 2;
103 pHTInfo
->MPDU_Density
= 0;
105 pHTInfo
->SelfMimoPs
= 3;
106 if (pHTInfo
->SelfMimoPs
== 2)
107 pHTInfo
->SelfMimoPs
= 3;
108 ieee
->bTxDisableRateFallBack
= 0;
109 ieee
->bTxUseDriverAssingedRate
= 0;
111 ieee
->bTxEnableFwCalcDur
= 1;
113 pHTInfo
->bRegRT2RTAggregation
= 1;
115 pHTInfo
->bRegRxReorderEnable
= 1;
116 pHTInfo
->RxReorderWinSize
= 64;
117 pHTInfo
->RxReorderPendingTime
= 30;
120 static u16
HTMcsToDataRate(struct rtllib_device
*ieee
, u8 nMcsRate
)
122 struct rt_hi_throughput
*pHTInfo
= ieee
->pHTInfo
;
124 u8 is40MHz
= (pHTInfo
->bCurBW40MHz
) ? 1 : 0;
125 u8 isShortGI
= (pHTInfo
->bCurBW40MHz
) ?
126 ((pHTInfo
->bCurShortGI40MHz
) ? 1 : 0) :
127 ((pHTInfo
->bCurShortGI20MHz
) ? 1 : 0);
128 return MCS_DATA_RATE
[is40MHz
][isShortGI
][(nMcsRate
& 0x7f)];
131 u16
TxCountToDataRate(struct rtllib_device
*ieee
, u8 nDataRate
)
133 u16 CCKOFDMRate
[12] = {0x02, 0x04, 0x0b, 0x16, 0x0c, 0x12, 0x18,
134 0x24, 0x30, 0x48, 0x60, 0x6c};
139 return CCKOFDMRate
[nDataRate
];
140 if (nDataRate
>= 0x10 && nDataRate
<= 0x1f) {
143 } else if (nDataRate
>= 0x20 && nDataRate
<= 0x2f) {
146 } else if (nDataRate
>= 0x30 && nDataRate
<= 0x3f) {
149 } else if (nDataRate
>= 0x40 && nDataRate
<= 0x4f) {
153 return MCS_DATA_RATE
[is40MHz
][isShortGI
][nDataRate
&0xf];
156 bool IsHTHalfNmodeAPs(struct rtllib_device
*ieee
)
158 bool retValue
= false;
159 struct rtllib_network
*net
= &ieee
->current_network
;
161 if ((memcmp(net
->bssid
, BELKINF5D8233V1_RALINK
, 3) == 0) ||
162 (memcmp(net
->bssid
, BELKINF5D82334V3_RALINK
, 3) == 0) ||
163 (memcmp(net
->bssid
, PCI_RALINK
, 3) == 0) ||
164 (memcmp(net
->bssid
, EDIMAX_RALINK
, 3) == 0) ||
165 (memcmp(net
->bssid
, AIRLINK_RALINK
, 3) == 0) ||
166 (net
->ralink_cap_exist
))
168 else if (!memcmp(net
->bssid
, UNKNOWN_BORADCOM
, 3) ||
169 !memcmp(net
->bssid
, LINKSYSWRT330_LINKSYSWRT300_BROADCOM
, 3) ||
170 !memcmp(net
->bssid
, LINKSYSWRT350_LINKSYSWRT150_BROADCOM
, 3) ||
171 (net
->broadcom_cap_exist
))
173 else if (net
->bssht
.bdRT2RTAggregation
)
181 static void HTIOTPeerDetermine(struct rtllib_device
*ieee
)
183 struct rt_hi_throughput
*pHTInfo
= ieee
->pHTInfo
;
184 struct rtllib_network
*net
= &ieee
->current_network
;
186 if (net
->bssht
.bdRT2RTAggregation
) {
187 pHTInfo
->IOTPeer
= HT_IOT_PEER_REALTEK
;
188 if (net
->bssht
.RT2RT_HT_Mode
& RT_HT_CAP_USE_92SE
)
189 pHTInfo
->IOTPeer
= HT_IOT_PEER_REALTEK_92SE
;
190 if (net
->bssht
.RT2RT_HT_Mode
& RT_HT_CAP_USE_SOFTAP
)
191 pHTInfo
->IOTPeer
= HT_IOT_PEER_92U_SOFTAP
;
192 } else if (net
->broadcom_cap_exist
)
193 pHTInfo
->IOTPeer
= HT_IOT_PEER_BROADCOM
;
194 else if (!memcmp(net
->bssid
, UNKNOWN_BORADCOM
, 3) ||
195 !memcmp(net
->bssid
, LINKSYSWRT330_LINKSYSWRT300_BROADCOM
, 3) ||
196 !memcmp(net
->bssid
, LINKSYSWRT350_LINKSYSWRT150_BROADCOM
, 3))
197 pHTInfo
->IOTPeer
= HT_IOT_PEER_BROADCOM
;
198 else if ((memcmp(net
->bssid
, BELKINF5D8233V1_RALINK
, 3) == 0) ||
199 (memcmp(net
->bssid
, BELKINF5D82334V3_RALINK
, 3) == 0) ||
200 (memcmp(net
->bssid
, PCI_RALINK
, 3) == 0) ||
201 (memcmp(net
->bssid
, EDIMAX_RALINK
, 3) == 0) ||
202 (memcmp(net
->bssid
, AIRLINK_RALINK
, 3) == 0) ||
203 net
->ralink_cap_exist
)
204 pHTInfo
->IOTPeer
= HT_IOT_PEER_RALINK
;
205 else if ((net
->atheros_cap_exist
) ||
206 (memcmp(net
->bssid
, DLINK_ATHEROS_1
, 3) == 0) ||
207 (memcmp(net
->bssid
, DLINK_ATHEROS_2
, 3) == 0))
208 pHTInfo
->IOTPeer
= HT_IOT_PEER_ATHEROS
;
209 else if ((memcmp(net
->bssid
, CISCO_BROADCOM
, 3) == 0) ||
210 net
->cisco_cap_exist
)
211 pHTInfo
->IOTPeer
= HT_IOT_PEER_CISCO
;
212 else if ((memcmp(net
->bssid
, LINKSYS_MARVELL_4400N
, 3) == 0) ||
213 net
->marvell_cap_exist
)
214 pHTInfo
->IOTPeer
= HT_IOT_PEER_MARVELL
;
215 else if (net
->airgo_cap_exist
)
216 pHTInfo
->IOTPeer
= HT_IOT_PEER_AIRGO
;
218 pHTInfo
->IOTPeer
= HT_IOT_PEER_UNKNOWN
;
220 netdev_dbg(ieee
->dev
, "IOTPEER: %x\n", pHTInfo
->IOTPeer
);
223 static u8
HTIOTActIsDisableMCS14(struct rtllib_device
*ieee
, u8
*PeerMacAddr
)
229 static bool HTIOTActIsDisableMCS15(struct rtllib_device
*ieee
)
234 static bool HTIOTActIsDisableMCSTwoSpatialStream(struct rtllib_device
*ieee
)
239 static u8
HTIOTActIsDisableEDCATurbo(struct rtllib_device
*ieee
,
245 static u8
HTIOTActIsMgntUseCCK6M(struct rtllib_device
*ieee
,
246 struct rtllib_network
*network
)
251 if (ieee
->pHTInfo
->IOTPeer
== HT_IOT_PEER_BROADCOM
)
257 static u8
HTIOTActIsCCDFsync(struct rtllib_device
*ieee
)
261 if (ieee
->pHTInfo
->IOTPeer
== HT_IOT_PEER_BROADCOM
)
266 static void HTIOTActDetermineRaFunc(struct rtllib_device
*ieee
, bool bPeerRx2ss
)
268 struct rt_hi_throughput
*pHTInfo
= ieee
->pHTInfo
;
270 pHTInfo
->IOTRaFunc
&= HT_IOT_RAFUNC_DISABLE_ALL
;
272 if (pHTInfo
->IOTPeer
== HT_IOT_PEER_RALINK
&& !bPeerRx2ss
)
273 pHTInfo
->IOTRaFunc
|= HT_IOT_RAFUNC_PEER_1R
;
275 if (pHTInfo
->IOTAction
& HT_IOT_ACT_AMSDU_ENABLE
)
276 pHTInfo
->IOTRaFunc
|= HT_IOT_RAFUNC_TX_AMSDU
;
280 void HTResetIOTSetting(struct rt_hi_throughput
*pHTInfo
)
282 pHTInfo
->IOTAction
= 0;
283 pHTInfo
->IOTPeer
= HT_IOT_PEER_UNKNOWN
;
284 pHTInfo
->IOTRaFunc
= 0;
287 void HTConstructCapabilityElement(struct rtllib_device
*ieee
, u8
*posHTCap
,
288 u8
*len
, u8 IsEncrypt
, bool bAssoc
)
290 struct rt_hi_throughput
*pHT
= ieee
->pHTInfo
;
291 struct ht_capab_ele
*pCapELE
= NULL
;
293 if ((posHTCap
== NULL
) || (pHT
== NULL
)) {
294 netdev_warn(ieee
->dev
,
295 "%s(): posHTCap and pHTInfo are null\n", __func__
);
298 memset(posHTCap
, 0, *len
);
300 if ((bAssoc
) && (pHT
->ePeerHTSpecVer
== HT_SPEC_VER_EWC
)) {
301 u8 EWC11NHTCap
[] = {0x00, 0x90, 0x4c, 0x33};
303 memcpy(posHTCap
, EWC11NHTCap
, sizeof(EWC11NHTCap
));
304 pCapELE
= (struct ht_capab_ele
*)&(posHTCap
[4]);
307 pCapELE
= (struct ht_capab_ele
*)posHTCap
;
311 pCapELE
->AdvCoding
= 0;
312 if (ieee
->GetHalfNmodeSupportByAPsHandler(ieee
->dev
))
313 pCapELE
->ChlWidth
= 0;
315 pCapELE
->ChlWidth
= (pHT
->bRegBW40MHz
? 1 : 0);
317 pCapELE
->MimoPwrSave
= pHT
->SelfMimoPs
;
318 pCapELE
->GreenField
= 0;
319 pCapELE
->ShortGI20Mhz
= 1;
320 pCapELE
->ShortGI40Mhz
= 1;
324 pCapELE
->DelayBA
= 0;
325 pCapELE
->MaxAMSDUSize
= (MAX_RECEIVE_BUFFER_SIZE
>= 7935) ? 1 : 0;
326 pCapELE
->DssCCk
= ((pHT
->bRegBW40MHz
) ? (pHT
->bRegSuppCCK
? 1 : 0) : 0);
328 pCapELE
->LSigTxopProtect
= 0;
331 netdev_dbg(ieee
->dev
,
332 "TX HT cap/info ele BW=%d MaxAMSDUSize:%d DssCCk:%d\n",
333 pCapELE
->ChlWidth
, pCapELE
->MaxAMSDUSize
, pCapELE
->DssCCk
);
336 pCapELE
->MPDUDensity
= 7;
337 pCapELE
->MaxRxAMPDUFactor
= 2;
339 pCapELE
->MaxRxAMPDUFactor
= 3;
340 pCapELE
->MPDUDensity
= 0;
343 memcpy(pCapELE
->MCS
, ieee
->Regdot11HTOperationalRateSet
, 16);
344 memset(&pCapELE
->ExtHTCapInfo
, 0, 2);
345 memset(pCapELE
->TxBFCap
, 0, 4);
350 if (pHT
->IOTAction
& HT_IOT_ACT_DISABLE_MCS15
)
351 pCapELE
->MCS
[1] &= 0x7f;
353 if (pHT
->IOTAction
& HT_IOT_ACT_DISABLE_MCS14
)
354 pCapELE
->MCS
[1] &= 0xbf;
356 if (pHT
->IOTAction
& HT_IOT_ACT_DISABLE_ALL_2SS
)
357 pCapELE
->MCS
[1] &= 0x00;
359 if (pHT
->IOTAction
& HT_IOT_ACT_DISABLE_RX_40MHZ_SHORT_GI
)
360 pCapELE
->ShortGI40Mhz
= 0;
362 if (ieee
->GetHalfNmodeSupportByAPsHandler(ieee
->dev
)) {
363 pCapELE
->ChlWidth
= 0;
369 void HTConstructInfoElement(struct rtllib_device
*ieee
, u8
*posHTInfo
,
370 u8
*len
, u8 IsEncrypt
)
372 struct rt_hi_throughput
*pHT
= ieee
->pHTInfo
;
373 struct ht_info_ele
*pHTInfoEle
= (struct ht_info_ele
*)posHTInfo
;
375 if ((posHTInfo
== NULL
) || (pHTInfoEle
== NULL
)) {
376 netdev_warn(ieee
->dev
,
377 "%s(): posHTInfo and pHTInfoEle are null\n",
382 memset(posHTInfo
, 0, *len
);
383 if ((ieee
->iw_mode
== IW_MODE_ADHOC
) ||
384 (ieee
->iw_mode
== IW_MODE_MASTER
)) {
385 pHTInfoEle
->ControlChl
= ieee
->current_network
.channel
;
386 pHTInfoEle
->ExtChlOffset
= ((pHT
->bRegBW40MHz
== false) ?
387 HT_EXTCHNL_OFFSET_NO_EXT
:
388 (ieee
->current_network
.channel
<= 6)
389 ? HT_EXTCHNL_OFFSET_UPPER
:
390 HT_EXTCHNL_OFFSET_LOWER
);
391 pHTInfoEle
->RecommemdedTxWidth
= pHT
->bRegBW40MHz
;
392 pHTInfoEle
->RIFS
= 0;
393 pHTInfoEle
->PSMPAccessOnly
= 0;
394 pHTInfoEle
->SrvIntGranularity
= 0;
395 pHTInfoEle
->OptMode
= pHT
->CurrentOpMode
;
396 pHTInfoEle
->NonGFDevPresent
= 0;
397 pHTInfoEle
->DualBeacon
= 0;
398 pHTInfoEle
->SecondaryBeacon
= 0;
399 pHTInfoEle
->LSigTxopProtectFull
= 0;
400 pHTInfoEle
->PcoActive
= 0;
401 pHTInfoEle
->PcoPhase
= 0;
403 memset(pHTInfoEle
->BasicMSC
, 0, 16);
413 void HTConstructRT2RTAggElement(struct rtllib_device
*ieee
, u8
*posRT2RTAgg
,
416 if (posRT2RTAgg
== NULL
) {
417 netdev_warn(ieee
->dev
, "%s(): posRT2RTAgg is null\n", __func__
);
420 memset(posRT2RTAgg
, 0, *len
);
421 *posRT2RTAgg
++ = 0x00;
422 *posRT2RTAgg
++ = 0xe0;
423 *posRT2RTAgg
++ = 0x4c;
424 *posRT2RTAgg
++ = 0x02;
425 *posRT2RTAgg
++ = 0x01;
429 if (ieee
->bSupportRemoteWakeUp
)
430 *posRT2RTAgg
|= RT_HT_CAP_USE_WOW
;
435 static u8
HT_PickMCSRate(struct rtllib_device
*ieee
, u8
*pOperateMCS
)
439 if (pOperateMCS
== NULL
) {
440 netdev_warn(ieee
->dev
, "%s(): pOperateMCS is null\n", __func__
);
444 switch (ieee
->mode
) {
448 for (i
= 0; i
<= 15; i
++)
453 pOperateMCS
[0] &= RATE_ADPT_1SS_MASK
;
454 pOperateMCS
[1] &= RATE_ADPT_2SS_MASK
;
455 pOperateMCS
[3] &= RATE_ADPT_MCS32_MASK
;
465 u8
HTGetHighestMCSRate(struct rtllib_device
*ieee
, u8
*pMCSRateSet
,
471 u8 availableMcsRate
[16];
473 if (pMCSRateSet
== NULL
|| pMCSFilter
== NULL
) {
474 netdev_warn(ieee
->dev
,
475 "%s(): pMCSRateSet and pMCSFilter are null\n",
479 for (i
= 0; i
< 16; i
++)
480 availableMcsRate
[i
] = pMCSRateSet
[i
] & pMCSFilter
[i
];
482 for (i
= 0; i
< 16; i
++) {
483 if (availableMcsRate
[i
] != 0)
489 for (i
= 0; i
< 16; i
++) {
490 if (availableMcsRate
[i
] != 0) {
491 bitMap
= availableMcsRate
[i
];
492 for (j
= 0; j
< 8; j
++) {
493 if ((bitMap
%2) != 0) {
494 if (HTMcsToDataRate(ieee
, (8*i
+j
)) >
495 HTMcsToDataRate(ieee
, mcsRate
))
502 return mcsRate
| 0x80;
505 static u8
HTFilterMCSRate(struct rtllib_device
*ieee
, u8
*pSupportMCS
,
511 for (i
= 0; i
<= 15; i
++)
512 pOperateMCS
[i
] = ieee
->Regdot11TxHTOperationalRateSet
[i
] &
515 HT_PickMCSRate(ieee
, pOperateMCS
);
517 if (ieee
->GetHalfNmodeSupportByAPsHandler(ieee
->dev
))
520 for (i
= 2; i
<= 15; i
++)
526 void HTSetConnectBwMode(struct rtllib_device
*ieee
,
527 enum ht_channel_width Bandwidth
,
528 enum ht_extchnl_offset Offset
);
530 void HTOnAssocRsp(struct rtllib_device
*ieee
)
532 struct rt_hi_throughput
*pHTInfo
= ieee
->pHTInfo
;
533 struct ht_capab_ele
*pPeerHTCap
= NULL
;
534 struct ht_info_ele
*pPeerHTInfo
= NULL
;
535 u16 nMaxAMSDUSize
= 0;
536 u8
*pMcsFilter
= NULL
;
538 static u8 EWC11NHTCap
[] = {0x00, 0x90, 0x4c, 0x33};
539 static u8 EWC11NHTInfo
[] = {0x00, 0x90, 0x4c, 0x34};
541 if (pHTInfo
->bCurrentHTSupport
== false) {
542 netdev_warn(ieee
->dev
, "%s(): HT_DISABLE\n", __func__
);
545 netdev_dbg(ieee
->dev
, "%s(): HT_ENABLE\n", __func__
);
547 if (!memcmp(pHTInfo
->PeerHTCapBuf
, EWC11NHTCap
, sizeof(EWC11NHTCap
)))
548 pPeerHTCap
= (struct ht_capab_ele
*)(&pHTInfo
->PeerHTCapBuf
[4]);
550 pPeerHTCap
= (struct ht_capab_ele
*)(pHTInfo
->PeerHTCapBuf
);
552 if (!memcmp(pHTInfo
->PeerHTInfoBuf
, EWC11NHTInfo
, sizeof(EWC11NHTInfo
)))
553 pPeerHTInfo
= (struct ht_info_ele
*)
554 (&pHTInfo
->PeerHTInfoBuf
[4]);
556 pPeerHTInfo
= (struct ht_info_ele
*)(pHTInfo
->PeerHTInfoBuf
);
560 print_hex_dump_bytes("HTOnAssocRsp(): ", DUMP_PREFIX_NONE
,
561 pPeerHTCap
, sizeof(struct ht_capab_ele
));
563 HTSetConnectBwMode(ieee
, (enum ht_channel_width
)(pPeerHTCap
->ChlWidth
),
564 (enum ht_extchnl_offset
)(pPeerHTInfo
->ExtChlOffset
));
565 pHTInfo
->bCurTxBW40MHz
= ((pPeerHTInfo
->RecommemdedTxWidth
== 1) ?
568 pHTInfo
->bCurShortGI20MHz
= ((pHTInfo
->bRegShortGI20MHz
) ?
569 ((pPeerHTCap
->ShortGI20Mhz
== 1) ?
570 true : false) : false);
571 pHTInfo
->bCurShortGI40MHz
= ((pHTInfo
->bRegShortGI40MHz
) ?
572 ((pPeerHTCap
->ShortGI40Mhz
== 1) ?
573 true : false) : false);
575 pHTInfo
->bCurSuppCCK
= ((pHTInfo
->bRegSuppCCK
) ?
576 ((pPeerHTCap
->DssCCk
== 1) ? true :
580 pHTInfo
->bCurrent_AMSDU_Support
= pHTInfo
->bAMSDU_Support
;
582 nMaxAMSDUSize
= (pPeerHTCap
->MaxAMSDUSize
== 0) ? 3839 : 7935;
584 if (pHTInfo
->nAMSDU_MaxSize
> nMaxAMSDUSize
)
585 pHTInfo
->nCurrent_AMSDU_MaxSize
= nMaxAMSDUSize
;
587 pHTInfo
->nCurrent_AMSDU_MaxSize
= pHTInfo
->nAMSDU_MaxSize
;
589 pHTInfo
->bCurrentAMPDUEnable
= pHTInfo
->bAMPDUEnable
;
590 if (ieee
->rtllib_ap_sec_type
&&
591 (ieee
->rtllib_ap_sec_type(ieee
)&(SEC_ALG_WEP
|SEC_ALG_TKIP
))) {
592 if ((pHTInfo
->IOTPeer
== HT_IOT_PEER_ATHEROS
) ||
593 (pHTInfo
->IOTPeer
== HT_IOT_PEER_UNKNOWN
))
594 pHTInfo
->bCurrentAMPDUEnable
= false;
597 if (!pHTInfo
->bRegRT2RTAggregation
) {
598 if (pHTInfo
->AMPDU_Factor
> pPeerHTCap
->MaxRxAMPDUFactor
)
599 pHTInfo
->CurrentAMPDUFactor
=
600 pPeerHTCap
->MaxRxAMPDUFactor
;
602 pHTInfo
->CurrentAMPDUFactor
= pHTInfo
->AMPDU_Factor
;
605 if (ieee
->current_network
.bssht
.bdRT2RTAggregation
) {
606 if (ieee
->pairwise_key_type
!= KEY_TYPE_NA
)
607 pHTInfo
->CurrentAMPDUFactor
=
608 pPeerHTCap
->MaxRxAMPDUFactor
;
610 pHTInfo
->CurrentAMPDUFactor
= HT_AGG_SIZE_64K
;
612 if (pPeerHTCap
->MaxRxAMPDUFactor
< HT_AGG_SIZE_32K
)
613 pHTInfo
->CurrentAMPDUFactor
=
614 pPeerHTCap
->MaxRxAMPDUFactor
;
616 pHTInfo
->CurrentAMPDUFactor
= HT_AGG_SIZE_32K
;
619 if (pHTInfo
->MPDU_Density
> pPeerHTCap
->MPDUDensity
)
620 pHTInfo
->CurrentMPDUDensity
= pHTInfo
->MPDU_Density
;
622 pHTInfo
->CurrentMPDUDensity
= pPeerHTCap
->MPDUDensity
;
623 if (pHTInfo
->IOTAction
& HT_IOT_ACT_TX_USE_AMSDU_8K
) {
624 pHTInfo
->bCurrentAMPDUEnable
= false;
625 pHTInfo
->ForcedAMSDUMode
= HT_AGG_FORCE_ENABLE
;
626 pHTInfo
->ForcedAMSDUMaxSize
= 7935;
628 pHTInfo
->bCurRxReorderEnable
= pHTInfo
->bRegRxReorderEnable
;
630 if (pPeerHTCap
->MCS
[0] == 0)
631 pPeerHTCap
->MCS
[0] = 0xff;
633 HTIOTActDetermineRaFunc(ieee
, ((pPeerHTCap
->MCS
[1]) != 0));
635 HTFilterMCSRate(ieee
, pPeerHTCap
->MCS
, ieee
->dot11HTOperationalRateSet
);
637 pHTInfo
->PeerMimoPs
= pPeerHTCap
->MimoPwrSave
;
638 if (pHTInfo
->PeerMimoPs
== MIMO_PS_STATIC
)
639 pMcsFilter
= MCS_FILTER_1SS
;
641 pMcsFilter
= MCS_FILTER_ALL
;
642 ieee
->HTHighestOperaRate
= HTGetHighestMCSRate(ieee
,
643 ieee
->dot11HTOperationalRateSet
, pMcsFilter
);
644 ieee
->HTCurrentOperaRate
= ieee
->HTHighestOperaRate
;
646 pHTInfo
->CurrentOpMode
= pPeerHTInfo
->OptMode
;
649 void HTInitializeHTInfo(struct rtllib_device
*ieee
)
651 struct rt_hi_throughput
*pHTInfo
= ieee
->pHTInfo
;
653 netdev_vdbg(ieee
->dev
, "%s()\n", __func__
);
654 pHTInfo
->bCurrentHTSupport
= false;
656 pHTInfo
->bCurBW40MHz
= false;
657 pHTInfo
->bCurTxBW40MHz
= false;
659 pHTInfo
->bCurShortGI20MHz
= false;
660 pHTInfo
->bCurShortGI40MHz
= false;
661 pHTInfo
->bForcedShortGI
= false;
663 pHTInfo
->bCurSuppCCK
= true;
665 pHTInfo
->bCurrent_AMSDU_Support
= false;
666 pHTInfo
->nCurrent_AMSDU_MaxSize
= pHTInfo
->nAMSDU_MaxSize
;
667 pHTInfo
->CurrentMPDUDensity
= pHTInfo
->MPDU_Density
;
668 pHTInfo
->CurrentAMPDUFactor
= pHTInfo
->AMPDU_Factor
;
670 memset((void *)(&(pHTInfo
->SelfHTCap
)), 0,
671 sizeof(pHTInfo
->SelfHTCap
));
672 memset((void *)(&(pHTInfo
->SelfHTInfo
)), 0,
673 sizeof(pHTInfo
->SelfHTInfo
));
674 memset((void *)(&(pHTInfo
->PeerHTCapBuf
)), 0,
675 sizeof(pHTInfo
->PeerHTCapBuf
));
676 memset((void *)(&(pHTInfo
->PeerHTInfoBuf
)), 0,
677 sizeof(pHTInfo
->PeerHTInfoBuf
));
679 pHTInfo
->bSwBwInProgress
= false;
681 pHTInfo
->ePeerHTSpecVer
= HT_SPEC_VER_IEEE
;
683 pHTInfo
->bCurrentRT2RTAggregation
= false;
684 pHTInfo
->bCurrentRT2RTLongSlotTime
= false;
685 pHTInfo
->RT2RT_HT_Mode
= (enum rt_ht_capability
)0;
687 pHTInfo
->IOTPeer
= 0;
688 pHTInfo
->IOTAction
= 0;
689 pHTInfo
->IOTRaFunc
= 0;
692 u8
*RegHTSuppRateSets
= &(ieee
->RegHTSuppRateSet
[0]);
694 RegHTSuppRateSets
[0] = 0xFF;
695 RegHTSuppRateSets
[1] = 0xFF;
696 RegHTSuppRateSets
[4] = 0x01;
700 void HTInitializeBssDesc(struct bss_ht
*pBssHT
)
703 pBssHT
->bdSupportHT
= false;
704 memset(pBssHT
->bdHTCapBuf
, 0, sizeof(pBssHT
->bdHTCapBuf
));
705 pBssHT
->bdHTCapLen
= 0;
706 memset(pBssHT
->bdHTInfoBuf
, 0, sizeof(pBssHT
->bdHTInfoBuf
));
707 pBssHT
->bdHTInfoLen
= 0;
709 pBssHT
->bdHTSpecVer
= HT_SPEC_VER_IEEE
;
711 pBssHT
->bdRT2RTAggregation
= false;
712 pBssHT
->bdRT2RTLongSlotTime
= false;
713 pBssHT
->RT2RT_HT_Mode
= (enum rt_ht_capability
)0;
716 void HTResetSelfAndSavePeerSetting(struct rtllib_device
*ieee
,
717 struct rtllib_network
*pNetwork
)
719 struct rt_hi_throughput
*pHTInfo
= ieee
->pHTInfo
;
722 netdev_vdbg(ieee
->dev
, "%s()\n", __func__
);
723 /* unmark bEnableHT flag here is the same reason why unmarked in
724 * function rtllib_softmac_new_net. WB 2008.09.10
726 if (pNetwork
->bssht
.bdSupportHT
) {
727 pHTInfo
->bCurrentHTSupport
= true;
728 pHTInfo
->ePeerHTSpecVer
= pNetwork
->bssht
.bdHTSpecVer
;
730 if (pNetwork
->bssht
.bdHTCapLen
> 0 &&
731 pNetwork
->bssht
.bdHTCapLen
<= sizeof(pHTInfo
->PeerHTCapBuf
))
732 memcpy(pHTInfo
->PeerHTCapBuf
,
733 pNetwork
->bssht
.bdHTCapBuf
,
734 pNetwork
->bssht
.bdHTCapLen
);
736 if (pNetwork
->bssht
.bdHTInfoLen
> 0 &&
737 pNetwork
->bssht
.bdHTInfoLen
<=
738 sizeof(pHTInfo
->PeerHTInfoBuf
))
739 memcpy(pHTInfo
->PeerHTInfoBuf
,
740 pNetwork
->bssht
.bdHTInfoBuf
,
741 pNetwork
->bssht
.bdHTInfoLen
);
743 if (pHTInfo
->bRegRT2RTAggregation
) {
744 pHTInfo
->bCurrentRT2RTAggregation
=
745 pNetwork
->bssht
.bdRT2RTAggregation
;
746 pHTInfo
->bCurrentRT2RTLongSlotTime
=
747 pNetwork
->bssht
.bdRT2RTLongSlotTime
;
748 pHTInfo
->RT2RT_HT_Mode
= pNetwork
->bssht
.RT2RT_HT_Mode
;
750 pHTInfo
->bCurrentRT2RTAggregation
= false;
751 pHTInfo
->bCurrentRT2RTLongSlotTime
= false;
752 pHTInfo
->RT2RT_HT_Mode
= (enum rt_ht_capability
)0;
755 HTIOTPeerDetermine(ieee
);
757 pHTInfo
->IOTAction
= 0;
758 bIOTAction
= HTIOTActIsDisableMCS14(ieee
, pNetwork
->bssid
);
760 pHTInfo
->IOTAction
|= HT_IOT_ACT_DISABLE_MCS14
;
762 bIOTAction
= HTIOTActIsDisableMCS15(ieee
);
764 pHTInfo
->IOTAction
|= HT_IOT_ACT_DISABLE_MCS15
;
766 bIOTAction
= HTIOTActIsDisableMCSTwoSpatialStream(ieee
);
768 pHTInfo
->IOTAction
|= HT_IOT_ACT_DISABLE_ALL_2SS
;
771 bIOTAction
= HTIOTActIsDisableEDCATurbo(ieee
, pNetwork
->bssid
);
773 pHTInfo
->IOTAction
|= HT_IOT_ACT_DISABLE_EDCA_TURBO
;
775 bIOTAction
= HTIOTActIsMgntUseCCK6M(ieee
, pNetwork
);
777 pHTInfo
->IOTAction
|= HT_IOT_ACT_MGNT_USE_CCK_6M
;
778 bIOTAction
= HTIOTActIsCCDFsync(ieee
);
780 pHTInfo
->IOTAction
|= HT_IOT_ACT_CDD_FSYNC
;
782 pHTInfo
->bCurrentHTSupport
= false;
783 pHTInfo
->bCurrentRT2RTAggregation
= false;
784 pHTInfo
->bCurrentRT2RTLongSlotTime
= false;
785 pHTInfo
->RT2RT_HT_Mode
= (enum rt_ht_capability
)0;
787 pHTInfo
->IOTAction
= 0;
788 pHTInfo
->IOTRaFunc
= 0;
792 void HT_update_self_and_peer_setting(struct rtllib_device
*ieee
,
793 struct rtllib_network
*pNetwork
)
795 struct rt_hi_throughput
*pHTInfo
= ieee
->pHTInfo
;
796 struct ht_info_ele
*pPeerHTInfo
=
797 (struct ht_info_ele
*)pNetwork
->bssht
.bdHTInfoBuf
;
799 if (pHTInfo
->bCurrentHTSupport
) {
800 if (pNetwork
->bssht
.bdHTInfoLen
!= 0)
801 pHTInfo
->CurrentOpMode
= pPeerHTInfo
->OptMode
;
804 EXPORT_SYMBOL(HT_update_self_and_peer_setting
);
806 void HTUseDefaultSetting(struct rtllib_device
*ieee
)
808 struct rt_hi_throughput
*pHTInfo
= ieee
->pHTInfo
;
810 if (pHTInfo
->bEnableHT
) {
811 pHTInfo
->bCurrentHTSupport
= true;
812 pHTInfo
->bCurSuppCCK
= pHTInfo
->bRegSuppCCK
;
814 pHTInfo
->bCurBW40MHz
= pHTInfo
->bRegBW40MHz
;
815 pHTInfo
->bCurShortGI20MHz
= pHTInfo
->bRegShortGI20MHz
;
817 pHTInfo
->bCurShortGI40MHz
= pHTInfo
->bRegShortGI40MHz
;
819 if (ieee
->iw_mode
== IW_MODE_ADHOC
)
820 ieee
->current_network
.qos_data
.active
=
821 ieee
->current_network
.qos_data
.supported
;
822 pHTInfo
->bCurrent_AMSDU_Support
= pHTInfo
->bAMSDU_Support
;
823 pHTInfo
->nCurrent_AMSDU_MaxSize
= pHTInfo
->nAMSDU_MaxSize
;
825 pHTInfo
->bCurrentAMPDUEnable
= pHTInfo
->bAMPDUEnable
;
826 pHTInfo
->CurrentAMPDUFactor
= pHTInfo
->AMPDU_Factor
;
828 pHTInfo
->CurrentMPDUDensity
= pHTInfo
->CurrentMPDUDensity
;
830 HTFilterMCSRate(ieee
, ieee
->Regdot11TxHTOperationalRateSet
,
831 ieee
->dot11HTOperationalRateSet
);
832 ieee
->HTHighestOperaRate
= HTGetHighestMCSRate(ieee
,
833 ieee
->dot11HTOperationalRateSet
,
835 ieee
->HTCurrentOperaRate
= ieee
->HTHighestOperaRate
;
838 pHTInfo
->bCurrentHTSupport
= false;
842 u8
HTCCheck(struct rtllib_device
*ieee
, u8
*pFrame
)
844 if (ieee
->pHTInfo
->bCurrentHTSupport
) {
845 if ((IsQoSDataFrame(pFrame
) && Frame_Order(pFrame
)) == 1) {
846 netdev_dbg(ieee
->dev
, "HT CONTROL FILED EXIST!!\n");
853 static void HTSetConnectBwModeCallback(struct rtllib_device
*ieee
)
855 struct rt_hi_throughput
*pHTInfo
= ieee
->pHTInfo
;
857 netdev_vdbg(ieee
->dev
, "%s()\n", __func__
);
859 if (pHTInfo
->bCurBW40MHz
) {
860 if (pHTInfo
->CurSTAExtChnlOffset
== HT_EXTCHNL_OFFSET_UPPER
)
861 ieee
->set_chan(ieee
->dev
,
862 ieee
->current_network
.channel
+ 2);
863 else if (pHTInfo
->CurSTAExtChnlOffset
==
864 HT_EXTCHNL_OFFSET_LOWER
)
865 ieee
->set_chan(ieee
->dev
,
866 ieee
->current_network
.channel
- 2);
868 ieee
->set_chan(ieee
->dev
,
869 ieee
->current_network
.channel
);
871 ieee
->SetBWModeHandler(ieee
->dev
, HT_CHANNEL_WIDTH_20_40
,
872 pHTInfo
->CurSTAExtChnlOffset
);
874 ieee
->set_chan(ieee
->dev
, ieee
->current_network
.channel
);
875 ieee
->SetBWModeHandler(ieee
->dev
, HT_CHANNEL_WIDTH_20
,
876 HT_EXTCHNL_OFFSET_NO_EXT
);
879 pHTInfo
->bSwBwInProgress
= false;
882 void HTSetConnectBwMode(struct rtllib_device
*ieee
,
883 enum ht_channel_width Bandwidth
,
884 enum ht_extchnl_offset Offset
)
886 struct rt_hi_throughput
*pHTInfo
= ieee
->pHTInfo
;
888 if (pHTInfo
->bRegBW40MHz
== false)
891 if (ieee
->GetHalfNmodeSupportByAPsHandler(ieee
->dev
))
892 Bandwidth
= HT_CHANNEL_WIDTH_20
;
894 if (pHTInfo
->bSwBwInProgress
) {
895 pr_info("%s: bSwBwInProgress!!\n", __func__
);
898 if (Bandwidth
== HT_CHANNEL_WIDTH_20_40
) {
899 if (ieee
->current_network
.channel
< 2 &&
900 Offset
== HT_EXTCHNL_OFFSET_LOWER
)
901 Offset
= HT_EXTCHNL_OFFSET_NO_EXT
;
902 if (Offset
== HT_EXTCHNL_OFFSET_UPPER
||
903 Offset
== HT_EXTCHNL_OFFSET_LOWER
) {
904 pHTInfo
->bCurBW40MHz
= true;
905 pHTInfo
->CurSTAExtChnlOffset
= Offset
;
907 pHTInfo
->bCurBW40MHz
= false;
908 pHTInfo
->CurSTAExtChnlOffset
= HT_EXTCHNL_OFFSET_NO_EXT
;
911 pHTInfo
->bCurBW40MHz
= false;
912 pHTInfo
->CurSTAExtChnlOffset
= HT_EXTCHNL_OFFSET_NO_EXT
;
915 pr_info("%s():pHTInfo->bCurBW40MHz:%x\n", __func__
,
916 pHTInfo
->bCurBW40MHz
);
918 pHTInfo
->bSwBwInProgress
= true;
920 HTSetConnectBwModeCallback(ieee
);