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 | } |
3cc112a0 | 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; |
3f1f39fb | 161 | else if (net->bssht.bd_rt2rt_aggregation) |
94a79942 LF |
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 | |
3f1f39fb | 174 | if (net->bssht.bd_rt2rt_aggregation) { |
94a79942 | 175 | pHTInfo->IOTPeer = HT_IOT_PEER_REALTEK; |
6628c674 | 176 | if (net->bssht.rt2rt_ht_mode & RT_HT_CAP_USE_92SE) |
94a79942 | 177 | pHTInfo->IOTPeer = HT_IOT_PEER_REALTEK_92SE; |
6628c674 | 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 | 216 | |
ec0dc6be | 217 | static bool HTIOTActIsDisableMCS15(struct rtllib_device *ieee) |
94a79942 | 218 | { |
e623d0f3 | 219 | return false; |
94a79942 LF |
220 | } |
221 | ||
ec0dc6be | 222 | static bool HTIOTActIsDisableMCSTwoSpatialStream(struct rtllib_device *ieee) |
94a79942 | 223 | { |
831cb9db | 224 | return false; |
94a79942 LF |
225 | } |
226 | ||
35e33b04 MK |
227 | static u8 HTIOTActIsDisableEDCATurbo(struct rtllib_device *ieee, |
228 | u8 *PeerMacAddr) | |
94a79942 LF |
229 | { |
230 | return false; | |
231 | } | |
232 | ||
ec0dc6be LF |
233 | static u8 HTIOTActIsMgntUseCCK6M(struct rtllib_device *ieee, |
234 | struct rtllib_network *network) | |
94a79942 LF |
235 | { |
236 | u8 retValue = 0; | |
237 | ||
94a79942 | 238 | if (ieee->pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM) |
94a79942 | 239 | retValue = 1; |
94a79942 LF |
240 | |
241 | return retValue; | |
242 | } | |
243 | ||
ec0dc6be | 244 | static u8 HTIOTActIsCCDFsync(struct rtllib_device *ieee) |
94a79942 LF |
245 | { |
246 | u8 retValue = 0; | |
831cb9db | 247 | |
94a79942 | 248 | if (ieee->pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM) |
94a79942 | 249 | retValue = 1; |
94a79942 LF |
250 | return retValue; |
251 | } | |
252 | ||
ec0dc6be | 253 | static void HTIOTActDetermineRaFunc(struct rtllib_device *ieee, bool bPeerRx2ss) |
94a79942 | 254 | { |
7796d93e | 255 | struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; |
3a6b70c3 | 256 | |
94a79942 LF |
257 | pHTInfo->IOTRaFunc &= HT_IOT_RAFUNC_DISABLE_ALL; |
258 | ||
259 | if (pHTInfo->IOTPeer == HT_IOT_PEER_RALINK && !bPeerRx2ss) | |
260 | pHTInfo->IOTRaFunc |= HT_IOT_RAFUNC_PEER_1R; | |
261 | ||
262 | if (pHTInfo->IOTAction & HT_IOT_ACT_AMSDU_ENABLE) | |
263 | pHTInfo->IOTRaFunc |= HT_IOT_RAFUNC_TX_AMSDU; | |
94a79942 LF |
264 | } |
265 | ||
831cb9db | 266 | void HTResetIOTSetting(struct rt_hi_throughput *pHTInfo) |
94a79942 LF |
267 | { |
268 | pHTInfo->IOTAction = 0; | |
269 | pHTInfo->IOTPeer = HT_IOT_PEER_UNKNOWN; | |
270 | pHTInfo->IOTRaFunc = 0; | |
271 | } | |
272 | ||
831cb9db LF |
273 | void HTConstructCapabilityElement(struct rtllib_device *ieee, u8 *posHTCap, |
274 | u8 *len, u8 IsEncrypt, bool bAssoc) | |
94a79942 | 275 | { |
7796d93e | 276 | struct rt_hi_throughput *pHT = ieee->pHTInfo; |
e92b71d5 | 277 | struct ht_capab_ele *pCapELE = NULL; |
94a79942 | 278 | |
831cb9db | 279 | if ((posHTCap == NULL) || (pHT == NULL)) { |
11e672c3 MK |
280 | netdev_warn(ieee->dev, |
281 | "%s(): posHTCap and pHTInfo are null\n", __func__); | |
94a79942 LF |
282 | return; |
283 | } | |
284 | memset(posHTCap, 0, *len); | |
285 | ||
831cb9db | 286 | if ((bAssoc) && (pHT->ePeerHTSpecVer == HT_SPEC_VER_EWC)) { |
94a79942 | 287 | u8 EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33}; |
3a6b70c3 | 288 | |
94a79942 | 289 | memcpy(posHTCap, EWC11NHTCap, sizeof(EWC11NHTCap)); |
e92b71d5 | 290 | pCapELE = (struct ht_capab_ele *)&(posHTCap[4]); |
94a79942 | 291 | *len = 30 + 2; |
831cb9db | 292 | } else { |
e92b71d5 | 293 | pCapELE = (struct ht_capab_ele *)posHTCap; |
94a79942 LF |
294 | *len = 26 + 2; |
295 | } | |
296 | ||
297 | pCapELE->AdvCoding = 0; | |
298 | if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) | |
299 | pCapELE->ChlWidth = 0; | |
300 | else | |
831cb9db | 301 | pCapELE->ChlWidth = (pHT->bRegBW40MHz ? 1 : 0); |
94a79942 LF |
302 | |
303 | pCapELE->MimoPwrSave = pHT->SelfMimoPs; | |
304 | pCapELE->GreenField = 0; | |
305 | pCapELE->ShortGI20Mhz = 1; | |
306 | pCapELE->ShortGI40Mhz = 1; | |
307 | ||
308 | pCapELE->TxSTBC = 1; | |
94a79942 LF |
309 | pCapELE->RxSTBC = 0; |
310 | pCapELE->DelayBA = 0; | |
831cb9db LF |
311 | pCapELE->MaxAMSDUSize = (MAX_RECEIVE_BUFFER_SIZE >= 7935) ? 1 : 0; |
312 | pCapELE->DssCCk = ((pHT->bRegBW40MHz) ? (pHT->bRegSuppCCK ? 1 : 0) : 0); | |
313 | pCapELE->PSMP = 0; | |
314 | pCapELE->LSigTxopProtect = 0; | |
94a79942 | 315 | |
b94436b5 MK |
316 | netdev_dbg(ieee->dev, |
317 | "TX HT cap/info ele BW=%d MaxAMSDUSize:%d DssCCk:%d\n", | |
318 | pCapELE->ChlWidth, pCapELE->MaxAMSDUSize, pCapELE->DssCCk); | |
94a79942 | 319 | |
831cb9db | 320 | if (IsEncrypt) { |
94a79942 LF |
321 | pCapELE->MPDUDensity = 7; |
322 | pCapELE->MaxRxAMPDUFactor = 2; | |
831cb9db | 323 | } else { |
94a79942 LF |
324 | pCapELE->MaxRxAMPDUFactor = 3; |
325 | pCapELE->MPDUDensity = 0; | |
326 | } | |
327 | ||
328 | memcpy(pCapELE->MCS, ieee->Regdot11HTOperationalRateSet, 16); | |
329 | memset(&pCapELE->ExtHTCapInfo, 0, 2); | |
330 | memset(pCapELE->TxBFCap, 0, 4); | |
331 | ||
332 | pCapELE->ASCap = 0; | |
333 | ||
334 | if (bAssoc) { | |
335 | if (pHT->IOTAction & HT_IOT_ACT_DISABLE_MCS15) | |
336 | pCapELE->MCS[1] &= 0x7f; | |
337 | ||
338 | if (pHT->IOTAction & HT_IOT_ACT_DISABLE_MCS14) | |
339 | pCapELE->MCS[1] &= 0xbf; | |
340 | ||
341 | if (pHT->IOTAction & HT_IOT_ACT_DISABLE_ALL_2SS) | |
342 | pCapELE->MCS[1] &= 0x00; | |
343 | ||
344 | if (pHT->IOTAction & HT_IOT_ACT_DISABLE_RX_40MHZ_SHORT_GI) | |
345 | pCapELE->ShortGI40Mhz = 0; | |
346 | ||
831cb9db | 347 | if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) { |
94a79942 | 348 | pCapELE->ChlWidth = 0; |
94a79942 LF |
349 | pCapELE->MCS[1] = 0; |
350 | } | |
351 | } | |
94a79942 | 352 | } |
831cb9db LF |
353 | |
354 | void HTConstructInfoElement(struct rtllib_device *ieee, u8 *posHTInfo, | |
355 | u8 *len, u8 IsEncrypt) | |
94a79942 | 356 | { |
7796d93e | 357 | struct rt_hi_throughput *pHT = ieee->pHTInfo; |
407e998e | 358 | struct ht_info_ele *pHTInfoEle = (struct ht_info_ele *)posHTInfo; |
3a6b70c3 | 359 | |
831cb9db | 360 | if ((posHTInfo == NULL) || (pHTInfoEle == NULL)) { |
11e672c3 MK |
361 | netdev_warn(ieee->dev, |
362 | "%s(): posHTInfo and pHTInfoEle are null\n", | |
363 | __func__); | |
94a79942 LF |
364 | return; |
365 | } | |
366 | ||
367 | memset(posHTInfo, 0, *len); | |
831cb9db LF |
368 | if ((ieee->iw_mode == IW_MODE_ADHOC) || |
369 | (ieee->iw_mode == IW_MODE_MASTER)) { | |
94a79942 | 370 | pHTInfoEle->ControlChl = ieee->current_network.channel; |
e785e87b | 371 | pHTInfoEle->ExtChlOffset = ((!pHT->bRegBW40MHz) ? |
831cb9db LF |
372 | HT_EXTCHNL_OFFSET_NO_EXT : |
373 | (ieee->current_network.channel <= 6) | |
374 | ? HT_EXTCHNL_OFFSET_UPPER : | |
375 | HT_EXTCHNL_OFFSET_LOWER); | |
94a79942 | 376 | pHTInfoEle->RecommemdedTxWidth = pHT->bRegBW40MHz; |
831cb9db | 377 | pHTInfoEle->RIFS = 0; |
94a79942 LF |
378 | pHTInfoEle->PSMPAccessOnly = 0; |
379 | pHTInfoEle->SrvIntGranularity = 0; | |
831cb9db | 380 | pHTInfoEle->OptMode = pHT->CurrentOpMode; |
94a79942 LF |
381 | pHTInfoEle->NonGFDevPresent = 0; |
382 | pHTInfoEle->DualBeacon = 0; | |
383 | pHTInfoEle->SecondaryBeacon = 0; | |
384 | pHTInfoEle->LSigTxopProtectFull = 0; | |
831cb9db LF |
385 | pHTInfoEle->PcoActive = 0; |
386 | pHTInfoEle->PcoPhase = 0; | |
94a79942 LF |
387 | |
388 | memset(pHTInfoEle->BasicMSC, 0, 16); | |
389 | ||
94a79942 LF |
390 | *len = 22 + 2; |
391 | ||
831cb9db | 392 | } else { |
94a79942 LF |
393 | *len = 0; |
394 | } | |
94a79942 LF |
395 | } |
396 | ||
831cb9db LF |
397 | void HTConstructRT2RTAggElement(struct rtllib_device *ieee, u8 *posRT2RTAgg, |
398 | u8 *len) | |
94a79942 LF |
399 | { |
400 | if (posRT2RTAgg == NULL) { | |
11e672c3 | 401 | netdev_warn(ieee->dev, "%s(): posRT2RTAgg is null\n", __func__); |
94a79942 LF |
402 | return; |
403 | } | |
404 | memset(posRT2RTAgg, 0, *len); | |
405 | *posRT2RTAgg++ = 0x00; | |
406 | *posRT2RTAgg++ = 0xe0; | |
407 | *posRT2RTAgg++ = 0x4c; | |
408 | *posRT2RTAgg++ = 0x02; | |
409 | *posRT2RTAgg++ = 0x01; | |
410 | ||
94a79942 | 411 | *posRT2RTAgg = 0x30; |
94a79942 | 412 | |
831cb9db | 413 | if (ieee->bSupportRemoteWakeUp) |
94a79942 | 414 | *posRT2RTAgg |= RT_HT_CAP_USE_WOW; |
94a79942 LF |
415 | |
416 | *len = 6 + 2; | |
94a79942 LF |
417 | } |
418 | ||
ec0dc6be | 419 | static u8 HT_PickMCSRate(struct rtllib_device *ieee, u8 *pOperateMCS) |
94a79942 | 420 | { |
831cb9db | 421 | u8 i; |
3a6b70c3 | 422 | |
831cb9db | 423 | if (pOperateMCS == NULL) { |
11e672c3 | 424 | netdev_warn(ieee->dev, "%s(): pOperateMCS is null\n", __func__); |
94a79942 LF |
425 | return false; |
426 | } | |
427 | ||
428 | switch (ieee->mode) { | |
429 | case IEEE_A: | |
430 | case IEEE_B: | |
431 | case IEEE_G: | |
831cb9db LF |
432 | for (i = 0; i <= 15; i++) |
433 | pOperateMCS[i] = 0; | |
94a79942 LF |
434 | break; |
435 | case IEEE_N_24G: | |
436 | case IEEE_N_5G: | |
831cb9db LF |
437 | pOperateMCS[0] &= RATE_ADPT_1SS_MASK; |
438 | pOperateMCS[1] &= RATE_ADPT_2SS_MASK; | |
439 | pOperateMCS[3] &= RATE_ADPT_MCS32_MASK; | |
94a79942 LF |
440 | break; |
441 | default: | |
442 | break; | |
94a79942 LF |
443 | } |
444 | ||
445 | return true; | |
446 | } | |
447 | ||
831cb9db LF |
448 | u8 HTGetHighestMCSRate(struct rtllib_device *ieee, u8 *pMCSRateSet, |
449 | u8 *pMCSFilter) | |
94a79942 LF |
450 | { |
451 | u8 i, j; | |
452 | u8 bitMap; | |
453 | u8 mcsRate = 0; | |
454 | u8 availableMcsRate[16]; | |
3a6b70c3 | 455 | |
831cb9db | 456 | if (pMCSRateSet == NULL || pMCSFilter == NULL) { |
11e672c3 MK |
457 | netdev_warn(ieee->dev, |
458 | "%s(): pMCSRateSet and pMCSFilter are null\n", | |
459 | __func__); | |
94a79942 LF |
460 | return false; |
461 | } | |
831cb9db | 462 | for (i = 0; i < 16; i++) |
94a79942 LF |
463 | availableMcsRate[i] = pMCSRateSet[i] & pMCSFilter[i]; |
464 | ||
831cb9db | 465 | for (i = 0; i < 16; i++) { |
94a79942 LF |
466 | if (availableMcsRate[i] != 0) |
467 | break; | |
468 | } | |
469 | if (i == 16) | |
470 | return false; | |
471 | ||
831cb9db LF |
472 | for (i = 0; i < 16; i++) { |
473 | if (availableMcsRate[i] != 0) { | |
94a79942 | 474 | bitMap = availableMcsRate[i]; |
831cb9db | 475 | for (j = 0; j < 8; j++) { |
3cc112a0 MB |
476 | if ((bitMap % 2) != 0) { |
477 | if (HTMcsToDataRate(ieee, (8 * i + j)) > | |
831cb9db | 478 | HTMcsToDataRate(ieee, mcsRate)) |
24542a00 | 479 | mcsRate = 8 * i + j; |
94a79942 | 480 | } |
be31fed4 | 481 | bitMap >>= 1; |
94a79942 LF |
482 | } |
483 | } | |
484 | } | |
831cb9db | 485 | return mcsRate | 0x80; |
94a79942 LF |
486 | } |
487 | ||
e0c84c1c MK |
488 | static u8 HTFilterMCSRate(struct rtllib_device *ieee, u8 *pSupportMCS, |
489 | u8 *pOperateMCS) | |
94a79942 | 490 | { |
831cb9db | 491 | u8 i; |
94a79942 | 492 | |
831cb9db LF |
493 | for (i = 0; i <= 15; i++) |
494 | pOperateMCS[i] = ieee->Regdot11TxHTOperationalRateSet[i] & | |
495 | pSupportMCS[i]; | |
94a79942 LF |
496 | |
497 | HT_PickMCSRate(ieee, pOperateMCS); | |
498 | ||
499 | if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) | |
500 | pOperateMCS[1] = 0; | |
501 | ||
831cb9db | 502 | for (i = 2; i <= 15; i++) |
94a79942 LF |
503 | pOperateMCS[i] = 0; |
504 | ||
505 | return true; | |
506 | } | |
831cb9db LF |
507 | |
508 | void HTSetConnectBwMode(struct rtllib_device *ieee, | |
509 | enum ht_channel_width Bandwidth, | |
510 | enum ht_extchnl_offset Offset); | |
511 | ||
94a79942 LF |
512 | void HTOnAssocRsp(struct rtllib_device *ieee) |
513 | { | |
7796d93e | 514 | struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; |
e92b71d5 | 515 | struct ht_capab_ele *pPeerHTCap = NULL; |
407e998e | 516 | struct ht_info_ele *pPeerHTInfo = NULL; |
831cb9db LF |
517 | u16 nMaxAMSDUSize = 0; |
518 | u8 *pMcsFilter = NULL; | |
94a79942 | 519 | |
831cb9db LF |
520 | static u8 EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33}; |
521 | static u8 EWC11NHTInfo[] = {0x00, 0x90, 0x4c, 0x34}; | |
94a79942 | 522 | |
e785e87b | 523 | if (!pHTInfo->bCurrentHTSupport) { |
11e672c3 | 524 | netdev_warn(ieee->dev, "%s(): HT_DISABLE\n", __func__); |
94a79942 LF |
525 | return; |
526 | } | |
b94436b5 | 527 | netdev_dbg(ieee->dev, "%s(): HT_ENABLE\n", __func__); |
94a79942 | 528 | |
831cb9db | 529 | if (!memcmp(pHTInfo->PeerHTCapBuf, EWC11NHTCap, sizeof(EWC11NHTCap))) |
e92b71d5 | 530 | pPeerHTCap = (struct ht_capab_ele *)(&pHTInfo->PeerHTCapBuf[4]); |
94a79942 | 531 | else |
e92b71d5 | 532 | pPeerHTCap = (struct ht_capab_ele *)(pHTInfo->PeerHTCapBuf); |
94a79942 LF |
533 | |
534 | if (!memcmp(pHTInfo->PeerHTInfoBuf, EWC11NHTInfo, sizeof(EWC11NHTInfo))) | |
831cb9db LF |
535 | pPeerHTInfo = (struct ht_info_ele *) |
536 | (&pHTInfo->PeerHTInfoBuf[4]); | |
94a79942 | 537 | else |
407e998e | 538 | pPeerHTInfo = (struct ht_info_ele *)(pHTInfo->PeerHTInfoBuf); |
94a79942 | 539 | |
72321415 | 540 | #ifdef VERBOSE_DEBUG |
b99692f4 | 541 | print_hex_dump_bytes("%s: ", __func__, DUMP_PREFIX_NONE, |
72321415 MK |
542 | pPeerHTCap, sizeof(struct ht_capab_ele)); |
543 | #endif | |
831cb9db LF |
544 | HTSetConnectBwMode(ieee, (enum ht_channel_width)(pPeerHTCap->ChlWidth), |
545 | (enum ht_extchnl_offset)(pPeerHTInfo->ExtChlOffset)); | |
546 | pHTInfo->bCurTxBW40MHz = ((pPeerHTInfo->RecommemdedTxWidth == 1) ? | |
547 | true : false); | |
94a79942 | 548 | |
831cb9db LF |
549 | pHTInfo->bCurShortGI20MHz = ((pHTInfo->bRegShortGI20MHz) ? |
550 | ((pPeerHTCap->ShortGI20Mhz == 1) ? | |
551 | true : false) : false); | |
552 | pHTInfo->bCurShortGI40MHz = ((pHTInfo->bRegShortGI40MHz) ? | |
553 | ((pPeerHTCap->ShortGI40Mhz == 1) ? | |
554 | true : false) : false); | |
94a79942 | 555 | |
831cb9db LF |
556 | pHTInfo->bCurSuppCCK = ((pHTInfo->bRegSuppCCK) ? |
557 | ((pPeerHTCap->DssCCk == 1) ? true : | |
558 | false) : false); | |
94a79942 | 559 | |
94a79942 LF |
560 | pHTInfo->bCurrent_AMSDU_Support = pHTInfo->bAMSDU_Support; |
561 | ||
831cb9db | 562 | nMaxAMSDUSize = (pPeerHTCap->MaxAMSDUSize == 0) ? 3839 : 7935; |
94a79942 | 563 | |
831cb9db | 564 | if (pHTInfo->nAMSDU_MaxSize > nMaxAMSDUSize) |
94a79942 LF |
565 | pHTInfo->nCurrent_AMSDU_MaxSize = nMaxAMSDUSize; |
566 | else | |
567 | pHTInfo->nCurrent_AMSDU_MaxSize = pHTInfo->nAMSDU_MaxSize; | |
568 | ||
569 | pHTInfo->bCurrentAMPDUEnable = pHTInfo->bAMPDUEnable; | |
570 | if (ieee->rtllib_ap_sec_type && | |
3cc112a0 | 571 | (ieee->rtllib_ap_sec_type(ieee) & (SEC_ALG_WEP | SEC_ALG_TKIP))) { |
831cb9db LF |
572 | if ((pHTInfo->IOTPeer == HT_IOT_PEER_ATHEROS) || |
573 | (pHTInfo->IOTPeer == HT_IOT_PEER_UNKNOWN)) | |
94a79942 LF |
574 | pHTInfo->bCurrentAMPDUEnable = false; |
575 | } | |
576 | ||
831cb9db | 577 | if (!pHTInfo->bRegRT2RTAggregation) { |
94a79942 | 578 | if (pHTInfo->AMPDU_Factor > pPeerHTCap->MaxRxAMPDUFactor) |
831cb9db LF |
579 | pHTInfo->CurrentAMPDUFactor = |
580 | pPeerHTCap->MaxRxAMPDUFactor; | |
94a79942 LF |
581 | else |
582 | pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor; | |
583 | ||
584 | } else { | |
3f1f39fb | 585 | if (ieee->current_network.bssht.bd_rt2rt_aggregation) { |
831cb9db LF |
586 | if (ieee->pairwise_key_type != KEY_TYPE_NA) |
587 | pHTInfo->CurrentAMPDUFactor = | |
588 | pPeerHTCap->MaxRxAMPDUFactor; | |
94a79942 LF |
589 | else |
590 | pHTInfo->CurrentAMPDUFactor = HT_AGG_SIZE_64K; | |
831cb9db | 591 | } else { |
94a79942 | 592 | if (pPeerHTCap->MaxRxAMPDUFactor < HT_AGG_SIZE_32K) |
831cb9db LF |
593 | pHTInfo->CurrentAMPDUFactor = |
594 | pPeerHTCap->MaxRxAMPDUFactor; | |
94a79942 LF |
595 | else |
596 | pHTInfo->CurrentAMPDUFactor = HT_AGG_SIZE_32K; | |
597 | } | |
598 | } | |
599 | if (pHTInfo->MPDU_Density > pPeerHTCap->MPDUDensity) | |
600 | pHTInfo->CurrentMPDUDensity = pHTInfo->MPDU_Density; | |
601 | else | |
602 | pHTInfo->CurrentMPDUDensity = pPeerHTCap->MPDUDensity; | |
831cb9db | 603 | if (pHTInfo->IOTAction & HT_IOT_ACT_TX_USE_AMSDU_8K) { |
94a79942 LF |
604 | pHTInfo->bCurrentAMPDUEnable = false; |
605 | pHTInfo->ForcedAMSDUMode = HT_AGG_FORCE_ENABLE; | |
606 | pHTInfo->ForcedAMSDUMaxSize = 7935; | |
607 | } | |
608 | pHTInfo->bCurRxReorderEnable = pHTInfo->bRegRxReorderEnable; | |
609 | ||
610 | if (pPeerHTCap->MCS[0] == 0) | |
611 | pPeerHTCap->MCS[0] = 0xff; | |
612 | ||
831cb9db | 613 | HTIOTActDetermineRaFunc(ieee, ((pPeerHTCap->MCS[1]) != 0)); |
94a79942 LF |
614 | |
615 | HTFilterMCSRate(ieee, pPeerHTCap->MCS, ieee->dot11HTOperationalRateSet); | |
616 | ||
617 | pHTInfo->PeerMimoPs = pPeerHTCap->MimoPwrSave; | |
618 | if (pHTInfo->PeerMimoPs == MIMO_PS_STATIC) | |
619 | pMcsFilter = MCS_FILTER_1SS; | |
620 | else | |
621 | pMcsFilter = MCS_FILTER_ALL; | |
831cb9db LF |
622 | ieee->HTHighestOperaRate = HTGetHighestMCSRate(ieee, |
623 | ieee->dot11HTOperationalRateSet, pMcsFilter); | |
94a79942 LF |
624 | ieee->HTCurrentOperaRate = ieee->HTHighestOperaRate; |
625 | ||
626 | pHTInfo->CurrentOpMode = pPeerHTInfo->OptMode; | |
94a79942 LF |
627 | } |
628 | ||
831cb9db | 629 | void HTInitializeHTInfo(struct rtllib_device *ieee) |
94a79942 | 630 | { |
7796d93e | 631 | struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; |
94a79942 | 632 | |
94a79942 LF |
633 | pHTInfo->bCurrentHTSupport = false; |
634 | ||
635 | pHTInfo->bCurBW40MHz = false; | |
636 | pHTInfo->bCurTxBW40MHz = false; | |
637 | ||
638 | pHTInfo->bCurShortGI20MHz = false; | |
639 | pHTInfo->bCurShortGI40MHz = false; | |
640 | pHTInfo->bForcedShortGI = false; | |
641 | ||
642 | pHTInfo->bCurSuppCCK = true; | |
643 | ||
644 | pHTInfo->bCurrent_AMSDU_Support = false; | |
645 | pHTInfo->nCurrent_AMSDU_MaxSize = pHTInfo->nAMSDU_MaxSize; | |
646 | pHTInfo->CurrentMPDUDensity = pHTInfo->MPDU_Density; | |
647 | pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor; | |
648 | ||
831cb9db LF |
649 | memset((void *)(&(pHTInfo->SelfHTCap)), 0, |
650 | sizeof(pHTInfo->SelfHTCap)); | |
651 | memset((void *)(&(pHTInfo->SelfHTInfo)), 0, | |
652 | sizeof(pHTInfo->SelfHTInfo)); | |
653 | memset((void *)(&(pHTInfo->PeerHTCapBuf)), 0, | |
654 | sizeof(pHTInfo->PeerHTCapBuf)); | |
655 | memset((void *)(&(pHTInfo->PeerHTInfoBuf)), 0, | |
656 | sizeof(pHTInfo->PeerHTInfoBuf)); | |
94a79942 LF |
657 | |
658 | pHTInfo->bSwBwInProgress = false; | |
94a79942 LF |
659 | |
660 | pHTInfo->ePeerHTSpecVer = HT_SPEC_VER_IEEE; | |
661 | ||
662 | pHTInfo->bCurrentRT2RTAggregation = false; | |
663 | pHTInfo->bCurrentRT2RTLongSlotTime = false; | |
bb9a7b3f | 664 | pHTInfo->RT2RT_HT_Mode = (enum rt_ht_capability)0; |
94a79942 LF |
665 | |
666 | pHTInfo->IOTPeer = 0; | |
667 | pHTInfo->IOTAction = 0; | |
668 | pHTInfo->IOTRaFunc = 0; | |
669 | ||
670 | { | |
831cb9db | 671 | u8 *RegHTSuppRateSets = &(ieee->RegHTSuppRateSet[0]); |
3a6b70c3 | 672 | |
94a79942 LF |
673 | RegHTSuppRateSets[0] = 0xFF; |
674 | RegHTSuppRateSets[1] = 0xFF; | |
675 | RegHTSuppRateSets[4] = 0x01; | |
676 | } | |
677 | } | |
831cb9db | 678 | |
a15e76ad | 679 | void HTInitializeBssDesc(struct bss_ht *pBssHT) |
94a79942 | 680 | { |
b3b55bd7 | 681 | pBssHT->bd_support_ht = false; |
b87b2108 | 682 | memset(pBssHT->bd_ht_cap_buf, 0, sizeof(pBssHT->bd_ht_cap_buf)); |
20e90635 | 683 | pBssHT->bd_ht_cap_len = 0; |
2408ee9e | 684 | memset(pBssHT->bd_ht_info_buf, 0, sizeof(pBssHT->bd_ht_info_buf)); |
060d3f6c | 685 | pBssHT->bd_ht_info_len = 0; |
94a79942 | 686 | |
2fbcd6de | 687 | pBssHT->bd_ht_spec_ver = HT_SPEC_VER_IEEE; |
94a79942 | 688 | |
3f1f39fb | 689 | pBssHT->bd_rt2rt_aggregation = false; |
fe403d4b | 690 | pBssHT->bd_rt2rt_long_slot_time = false; |
6628c674 | 691 | pBssHT->rt2rt_ht_mode = (enum rt_ht_capability)0; |
94a79942 LF |
692 | } |
693 | ||
831cb9db LF |
694 | void HTResetSelfAndSavePeerSetting(struct rtllib_device *ieee, |
695 | struct rtllib_network *pNetwork) | |
94a79942 | 696 | { |
7796d93e | 697 | struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; |
94a79942 LF |
698 | u8 bIOTAction = 0; |
699 | ||
831cb9db | 700 | /* unmark bEnableHT flag here is the same reason why unmarked in |
14b40d92 MK |
701 | * function rtllib_softmac_new_net. WB 2008.09.10 |
702 | */ | |
b3b55bd7 | 703 | if (pNetwork->bssht.bd_support_ht) { |
94a79942 | 704 | pHTInfo->bCurrentHTSupport = true; |
2fbcd6de | 705 | pHTInfo->ePeerHTSpecVer = pNetwork->bssht.bd_ht_spec_ver; |
94a79942 | 706 | |
20e90635 WD |
707 | if (pNetwork->bssht.bd_ht_cap_len > 0 && |
708 | pNetwork->bssht.bd_ht_cap_len <= sizeof(pHTInfo->PeerHTCapBuf)) | |
831cb9db | 709 | memcpy(pHTInfo->PeerHTCapBuf, |
b87b2108 | 710 | pNetwork->bssht.bd_ht_cap_buf, |
20e90635 | 711 | pNetwork->bssht.bd_ht_cap_len); |
831cb9db | 712 | |
060d3f6c WD |
713 | if (pNetwork->bssht.bd_ht_info_len > 0 && |
714 | pNetwork->bssht.bd_ht_info_len <= | |
831cb9db LF |
715 | sizeof(pHTInfo->PeerHTInfoBuf)) |
716 | memcpy(pHTInfo->PeerHTInfoBuf, | |
2408ee9e | 717 | pNetwork->bssht.bd_ht_info_buf, |
060d3f6c | 718 | pNetwork->bssht.bd_ht_info_len); |
831cb9db LF |
719 | |
720 | if (pHTInfo->bRegRT2RTAggregation) { | |
721 | pHTInfo->bCurrentRT2RTAggregation = | |
3f1f39fb | 722 | pNetwork->bssht.bd_rt2rt_aggregation; |
831cb9db | 723 | pHTInfo->bCurrentRT2RTLongSlotTime = |
fe403d4b | 724 | pNetwork->bssht.bd_rt2rt_long_slot_time; |
6628c674 | 725 | pHTInfo->RT2RT_HT_Mode = pNetwork->bssht.rt2rt_ht_mode; |
831cb9db | 726 | } else { |
94a79942 LF |
727 | pHTInfo->bCurrentRT2RTAggregation = false; |
728 | pHTInfo->bCurrentRT2RTLongSlotTime = false; | |
bb9a7b3f | 729 | pHTInfo->RT2RT_HT_Mode = (enum rt_ht_capability)0; |
94a79942 LF |
730 | } |
731 | ||
732 | HTIOTPeerDetermine(ieee); | |
733 | ||
734 | pHTInfo->IOTAction = 0; | |
735 | bIOTAction = HTIOTActIsDisableMCS14(ieee, pNetwork->bssid); | |
736 | if (bIOTAction) | |
737 | pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_MCS14; | |
738 | ||
739 | bIOTAction = HTIOTActIsDisableMCS15(ieee); | |
740 | if (bIOTAction) | |
741 | pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_MCS15; | |
742 | ||
743 | bIOTAction = HTIOTActIsDisableMCSTwoSpatialStream(ieee); | |
744 | if (bIOTAction) | |
745 | pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_ALL_2SS; | |
746 | ||
94a79942 LF |
747 | bIOTAction = HTIOTActIsDisableEDCATurbo(ieee, pNetwork->bssid); |
748 | if (bIOTAction) | |
749 | pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_EDCA_TURBO; | |
750 | ||
831cb9db | 751 | bIOTAction = HTIOTActIsMgntUseCCK6M(ieee, pNetwork); |
94a79942 LF |
752 | if (bIOTAction) |
753 | pHTInfo->IOTAction |= HT_IOT_ACT_MGNT_USE_CCK_6M; | |
94a79942 LF |
754 | bIOTAction = HTIOTActIsCCDFsync(ieee); |
755 | if (bIOTAction) | |
756 | pHTInfo->IOTAction |= HT_IOT_ACT_CDD_FSYNC; | |
94a79942 LF |
757 | } else { |
758 | pHTInfo->bCurrentHTSupport = false; | |
759 | pHTInfo->bCurrentRT2RTAggregation = false; | |
760 | pHTInfo->bCurrentRT2RTLongSlotTime = false; | |
bb9a7b3f | 761 | pHTInfo->RT2RT_HT_Mode = (enum rt_ht_capability)0; |
94a79942 LF |
762 | |
763 | pHTInfo->IOTAction = 0; | |
764 | pHTInfo->IOTRaFunc = 0; | |
765 | } | |
94a79942 LF |
766 | } |
767 | ||
976d5341 SM |
768 | void HT_update_self_and_peer_setting(struct rtllib_device *ieee, |
769 | struct rtllib_network *pNetwork) | |
94a79942 | 770 | { |
7796d93e | 771 | struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; |
831cb9db | 772 | struct ht_info_ele *pPeerHTInfo = |
2408ee9e | 773 | (struct ht_info_ele *)pNetwork->bssht.bd_ht_info_buf; |
94a79942 | 774 | |
831cb9db | 775 | if (pHTInfo->bCurrentHTSupport) { |
060d3f6c | 776 | if (pNetwork->bssht.bd_ht_info_len != 0) |
94a79942 | 777 | pHTInfo->CurrentOpMode = pPeerHTInfo->OptMode; |
94a79942 LF |
778 | } |
779 | } | |
976d5341 | 780 | EXPORT_SYMBOL(HT_update_self_and_peer_setting); |
94a79942 | 781 | |
831cb9db | 782 | void HTUseDefaultSetting(struct rtllib_device *ieee) |
94a79942 | 783 | { |
7796d93e | 784 | struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; |
94a79942 | 785 | |
cb762154 | 786 | if (pHTInfo->bEnableHT) { |
94a79942 LF |
787 | pHTInfo->bCurrentHTSupport = true; |
788 | pHTInfo->bCurSuppCCK = pHTInfo->bRegSuppCCK; | |
789 | ||
790 | pHTInfo->bCurBW40MHz = pHTInfo->bRegBW40MHz; | |
831cb9db | 791 | pHTInfo->bCurShortGI20MHz = pHTInfo->bRegShortGI20MHz; |
94a79942 | 792 | |
831cb9db | 793 | pHTInfo->bCurShortGI40MHz = pHTInfo->bRegShortGI40MHz; |
94a79942 LF |
794 | |
795 | if (ieee->iw_mode == IW_MODE_ADHOC) | |
831cb9db LF |
796 | ieee->current_network.qos_data.active = |
797 | ieee->current_network.qos_data.supported; | |
94a79942 LF |
798 | pHTInfo->bCurrent_AMSDU_Support = pHTInfo->bAMSDU_Support; |
799 | pHTInfo->nCurrent_AMSDU_MaxSize = pHTInfo->nAMSDU_MaxSize; | |
800 | ||
801 | pHTInfo->bCurrentAMPDUEnable = pHTInfo->bAMPDUEnable; | |
802 | pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor; | |
803 | ||
804 | pHTInfo->CurrentMPDUDensity = pHTInfo->CurrentMPDUDensity; | |
805 | ||
831cb9db LF |
806 | HTFilterMCSRate(ieee, ieee->Regdot11TxHTOperationalRateSet, |
807 | ieee->dot11HTOperationalRateSet); | |
808 | ieee->HTHighestOperaRate = HTGetHighestMCSRate(ieee, | |
809 | ieee->dot11HTOperationalRateSet, | |
810 | MCS_FILTER_ALL); | |
94a79942 LF |
811 | ieee->HTCurrentOperaRate = ieee->HTHighestOperaRate; |
812 | ||
cb762154 | 813 | } else { |
94a79942 LF |
814 | pHTInfo->bCurrentHTSupport = false; |
815 | } | |
94a79942 | 816 | } |
cb762154 | 817 | |
831cb9db | 818 | u8 HTCCheck(struct rtllib_device *ieee, u8 *pFrame) |
94a79942 | 819 | { |
831cb9db LF |
820 | if (ieee->pHTInfo->bCurrentHTSupport) { |
821 | if ((IsQoSDataFrame(pFrame) && Frame_Order(pFrame)) == 1) { | |
b94436b5 | 822 | netdev_dbg(ieee->dev, "HT CONTROL FILED EXIST!!\n"); |
94a79942 LF |
823 | return true; |
824 | } | |
825 | } | |
826 | return false; | |
827 | } | |
828 | ||
ec0dc6be | 829 | static void HTSetConnectBwModeCallback(struct rtllib_device *ieee) |
831cb9db LF |
830 | { |
831 | struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; | |
832 | ||
831cb9db LF |
833 | if (pHTInfo->bCurBW40MHz) { |
834 | if (pHTInfo->CurSTAExtChnlOffset == HT_EXTCHNL_OFFSET_UPPER) | |
835 | ieee->set_chan(ieee->dev, | |
836 | ieee->current_network.channel + 2); | |
837 | else if (pHTInfo->CurSTAExtChnlOffset == | |
838 | HT_EXTCHNL_OFFSET_LOWER) | |
839 | ieee->set_chan(ieee->dev, | |
840 | ieee->current_network.channel - 2); | |
841 | else | |
842 | ieee->set_chan(ieee->dev, | |
843 | ieee->current_network.channel); | |
844 | ||
845 | ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20_40, | |
846 | pHTInfo->CurSTAExtChnlOffset); | |
847 | } else { | |
848 | ieee->set_chan(ieee->dev, ieee->current_network.channel); | |
849 | ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20, | |
850 | HT_EXTCHNL_OFFSET_NO_EXT); | |
851 | } | |
852 | ||
853 | pHTInfo->bSwBwInProgress = false; | |
854 | } | |
855 | ||
856 | void HTSetConnectBwMode(struct rtllib_device *ieee, | |
857 | enum ht_channel_width Bandwidth, | |
858 | enum ht_extchnl_offset Offset) | |
94a79942 | 859 | { |
7796d93e | 860 | struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; |
94a79942 | 861 | |
e785e87b | 862 | if (!pHTInfo->bRegBW40MHz) |
94a79942 LF |
863 | return; |
864 | ||
865 | if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) | |
831cb9db | 866 | Bandwidth = HT_CHANNEL_WIDTH_20; |
94a79942 LF |
867 | |
868 | if (pHTInfo->bSwBwInProgress) { | |
43446728 | 869 | pr_info("%s: bSwBwInProgress!!\n", __func__); |
94a79942 LF |
870 | return; |
871 | } | |
831cb9db LF |
872 | if (Bandwidth == HT_CHANNEL_WIDTH_20_40) { |
873 | if (ieee->current_network.channel < 2 && | |
874 | Offset == HT_EXTCHNL_OFFSET_LOWER) | |
94a79942 | 875 | Offset = HT_EXTCHNL_OFFSET_NO_EXT; |
831cb9db LF |
876 | if (Offset == HT_EXTCHNL_OFFSET_UPPER || |
877 | Offset == HT_EXTCHNL_OFFSET_LOWER) { | |
94a79942 LF |
878 | pHTInfo->bCurBW40MHz = true; |
879 | pHTInfo->CurSTAExtChnlOffset = Offset; | |
880 | } else { | |
881 | pHTInfo->bCurBW40MHz = false; | |
882 | pHTInfo->CurSTAExtChnlOffset = HT_EXTCHNL_OFFSET_NO_EXT; | |
883 | } | |
884 | } else { | |
885 | pHTInfo->bCurBW40MHz = false; | |
886 | pHTInfo->CurSTAExtChnlOffset = HT_EXTCHNL_OFFSET_NO_EXT; | |
887 | } | |
888 | ||
ad3cafd7 MP |
889 | netdev_dbg(ieee->dev, "%s():pHTInfo->bCurBW40MHz:%x\n", __func__, |
890 | pHTInfo->bCurBW40MHz); | |
94a79942 LF |
891 | |
892 | pHTInfo->bSwBwInProgress = true; | |
893 | ||
894 | HTSetConnectBwModeCallback(ieee); | |
94a79942 | 895 | } |