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