Commit | Line | Data |
---|---|---|
18056f34 GKH |
1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* | |
94a79942 LF |
3 | * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. |
4 | * | |
18056f34 GKH |
5 | * Contact Information: wlanfae <wlanfae@realtek.com> |
6 | */ | |
94a79942 LF |
7 | #include "rtllib.h" |
8 | #include "rtl819x_HT.h" | |
831cb9db LF |
9 | u8 MCS_FILTER_ALL[16] = { |
10 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
11 | 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | |
12 | }; | |
13 | ||
14 | u8 MCS_FILTER_1SS[16] = { | |
15 | 0xff, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, | |
16 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} | |
17 | ; | |
18 | ||
19 | u16 MCS_DATA_RATE[2][2][77] = { | |
20 | {{13, 26, 39, 52, 78, 104, 117, 130, 26, 52, 78, 104, 156, 208, 234, | |
21 | 260, 39, 78, 117, 234, 312, 351, 390, 52, 104, 156, 208, 312, 416, | |
22 | 468, 520, 0, 78, 104, 130, 117, 156, 195, 104, 130, 130, 156, 182, | |
23 | 182, 208, 156, 195, 195, 234, 273, 273, 312, 130, 156, 181, 156, | |
24 | 181, 208, 234, 208, 234, 260, 260, 286, 195, 234, 273, 234, 273, | |
31f1c464 | 25 | 312, 351, 312, 351, 390, 390, 429}, |
831cb9db LF |
26 | {14, 29, 43, 58, 87, 116, 130, 144, 29, 58, 87, 116, 173, 231, 260, 289, |
27 | 43, 87, 130, 173, 260, 347, 390, 433, 58, 116, 173, 231, 347, 462, 520, | |
28 | 578, 0, 87, 116, 144, 130, 173, 217, 116, 144, 144, 173, 202, 202, 231, | |
29 | 173, 217, 217, 260, 303, 303, 347, 144, 173, 202, 173, 202, 231, 260, | |
30 | 231, 260, 289, 289, 318, 217, 260, 303, 260, 303, 347, 390, 347, 390, | |
31f1c464 | 31 | 433, 433, 477} }, |
831cb9db LF |
32 | {{27, 54, 81, 108, 162, 216, 243, 270, 54, 108, 162, 216, 324, 432, 486, |
33 | 540, 81, 162, 243, 324, 486, 648, 729, 810, 108, 216, 324, 432, 648, | |
34 | 864, 972, 1080, 12, 162, 216, 270, 243, 324, 405, 216, 270, 270, 324, | |
35 | 378, 378, 432, 324, 405, 405, 486, 567, 567, 648, 270, 324, 378, 324, | |
36 | 378, 432, 486, 432, 486, 540, 540, 594, 405, 486, 567, 486, 567, 648, | |
37 | 729, 648, 729, 810, 810, 891}, | |
38 | {30, 60, 90, 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540, | |
39 | 600, 90, 180, 270, 360, 540, 720, 810, 900, 120, 240, 360, 480, 720, | |
40 | 960, 1080, 1200, 13, 180, 240, 300, 270, 360, 450, 240, 300, 300, 360, | |
41 | 420, 420, 480, 360, 450, 450, 540, 630, 630, 720, 300, 360, 420, 360, | |
42 | 420, 480, 540, 480, 540, 600, 600, 660, 450, 540, 630, 540, 630, 720, | |
43 | 810, 720, 810, 900, 900, 990} } | |
44 | }; | |
94a79942 LF |
45 | |
46 | static u8 UNKNOWN_BORADCOM[3] = {0x00, 0x14, 0xbf}; | |
831cb9db | 47 | |
94a79942 | 48 | static u8 LINKSYSWRT330_LINKSYSWRT300_BROADCOM[3] = {0x00, 0x1a, 0x70}; |
831cb9db | 49 | |
94a79942 | 50 | static u8 LINKSYSWRT350_LINKSYSWRT150_BROADCOM[3] = {0x00, 0x1d, 0x7e}; |
831cb9db | 51 | |
94a79942 | 52 | static u8 BELKINF5D8233V1_RALINK[3] = {0x00, 0x17, 0x3f}; |
831cb9db | 53 | |
94a79942 | 54 | static u8 BELKINF5D82334V3_RALINK[3] = {0x00, 0x1c, 0xdf}; |
831cb9db | 55 | |
94a79942 | 56 | static u8 PCI_RALINK[3] = {0x00, 0x90, 0xcc}; |
831cb9db | 57 | |
94a79942 | 58 | static u8 EDIMAX_RALINK[3] = {0x00, 0x0e, 0x2e}; |
831cb9db | 59 | |
94a79942 | 60 | static u8 AIRLINK_RALINK[3] = {0x00, 0x18, 0x02}; |
831cb9db | 61 | |
94a79942 | 62 | static u8 DLINK_ATHEROS_1[3] = {0x00, 0x1c, 0xf0}; |
831cb9db | 63 | |
94a79942 | 64 | static u8 DLINK_ATHEROS_2[3] = {0x00, 0x21, 0x91}; |
831cb9db | 65 | |
94a79942 | 66 | static u8 CISCO_BROADCOM[3] = {0x00, 0x17, 0x94}; |
831cb9db | 67 | |
94a79942 | 68 | static u8 LINKSYS_MARVELL_4400N[3] = {0x00, 0x14, 0xa4}; |
831cb9db LF |
69 | |
70 | void HTUpdateDefaultSetting(struct rtllib_device *ieee) | |
94a79942 | 71 | { |
7796d93e | 72 | struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; |
94a79942 | 73 | |
94a79942 LF |
74 | pHTInfo->bAcceptAddbaReq = 1; |
75 | ||
831cb9db LF |
76 | pHTInfo->bRegShortGI20MHz = 1; |
77 | pHTInfo->bRegShortGI40MHz = 1; | |
94a79942 LF |
78 | |
79 | pHTInfo->bRegBW40MHz = 1; | |
80 | ||
81 | if (pHTInfo->bRegBW40MHz) | |
82 | pHTInfo->bRegSuppCCK = 1; | |
83 | else | |
84 | pHTInfo->bRegSuppCCK = true; | |
85 | ||
86 | pHTInfo->nAMSDU_MaxSize = 7935UL; | |
87 | pHTInfo->bAMSDU_Support = 0; | |
88 | ||
89 | pHTInfo->bAMPDUEnable = 1; | |
90 | pHTInfo->AMPDU_Factor = 2; | |
91 | pHTInfo->MPDU_Density = 0; | |
92 | ||
93 | pHTInfo->SelfMimoPs = 3; | |
94 | if (pHTInfo->SelfMimoPs == 2) | |
95 | pHTInfo->SelfMimoPs = 3; | |
96 | ieee->bTxDisableRateFallBack = 0; | |
97 | ieee->bTxUseDriverAssingedRate = 0; | |
98 | ||
99 | ieee->bTxEnableFwCalcDur = 1; | |
100 | ||
101 | pHTInfo->bRegRT2RTAggregation = 1; | |
102 | ||
103 | pHTInfo->bRegRxReorderEnable = 1; | |
104 | pHTInfo->RxReorderWinSize = 64; | |
105 | pHTInfo->RxReorderPendingTime = 30; | |
94a79942 | 106 | } |
831cb9db | 107 | |
e0c84c1c | 108 | static u16 HTMcsToDataRate(struct rtllib_device *ieee, u8 nMcsRate) |
94a79942 | 109 | { |
7796d93e | 110 | struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; |
94a79942 | 111 | |
831cb9db LF |
112 | u8 is40MHz = (pHTInfo->bCurBW40MHz) ? 1 : 0; |
113 | u8 isShortGI = (pHTInfo->bCurBW40MHz) ? | |
114 | ((pHTInfo->bCurShortGI40MHz) ? 1 : 0) : | |
115 | ((pHTInfo->bCurShortGI20MHz) ? 1 : 0); | |
116 | return MCS_DATA_RATE[is40MHz][isShortGI][(nMcsRate & 0x7f)]; | |
94a79942 LF |
117 | } |
118 | ||
831cb9db | 119 | u16 TxCountToDataRate(struct rtllib_device *ieee, u8 nDataRate) |
94a79942 | 120 | { |
831cb9db LF |
121 | u16 CCKOFDMRate[12] = {0x02, 0x04, 0x0b, 0x16, 0x0c, 0x12, 0x18, |
122 | 0x24, 0x30, 0x48, 0x60, 0x6c}; | |
94a79942 LF |
123 | u8 is40MHz = 0; |
124 | u8 isShortGI = 0; | |
125 | ||
285b7c00 | 126 | if (nDataRate < 12) |
94a79942 | 127 | return CCKOFDMRate[nDataRate]; |
285b7c00 MK |
128 | if (nDataRate >= 0x10 && nDataRate <= 0x1f) { |
129 | is40MHz = 0; | |
130 | isShortGI = 0; | |
131 | } else if (nDataRate >= 0x20 && nDataRate <= 0x2f) { | |
132 | is40MHz = 1; | |
133 | isShortGI = 0; | |
134 | } else if (nDataRate >= 0x30 && nDataRate <= 0x3f) { | |
135 | is40MHz = 0; | |
136 | isShortGI = 1; | |
137 | } else if (nDataRate >= 0x40 && nDataRate <= 0x4f) { | |
138 | is40MHz = 1; | |
139 | isShortGI = 1; | |
94a79942 | 140 | } |
285b7c00 | 141 | return MCS_DATA_RATE[is40MHz][isShortGI][nDataRate&0xf]; |
94a79942 LF |
142 | } |
143 | ||
831cb9db | 144 | bool IsHTHalfNmodeAPs(struct rtllib_device *ieee) |
94a79942 LF |
145 | { |
146 | bool retValue = false; | |
831cb9db LF |
147 | struct rtllib_network *net = &ieee->current_network; |
148 | ||
149 | if ((memcmp(net->bssid, BELKINF5D8233V1_RALINK, 3) == 0) || | |
150 | (memcmp(net->bssid, BELKINF5D82334V3_RALINK, 3) == 0) || | |
151 | (memcmp(net->bssid, PCI_RALINK, 3) == 0) || | |
152 | (memcmp(net->bssid, EDIMAX_RALINK, 3) == 0) || | |
153 | (memcmp(net->bssid, AIRLINK_RALINK, 3) == 0) || | |
154 | (net->ralink_cap_exist)) | |
155 | retValue = true; | |
156 | else if (!memcmp(net->bssid, UNKNOWN_BORADCOM, 3) || | |
157 | !memcmp(net->bssid, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3) || | |
158 | !memcmp(net->bssid, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3) || | |
159 | (net->broadcom_cap_exist)) | |
94a79942 | 160 | retValue = true; |
94a79942 LF |
161 | else if (net->bssht.bdRT2RTAggregation) |
162 | retValue = true; | |
163 | else | |
164 | retValue = false; | |
165 | ||
166 | return retValue; | |
167 | } | |
168 | ||
ec0dc6be | 169 | static void HTIOTPeerDetermine(struct rtllib_device *ieee) |
94a79942 | 170 | { |
7796d93e | 171 | struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; |
831cb9db | 172 | struct rtllib_network *net = &ieee->current_network; |
3a6b70c3 | 173 | |
831cb9db | 174 | if (net->bssht.bdRT2RTAggregation) { |
94a79942 | 175 | pHTInfo->IOTPeer = HT_IOT_PEER_REALTEK; |
831cb9db | 176 | if (net->bssht.RT2RT_HT_Mode & RT_HT_CAP_USE_92SE) |
94a79942 | 177 | pHTInfo->IOTPeer = HT_IOT_PEER_REALTEK_92SE; |
831cb9db | 178 | if (net->bssht.RT2RT_HT_Mode & RT_HT_CAP_USE_SOFTAP) |
94a79942 | 179 | pHTInfo->IOTPeer = HT_IOT_PEER_92U_SOFTAP; |
8b5b1b81 | 180 | } else if (net->broadcom_cap_exist) { |
94a79942 | 181 | pHTInfo->IOTPeer = HT_IOT_PEER_BROADCOM; |
8b5b1b81 | 182 | } else if (!memcmp(net->bssid, UNKNOWN_BORADCOM, 3) || |
831cb9db | 183 | !memcmp(net->bssid, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3) || |
8b5b1b81 | 184 | !memcmp(net->bssid, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3)) { |
94a79942 | 185 | pHTInfo->IOTPeer = HT_IOT_PEER_BROADCOM; |
8b5b1b81 | 186 | } else if ((memcmp(net->bssid, BELKINF5D8233V1_RALINK, 3) == 0) || |
831cb9db LF |
187 | (memcmp(net->bssid, BELKINF5D82334V3_RALINK, 3) == 0) || |
188 | (memcmp(net->bssid, PCI_RALINK, 3) == 0) || | |
189 | (memcmp(net->bssid, EDIMAX_RALINK, 3) == 0) || | |
190 | (memcmp(net->bssid, AIRLINK_RALINK, 3) == 0) || | |
8b5b1b81 | 191 | net->ralink_cap_exist) { |
94a79942 | 192 | pHTInfo->IOTPeer = HT_IOT_PEER_RALINK; |
8b5b1b81 | 193 | } else if ((net->atheros_cap_exist) || |
831cb9db | 194 | (memcmp(net->bssid, DLINK_ATHEROS_1, 3) == 0) || |
8b5b1b81 | 195 | (memcmp(net->bssid, DLINK_ATHEROS_2, 3) == 0)) { |
94a79942 | 196 | pHTInfo->IOTPeer = HT_IOT_PEER_ATHEROS; |
8b5b1b81 EV |
197 | } else if ((memcmp(net->bssid, CISCO_BROADCOM, 3) == 0) || |
198 | net->cisco_cap_exist) { | |
94a79942 | 199 | pHTInfo->IOTPeer = HT_IOT_PEER_CISCO; |
8b5b1b81 EV |
200 | } else if ((memcmp(net->bssid, LINKSYS_MARVELL_4400N, 3) == 0) || |
201 | net->marvell_cap_exist) { | |
94a79942 | 202 | pHTInfo->IOTPeer = HT_IOT_PEER_MARVELL; |
8b5b1b81 | 203 | } else if (net->airgo_cap_exist) { |
94a79942 | 204 | pHTInfo->IOTPeer = HT_IOT_PEER_AIRGO; |
8b5b1b81 | 205 | } else { |
94a79942 | 206 | pHTInfo->IOTPeer = HT_IOT_PEER_UNKNOWN; |
8b5b1b81 | 207 | } |
94a79942 | 208 | |
b94436b5 | 209 | netdev_dbg(ieee->dev, "IOTPEER: %x\n", pHTInfo->IOTPeer); |
94a79942 LF |
210 | } |
211 | ||
ec0dc6be | 212 | static u8 HTIOTActIsDisableMCS14(struct rtllib_device *ieee, u8 *PeerMacAddr) |
94a79942 LF |
213 | { |
214 | return 0; | |
831cb9db | 215 | } |
94a79942 LF |
216 | |
217 | ||
ec0dc6be | 218 | static bool HTIOTActIsDisableMCS15(struct rtllib_device *ieee) |
94a79942 | 219 | { |
e623d0f3 | 220 | return false; |
94a79942 LF |
221 | } |
222 | ||
ec0dc6be | 223 | static bool HTIOTActIsDisableMCSTwoSpatialStream(struct rtllib_device *ieee) |
94a79942 | 224 | { |
831cb9db | 225 | return false; |
94a79942 LF |
226 | } |
227 | ||
35e33b04 MK |
228 | static u8 HTIOTActIsDisableEDCATurbo(struct rtllib_device *ieee, |
229 | u8 *PeerMacAddr) | |
94a79942 LF |
230 | { |
231 | return false; | |
232 | } | |
233 | ||
ec0dc6be LF |
234 | static u8 HTIOTActIsMgntUseCCK6M(struct rtllib_device *ieee, |
235 | struct rtllib_network *network) | |
94a79942 LF |
236 | { |
237 | u8 retValue = 0; | |
238 | ||
239 | ||
94a79942 | 240 | if (ieee->pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM) |
94a79942 | 241 | retValue = 1; |
94a79942 LF |
242 | |
243 | return retValue; | |
244 | } | |
245 | ||
ec0dc6be | 246 | static u8 HTIOTActIsCCDFsync(struct rtllib_device *ieee) |
94a79942 LF |
247 | { |
248 | u8 retValue = 0; | |
831cb9db | 249 | |
94a79942 | 250 | if (ieee->pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM) |
94a79942 | 251 | retValue = 1; |
94a79942 LF |
252 | return retValue; |
253 | } | |
254 | ||
ec0dc6be | 255 | static void HTIOTActDetermineRaFunc(struct rtllib_device *ieee, bool bPeerRx2ss) |
94a79942 | 256 | { |
7796d93e | 257 | struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; |
3a6b70c3 | 258 | |
94a79942 LF |
259 | pHTInfo->IOTRaFunc &= HT_IOT_RAFUNC_DISABLE_ALL; |
260 | ||
261 | if (pHTInfo->IOTPeer == HT_IOT_PEER_RALINK && !bPeerRx2ss) | |
262 | pHTInfo->IOTRaFunc |= HT_IOT_RAFUNC_PEER_1R; | |
263 | ||
264 | if (pHTInfo->IOTAction & HT_IOT_ACT_AMSDU_ENABLE) | |
265 | pHTInfo->IOTRaFunc |= HT_IOT_RAFUNC_TX_AMSDU; | |
266 | ||
267 | } | |
268 | ||
831cb9db | 269 | void HTResetIOTSetting(struct rt_hi_throughput *pHTInfo) |
94a79942 LF |
270 | { |
271 | pHTInfo->IOTAction = 0; | |
272 | pHTInfo->IOTPeer = HT_IOT_PEER_UNKNOWN; | |
273 | pHTInfo->IOTRaFunc = 0; | |
274 | } | |
275 | ||
831cb9db LF |
276 | void HTConstructCapabilityElement(struct rtllib_device *ieee, u8 *posHTCap, |
277 | u8 *len, u8 IsEncrypt, bool bAssoc) | |
94a79942 | 278 | { |
7796d93e | 279 | struct rt_hi_throughput *pHT = ieee->pHTInfo; |
e92b71d5 | 280 | struct ht_capab_ele *pCapELE = NULL; |
94a79942 | 281 | |
831cb9db | 282 | if ((posHTCap == NULL) || (pHT == NULL)) { |
11e672c3 MK |
283 | netdev_warn(ieee->dev, |
284 | "%s(): posHTCap and pHTInfo are null\n", __func__); | |
94a79942 LF |
285 | return; |
286 | } | |
287 | memset(posHTCap, 0, *len); | |
288 | ||
831cb9db | 289 | if ((bAssoc) && (pHT->ePeerHTSpecVer == HT_SPEC_VER_EWC)) { |
94a79942 | 290 | u8 EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33}; |
3a6b70c3 | 291 | |
94a79942 | 292 | memcpy(posHTCap, EWC11NHTCap, sizeof(EWC11NHTCap)); |
e92b71d5 | 293 | pCapELE = (struct ht_capab_ele *)&(posHTCap[4]); |
94a79942 | 294 | *len = 30 + 2; |
831cb9db | 295 | } else { |
e92b71d5 | 296 | pCapELE = (struct ht_capab_ele *)posHTCap; |
94a79942 LF |
297 | *len = 26 + 2; |
298 | } | |
299 | ||
300 | pCapELE->AdvCoding = 0; | |
301 | if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) | |
302 | pCapELE->ChlWidth = 0; | |
303 | else | |
831cb9db | 304 | pCapELE->ChlWidth = (pHT->bRegBW40MHz ? 1 : 0); |
94a79942 LF |
305 | |
306 | pCapELE->MimoPwrSave = pHT->SelfMimoPs; | |
307 | pCapELE->GreenField = 0; | |
308 | pCapELE->ShortGI20Mhz = 1; | |
309 | pCapELE->ShortGI40Mhz = 1; | |
310 | ||
311 | pCapELE->TxSTBC = 1; | |
94a79942 LF |
312 | pCapELE->RxSTBC = 0; |
313 | pCapELE->DelayBA = 0; | |
831cb9db LF |
314 | pCapELE->MaxAMSDUSize = (MAX_RECEIVE_BUFFER_SIZE >= 7935) ? 1 : 0; |
315 | pCapELE->DssCCk = ((pHT->bRegBW40MHz) ? (pHT->bRegSuppCCK ? 1 : 0) : 0); | |
316 | pCapELE->PSMP = 0; | |
317 | pCapELE->LSigTxopProtect = 0; | |
94a79942 LF |
318 | |
319 | ||
b94436b5 MK |
320 | netdev_dbg(ieee->dev, |
321 | "TX HT cap/info ele BW=%d MaxAMSDUSize:%d DssCCk:%d\n", | |
322 | pCapELE->ChlWidth, pCapELE->MaxAMSDUSize, pCapELE->DssCCk); | |
94a79942 | 323 | |
831cb9db | 324 | if (IsEncrypt) { |
94a79942 LF |
325 | pCapELE->MPDUDensity = 7; |
326 | pCapELE->MaxRxAMPDUFactor = 2; | |
831cb9db | 327 | } else { |
94a79942 LF |
328 | pCapELE->MaxRxAMPDUFactor = 3; |
329 | pCapELE->MPDUDensity = 0; | |
330 | } | |
331 | ||
332 | memcpy(pCapELE->MCS, ieee->Regdot11HTOperationalRateSet, 16); | |
333 | memset(&pCapELE->ExtHTCapInfo, 0, 2); | |
334 | memset(pCapELE->TxBFCap, 0, 4); | |
335 | ||
336 | pCapELE->ASCap = 0; | |
337 | ||
338 | if (bAssoc) { | |
339 | if (pHT->IOTAction & HT_IOT_ACT_DISABLE_MCS15) | |
340 | pCapELE->MCS[1] &= 0x7f; | |
341 | ||
342 | if (pHT->IOTAction & HT_IOT_ACT_DISABLE_MCS14) | |
343 | pCapELE->MCS[1] &= 0xbf; | |
344 | ||
345 | if (pHT->IOTAction & HT_IOT_ACT_DISABLE_ALL_2SS) | |
346 | pCapELE->MCS[1] &= 0x00; | |
347 | ||
348 | if (pHT->IOTAction & HT_IOT_ACT_DISABLE_RX_40MHZ_SHORT_GI) | |
349 | pCapELE->ShortGI40Mhz = 0; | |
350 | ||
831cb9db | 351 | if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) { |
94a79942 | 352 | pCapELE->ChlWidth = 0; |
94a79942 LF |
353 | pCapELE->MCS[1] = 0; |
354 | } | |
355 | } | |
94a79942 | 356 | } |
831cb9db LF |
357 | |
358 | void HTConstructInfoElement(struct rtllib_device *ieee, u8 *posHTInfo, | |
359 | u8 *len, u8 IsEncrypt) | |
94a79942 | 360 | { |
7796d93e | 361 | struct rt_hi_throughput *pHT = ieee->pHTInfo; |
407e998e | 362 | struct ht_info_ele *pHTInfoEle = (struct ht_info_ele *)posHTInfo; |
3a6b70c3 | 363 | |
831cb9db | 364 | if ((posHTInfo == NULL) || (pHTInfoEle == NULL)) { |
11e672c3 MK |
365 | netdev_warn(ieee->dev, |
366 | "%s(): posHTInfo and pHTInfoEle are null\n", | |
367 | __func__); | |
94a79942 LF |
368 | return; |
369 | } | |
370 | ||
371 | memset(posHTInfo, 0, *len); | |
831cb9db LF |
372 | if ((ieee->iw_mode == IW_MODE_ADHOC) || |
373 | (ieee->iw_mode == IW_MODE_MASTER)) { | |
94a79942 | 374 | pHTInfoEle->ControlChl = ieee->current_network.channel; |
e785e87b | 375 | pHTInfoEle->ExtChlOffset = ((!pHT->bRegBW40MHz) ? |
831cb9db LF |
376 | HT_EXTCHNL_OFFSET_NO_EXT : |
377 | (ieee->current_network.channel <= 6) | |
378 | ? HT_EXTCHNL_OFFSET_UPPER : | |
379 | HT_EXTCHNL_OFFSET_LOWER); | |
94a79942 | 380 | pHTInfoEle->RecommemdedTxWidth = pHT->bRegBW40MHz; |
831cb9db | 381 | pHTInfoEle->RIFS = 0; |
94a79942 LF |
382 | pHTInfoEle->PSMPAccessOnly = 0; |
383 | pHTInfoEle->SrvIntGranularity = 0; | |
831cb9db | 384 | pHTInfoEle->OptMode = pHT->CurrentOpMode; |
94a79942 LF |
385 | pHTInfoEle->NonGFDevPresent = 0; |
386 | pHTInfoEle->DualBeacon = 0; | |
387 | pHTInfoEle->SecondaryBeacon = 0; | |
388 | pHTInfoEle->LSigTxopProtectFull = 0; | |
831cb9db LF |
389 | pHTInfoEle->PcoActive = 0; |
390 | pHTInfoEle->PcoPhase = 0; | |
94a79942 LF |
391 | |
392 | memset(pHTInfoEle->BasicMSC, 0, 16); | |
393 | ||
394 | ||
395 | *len = 22 + 2; | |
396 | ||
831cb9db | 397 | } else { |
94a79942 LF |
398 | *len = 0; |
399 | } | |
94a79942 LF |
400 | } |
401 | ||
831cb9db LF |
402 | void HTConstructRT2RTAggElement(struct rtllib_device *ieee, u8 *posRT2RTAgg, |
403 | u8 *len) | |
94a79942 LF |
404 | { |
405 | if (posRT2RTAgg == NULL) { | |
11e672c3 | 406 | netdev_warn(ieee->dev, "%s(): posRT2RTAgg is null\n", __func__); |
94a79942 LF |
407 | return; |
408 | } | |
409 | memset(posRT2RTAgg, 0, *len); | |
410 | *posRT2RTAgg++ = 0x00; | |
411 | *posRT2RTAgg++ = 0xe0; | |
412 | *posRT2RTAgg++ = 0x4c; | |
413 | *posRT2RTAgg++ = 0x02; | |
414 | *posRT2RTAgg++ = 0x01; | |
415 | ||
94a79942 | 416 | *posRT2RTAgg = 0x30; |
94a79942 | 417 | |
831cb9db | 418 | if (ieee->bSupportRemoteWakeUp) |
94a79942 | 419 | *posRT2RTAgg |= RT_HT_CAP_USE_WOW; |
94a79942 LF |
420 | |
421 | *len = 6 + 2; | |
94a79942 LF |
422 | } |
423 | ||
ec0dc6be | 424 | static u8 HT_PickMCSRate(struct rtllib_device *ieee, u8 *pOperateMCS) |
94a79942 | 425 | { |
831cb9db | 426 | u8 i; |
3a6b70c3 | 427 | |
831cb9db | 428 | if (pOperateMCS == NULL) { |
11e672c3 | 429 | netdev_warn(ieee->dev, "%s(): pOperateMCS is null\n", __func__); |
94a79942 LF |
430 | return false; |
431 | } | |
432 | ||
433 | switch (ieee->mode) { | |
434 | case IEEE_A: | |
435 | case IEEE_B: | |
436 | case IEEE_G: | |
831cb9db LF |
437 | for (i = 0; i <= 15; i++) |
438 | pOperateMCS[i] = 0; | |
94a79942 LF |
439 | break; |
440 | case IEEE_N_24G: | |
441 | case IEEE_N_5G: | |
831cb9db LF |
442 | pOperateMCS[0] &= RATE_ADPT_1SS_MASK; |
443 | pOperateMCS[1] &= RATE_ADPT_2SS_MASK; | |
444 | pOperateMCS[3] &= RATE_ADPT_MCS32_MASK; | |
94a79942 LF |
445 | break; |
446 | default: | |
447 | break; | |
448 | ||
449 | } | |
450 | ||
451 | return true; | |
452 | } | |
453 | ||
831cb9db LF |
454 | u8 HTGetHighestMCSRate(struct rtllib_device *ieee, u8 *pMCSRateSet, |
455 | u8 *pMCSFilter) | |
94a79942 LF |
456 | { |
457 | u8 i, j; | |
458 | u8 bitMap; | |
459 | u8 mcsRate = 0; | |
460 | u8 availableMcsRate[16]; | |
3a6b70c3 | 461 | |
831cb9db | 462 | if (pMCSRateSet == NULL || pMCSFilter == NULL) { |
11e672c3 MK |
463 | netdev_warn(ieee->dev, |
464 | "%s(): pMCSRateSet and pMCSFilter are null\n", | |
465 | __func__); | |
94a79942 LF |
466 | return false; |
467 | } | |
831cb9db | 468 | for (i = 0; i < 16; i++) |
94a79942 LF |
469 | availableMcsRate[i] = pMCSRateSet[i] & pMCSFilter[i]; |
470 | ||
831cb9db | 471 | for (i = 0; i < 16; i++) { |
94a79942 LF |
472 | if (availableMcsRate[i] != 0) |
473 | break; | |
474 | } | |
475 | if (i == 16) | |
476 | return false; | |
477 | ||
831cb9db LF |
478 | for (i = 0; i < 16; i++) { |
479 | if (availableMcsRate[i] != 0) { | |
94a79942 | 480 | bitMap = availableMcsRate[i]; |
831cb9db LF |
481 | for (j = 0; j < 8; j++) { |
482 | if ((bitMap%2) != 0) { | |
483 | if (HTMcsToDataRate(ieee, (8*i+j)) > | |
484 | HTMcsToDataRate(ieee, mcsRate)) | |
24542a00 | 485 | mcsRate = 8 * i + j; |
94a79942 | 486 | } |
be31fed4 | 487 | bitMap >>= 1; |
94a79942 LF |
488 | } |
489 | } | |
490 | } | |
831cb9db | 491 | return mcsRate | 0x80; |
94a79942 LF |
492 | } |
493 | ||
e0c84c1c MK |
494 | static u8 HTFilterMCSRate(struct rtllib_device *ieee, u8 *pSupportMCS, |
495 | u8 *pOperateMCS) | |
94a79942 LF |
496 | { |
497 | ||
831cb9db | 498 | u8 i; |
94a79942 | 499 | |
831cb9db LF |
500 | for (i = 0; i <= 15; i++) |
501 | pOperateMCS[i] = ieee->Regdot11TxHTOperationalRateSet[i] & | |
502 | pSupportMCS[i]; | |
94a79942 LF |
503 | |
504 | HT_PickMCSRate(ieee, pOperateMCS); | |
505 | ||
506 | if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) | |
507 | pOperateMCS[1] = 0; | |
508 | ||
831cb9db | 509 | for (i = 2; i <= 15; i++) |
94a79942 LF |
510 | pOperateMCS[i] = 0; |
511 | ||
512 | return true; | |
513 | } | |
831cb9db LF |
514 | |
515 | void HTSetConnectBwMode(struct rtllib_device *ieee, | |
516 | enum ht_channel_width Bandwidth, | |
517 | enum ht_extchnl_offset Offset); | |
518 | ||
94a79942 LF |
519 | void HTOnAssocRsp(struct rtllib_device *ieee) |
520 | { | |
7796d93e | 521 | struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; |
e92b71d5 | 522 | struct ht_capab_ele *pPeerHTCap = NULL; |
407e998e | 523 | struct ht_info_ele *pPeerHTInfo = NULL; |
831cb9db LF |
524 | u16 nMaxAMSDUSize = 0; |
525 | u8 *pMcsFilter = NULL; | |
94a79942 | 526 | |
831cb9db LF |
527 | static u8 EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33}; |
528 | static u8 EWC11NHTInfo[] = {0x00, 0x90, 0x4c, 0x34}; | |
94a79942 | 529 | |
e785e87b | 530 | if (!pHTInfo->bCurrentHTSupport) { |
11e672c3 | 531 | netdev_warn(ieee->dev, "%s(): HT_DISABLE\n", __func__); |
94a79942 LF |
532 | return; |
533 | } | |
b94436b5 | 534 | netdev_dbg(ieee->dev, "%s(): HT_ENABLE\n", __func__); |
94a79942 | 535 | |
831cb9db | 536 | if (!memcmp(pHTInfo->PeerHTCapBuf, EWC11NHTCap, sizeof(EWC11NHTCap))) |
e92b71d5 | 537 | pPeerHTCap = (struct ht_capab_ele *)(&pHTInfo->PeerHTCapBuf[4]); |
94a79942 | 538 | else |
e92b71d5 | 539 | pPeerHTCap = (struct ht_capab_ele *)(pHTInfo->PeerHTCapBuf); |
94a79942 LF |
540 | |
541 | if (!memcmp(pHTInfo->PeerHTInfoBuf, EWC11NHTInfo, sizeof(EWC11NHTInfo))) | |
831cb9db LF |
542 | pPeerHTInfo = (struct ht_info_ele *) |
543 | (&pHTInfo->PeerHTInfoBuf[4]); | |
94a79942 | 544 | else |
407e998e | 545 | pPeerHTInfo = (struct ht_info_ele *)(pHTInfo->PeerHTInfoBuf); |
94a79942 | 546 | |
72321415 MK |
547 | |
548 | #ifdef VERBOSE_DEBUG | |
b99692f4 | 549 | print_hex_dump_bytes("%s: ", __func__, DUMP_PREFIX_NONE, |
72321415 MK |
550 | pPeerHTCap, sizeof(struct ht_capab_ele)); |
551 | #endif | |
831cb9db LF |
552 | HTSetConnectBwMode(ieee, (enum ht_channel_width)(pPeerHTCap->ChlWidth), |
553 | (enum ht_extchnl_offset)(pPeerHTInfo->ExtChlOffset)); | |
554 | pHTInfo->bCurTxBW40MHz = ((pPeerHTInfo->RecommemdedTxWidth == 1) ? | |
555 | true : false); | |
94a79942 | 556 | |
831cb9db LF |
557 | pHTInfo->bCurShortGI20MHz = ((pHTInfo->bRegShortGI20MHz) ? |
558 | ((pPeerHTCap->ShortGI20Mhz == 1) ? | |
559 | true : false) : false); | |
560 | pHTInfo->bCurShortGI40MHz = ((pHTInfo->bRegShortGI40MHz) ? | |
561 | ((pPeerHTCap->ShortGI40Mhz == 1) ? | |
562 | true : false) : false); | |
94a79942 | 563 | |
831cb9db LF |
564 | pHTInfo->bCurSuppCCK = ((pHTInfo->bRegSuppCCK) ? |
565 | ((pPeerHTCap->DssCCk == 1) ? true : | |
566 | false) : false); | |
94a79942 LF |
567 | |
568 | ||
569 | pHTInfo->bCurrent_AMSDU_Support = pHTInfo->bAMSDU_Support; | |
570 | ||
831cb9db | 571 | nMaxAMSDUSize = (pPeerHTCap->MaxAMSDUSize == 0) ? 3839 : 7935; |
94a79942 | 572 | |
831cb9db | 573 | if (pHTInfo->nAMSDU_MaxSize > nMaxAMSDUSize) |
94a79942 LF |
574 | pHTInfo->nCurrent_AMSDU_MaxSize = nMaxAMSDUSize; |
575 | else | |
576 | pHTInfo->nCurrent_AMSDU_MaxSize = pHTInfo->nAMSDU_MaxSize; | |
577 | ||
578 | pHTInfo->bCurrentAMPDUEnable = pHTInfo->bAMPDUEnable; | |
579 | if (ieee->rtllib_ap_sec_type && | |
831cb9db LF |
580 | (ieee->rtllib_ap_sec_type(ieee)&(SEC_ALG_WEP|SEC_ALG_TKIP))) { |
581 | if ((pHTInfo->IOTPeer == HT_IOT_PEER_ATHEROS) || | |
582 | (pHTInfo->IOTPeer == HT_IOT_PEER_UNKNOWN)) | |
94a79942 LF |
583 | pHTInfo->bCurrentAMPDUEnable = false; |
584 | } | |
585 | ||
831cb9db | 586 | if (!pHTInfo->bRegRT2RTAggregation) { |
94a79942 | 587 | if (pHTInfo->AMPDU_Factor > pPeerHTCap->MaxRxAMPDUFactor) |
831cb9db LF |
588 | pHTInfo->CurrentAMPDUFactor = |
589 | pPeerHTCap->MaxRxAMPDUFactor; | |
94a79942 LF |
590 | else |
591 | pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor; | |
592 | ||
593 | } else { | |
831cb9db LF |
594 | if (ieee->current_network.bssht.bdRT2RTAggregation) { |
595 | if (ieee->pairwise_key_type != KEY_TYPE_NA) | |
596 | pHTInfo->CurrentAMPDUFactor = | |
597 | pPeerHTCap->MaxRxAMPDUFactor; | |
94a79942 LF |
598 | else |
599 | pHTInfo->CurrentAMPDUFactor = HT_AGG_SIZE_64K; | |
831cb9db | 600 | } else { |
94a79942 | 601 | if (pPeerHTCap->MaxRxAMPDUFactor < HT_AGG_SIZE_32K) |
831cb9db LF |
602 | pHTInfo->CurrentAMPDUFactor = |
603 | pPeerHTCap->MaxRxAMPDUFactor; | |
94a79942 LF |
604 | else |
605 | pHTInfo->CurrentAMPDUFactor = HT_AGG_SIZE_32K; | |
606 | } | |
607 | } | |
608 | if (pHTInfo->MPDU_Density > pPeerHTCap->MPDUDensity) | |
609 | pHTInfo->CurrentMPDUDensity = pHTInfo->MPDU_Density; | |
610 | else | |
611 | pHTInfo->CurrentMPDUDensity = pPeerHTCap->MPDUDensity; | |
831cb9db | 612 | if (pHTInfo->IOTAction & HT_IOT_ACT_TX_USE_AMSDU_8K) { |
94a79942 LF |
613 | pHTInfo->bCurrentAMPDUEnable = false; |
614 | pHTInfo->ForcedAMSDUMode = HT_AGG_FORCE_ENABLE; | |
615 | pHTInfo->ForcedAMSDUMaxSize = 7935; | |
616 | } | |
617 | pHTInfo->bCurRxReorderEnable = pHTInfo->bRegRxReorderEnable; | |
618 | ||
619 | if (pPeerHTCap->MCS[0] == 0) | |
620 | pPeerHTCap->MCS[0] = 0xff; | |
621 | ||
831cb9db | 622 | HTIOTActDetermineRaFunc(ieee, ((pPeerHTCap->MCS[1]) != 0)); |
94a79942 LF |
623 | |
624 | HTFilterMCSRate(ieee, pPeerHTCap->MCS, ieee->dot11HTOperationalRateSet); | |
625 | ||
626 | pHTInfo->PeerMimoPs = pPeerHTCap->MimoPwrSave; | |
627 | if (pHTInfo->PeerMimoPs == MIMO_PS_STATIC) | |
628 | pMcsFilter = MCS_FILTER_1SS; | |
629 | else | |
630 | pMcsFilter = MCS_FILTER_ALL; | |
831cb9db LF |
631 | ieee->HTHighestOperaRate = HTGetHighestMCSRate(ieee, |
632 | ieee->dot11HTOperationalRateSet, pMcsFilter); | |
94a79942 LF |
633 | ieee->HTCurrentOperaRate = ieee->HTHighestOperaRate; |
634 | ||
635 | pHTInfo->CurrentOpMode = pPeerHTInfo->OptMode; | |
94a79942 LF |
636 | } |
637 | ||
831cb9db | 638 | void HTInitializeHTInfo(struct rtllib_device *ieee) |
94a79942 | 639 | { |
7796d93e | 640 | struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; |
94a79942 | 641 | |
b94436b5 | 642 | netdev_vdbg(ieee->dev, "%s()\n", __func__); |
94a79942 LF |
643 | pHTInfo->bCurrentHTSupport = false; |
644 | ||
645 | pHTInfo->bCurBW40MHz = false; | |
646 | pHTInfo->bCurTxBW40MHz = false; | |
647 | ||
648 | pHTInfo->bCurShortGI20MHz = false; | |
649 | pHTInfo->bCurShortGI40MHz = false; | |
650 | pHTInfo->bForcedShortGI = false; | |
651 | ||
652 | pHTInfo->bCurSuppCCK = true; | |
653 | ||
654 | pHTInfo->bCurrent_AMSDU_Support = false; | |
655 | pHTInfo->nCurrent_AMSDU_MaxSize = pHTInfo->nAMSDU_MaxSize; | |
656 | pHTInfo->CurrentMPDUDensity = pHTInfo->MPDU_Density; | |
657 | pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor; | |
658 | ||
831cb9db LF |
659 | memset((void *)(&(pHTInfo->SelfHTCap)), 0, |
660 | sizeof(pHTInfo->SelfHTCap)); | |
661 | memset((void *)(&(pHTInfo->SelfHTInfo)), 0, | |
662 | sizeof(pHTInfo->SelfHTInfo)); | |
663 | memset((void *)(&(pHTInfo->PeerHTCapBuf)), 0, | |
664 | sizeof(pHTInfo->PeerHTCapBuf)); | |
665 | memset((void *)(&(pHTInfo->PeerHTInfoBuf)), 0, | |
666 | sizeof(pHTInfo->PeerHTInfoBuf)); | |
94a79942 LF |
667 | |
668 | pHTInfo->bSwBwInProgress = false; | |
94a79942 LF |
669 | |
670 | pHTInfo->ePeerHTSpecVer = HT_SPEC_VER_IEEE; | |
671 | ||
672 | pHTInfo->bCurrentRT2RTAggregation = false; | |
673 | pHTInfo->bCurrentRT2RTLongSlotTime = false; | |
bb9a7b3f | 674 | pHTInfo->RT2RT_HT_Mode = (enum rt_ht_capability)0; |
94a79942 LF |
675 | |
676 | pHTInfo->IOTPeer = 0; | |
677 | pHTInfo->IOTAction = 0; | |
678 | pHTInfo->IOTRaFunc = 0; | |
679 | ||
680 | { | |
831cb9db | 681 | u8 *RegHTSuppRateSets = &(ieee->RegHTSuppRateSet[0]); |
3a6b70c3 | 682 | |
94a79942 LF |
683 | RegHTSuppRateSets[0] = 0xFF; |
684 | RegHTSuppRateSets[1] = 0xFF; | |
685 | RegHTSuppRateSets[4] = 0x01; | |
686 | } | |
687 | } | |
831cb9db | 688 | |
a15e76ad | 689 | void HTInitializeBssDesc(struct bss_ht *pBssHT) |
94a79942 LF |
690 | { |
691 | ||
b3b55bd7 | 692 | pBssHT->bd_support_ht = false; |
94a79942 LF |
693 | memset(pBssHT->bdHTCapBuf, 0, sizeof(pBssHT->bdHTCapBuf)); |
694 | pBssHT->bdHTCapLen = 0; | |
695 | memset(pBssHT->bdHTInfoBuf, 0, sizeof(pBssHT->bdHTInfoBuf)); | |
696 | pBssHT->bdHTInfoLen = 0; | |
697 | ||
831cb9db | 698 | pBssHT->bdHTSpecVer = HT_SPEC_VER_IEEE; |
94a79942 LF |
699 | |
700 | pBssHT->bdRT2RTAggregation = false; | |
701 | pBssHT->bdRT2RTLongSlotTime = false; | |
bb9a7b3f | 702 | pBssHT->RT2RT_HT_Mode = (enum rt_ht_capability)0; |
94a79942 LF |
703 | } |
704 | ||
831cb9db LF |
705 | void HTResetSelfAndSavePeerSetting(struct rtllib_device *ieee, |
706 | struct rtllib_network *pNetwork) | |
94a79942 | 707 | { |
7796d93e | 708 | struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; |
94a79942 LF |
709 | u8 bIOTAction = 0; |
710 | ||
b94436b5 | 711 | netdev_vdbg(ieee->dev, "%s()\n", __func__); |
831cb9db | 712 | /* unmark bEnableHT flag here is the same reason why unmarked in |
14b40d92 MK |
713 | * function rtllib_softmac_new_net. WB 2008.09.10 |
714 | */ | |
b3b55bd7 | 715 | if (pNetwork->bssht.bd_support_ht) { |
94a79942 LF |
716 | pHTInfo->bCurrentHTSupport = true; |
717 | pHTInfo->ePeerHTSpecVer = pNetwork->bssht.bdHTSpecVer; | |
718 | ||
831cb9db LF |
719 | if (pNetwork->bssht.bdHTCapLen > 0 && |
720 | pNetwork->bssht.bdHTCapLen <= sizeof(pHTInfo->PeerHTCapBuf)) | |
721 | memcpy(pHTInfo->PeerHTCapBuf, | |
722 | pNetwork->bssht.bdHTCapBuf, | |
723 | pNetwork->bssht.bdHTCapLen); | |
724 | ||
725 | if (pNetwork->bssht.bdHTInfoLen > 0 && | |
726 | pNetwork->bssht.bdHTInfoLen <= | |
727 | sizeof(pHTInfo->PeerHTInfoBuf)) | |
728 | memcpy(pHTInfo->PeerHTInfoBuf, | |
729 | pNetwork->bssht.bdHTInfoBuf, | |
730 | pNetwork->bssht.bdHTInfoLen); | |
731 | ||
732 | if (pHTInfo->bRegRT2RTAggregation) { | |
733 | pHTInfo->bCurrentRT2RTAggregation = | |
734 | pNetwork->bssht.bdRT2RTAggregation; | |
735 | pHTInfo->bCurrentRT2RTLongSlotTime = | |
736 | pNetwork->bssht.bdRT2RTLongSlotTime; | |
94a79942 | 737 | pHTInfo->RT2RT_HT_Mode = pNetwork->bssht.RT2RT_HT_Mode; |
831cb9db | 738 | } else { |
94a79942 LF |
739 | pHTInfo->bCurrentRT2RTAggregation = false; |
740 | pHTInfo->bCurrentRT2RTLongSlotTime = false; | |
bb9a7b3f | 741 | pHTInfo->RT2RT_HT_Mode = (enum rt_ht_capability)0; |
94a79942 LF |
742 | } |
743 | ||
744 | HTIOTPeerDetermine(ieee); | |
745 | ||
746 | pHTInfo->IOTAction = 0; | |
747 | bIOTAction = HTIOTActIsDisableMCS14(ieee, pNetwork->bssid); | |
748 | if (bIOTAction) | |
749 | pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_MCS14; | |
750 | ||
751 | bIOTAction = HTIOTActIsDisableMCS15(ieee); | |
752 | if (bIOTAction) | |
753 | pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_MCS15; | |
754 | ||
755 | bIOTAction = HTIOTActIsDisableMCSTwoSpatialStream(ieee); | |
756 | if (bIOTAction) | |
757 | pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_ALL_2SS; | |
758 | ||
759 | ||
760 | bIOTAction = HTIOTActIsDisableEDCATurbo(ieee, pNetwork->bssid); | |
761 | if (bIOTAction) | |
762 | pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_EDCA_TURBO; | |
763 | ||
831cb9db | 764 | bIOTAction = HTIOTActIsMgntUseCCK6M(ieee, pNetwork); |
94a79942 LF |
765 | if (bIOTAction) |
766 | pHTInfo->IOTAction |= HT_IOT_ACT_MGNT_USE_CCK_6M; | |
94a79942 LF |
767 | bIOTAction = HTIOTActIsCCDFsync(ieee); |
768 | if (bIOTAction) | |
769 | pHTInfo->IOTAction |= HT_IOT_ACT_CDD_FSYNC; | |
94a79942 LF |
770 | } else { |
771 | pHTInfo->bCurrentHTSupport = false; | |
772 | pHTInfo->bCurrentRT2RTAggregation = false; | |
773 | pHTInfo->bCurrentRT2RTLongSlotTime = false; | |
bb9a7b3f | 774 | pHTInfo->RT2RT_HT_Mode = (enum rt_ht_capability)0; |
94a79942 LF |
775 | |
776 | pHTInfo->IOTAction = 0; | |
777 | pHTInfo->IOTRaFunc = 0; | |
778 | } | |
94a79942 LF |
779 | } |
780 | ||
976d5341 SM |
781 | void HT_update_self_and_peer_setting(struct rtllib_device *ieee, |
782 | struct rtllib_network *pNetwork) | |
94a79942 | 783 | { |
7796d93e | 784 | struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; |
831cb9db LF |
785 | struct ht_info_ele *pPeerHTInfo = |
786 | (struct ht_info_ele *)pNetwork->bssht.bdHTInfoBuf; | |
94a79942 | 787 | |
831cb9db | 788 | if (pHTInfo->bCurrentHTSupport) { |
94a79942 LF |
789 | if (pNetwork->bssht.bdHTInfoLen != 0) |
790 | pHTInfo->CurrentOpMode = pPeerHTInfo->OptMode; | |
94a79942 LF |
791 | } |
792 | } | |
976d5341 | 793 | EXPORT_SYMBOL(HT_update_self_and_peer_setting); |
94a79942 | 794 | |
831cb9db | 795 | void HTUseDefaultSetting(struct rtllib_device *ieee) |
94a79942 | 796 | { |
7796d93e | 797 | struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; |
94a79942 | 798 | |
cb762154 | 799 | if (pHTInfo->bEnableHT) { |
94a79942 LF |
800 | pHTInfo->bCurrentHTSupport = true; |
801 | pHTInfo->bCurSuppCCK = pHTInfo->bRegSuppCCK; | |
802 | ||
803 | pHTInfo->bCurBW40MHz = pHTInfo->bRegBW40MHz; | |
831cb9db | 804 | pHTInfo->bCurShortGI20MHz = pHTInfo->bRegShortGI20MHz; |
94a79942 | 805 | |
831cb9db | 806 | pHTInfo->bCurShortGI40MHz = pHTInfo->bRegShortGI40MHz; |
94a79942 LF |
807 | |
808 | if (ieee->iw_mode == IW_MODE_ADHOC) | |
831cb9db LF |
809 | ieee->current_network.qos_data.active = |
810 | ieee->current_network.qos_data.supported; | |
94a79942 LF |
811 | pHTInfo->bCurrent_AMSDU_Support = pHTInfo->bAMSDU_Support; |
812 | pHTInfo->nCurrent_AMSDU_MaxSize = pHTInfo->nAMSDU_MaxSize; | |
813 | ||
814 | pHTInfo->bCurrentAMPDUEnable = pHTInfo->bAMPDUEnable; | |
815 | pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor; | |
816 | ||
817 | pHTInfo->CurrentMPDUDensity = pHTInfo->CurrentMPDUDensity; | |
818 | ||
831cb9db LF |
819 | HTFilterMCSRate(ieee, ieee->Regdot11TxHTOperationalRateSet, |
820 | ieee->dot11HTOperationalRateSet); | |
821 | ieee->HTHighestOperaRate = HTGetHighestMCSRate(ieee, | |
822 | ieee->dot11HTOperationalRateSet, | |
823 | MCS_FILTER_ALL); | |
94a79942 LF |
824 | ieee->HTCurrentOperaRate = ieee->HTHighestOperaRate; |
825 | ||
cb762154 | 826 | } else { |
94a79942 LF |
827 | pHTInfo->bCurrentHTSupport = false; |
828 | } | |
94a79942 | 829 | } |
cb762154 | 830 | |
831cb9db | 831 | u8 HTCCheck(struct rtllib_device *ieee, u8 *pFrame) |
94a79942 | 832 | { |
831cb9db LF |
833 | if (ieee->pHTInfo->bCurrentHTSupport) { |
834 | if ((IsQoSDataFrame(pFrame) && Frame_Order(pFrame)) == 1) { | |
b94436b5 | 835 | netdev_dbg(ieee->dev, "HT CONTROL FILED EXIST!!\n"); |
94a79942 LF |
836 | return true; |
837 | } | |
838 | } | |
839 | return false; | |
840 | } | |
841 | ||
ec0dc6be | 842 | static void HTSetConnectBwModeCallback(struct rtllib_device *ieee) |
831cb9db LF |
843 | { |
844 | struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; | |
845 | ||
b94436b5 MK |
846 | netdev_vdbg(ieee->dev, "%s()\n", __func__); |
847 | ||
831cb9db LF |
848 | if (pHTInfo->bCurBW40MHz) { |
849 | if (pHTInfo->CurSTAExtChnlOffset == HT_EXTCHNL_OFFSET_UPPER) | |
850 | ieee->set_chan(ieee->dev, | |
851 | ieee->current_network.channel + 2); | |
852 | else if (pHTInfo->CurSTAExtChnlOffset == | |
853 | HT_EXTCHNL_OFFSET_LOWER) | |
854 | ieee->set_chan(ieee->dev, | |
855 | ieee->current_network.channel - 2); | |
856 | else | |
857 | ieee->set_chan(ieee->dev, | |
858 | ieee->current_network.channel); | |
859 | ||
860 | ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20_40, | |
861 | pHTInfo->CurSTAExtChnlOffset); | |
862 | } else { | |
863 | ieee->set_chan(ieee->dev, ieee->current_network.channel); | |
864 | ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20, | |
865 | HT_EXTCHNL_OFFSET_NO_EXT); | |
866 | } | |
867 | ||
868 | pHTInfo->bSwBwInProgress = false; | |
869 | } | |
870 | ||
871 | void HTSetConnectBwMode(struct rtllib_device *ieee, | |
872 | enum ht_channel_width Bandwidth, | |
873 | enum ht_extchnl_offset Offset) | |
94a79942 | 874 | { |
7796d93e | 875 | struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; |
94a79942 | 876 | |
e785e87b | 877 | if (!pHTInfo->bRegBW40MHz) |
94a79942 LF |
878 | return; |
879 | ||
880 | if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) | |
831cb9db | 881 | Bandwidth = HT_CHANNEL_WIDTH_20; |
94a79942 LF |
882 | |
883 | if (pHTInfo->bSwBwInProgress) { | |
43446728 | 884 | pr_info("%s: bSwBwInProgress!!\n", __func__); |
94a79942 LF |
885 | return; |
886 | } | |
831cb9db LF |
887 | if (Bandwidth == HT_CHANNEL_WIDTH_20_40) { |
888 | if (ieee->current_network.channel < 2 && | |
889 | Offset == HT_EXTCHNL_OFFSET_LOWER) | |
94a79942 | 890 | Offset = HT_EXTCHNL_OFFSET_NO_EXT; |
831cb9db LF |
891 | if (Offset == HT_EXTCHNL_OFFSET_UPPER || |
892 | Offset == HT_EXTCHNL_OFFSET_LOWER) { | |
94a79942 LF |
893 | pHTInfo->bCurBW40MHz = true; |
894 | pHTInfo->CurSTAExtChnlOffset = Offset; | |
895 | } else { | |
896 | pHTInfo->bCurBW40MHz = false; | |
897 | pHTInfo->CurSTAExtChnlOffset = HT_EXTCHNL_OFFSET_NO_EXT; | |
898 | } | |
899 | } else { | |
900 | pHTInfo->bCurBW40MHz = false; | |
901 | pHTInfo->CurSTAExtChnlOffset = HT_EXTCHNL_OFFSET_NO_EXT; | |
902 | } | |
903 | ||
ad3cafd7 MP |
904 | netdev_dbg(ieee->dev, "%s():pHTInfo->bCurBW40MHz:%x\n", __func__, |
905 | pHTInfo->bCurBW40MHz); | |
94a79942 LF |
906 | |
907 | pHTInfo->bSwBwInProgress = true; | |
908 | ||
909 | HTSetConnectBwModeCallback(ieee); | |
94a79942 | 910 | } |