aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/rt2860/common
diff options
context:
space:
mode:
authorLarry Finger <Larry.Finger@lwfinger.net>2011-04-08 21:33:25 -0400
committerLarry Finger <Larry.Finger@lwfinger.net>2011-04-08 21:33:25 -0400
commitfefecc6989b4b24276797270c0e229c07be02ad3 (patch)
tree7c03f0f798ab84e5cf0c14a6648c991efd37c160 /drivers/staging/rt2860/common
parent0c3efe54d0165cecf0698b468e253577b555dde6 (diff)
staging: rt2860sta and rt2870sta: Remove drivers replaced in net/wireless
The staging driver rt2860sta is replaced by mainline driver rt2800pci, and rt2870sta is replaced by rt2800usb. As a result, the staging drivers are deleted. Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net> ---
Diffstat (limited to 'drivers/staging/rt2860/common')
-rw-r--r--drivers/staging/rt2860/common/action.c606
-rw-r--r--drivers/staging/rt2860/common/action.h56
-rw-r--r--drivers/staging/rt2860/common/ba_action.c1650
-rw-r--r--drivers/staging/rt2860/common/cmm_aes.c1311
-rw-r--r--drivers/staging/rt2860/common/cmm_asic.c2565
-rw-r--r--drivers/staging/rt2860/common/cmm_cfg.c258
-rw-r--r--drivers/staging/rt2860/common/cmm_data.c2361
-rw-r--r--drivers/staging/rt2860/common/cmm_data_pci.c1096
-rw-r--r--drivers/staging/rt2860/common/cmm_data_usb.c951
-rw-r--r--drivers/staging/rt2860/common/cmm_info.c955
-rw-r--r--drivers/staging/rt2860/common/cmm_mac_pci.c1661
-rw-r--r--drivers/staging/rt2860/common/cmm_mac_usb.c1162
-rw-r--r--drivers/staging/rt2860/common/cmm_sanity.c1205
-rw-r--r--drivers/staging/rt2860/common/cmm_sync.c718
-rw-r--r--drivers/staging/rt2860/common/cmm_tkip.c833
-rw-r--r--drivers/staging/rt2860/common/cmm_wep.c473
-rw-r--r--drivers/staging/rt2860/common/cmm_wpa.c3010
-rw-r--r--drivers/staging/rt2860/common/crypt_hmac.c187
-rw-r--r--drivers/staging/rt2860/common/crypt_md5.c339
-rw-r--r--drivers/staging/rt2860/common/crypt_sha2.c269
-rw-r--r--drivers/staging/rt2860/common/dfs.c68
-rw-r--r--drivers/staging/rt2860/common/ee_efuse.c351
-rw-r--r--drivers/staging/rt2860/common/ee_prom.c197
-rw-r--r--drivers/staging/rt2860/common/eeprom.c91
-rw-r--r--drivers/staging/rt2860/common/mlme.c6068
-rw-r--r--drivers/staging/rt2860/common/rt_channel.c1705
-rw-r--r--drivers/staging/rt2860/common/rt_rf.c187
-rw-r--r--drivers/staging/rt2860/common/rtmp_init.c3536
-rw-r--r--drivers/staging/rt2860/common/rtmp_mcu.c336
-rw-r--r--drivers/staging/rt2860/common/rtmp_timer.c302
-rw-r--r--drivers/staging/rt2860/common/spectrum.c2205
31 files changed, 0 insertions, 36712 deletions
diff --git a/drivers/staging/rt2860/common/action.c b/drivers/staging/rt2860/common/action.c
deleted file mode 100644
index 56ad236e114..00000000000
--- a/drivers/staging/rt2860/common/action.c
+++ /dev/null
@@ -1,606 +0,0 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 action.c
29
30 Abstract:
31 Handle association related requests either from WSTA or from local MLME
32
33 Revision History:
34 Who When What
35 -------- ---------- ----------------------------------------------
36 Jan Lee 2006 created for rt2860
37 */
38
39#include "../rt_config.h"
40#include "action.h"
41
42static void ReservedAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
43
44/*
45 ==========================================================================
46 Description:
47 association state machine init, including state transition and timer init
48 Parameters:
49 S - pointer to the association state machine
50 Note:
51 The state machine looks like the following
52
53 ASSOC_IDLE
54 MT2_MLME_DISASSOC_REQ mlme_disassoc_req_action
55 MT2_PEER_DISASSOC_REQ peer_disassoc_action
56 MT2_PEER_ASSOC_REQ drop
57 MT2_PEER_REASSOC_REQ drop
58 MT2_CLS3ERR cls3err_action
59 ==========================================================================
60 */
61void ActionStateMachineInit(struct rt_rtmp_adapter *pAd,
62 struct rt_state_machine *S,
63 OUT STATE_MACHINE_FUNC Trans[])
64{
65 StateMachineInit(S, (STATE_MACHINE_FUNC *) Trans, MAX_ACT_STATE,
66 MAX_ACT_MSG, (STATE_MACHINE_FUNC) Drop, ACT_IDLE,
67 ACT_MACHINE_BASE);
68
69 StateMachineSetAction(S, ACT_IDLE, MT2_PEER_SPECTRUM_CATE,
70 (STATE_MACHINE_FUNC) PeerSpectrumAction);
71 StateMachineSetAction(S, ACT_IDLE, MT2_PEER_QOS_CATE,
72 (STATE_MACHINE_FUNC) PeerQOSAction);
73
74 StateMachineSetAction(S, ACT_IDLE, MT2_PEER_DLS_CATE,
75 (STATE_MACHINE_FUNC) ReservedAction);
76
77 StateMachineSetAction(S, ACT_IDLE, MT2_PEER_BA_CATE,
78 (STATE_MACHINE_FUNC) PeerBAAction);
79 StateMachineSetAction(S, ACT_IDLE, MT2_PEER_HT_CATE,
80 (STATE_MACHINE_FUNC) PeerHTAction);
81 StateMachineSetAction(S, ACT_IDLE, MT2_MLME_ADD_BA_CATE,
82 (STATE_MACHINE_FUNC) MlmeADDBAAction);
83 StateMachineSetAction(S, ACT_IDLE, MT2_MLME_ORI_DELBA_CATE,
84 (STATE_MACHINE_FUNC) MlmeDELBAAction);
85 StateMachineSetAction(S, ACT_IDLE, MT2_MLME_REC_DELBA_CATE,
86 (STATE_MACHINE_FUNC) MlmeDELBAAction);
87
88 StateMachineSetAction(S, ACT_IDLE, MT2_PEER_PUBLIC_CATE,
89 (STATE_MACHINE_FUNC) PeerPublicAction);
90 StateMachineSetAction(S, ACT_IDLE, MT2_PEER_RM_CATE,
91 (STATE_MACHINE_FUNC) PeerRMAction);
92
93 StateMachineSetAction(S, ACT_IDLE, MT2_MLME_QOS_CATE,
94 (STATE_MACHINE_FUNC) MlmeQOSAction);
95 StateMachineSetAction(S, ACT_IDLE, MT2_MLME_DLS_CATE,
96 (STATE_MACHINE_FUNC) MlmeDLSAction);
97 StateMachineSetAction(S, ACT_IDLE, MT2_ACT_INVALID,
98 (STATE_MACHINE_FUNC) MlmeInvalidAction);
99}
100
101void MlmeADDBAAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
102{
103 struct rt_mlme_addba_req *pInfo;
104 u8 Addr[6];
105 u8 *pOutBuffer = NULL;
106 int NStatus;
107 unsigned long Idx;
108 struct rt_frame_addba_req Frame;
109 unsigned long FrameLen;
110 struct rt_ba_ori_entry *pBAEntry = NULL;
111
112 pInfo = (struct rt_mlme_addba_req *)Elem->Msg;
113 NdisZeroMemory(&Frame, sizeof(struct rt_frame_addba_req));
114
115 if (MlmeAddBAReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr)) {
116 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */
117 if (NStatus != NDIS_STATUS_SUCCESS) {
118 DBGPRINT(RT_DEBUG_TRACE,
119 ("BA - MlmeADDBAAction() allocate memory failed \n"));
120 return;
121 }
122 /* 1. find entry */
123 Idx =
124 pAd->MacTab.Content[pInfo->Wcid].BAOriWcidArray[pInfo->TID];
125 if (Idx == 0) {
126 MlmeFreeMemory(pAd, pOutBuffer);
127 DBGPRINT(RT_DEBUG_ERROR,
128 ("BA - MlmeADDBAAction() can't find BAOriEntry \n"));
129 return;
130 } else {
131 pBAEntry = &pAd->BATable.BAOriEntry[Idx];
132 }
133
134 {
135 if (ADHOC_ON(pAd))
136 ActHeaderInit(pAd, &Frame.Hdr, pInfo->pAddr,
137 pAd->CurrentAddress,
138 pAd->CommonCfg.Bssid);
139 else
140 ActHeaderInit(pAd, &Frame.Hdr,
141 pAd->CommonCfg.Bssid,
142 pAd->CurrentAddress,
143 pInfo->pAddr);
144 }
145
146 Frame.Category = CATEGORY_BA;
147 Frame.Action = ADDBA_REQ;
148 Frame.BaParm.AMSDUSupported = 0;
149 Frame.BaParm.BAPolicy = IMMED_BA;
150 Frame.BaParm.TID = pInfo->TID;
151 Frame.BaParm.BufSize = pInfo->BaBufSize;
152 Frame.Token = pInfo->Token;
153 Frame.TimeOutValue = pInfo->TimeOutValue;
154 Frame.BaStartSeq.field.FragNum = 0;
155 Frame.BaStartSeq.field.StartSeq =
156 pAd->MacTab.Content[pInfo->Wcid].TxSeq[pInfo->TID];
157
158 *(u16 *) (&Frame.BaParm) =
159 cpu2le16(*(u16 *) (&Frame.BaParm));
160 Frame.TimeOutValue = cpu2le16(Frame.TimeOutValue);
161 Frame.BaStartSeq.word = cpu2le16(Frame.BaStartSeq.word);
162
163 MakeOutgoingFrame(pOutBuffer, &FrameLen,
164 sizeof(struct rt_frame_addba_req), &Frame, END_OF_ARGS);
165
166 MiniportMMRequest(pAd,
167 (MGMT_USE_QUEUE_FLAG |
168 MapUserPriorityToAccessCategory[pInfo->TID]),
169 pOutBuffer, FrameLen);
170
171 MlmeFreeMemory(pAd, pOutBuffer);
172
173 DBGPRINT(RT_DEBUG_TRACE,
174 ("BA - Send ADDBA request. StartSeq = %x, FrameLen = %ld. BufSize = %d\n",
175 Frame.BaStartSeq.field.StartSeq, FrameLen,
176 Frame.BaParm.BufSize));
177 }
178}
179
180/*
181 ==========================================================================
182 Description:
183 send DELBA and delete BaEntry if any
184 Parametrs:
185 Elem - MLME message struct rt_mlme_delba_req
186
187 IRQL = DISPATCH_LEVEL
188
189 ==========================================================================
190 */
191void MlmeDELBAAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
192{
193 struct rt_mlme_delba_req *pInfo;
194 u8 *pOutBuffer = NULL;
195 u8 *pOutBuffer2 = NULL;
196 int NStatus;
197 unsigned long Idx;
198 struct rt_frame_delba_req Frame;
199 unsigned long FrameLen;
200 struct rt_frame_bar FrameBar;
201
202 pInfo = (struct rt_mlme_delba_req *)Elem->Msg;
203 /* must send back DELBA */
204 NdisZeroMemory(&Frame, sizeof(struct rt_frame_delba_req));
205 DBGPRINT(RT_DEBUG_TRACE,
206 ("==> MlmeDELBAAction(), Initiator(%d) \n", pInfo->Initiator));
207
208 if (MlmeDelBAReqSanity(pAd, Elem->Msg, Elem->MsgLen)) {
209 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */
210 if (NStatus != NDIS_STATUS_SUCCESS) {
211 DBGPRINT(RT_DEBUG_ERROR,
212 ("BA - MlmeDELBAAction() allocate memory failed 1. \n"));
213 return;
214 }
215
216 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer2); /*Get an unused nonpaged memory */
217 if (NStatus != NDIS_STATUS_SUCCESS) {
218 MlmeFreeMemory(pAd, pOutBuffer);
219 DBGPRINT(RT_DEBUG_ERROR,
220 ("BA - MlmeDELBAAction() allocate memory failed 2. \n"));
221 return;
222 }
223 /* SEND BAR (Send BAR to refresh peer reordering buffer.) */
224 Idx =
225 pAd->MacTab.Content[pInfo->Wcid].BAOriWcidArray[pInfo->TID];
226
227 BarHeaderInit(pAd, &FrameBar,
228 pAd->MacTab.Content[pInfo->Wcid].Addr,
229 pAd->CurrentAddress);
230
231 FrameBar.StartingSeq.field.FragNum = 0; /* make sure sequence not clear in DEL funciton. */
232 FrameBar.StartingSeq.field.StartSeq = pAd->MacTab.Content[pInfo->Wcid].TxSeq[pInfo->TID]; /* make sure sequence not clear in DEL funciton. */
233 FrameBar.BarControl.TID = pInfo->TID; /* make sure sequence not clear in DEL funciton. */
234 FrameBar.BarControl.ACKPolicy = IMMED_BA; /* make sure sequence not clear in DEL funciton. */
235 FrameBar.BarControl.Compressed = 1; /* make sure sequence not clear in DEL funciton. */
236 FrameBar.BarControl.MTID = 0; /* make sure sequence not clear in DEL funciton. */
237
238 MakeOutgoingFrame(pOutBuffer2, &FrameLen,
239 sizeof(struct rt_frame_bar), &FrameBar, END_OF_ARGS);
240 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer2, FrameLen);
241 MlmeFreeMemory(pAd, pOutBuffer2);
242 DBGPRINT(RT_DEBUG_TRACE,
243 ("BA - MlmeDELBAAction() . Send BAR to refresh peer reordering buffer \n"));
244
245 /* SEND DELBA FRAME */
246 FrameLen = 0;
247
248 {
249 if (ADHOC_ON(pAd))
250 ActHeaderInit(pAd, &Frame.Hdr,
251 pAd->MacTab.Content[pInfo->Wcid].
252 Addr, pAd->CurrentAddress,
253 pAd->CommonCfg.Bssid);
254 else
255 ActHeaderInit(pAd, &Frame.Hdr,
256 pAd->CommonCfg.Bssid,
257 pAd->CurrentAddress,
258 pAd->MacTab.Content[pInfo->Wcid].
259 Addr);
260 }
261
262 Frame.Category = CATEGORY_BA;
263 Frame.Action = DELBA;
264 Frame.DelbaParm.Initiator = pInfo->Initiator;
265 Frame.DelbaParm.TID = pInfo->TID;
266 Frame.ReasonCode = 39; /* Time Out */
267 *(u16 *) (&Frame.DelbaParm) =
268 cpu2le16(*(u16 *) (&Frame.DelbaParm));
269 Frame.ReasonCode = cpu2le16(Frame.ReasonCode);
270
271 MakeOutgoingFrame(pOutBuffer, &FrameLen,
272 sizeof(struct rt_frame_delba_req), &Frame, END_OF_ARGS);
273 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
274 MlmeFreeMemory(pAd, pOutBuffer);
275 DBGPRINT(RT_DEBUG_TRACE,
276 ("BA - MlmeDELBAAction() . 3 DELBA sent. Initiator(%d)\n",
277 pInfo->Initiator));
278 }
279}
280
281void MlmeQOSAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
282{
283}
284
285void MlmeDLSAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
286{
287}
288
289void MlmeInvalidAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
290{
291 /*u8 * pOutBuffer = NULL; */
292 /*Return the receiving frame except the MSB of category filed set to 1. 7.3.1.11 */
293}
294
295void PeerQOSAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
296{
297}
298
299void PeerBAAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
300{
301 u8 Action = Elem->Msg[LENGTH_802_11 + 1];
302
303 switch (Action) {
304 case ADDBA_REQ:
305 PeerAddBAReqAction(pAd, Elem);
306 break;
307 case ADDBA_RESP:
308 PeerAddBARspAction(pAd, Elem);
309 break;
310 case DELBA:
311 PeerDelBAAction(pAd, Elem);
312 break;
313 }
314}
315
316void PeerPublicAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
317{
318 if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
319 return;
320}
321
322static void ReservedAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
323{
324 u8 Category;
325
326 if (Elem->MsgLen <= LENGTH_802_11) {
327 return;
328 }
329
330 Category = Elem->Msg[LENGTH_802_11];
331 DBGPRINT(RT_DEBUG_TRACE,
332 ("Rcv reserved category(%d) Action Frame\n", Category));
333 hex_dump("Reserved Action Frame", &Elem->Msg[0], Elem->MsgLen);
334}
335
336void PeerRMAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
337{
338 return;
339}
340
341static void respond_ht_information_exchange_action(struct rt_rtmp_adapter *pAd,
342 struct rt_mlme_queue_elem *Elem)
343{
344 u8 *pOutBuffer = NULL;
345 int NStatus;
346 unsigned long FrameLen;
347 struct rt_frame_ht_info HTINFOframe, *pFrame;
348 u8 *pAddr;
349
350 /* 2. Always send back ADDBA Response */
351 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */
352
353 if (NStatus != NDIS_STATUS_SUCCESS) {
354 DBGPRINT(RT_DEBUG_TRACE,
355 ("ACTION - respond_ht_information_exchange_action() allocate memory failed \n"));
356 return;
357 }
358 /* get RA */
359 pFrame = (struct rt_frame_ht_info *) & Elem->Msg[0];
360 pAddr = pFrame->Hdr.Addr2;
361
362 NdisZeroMemory(&HTINFOframe, sizeof(struct rt_frame_ht_info));
363 /* 2-1. Prepare ADDBA Response frame. */
364 {
365 if (ADHOC_ON(pAd))
366 ActHeaderInit(pAd, &HTINFOframe.Hdr, pAddr,
367 pAd->CurrentAddress,
368 pAd->CommonCfg.Bssid);
369 else
370 ActHeaderInit(pAd, &HTINFOframe.Hdr,
371 pAd->CommonCfg.Bssid, pAd->CurrentAddress,
372 pAddr);
373 }
374
375 HTINFOframe.Category = CATEGORY_HT;
376 HTINFOframe.Action = HT_INFO_EXCHANGE;
377 HTINFOframe.HT_Info.Request = 0;
378 HTINFOframe.HT_Info.Forty_MHz_Intolerant =
379 pAd->CommonCfg.HtCapability.HtCapInfo.Forty_Mhz_Intolerant;
380 HTINFOframe.HT_Info.STA_Channel_Width =
381 pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth;
382
383 MakeOutgoingFrame(pOutBuffer, &FrameLen,
384 sizeof(struct rt_frame_ht_info), &HTINFOframe, END_OF_ARGS);
385
386 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
387 MlmeFreeMemory(pAd, pOutBuffer);
388}
389
390void PeerHTAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
391{
392 u8 Action = Elem->Msg[LENGTH_802_11 + 1];
393
394 if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
395 return;
396
397 switch (Action) {
398 case NOTIFY_BW_ACTION:
399 DBGPRINT(RT_DEBUG_TRACE,
400 ("ACTION - HT Notify Channel bandwidth action----> \n"));
401
402 if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) {
403 /* Note, this is to patch DIR-1353 AP. When the AP set to Wep, it will use legacy mode. But AP still keeps */
404 /* sending BW_Notify Action frame, and cause us to linkup and linkdown. */
405 /* In legacy mode, don't need to parse HT action frame. */
406 DBGPRINT(RT_DEBUG_TRACE,
407 ("ACTION -Ignore HT Notify Channel BW when link as legacy mode. BW = %d---> \n",
408 Elem->Msg[LENGTH_802_11 + 2]));
409 break;
410 }
411
412 if (Elem->Msg[LENGTH_802_11 + 2] == 0) /* 7.4.8.2. if value is 1, keep the same as supported channel bandwidth. */
413 pAd->MacTab.Content[Elem->Wcid].HTPhyMode.field.BW = 0;
414
415 break;
416 case SMPS_ACTION:
417 /* 7.3.1.25 */
418 DBGPRINT(RT_DEBUG_TRACE, ("ACTION - SMPS action----> \n"));
419 if (((Elem->Msg[LENGTH_802_11 + 2] & 0x1) == 0)) {
420 pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_ENABLE;
421 } else if (((Elem->Msg[LENGTH_802_11 + 2] & 0x2) == 0)) {
422 pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_STATIC;
423 } else {
424 pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_DYNAMIC;
425 }
426
427 DBGPRINT(RT_DEBUG_TRACE,
428 ("Aid(%d) MIMO PS = %d\n", Elem->Wcid,
429 pAd->MacTab.Content[Elem->Wcid].MmpsMode));
430 /* rt2860c : add something for smps change. */
431 break;
432
433 case SETPCO_ACTION:
434 break;
435 case MIMO_CHA_MEASURE_ACTION:
436 break;
437 case HT_INFO_EXCHANGE:
438 {
439 struct rt_ht_information_octet *pHT_info;
440
441 pHT_info =
442 (struct rt_ht_information_octet *) & Elem->Msg[LENGTH_802_11 +
443 2];
444 /* 7.4.8.10 */
445 DBGPRINT(RT_DEBUG_TRACE,
446 ("ACTION - HT Information Exchange action----> \n"));
447 if (pHT_info->Request) {
448 respond_ht_information_exchange_action(pAd,
449 Elem);
450 }
451 }
452 break;
453 }
454}
455
456/*
457 ==========================================================================
458 Description:
459 Retry sending ADDBA Reqest.
460
461 IRQL = DISPATCH_LEVEL
462
463 Parametrs:
464 p8023Header: if this is already 802.3 format, p8023Header is NULL
465
466 Return : TRUE if put into rx reordering buffer, shouldn't indicaterxhere.
467 FALSE , then continue indicaterx at this moment.
468 ==========================================================================
469 */
470void ORIBATimerTimeout(struct rt_rtmp_adapter *pAd)
471{
472 struct rt_mac_table_entry *pEntry;
473 int i, total;
474 u8 TID;
475
476 total = pAd->MacTab.Size * NUM_OF_TID;
477
478 for (i = 1; ((i < MAX_LEN_OF_BA_ORI_TABLE) && (total > 0)); i++) {
479 if (pAd->BATable.BAOriEntry[i].ORI_BA_Status == Originator_Done) {
480 pEntry =
481 &pAd->MacTab.Content[pAd->BATable.BAOriEntry[i].
482 Wcid];
483 TID = pAd->BATable.BAOriEntry[i].TID;
484
485 ASSERT(pAd->BATable.BAOriEntry[i].Wcid <
486 MAX_LEN_OF_MAC_TABLE);
487 }
488 total--;
489 }
490}
491
492void SendRefreshBAR(struct rt_rtmp_adapter *pAd, struct rt_mac_table_entry *pEntry)
493{
494 struct rt_frame_bar FrameBar;
495 unsigned long FrameLen;
496 int NStatus;
497 u8 *pOutBuffer = NULL;
498 u16 Sequence;
499 u8 i, TID;
500 u16 idx;
501 struct rt_ba_ori_entry *pBAEntry;
502
503 for (i = 0; i < NUM_OF_TID; i++) {
504 idx = pEntry->BAOriWcidArray[i];
505 if (idx == 0) {
506 continue;
507 }
508 pBAEntry = &pAd->BATable.BAOriEntry[idx];
509
510 if (pBAEntry->ORI_BA_Status == Originator_Done) {
511 TID = pBAEntry->TID;
512
513 ASSERT(pBAEntry->Wcid < MAX_LEN_OF_MAC_TABLE);
514
515 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */
516 if (NStatus != NDIS_STATUS_SUCCESS) {
517 DBGPRINT(RT_DEBUG_ERROR,
518 ("BA - MlmeADDBAAction() allocate memory failed \n"));
519 return;
520 }
521
522 Sequence = pEntry->TxSeq[TID];
523
524 BarHeaderInit(pAd, &FrameBar, pEntry->Addr,
525 pAd->CurrentAddress);
526
527 FrameBar.StartingSeq.field.FragNum = 0; /* make sure sequence not clear in DEL function. */
528 FrameBar.StartingSeq.field.StartSeq = Sequence; /* make sure sequence not clear in DEL funciton. */
529 FrameBar.BarControl.TID = TID; /* make sure sequence not clear in DEL funciton. */
530
531 MakeOutgoingFrame(pOutBuffer, &FrameLen,
532 sizeof(struct rt_frame_bar), &FrameBar,
533 END_OF_ARGS);
534 /*if (!(CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_RALINK_CHIPSET))) */
535 if (1) /* Now we always send BAR. */
536 {
537 /*MiniportMMRequestUnlock(pAd, 0, pOutBuffer, FrameLen); */
538 MiniportMMRequest(pAd,
539 (MGMT_USE_QUEUE_FLAG |
540 MapUserPriorityToAccessCategory
541 [TID]), pOutBuffer,
542 FrameLen);
543
544 }
545 MlmeFreeMemory(pAd, pOutBuffer);
546 }
547 }
548}
549
550void ActHeaderInit(struct rt_rtmp_adapter *pAd,
551 struct rt_header_802_11 * pHdr80211,
552 u8 *Addr1, u8 *Addr2, u8 *Addr3)
553{
554 NdisZeroMemory(pHdr80211, sizeof(struct rt_header_802_11));
555 pHdr80211->FC.Type = BTYPE_MGMT;
556 pHdr80211->FC.SubType = SUBTYPE_ACTION;
557
558 COPY_MAC_ADDR(pHdr80211->Addr1, Addr1);
559 COPY_MAC_ADDR(pHdr80211->Addr2, Addr2);
560 COPY_MAC_ADDR(pHdr80211->Addr3, Addr3);
561}
562
563void BarHeaderInit(struct rt_rtmp_adapter *pAd,
564 struct rt_frame_bar * pCntlBar, u8 *pDA, u8 *pSA)
565{
566 NdisZeroMemory(pCntlBar, sizeof(struct rt_frame_bar));
567 pCntlBar->FC.Type = BTYPE_CNTL;
568 pCntlBar->FC.SubType = SUBTYPE_BLOCK_ACK_REQ;
569 pCntlBar->BarControl.MTID = 0;
570 pCntlBar->BarControl.Compressed = 1;
571 pCntlBar->BarControl.ACKPolicy = 0;
572
573 pCntlBar->Duration =
574 16 + RTMPCalcDuration(pAd, RATE_1, sizeof(struct rt_frame_ba));
575
576 COPY_MAC_ADDR(pCntlBar->Addr1, pDA);
577 COPY_MAC_ADDR(pCntlBar->Addr2, pSA);
578}
579
580/*
581 ==========================================================================
582 Description:
583 Insert Category and action code into the action frame.
584
585 Parametrs:
586 1. frame buffer pointer.
587 2. frame length.
588 3. category code of the frame.
589 4. action code of the frame.
590
591 Return : None.
592 ==========================================================================
593 */
594void InsertActField(struct rt_rtmp_adapter *pAd,
595 u8 *pFrameBuf,
596 unsigned long *pFrameLen, u8 Category, u8 ActCode)
597{
598 unsigned long TempLen;
599
600 MakeOutgoingFrame(pFrameBuf, &TempLen,
601 1, &Category, 1, &ActCode, END_OF_ARGS);
602
603 *pFrameLen = *pFrameLen + TempLen;
604
605 return;
606}
diff --git a/drivers/staging/rt2860/common/action.h b/drivers/staging/rt2860/common/action.h
deleted file mode 100644
index 974f8b84039..00000000000
--- a/drivers/staging/rt2860/common/action.h
+++ /dev/null
@@ -1,56 +0,0 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 aironet.h
29
30 Abstract:
31
32 Revision History:
33 Who When What
34 -------- ---------- ----------------------------------------------
35 Name Date Modification logs
36 Paul Lin 04-06-15 Initial
37*/
38
39#ifndef __ACTION_H__
40#define __ACTION_H__
41
42struct PACKED rt_ht_information_octet {
43 u8 Request:1;
44 u8 Forty_MHz_Intolerant:1;
45 u8 STA_Channel_Width:1;
46 u8 Reserved:5;
47};
48
49struct PACKED rt_frame_ht_info {
50 struct rt_header_802_11 Hdr;
51 u8 Category;
52 u8 Action;
53 struct rt_ht_information_octet HT_Info;
54};
55
56#endif /* __ACTION_H__ */
diff --git a/drivers/staging/rt2860/common/ba_action.c b/drivers/staging/rt2860/common/ba_action.c
deleted file mode 100644
index 133bc1b87d2..00000000000
--- a/drivers/staging/rt2860/common/ba_action.c
+++ /dev/null
@@ -1,1650 +0,0 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26 */
27
28#include "../rt_config.h"
29#include <linux/kernel.h>
30
31#define BA_ORI_INIT_SEQ (pEntry->TxSeq[TID]) /*1 // initial sequence number of BA session */
32
33#define ORI_SESSION_MAX_RETRY 8
34#define ORI_BA_SESSION_TIMEOUT (2000) /* ms */
35#define REC_BA_SESSION_IDLE_TIMEOUT (1000) /* ms */
36
37#define REORDERING_PACKET_TIMEOUT ((100 * OS_HZ)/1000) /* system ticks -- 100 ms */
38#define MAX_REORDERING_PACKET_TIMEOUT ((3000 * OS_HZ)/1000) /* system ticks -- 100 ms */
39
40#define RESET_RCV_SEQ (0xFFFF)
41
42static void ba_mpdu_blk_free(struct rt_rtmp_adapter *pAd,
43 struct reordering_mpdu *mpdu_blk);
44
45struct rt_ba_ori_entry *BATableAllocOriEntry(struct rt_rtmp_adapter *pAd, u16 * Idx);
46
47struct rt_ba_rec_entry *BATableAllocRecEntry(struct rt_rtmp_adapter *pAd, u16 * Idx);
48
49void BAOriSessionSetupTimeout(void *SystemSpecific1,
50 void *FunctionContext,
51 void *SystemSpecific2,
52 void *SystemSpecific3);
53
54void BARecSessionIdleTimeout(void *SystemSpecific1,
55 void *FunctionContext,
56 void *SystemSpecific2,
57 void *SystemSpecific3);
58
59BUILD_TIMER_FUNCTION(BAOriSessionSetupTimeout);
60BUILD_TIMER_FUNCTION(BARecSessionIdleTimeout);
61
62#define ANNOUNCE_REORDERING_PACKET(_pAd, _mpdu_blk) \
63 Announce_Reordering_Packet(_pAd, _mpdu_blk);
64
65void BA_MaxWinSizeReasign(struct rt_rtmp_adapter *pAd,
66 struct rt_mac_table_entry *pEntryPeer, u8 * pWinSize)
67{
68 u8 MaxSize;
69
70 if (pAd->MACVersion >= RALINK_2883_VERSION) /* 3*3 */
71 {
72 if (pAd->MACVersion >= RALINK_3070_VERSION) {
73 if (pEntryPeer->WepStatus !=
74 Ndis802_11EncryptionDisabled)
75 MaxSize = 7; /* for non-open mode */
76 else
77 MaxSize = 13;
78 } else
79 MaxSize = 31;
80 } else if (pAd->MACVersion >= RALINK_2880E_VERSION) /* 2880 e */
81 {
82 if (pEntryPeer->WepStatus != Ndis802_11EncryptionDisabled)
83 MaxSize = 7; /* for non-open mode */
84 else
85 MaxSize = 13;
86 } else
87 MaxSize = 7;
88
89 DBGPRINT(RT_DEBUG_TRACE, ("ba> Win Size = %d, Max Size = %d\n",
90 *pWinSize, MaxSize));
91
92 if ((*pWinSize) > MaxSize) {
93 DBGPRINT(RT_DEBUG_TRACE,
94 ("ba> reassign max win size from %d to %d\n",
95 *pWinSize, MaxSize));
96
97 *pWinSize = MaxSize;
98 }
99}
100
101void Announce_Reordering_Packet(struct rt_rtmp_adapter *pAd,
102 IN struct reordering_mpdu *mpdu)
103{
104 void *pPacket;
105
106 pPacket = mpdu->pPacket;
107
108 if (mpdu->bAMSDU) {
109 ASSERT(0);
110 BA_Reorder_AMSDU_Announce(pAd, pPacket);
111 } else {
112 /* */
113 /* pass this 802.3 packet to upper layer or forward this packet to WM directly */
114 /* */
115
116 ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pPacket,
117 RTMP_GET_PACKET_IF(pPacket));
118 }
119}
120
121/*
122 * Insert a reordering mpdu into sorted linked list by sequence no.
123 */
124BOOLEAN ba_reordering_mpdu_insertsorted(struct reordering_list *list,
125 struct reordering_mpdu *mpdu)
126{
127
128 struct reordering_mpdu **ppScan = &list->next;
129
130 while (*ppScan != NULL) {
131 if (SEQ_SMALLER((*ppScan)->Sequence, mpdu->Sequence, MAXSEQ)) {
132 ppScan = &(*ppScan)->next;
133 } else if ((*ppScan)->Sequence == mpdu->Sequence) {
134 /* give up this duplicated frame */
135 return (FALSE);
136 } else {
137 /* find position */
138 break;
139 }
140 }
141
142 mpdu->next = *ppScan;
143 *ppScan = mpdu;
144 list->qlen++;
145 return TRUE;
146}
147
148/*
149 * caller lock critical section if necessary
150 */
151static inline void ba_enqueue(struct reordering_list *list,
152 struct reordering_mpdu *mpdu_blk)
153{
154 list->qlen++;
155 mpdu_blk->next = list->next;
156 list->next = mpdu_blk;
157}
158
159/*
160 * caller lock critical section if necessary
161 */
162static inline struct reordering_mpdu *ba_dequeue(struct reordering_list *list)
163{
164 struct reordering_mpdu *mpdu_blk = NULL;
165
166 ASSERT(list);
167
168 if (list->qlen) {
169 list->qlen--;
170 mpdu_blk = list->next;
171 if (mpdu_blk) {
172 list->next = mpdu_blk->next;
173 mpdu_blk->next = NULL;
174 }
175 }
176 return mpdu_blk;
177}
178
179static inline struct reordering_mpdu *ba_reordering_mpdu_dequeue(struct
180 reordering_list
181 *list)
182{
183 return (ba_dequeue(list));
184}
185
186static inline struct reordering_mpdu *ba_reordering_mpdu_probe(struct
187 reordering_list
188 *list)
189{
190 ASSERT(list);
191
192 return (list->next);
193}
194
195/*
196 * free all resource for reordering mechanism
197 */
198void ba_reordering_resource_release(struct rt_rtmp_adapter *pAd)
199{
200 struct rt_ba_table *Tab;
201 struct rt_ba_rec_entry *pBAEntry;
202 struct reordering_mpdu *mpdu_blk;
203 int i;
204
205 Tab = &pAd->BATable;
206
207 /* I. release all pending reordering packet */
208 NdisAcquireSpinLock(&pAd->BATabLock);
209 for (i = 0; i < MAX_LEN_OF_BA_REC_TABLE; i++) {
210 pBAEntry = &Tab->BARecEntry[i];
211 if (pBAEntry->REC_BA_Status != Recipient_NONE) {
212 while ((mpdu_blk =
213 ba_reordering_mpdu_dequeue(&pBAEntry->list))) {
214 ASSERT(mpdu_blk->pPacket);
215 RELEASE_NDIS_PACKET(pAd, mpdu_blk->pPacket,
216 NDIS_STATUS_FAILURE);
217 ba_mpdu_blk_free(pAd, mpdu_blk);
218 }
219 }
220 }
221 NdisReleaseSpinLock(&pAd->BATabLock);
222
223 ASSERT(pBAEntry->list.qlen == 0);
224 /* II. free memory of reordering mpdu table */
225 NdisAcquireSpinLock(&pAd->mpdu_blk_pool.lock);
226 os_free_mem(pAd, pAd->mpdu_blk_pool.mem);
227 NdisReleaseSpinLock(&pAd->mpdu_blk_pool.lock);
228}
229
230/*
231 * Allocate all resource for reordering mechanism
232 */
233BOOLEAN ba_reordering_resource_init(struct rt_rtmp_adapter *pAd, int num)
234{
235 int i;
236 u8 *mem;
237 struct reordering_mpdu *mpdu_blk;
238 struct reordering_list *freelist;
239
240 /* allocate spinlock */
241 NdisAllocateSpinLock(&pAd->mpdu_blk_pool.lock);
242
243 /* initialize freelist */
244 freelist = &pAd->mpdu_blk_pool.freelist;
245 freelist->next = NULL;
246 freelist->qlen = 0;
247
248 DBGPRINT(RT_DEBUG_TRACE,
249 ("Allocate %d memory for BA reordering\n",
250 (u32)(num * sizeof(struct reordering_mpdu))));
251
252 /* allocate number of mpdu_blk memory */
253 os_alloc_mem(pAd, (u8 **) & mem,
254 (num * sizeof(struct reordering_mpdu)));
255
256 pAd->mpdu_blk_pool.mem = mem;
257
258 if (mem == NULL) {
259 DBGPRINT(RT_DEBUG_ERROR,
260 ("Can't Allocate Memory for BA Reordering\n"));
261 return (FALSE);
262 }
263
264 /* build mpdu_blk free list */
265 for (i = 0; i < num; i++) {
266 /* get mpdu_blk */
267 mpdu_blk = (struct reordering_mpdu *)mem;
268 /* initial mpdu_blk */
269 NdisZeroMemory(mpdu_blk, sizeof(struct reordering_mpdu));
270 /* next mpdu_blk */
271 mem += sizeof(struct reordering_mpdu);
272 /* insert mpdu_blk into freelist */
273 ba_enqueue(freelist, mpdu_blk);
274 }
275
276 return (TRUE);
277}
278
279/*static int blk_count=0; // sample take off, no use */
280
281static struct reordering_mpdu *ba_mpdu_blk_alloc(struct rt_rtmp_adapter *pAd)
282{
283 struct reordering_mpdu *mpdu_blk;
284
285 NdisAcquireSpinLock(&pAd->mpdu_blk_pool.lock);
286 mpdu_blk = ba_dequeue(&pAd->mpdu_blk_pool.freelist);
287 if (mpdu_blk) {
288/* blk_count++; */
289 /* reset mpdu_blk */
290 NdisZeroMemory(mpdu_blk, sizeof(struct reordering_mpdu));
291 }
292 NdisReleaseSpinLock(&pAd->mpdu_blk_pool.lock);
293 return mpdu_blk;
294}
295
296static void ba_mpdu_blk_free(struct rt_rtmp_adapter *pAd,
297 struct reordering_mpdu *mpdu_blk)
298{
299 ASSERT(mpdu_blk);
300
301 NdisAcquireSpinLock(&pAd->mpdu_blk_pool.lock);
302/* blk_count--; */
303 ba_enqueue(&pAd->mpdu_blk_pool.freelist, mpdu_blk);
304 NdisReleaseSpinLock(&pAd->mpdu_blk_pool.lock);
305}
306
307static u16 ba_indicate_reordering_mpdus_in_order(struct rt_rtmp_adapter *pAd,
308 struct rt_ba_rec_entry *pBAEntry,
309 u16 StartSeq)
310{
311 struct reordering_mpdu *mpdu_blk;
312 u16 LastIndSeq = RESET_RCV_SEQ;
313
314 NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
315
316 while ((mpdu_blk = ba_reordering_mpdu_probe(&pBAEntry->list))) {
317 /* find in-order frame */
318 if (!SEQ_STEPONE(mpdu_blk->Sequence, StartSeq, MAXSEQ)) {
319 break;
320 }
321 /* dequeue in-order frame from reodering list */
322 mpdu_blk = ba_reordering_mpdu_dequeue(&pBAEntry->list);
323 /* pass this frame up */
324 ANNOUNCE_REORDERING_PACKET(pAd, mpdu_blk);
325 /* move to next sequence */
326 StartSeq = mpdu_blk->Sequence;
327 LastIndSeq = StartSeq;
328 /* free mpdu_blk */
329 ba_mpdu_blk_free(pAd, mpdu_blk);
330 }
331
332 NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
333
334 /* update last indicated sequence */
335 return LastIndSeq;
336}
337
338static void ba_indicate_reordering_mpdus_le_seq(struct rt_rtmp_adapter *pAd,
339 struct rt_ba_rec_entry *pBAEntry,
340 u16 Sequence)
341{
342 struct reordering_mpdu *mpdu_blk;
343
344 NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
345 while ((mpdu_blk = ba_reordering_mpdu_probe(&pBAEntry->list))) {
346 /* find in-order frame */
347 if ((mpdu_blk->Sequence == Sequence)
348 || SEQ_SMALLER(mpdu_blk->Sequence, Sequence, MAXSEQ)) {
349 /* dequeue in-order frame from reodering list */
350 mpdu_blk = ba_reordering_mpdu_dequeue(&pBAEntry->list);
351 /* pass this frame up */
352 ANNOUNCE_REORDERING_PACKET(pAd, mpdu_blk);
353 /* free mpdu_blk */
354 ba_mpdu_blk_free(pAd, mpdu_blk);
355 } else {
356 break;
357 }
358 }
359 NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
360}
361
362static void ba_refresh_reordering_mpdus(struct rt_rtmp_adapter *pAd,
363 struct rt_ba_rec_entry *pBAEntry)
364{
365 struct reordering_mpdu *mpdu_blk;
366
367 NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
368
369 /* dequeue in-order frame from reodering list */
370 while ((mpdu_blk = ba_reordering_mpdu_dequeue(&pBAEntry->list))) {
371 /* pass this frame up */
372 ANNOUNCE_REORDERING_PACKET(pAd, mpdu_blk);
373
374 pBAEntry->LastIndSeq = mpdu_blk->Sequence;
375 ba_mpdu_blk_free(pAd, mpdu_blk);
376
377 /* update last indicated sequence */
378 }
379 ASSERT(pBAEntry->list.qlen == 0);
380 pBAEntry->LastIndSeq = RESET_RCV_SEQ;
381 NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
382}
383
384/*static */
385void ba_flush_reordering_timeout_mpdus(struct rt_rtmp_adapter *pAd,
386 struct rt_ba_rec_entry *pBAEntry,
387 unsigned long Now32)
388{
389 u16 Sequence;
390
391/* if ((RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+REORDERING_PACKET_TIMEOUT)) && */
392/* (pBAEntry->list.qlen > ((pBAEntry->BAWinSize*7)/8))) //|| */
393/* (RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(10*REORDERING_PACKET_TIMEOUT))) && */
394/* (pBAEntry->list.qlen > (pBAEntry->BAWinSize/8))) */
395 if (RTMP_TIME_AFTER
396 ((unsigned long)Now32,
397 (unsigned long)(pBAEntry->LastIndSeqAtTimer +
398 (MAX_REORDERING_PACKET_TIMEOUT / 6)))
399 && (pBAEntry->list.qlen > 1)
400 ) {
401 DBGPRINT(RT_DEBUG_TRACE,
402 ("timeout[%d] (%08lx-%08lx = %d > %d): %x, flush all!\n ",
403 pBAEntry->list.qlen, Now32,
404 (pBAEntry->LastIndSeqAtTimer),
405 (int)((long)Now32 -
406 (long)(pBAEntry->LastIndSeqAtTimer)),
407 MAX_REORDERING_PACKET_TIMEOUT, pBAEntry->LastIndSeq));
408 ba_refresh_reordering_mpdus(pAd, pBAEntry);
409 pBAEntry->LastIndSeqAtTimer = Now32;
410 } else
411 if (RTMP_TIME_AFTER
412 ((unsigned long)Now32,
413 (unsigned long)(pBAEntry->LastIndSeqAtTimer +
414 (REORDERING_PACKET_TIMEOUT)))
415 && (pBAEntry->list.qlen > 0)
416 ) {
417 /* */
418 /* force LastIndSeq to shift to LastIndSeq+1 */
419 /* */
420 Sequence = (pBAEntry->LastIndSeq + 1) & MAXSEQ;
421 ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, Sequence);
422 pBAEntry->LastIndSeqAtTimer = Now32;
423 pBAEntry->LastIndSeq = Sequence;
424 /* */
425 /* indicate in-order mpdus */
426 /* */
427 Sequence =
428 ba_indicate_reordering_mpdus_in_order(pAd, pBAEntry,
429 Sequence);
430 if (Sequence != RESET_RCV_SEQ) {
431 pBAEntry->LastIndSeq = Sequence;
432 }
433
434 DBGPRINT(RT_DEBUG_OFF,
435 ("%x, flush one!\n", pBAEntry->LastIndSeq));
436
437 }
438}
439
440/*
441 * generate ADDBA request to
442 * set up BA agreement
443 */
444void BAOriSessionSetUp(struct rt_rtmp_adapter *pAd,
445 struct rt_mac_table_entry *pEntry,
446 u8 TID,
447 u16 TimeOut,
448 unsigned long DelayTime, IN BOOLEAN isForced)
449{
450 /*struct rt_mlme_addba_req AddbaReq; */
451 struct rt_ba_ori_entry *pBAEntry = NULL;
452 u16 Idx;
453 BOOLEAN Cancelled;
454
455 if ((pAd->CommonCfg.BACapability.field.AutoBA != TRUE)
456 && (isForced == FALSE))
457 return;
458
459 /* if this entry is limited to use legacy tx mode, it doesn't generate BA. */
460 if (RTMPStaFixedTxMode(pAd, pEntry) != FIXED_TXMODE_HT)
461 return;
462
463 if ((pEntry->BADeclineBitmap & (1 << TID)) && (isForced == FALSE)) {
464 /* try again after 3 secs */
465 DelayTime = 3000;
466/* DBGPRINT(RT_DEBUG_TRACE, ("DeCline BA from Peer\n")); */
467/* return; */
468 }
469
470 Idx = pEntry->BAOriWcidArray[TID];
471 if (Idx == 0) {
472 /* allocate a BA session */
473 pBAEntry = BATableAllocOriEntry(pAd, &Idx);
474 if (pBAEntry == NULL) {
475 DBGPRINT(RT_DEBUG_TRACE,
476 ("ADDBA - MlmeADDBAAction() allocate BA session failed \n"));
477 return;
478 }
479 } else {
480 pBAEntry = &pAd->BATable.BAOriEntry[Idx];
481 }
482
483 if (pBAEntry->ORI_BA_Status >= Originator_WaitRes) {
484 return;
485 }
486
487 pEntry->BAOriWcidArray[TID] = Idx;
488
489 /* Initialize BA session */
490 pBAEntry->ORI_BA_Status = Originator_WaitRes;
491 pBAEntry->Wcid = pEntry->Aid;
492 pBAEntry->BAWinSize = pAd->CommonCfg.BACapability.field.RxBAWinLimit;
493 pBAEntry->Sequence = BA_ORI_INIT_SEQ;
494 pBAEntry->Token = 1; /* (2008-01-21) Jan Lee recommends it - this token can't be 0 */
495 pBAEntry->TID = TID;
496 pBAEntry->TimeOutValue = TimeOut;
497 pBAEntry->pAdapter = pAd;
498
499 if (!(pEntry->TXBAbitmap & (1 << TID))) {
500 RTMPInitTimer(pAd, &pBAEntry->ORIBATimer,
501 GET_TIMER_FUNCTION(BAOriSessionSetupTimeout),
502 pBAEntry, FALSE);
503 } else
504 RTMPCancelTimer(&pBAEntry->ORIBATimer, &Cancelled);
505
506 /* set timer to send ADDBA request */
507 RTMPSetTimer(&pBAEntry->ORIBATimer, DelayTime);
508}
509
510void BAOriSessionAdd(struct rt_rtmp_adapter *pAd,
511 struct rt_mac_table_entry *pEntry, struct rt_frame_addba_rsp * pFrame)
512{
513 struct rt_ba_ori_entry *pBAEntry = NULL;
514 BOOLEAN Cancelled;
515 u8 TID;
516 u16 Idx;
517 u8 *pOutBuffer2 = NULL;
518 int NStatus;
519 unsigned long FrameLen;
520 struct rt_frame_bar FrameBar;
521
522 TID = pFrame->BaParm.TID;
523 Idx = pEntry->BAOriWcidArray[TID];
524 pBAEntry = &pAd->BATable.BAOriEntry[Idx];
525
526 /* Start fill in parameters. */
527 if ((Idx != 0) && (pBAEntry->TID == TID)
528 && (pBAEntry->ORI_BA_Status == Originator_WaitRes)) {
529 pBAEntry->BAWinSize =
530 min(pBAEntry->BAWinSize, ((u8)pFrame->BaParm.BufSize));
531 BA_MaxWinSizeReasign(pAd, pEntry, &pBAEntry->BAWinSize);
532
533 pBAEntry->TimeOutValue = pFrame->TimeOutValue;
534 pBAEntry->ORI_BA_Status = Originator_Done;
535 pAd->BATable.numDoneOriginator++;
536
537 /* reset sequence number */
538 pBAEntry->Sequence = BA_ORI_INIT_SEQ;
539 /* Set Bitmap flag. */
540 pEntry->TXBAbitmap |= (1 << TID);
541 RTMPCancelTimer(&pBAEntry->ORIBATimer, &Cancelled);
542
543 pBAEntry->ORIBATimer.TimerValue = 0; /*pFrame->TimeOutValue; */
544
545 DBGPRINT(RT_DEBUG_TRACE,
546 ("%s : TXBAbitmap = %x, BAWinSize = %d, TimeOut = %ld\n",
547 __func__, pEntry->TXBAbitmap, pBAEntry->BAWinSize,
548 pBAEntry->ORIBATimer.TimerValue));
549
550 /* SEND BAR ; */
551 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer2); /*Get an unused nonpaged memory */
552 if (NStatus != NDIS_STATUS_SUCCESS) {
553 DBGPRINT(RT_DEBUG_TRACE,
554 ("BA - BAOriSessionAdd() allocate memory failed \n"));
555 return;
556 }
557
558 BarHeaderInit(pAd, &FrameBar,
559 pAd->MacTab.Content[pBAEntry->Wcid].Addr,
560 pAd->CurrentAddress);
561
562 FrameBar.StartingSeq.field.FragNum = 0; /* make sure sequence not clear in DEL function. */
563 FrameBar.StartingSeq.field.StartSeq = pBAEntry->Sequence; /* make sure sequence not clear in DEL funciton. */
564 FrameBar.BarControl.TID = pBAEntry->TID; /* make sure sequence not clear in DEL funciton. */
565 MakeOutgoingFrame(pOutBuffer2, &FrameLen,
566 sizeof(struct rt_frame_bar), &FrameBar, END_OF_ARGS);
567 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer2, FrameLen);
568 MlmeFreeMemory(pAd, pOutBuffer2);
569
570 if (pBAEntry->ORIBATimer.TimerValue)
571 RTMPSetTimer(&pBAEntry->ORIBATimer, pBAEntry->ORIBATimer.TimerValue); /* in mSec */
572 }
573}
574
575BOOLEAN BARecSessionAdd(struct rt_rtmp_adapter *pAd,
576 struct rt_mac_table_entry *pEntry, struct rt_frame_addba_req * pFrame)
577{
578 struct rt_ba_rec_entry *pBAEntry = NULL;
579 BOOLEAN Status = TRUE;
580 BOOLEAN Cancelled;
581 u16 Idx;
582 u8 TID;
583 u8 BAWinSize;
584 /*u32 Value; */
585 /*u32 offset; */
586
587 ASSERT(pEntry);
588
589 /* find TID */
590 TID = pFrame->BaParm.TID;
591
592 BAWinSize =
593 min(((u8)pFrame->BaParm.BufSize),
594 (u8)pAd->CommonCfg.BACapability.field.RxBAWinLimit);
595
596 /* Intel patch */
597 if (BAWinSize == 0) {
598 BAWinSize = 64;
599 }
600
601 Idx = pEntry->BARecWcidArray[TID];
602
603 if (Idx == 0) {
604 pBAEntry = BATableAllocRecEntry(pAd, &Idx);
605 } else {
606 pBAEntry = &pAd->BATable.BARecEntry[Idx];
607 /* flush all pending reordering mpdus */
608 ba_refresh_reordering_mpdus(pAd, pBAEntry);
609 }
610
611 DBGPRINT(RT_DEBUG_TRACE,
612 ("%s(%ld): Idx = %d, BAWinSize(req %d) = %d\n", __func__,
613 pAd->BATable.numAsRecipient, Idx, pFrame->BaParm.BufSize,
614 BAWinSize));
615
616 /* Start fill in parameters. */
617 if (pBAEntry != NULL) {
618 ASSERT(pBAEntry->list.qlen == 0);
619
620 pBAEntry->REC_BA_Status = Recipient_HandleRes;
621 pBAEntry->BAWinSize = BAWinSize;
622 pBAEntry->Wcid = pEntry->Aid;
623 pBAEntry->TID = TID;
624 pBAEntry->TimeOutValue = pFrame->TimeOutValue;
625 pBAEntry->REC_BA_Status = Recipient_Accept;
626 /* initial sequence number */
627 pBAEntry->LastIndSeq = RESET_RCV_SEQ; /*pFrame->BaStartSeq.field.StartSeq; */
628
629 DBGPRINT(RT_DEBUG_OFF,
630 ("Start Seq = %08x\n",
631 pFrame->BaStartSeq.field.StartSeq));
632
633 if (pEntry->RXBAbitmap & (1 << TID)) {
634 RTMPCancelTimer(&pBAEntry->RECBATimer, &Cancelled);
635 } else {
636 RTMPInitTimer(pAd, &pBAEntry->RECBATimer,
637 GET_TIMER_FUNCTION
638 (BARecSessionIdleTimeout), pBAEntry,
639 TRUE);
640 }
641
642 /* Set Bitmap flag. */
643 pEntry->RXBAbitmap |= (1 << TID);
644 pEntry->BARecWcidArray[TID] = Idx;
645
646 pEntry->BADeclineBitmap &= ~(1 << TID);
647
648 /* Set BA session mask in WCID table. */
649 RTMP_ADD_BA_SESSION_TO_ASIC(pAd, pEntry->Aid, TID);
650
651 DBGPRINT(RT_DEBUG_TRACE,
652 ("MACEntry[%d]RXBAbitmap = 0x%x. BARecWcidArray=%d\n",
653 pEntry->Aid, pEntry->RXBAbitmap,
654 pEntry->BARecWcidArray[TID]));
655 } else {
656 Status = FALSE;
657 DBGPRINT(RT_DEBUG_TRACE,
658 ("Can't Accept ADDBA for %pM TID = %d\n",
659 pEntry->Addr, TID));
660 }
661 return (Status);
662}
663
664struct rt_ba_rec_entry *BATableAllocRecEntry(struct rt_rtmp_adapter *pAd, u16 * Idx)
665{
666 int i;
667 struct rt_ba_rec_entry *pBAEntry = NULL;
668
669 NdisAcquireSpinLock(&pAd->BATabLock);
670
671 if (pAd->BATable.numAsRecipient >= MAX_BARECI_SESSION) {
672 DBGPRINT(RT_DEBUG_OFF, ("BA Recipeint Session (%ld) > %d\n",
673 pAd->BATable.numAsRecipient,
674 MAX_BARECI_SESSION));
675 goto done;
676 }
677 /* reserve idx 0 to identify BAWcidArray[TID] as empty */
678 for (i = 1; i < MAX_LEN_OF_BA_REC_TABLE; i++) {
679 pBAEntry = &pAd->BATable.BARecEntry[i];
680 if ((pBAEntry->REC_BA_Status == Recipient_NONE)) {
681 /* get one */
682 pAd->BATable.numAsRecipient++;
683 pBAEntry->REC_BA_Status = Recipient_USED;
684 *Idx = i;
685 break;
686 }
687 }
688
689done:
690 NdisReleaseSpinLock(&pAd->BATabLock);
691 return pBAEntry;
692}
693
694struct rt_ba_ori_entry *BATableAllocOriEntry(struct rt_rtmp_adapter *pAd, u16 * Idx)
695{
696 int i;
697 struct rt_ba_ori_entry *pBAEntry = NULL;
698
699 NdisAcquireSpinLock(&pAd->BATabLock);
700
701 if (pAd->BATable.numAsOriginator >= (MAX_LEN_OF_BA_ORI_TABLE)) {
702 goto done;
703 }
704 /* reserve idx 0 to identify BAWcidArray[TID] as empty */
705 for (i = 1; i < MAX_LEN_OF_BA_ORI_TABLE; i++) {
706 pBAEntry = &pAd->BATable.BAOriEntry[i];
707 if ((pBAEntry->ORI_BA_Status == Originator_NONE)) {
708 /* get one */
709 pAd->BATable.numAsOriginator++;
710 pBAEntry->ORI_BA_Status = Originator_USED;
711 pBAEntry->pAdapter = pAd;
712 *Idx = i;
713 break;
714 }
715 }
716
717done:
718 NdisReleaseSpinLock(&pAd->BATabLock);
719 return pBAEntry;
720}
721
722void BATableFreeOriEntry(struct rt_rtmp_adapter *pAd, unsigned long Idx)
723{
724 struct rt_ba_ori_entry *pBAEntry = NULL;
725 struct rt_mac_table_entry *pEntry;
726
727 if ((Idx == 0) || (Idx >= MAX_LEN_OF_BA_ORI_TABLE))
728 return;
729
730 pBAEntry = &pAd->BATable.BAOriEntry[Idx];
731
732 if (pBAEntry->ORI_BA_Status != Originator_NONE) {
733 pEntry = &pAd->MacTab.Content[pBAEntry->Wcid];
734 pEntry->BAOriWcidArray[pBAEntry->TID] = 0;
735
736 NdisAcquireSpinLock(&pAd->BATabLock);
737 if (pBAEntry->ORI_BA_Status == Originator_Done) {
738 pAd->BATable.numDoneOriginator -= 1;
739 pEntry->TXBAbitmap &= (~(1 << (pBAEntry->TID)));
740 DBGPRINT(RT_DEBUG_TRACE,
741 ("BATableFreeOriEntry numAsOriginator= %ld\n",
742 pAd->BATable.numAsRecipient));
743 /* Erase Bitmap flag. */
744 }
745
746 ASSERT(pAd->BATable.numAsOriginator != 0);
747
748 pAd->BATable.numAsOriginator -= 1;
749
750 pBAEntry->ORI_BA_Status = Originator_NONE;
751 pBAEntry->Token = 0;
752 NdisReleaseSpinLock(&pAd->BATabLock);
753 }
754}
755
756void BATableFreeRecEntry(struct rt_rtmp_adapter *pAd, unsigned long Idx)
757{
758 struct rt_ba_rec_entry *pBAEntry = NULL;
759 struct rt_mac_table_entry *pEntry;
760
761 if ((Idx == 0) || (Idx >= MAX_LEN_OF_BA_REC_TABLE))
762 return;
763
764 pBAEntry = &pAd->BATable.BARecEntry[Idx];
765
766 if (pBAEntry->REC_BA_Status != Recipient_NONE) {
767 pEntry = &pAd->MacTab.Content[pBAEntry->Wcid];
768 pEntry->BARecWcidArray[pBAEntry->TID] = 0;
769
770 NdisAcquireSpinLock(&pAd->BATabLock);
771
772 ASSERT(pAd->BATable.numAsRecipient != 0);
773
774 pAd->BATable.numAsRecipient -= 1;
775
776 pBAEntry->REC_BA_Status = Recipient_NONE;
777 NdisReleaseSpinLock(&pAd->BATabLock);
778 }
779}
780
781void BAOriSessionTearDown(struct rt_rtmp_adapter *pAd,
782 u8 Wcid,
783 u8 TID,
784 IN BOOLEAN bPassive, IN BOOLEAN bForceSend)
785{
786 unsigned long Idx = 0;
787 struct rt_ba_ori_entry *pBAEntry;
788 BOOLEAN Cancelled;
789
790 if (Wcid >= MAX_LEN_OF_MAC_TABLE) {
791 return;
792 }
793 /* */
794 /* Locate corresponding BA Originator Entry in BA Table with the (pAddr,TID). */
795 /* */
796 Idx = pAd->MacTab.Content[Wcid].BAOriWcidArray[TID];
797 if ((Idx == 0) || (Idx >= MAX_LEN_OF_BA_ORI_TABLE)) {
798 if (bForceSend == TRUE) {
799 /* force send specified TID DelBA */
800 struct rt_mlme_delba_req DelbaReq;
801 struct rt_mlme_queue_elem *Elem =
802 kmalloc(sizeof(struct rt_mlme_queue_elem),
803 MEM_ALLOC_FLAG);
804 if (Elem != NULL) {
805 NdisZeroMemory(&DelbaReq, sizeof(DelbaReq));
806 NdisZeroMemory(Elem, sizeof(struct rt_mlme_queue_elem));
807
808 COPY_MAC_ADDR(DelbaReq.Addr,
809 pAd->MacTab.Content[Wcid].Addr);
810 DelbaReq.Wcid = Wcid;
811 DelbaReq.TID = TID;
812 DelbaReq.Initiator = ORIGINATOR;
813 Elem->MsgLen = sizeof(DelbaReq);
814 NdisMoveMemory(Elem->Msg, &DelbaReq,
815 sizeof(DelbaReq));
816 MlmeDELBAAction(pAd, Elem);
817 kfree(Elem);
818 } else {
819 DBGPRINT(RT_DEBUG_ERROR,
820 ("%s(bForceSend):alloc memory failed!\n",
821 __func__));
822 }
823 }
824
825 return;
826 }
827
828 DBGPRINT(RT_DEBUG_TRACE,
829 ("%s===>Wcid=%d.TID=%d \n", __func__, Wcid, TID));
830
831 pBAEntry = &pAd->BATable.BAOriEntry[Idx];
832 DBGPRINT(RT_DEBUG_TRACE,
833 ("\t===>Idx = %ld, Wcid=%d.TID=%d, ORI_BA_Status = %d \n", Idx,
834 Wcid, TID, pBAEntry->ORI_BA_Status));
835 /* */
836 /* Prepare DelBA action frame and send to the peer. */
837 /* */
838 if ((bPassive == FALSE) && (TID == pBAEntry->TID)
839 && (pBAEntry->ORI_BA_Status == Originator_Done)) {
840 struct rt_mlme_delba_req DelbaReq;
841 struct rt_mlme_queue_elem *Elem =
842 kmalloc(sizeof(struct rt_mlme_queue_elem),
843 MEM_ALLOC_FLAG);
844 if (Elem != NULL) {
845 NdisZeroMemory(&DelbaReq, sizeof(DelbaReq));
846 NdisZeroMemory(Elem, sizeof(struct rt_mlme_queue_elem));
847
848 COPY_MAC_ADDR(DelbaReq.Addr,
849 pAd->MacTab.Content[Wcid].Addr);
850 DelbaReq.Wcid = Wcid;
851 DelbaReq.TID = pBAEntry->TID;
852 DelbaReq.Initiator = ORIGINATOR;
853 Elem->MsgLen = sizeof(DelbaReq);
854 NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq));
855 MlmeDELBAAction(pAd, Elem);
856 kfree(Elem);
857 } else {
858 DBGPRINT(RT_DEBUG_ERROR,
859 ("%s():alloc memory failed!\n", __func__));
860 return;
861 }
862 }
863 RTMPCancelTimer(&pBAEntry->ORIBATimer, &Cancelled);
864 BATableFreeOriEntry(pAd, Idx);
865
866 if (bPassive) {
867 /*BAOriSessionSetUp(pAd, &pAd->MacTab.Content[Wcid], TID, 0, 10000, TRUE); */
868 }
869}
870
871void BARecSessionTearDown(struct rt_rtmp_adapter *pAd,
872 u8 Wcid, u8 TID, IN BOOLEAN bPassive)
873{
874 unsigned long Idx = 0;
875 struct rt_ba_rec_entry *pBAEntry;
876
877 if (Wcid >= MAX_LEN_OF_MAC_TABLE) {
878 return;
879 }
880 /* */
881 /* Locate corresponding BA Originator Entry in BA Table with the (pAddr,TID). */
882 /* */
883 Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID];
884 if (Idx == 0)
885 return;
886
887 DBGPRINT(RT_DEBUG_TRACE,
888 ("%s===>Wcid=%d.TID=%d \n", __func__, Wcid, TID));
889
890 pBAEntry = &pAd->BATable.BARecEntry[Idx];
891 DBGPRINT(RT_DEBUG_TRACE,
892 ("\t===>Idx = %ld, Wcid=%d.TID=%d, REC_BA_Status = %d \n", Idx,
893 Wcid, TID, pBAEntry->REC_BA_Status));
894 /* */
895 /* Prepare DelBA action frame and send to the peer. */
896 /* */
897 if ((TID == pBAEntry->TID)
898 && (pBAEntry->REC_BA_Status == Recipient_Accept)) {
899 struct rt_mlme_delba_req DelbaReq;
900 BOOLEAN Cancelled;
901 /*unsigned long offset; */
902 /*u32 VALUE; */
903
904 RTMPCancelTimer(&pBAEntry->RECBATimer, &Cancelled);
905
906 /* */
907 /* 1. Send DELBA Action Frame */
908 /* */
909 if (bPassive == FALSE) {
910 struct rt_mlme_queue_elem *Elem =
911 kmalloc(sizeof(struct rt_mlme_queue_elem),
912 MEM_ALLOC_FLAG);
913 if (Elem != NULL) {
914 NdisZeroMemory(&DelbaReq, sizeof(DelbaReq));
915 NdisZeroMemory(Elem, sizeof(struct rt_mlme_queue_elem));
916
917 COPY_MAC_ADDR(DelbaReq.Addr,
918 pAd->MacTab.Content[Wcid].Addr);
919 DelbaReq.Wcid = Wcid;
920 DelbaReq.TID = TID;
921 DelbaReq.Initiator = RECIPIENT;
922 Elem->MsgLen = sizeof(DelbaReq);
923 NdisMoveMemory(Elem->Msg, &DelbaReq,
924 sizeof(DelbaReq));
925 MlmeDELBAAction(pAd, Elem);
926 kfree(Elem);
927 } else {
928 DBGPRINT(RT_DEBUG_ERROR,
929 ("%s():alloc memory failed!\n",
930 __func__));
931 return;
932 }
933 }
934
935 /* */
936 /* 2. Free resource of BA session */
937 /* */
938 /* flush all pending reordering mpdus */
939 ba_refresh_reordering_mpdus(pAd, pBAEntry);
940
941 NdisAcquireSpinLock(&pAd->BATabLock);
942
943 /* Erase Bitmap flag. */
944 pBAEntry->LastIndSeq = RESET_RCV_SEQ;
945 pBAEntry->BAWinSize = 0;
946 /* Erase Bitmap flag at software mactable */
947 pAd->MacTab.Content[Wcid].RXBAbitmap &=
948 (~(1 << (pBAEntry->TID)));
949 pAd->MacTab.Content[Wcid].BARecWcidArray[TID] = 0;
950
951 RTMP_DEL_BA_SESSION_FROM_ASIC(pAd, Wcid, TID);
952
953 NdisReleaseSpinLock(&pAd->BATabLock);
954
955 }
956
957 BATableFreeRecEntry(pAd, Idx);
958}
959
960void BASessionTearDownALL(struct rt_rtmp_adapter *pAd, u8 Wcid)
961{
962 int i;
963
964 for (i = 0; i < NUM_OF_TID; i++) {
965 BAOriSessionTearDown(pAd, Wcid, i, FALSE, FALSE);
966 BARecSessionTearDown(pAd, Wcid, i, FALSE);
967 }
968}
969
970/*
971 ==========================================================================
972 Description:
973 Retry sending ADDBA Reqest.
974
975 IRQL = DISPATCH_LEVEL
976
977 Parametrs:
978 p8023Header: if this is already 802.3 format, p8023Header is NULL
979
980 Return : TRUE if put into rx reordering buffer, shouldn't indicaterxhere.
981 FALSE , then continue indicaterx at this moment.
982 ==========================================================================
983 */
984void BAOriSessionSetupTimeout(void *SystemSpecific1,
985 void *FunctionContext,
986 void *SystemSpecific2,
987 void *SystemSpecific3)
988{
989 struct rt_ba_ori_entry *pBAEntry = (struct rt_ba_ori_entry *)FunctionContext;
990 struct rt_mac_table_entry *pEntry;
991 struct rt_rtmp_adapter *pAd;
992
993 if (pBAEntry == NULL)
994 return;
995
996 pAd = pBAEntry->pAdapter;
997
998 {
999 /* Do nothing if monitor mode is on */
1000 if (MONITOR_ON(pAd))
1001 return;
1002 }
1003
1004 pEntry = &pAd->MacTab.Content[pBAEntry->Wcid];
1005
1006 if ((pBAEntry->ORI_BA_Status == Originator_WaitRes)
1007 && (pBAEntry->Token < ORI_SESSION_MAX_RETRY)) {
1008 struct rt_mlme_addba_req AddbaReq;
1009
1010 NdisZeroMemory(&AddbaReq, sizeof(AddbaReq));
1011 COPY_MAC_ADDR(AddbaReq.pAddr, pEntry->Addr);
1012 AddbaReq.Wcid = (u8)(pEntry->Aid);
1013 AddbaReq.TID = pBAEntry->TID;
1014 AddbaReq.BaBufSize =
1015 pAd->CommonCfg.BACapability.field.RxBAWinLimit;
1016 AddbaReq.TimeOutValue = 0;
1017 AddbaReq.Token = pBAEntry->Token;
1018 MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ADD_BA_CATE,
1019 sizeof(struct rt_mlme_addba_req), (void *)& AddbaReq);
1020 RTMP_MLME_HANDLER(pAd);
1021 DBGPRINT(RT_DEBUG_TRACE,
1022 ("BA Ori Session Timeout(%d) : Send ADD BA again\n",
1023 pBAEntry->Token));
1024
1025 pBAEntry->Token++;
1026 RTMPSetTimer(&pBAEntry->ORIBATimer, ORI_BA_SESSION_TIMEOUT);
1027 } else {
1028 BATableFreeOriEntry(pAd, pEntry->BAOriWcidArray[pBAEntry->TID]);
1029 }
1030}
1031
1032/*
1033 ==========================================================================
1034 Description:
1035 Retry sending ADDBA Reqest.
1036
1037 IRQL = DISPATCH_LEVEL
1038
1039 Parametrs:
1040 p8023Header: if this is already 802.3 format, p8023Header is NULL
1041
1042 Return : TRUE if put into rx reordering buffer, shouldn't indicaterxhere.
1043 FALSE , then continue indicaterx at this moment.
1044 ==========================================================================
1045 */
1046void BARecSessionIdleTimeout(void *SystemSpecific1,
1047 void *FunctionContext,
1048 void *SystemSpecific2, void *SystemSpecific3)
1049{
1050
1051 struct rt_ba_rec_entry *pBAEntry = (struct rt_ba_rec_entry *)FunctionContext;
1052 struct rt_rtmp_adapter *pAd;
1053 unsigned long Now32;
1054
1055 if (pBAEntry == NULL)
1056 return;
1057
1058 if ((pBAEntry->REC_BA_Status == Recipient_Accept)) {
1059 NdisGetSystemUpTime(&Now32);
1060
1061 if (RTMP_TIME_AFTER
1062 ((unsigned long)Now32,
1063 (unsigned long)(pBAEntry->LastIndSeqAtTimer +
1064 REC_BA_SESSION_IDLE_TIMEOUT))) {
1065 pAd = pBAEntry->pAdapter;
1066 /* flush all pending reordering mpdus */
1067 ba_refresh_reordering_mpdus(pAd, pBAEntry);
1068 DBGPRINT(RT_DEBUG_OFF,
1069 ("%ld: REC BA session Timeout\n", Now32));
1070 }
1071 }
1072}
1073
1074void PeerAddBAReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
1075{
1076 /* 7.4.4.1 */
1077 /*unsigned long Idx; */
1078 u8 Status = 1;
1079 u8 pAddr[6];
1080 struct rt_frame_addba_rsp ADDframe;
1081 u8 *pOutBuffer = NULL;
1082 int NStatus;
1083 struct rt_frame_addba_req * pAddreqFrame = NULL;
1084 /*u8 BufSize; */
1085 unsigned long FrameLen;
1086 unsigned long *ptemp;
1087 struct rt_mac_table_entry *pMacEntry;
1088
1089 DBGPRINT(RT_DEBUG_TRACE,
1090 ("%s ==> (Wcid = %d)\n", __func__, Elem->Wcid));
1091
1092 /*hex_dump("AddBAReq", Elem->Msg, Elem->MsgLen); */
1093
1094 /*ADDBA Request from unknown peer, ignore this. */
1095 if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
1096 return;
1097
1098 pMacEntry = &pAd->MacTab.Content[Elem->Wcid];
1099 DBGPRINT(RT_DEBUG_TRACE, ("BA - PeerAddBAReqAction----> \n"));
1100 ptemp = (unsigned long *)Elem->Msg;
1101 /*DBGPRINT_RAW(RT_DEBUG_EMU, ("%08x:: %08x:: %08x:: %08x:: %08x:: %08x:: %08x:: %08x:: %08x\n", *(ptemp), *(ptemp+1), *(ptemp+2), *(ptemp+3), *(ptemp+4), *(ptemp+5), *(ptemp+6), *(ptemp+7), *(ptemp+8))); */
1102
1103 if (PeerAddBAReqActionSanity(pAd, Elem->Msg, Elem->MsgLen, pAddr)) {
1104
1105 if ((pAd->CommonCfg.bBADecline == FALSE)
1106 && IS_HT_STA(pMacEntry)) {
1107 pAddreqFrame = (struct rt_frame_addba_req *) (&Elem->Msg[0]);
1108 DBGPRINT(RT_DEBUG_OFF,
1109 ("Rcv Wcid(%d) AddBAReq\n", Elem->Wcid));
1110 if (BARecSessionAdd
1111 (pAd, &pAd->MacTab.Content[Elem->Wcid],
1112 pAddreqFrame))
1113 Status = 0;
1114 else
1115 Status = 38; /* more parameters have invalid values */
1116 } else {
1117 Status = 37; /* the request has been declined. */
1118 }
1119 }
1120
1121 if (pAd->MacTab.Content[Elem->Wcid].ValidAsCLI)
1122 ASSERT(pAd->MacTab.Content[Elem->Wcid].Sst == SST_ASSOC);
1123
1124 pAddreqFrame = (struct rt_frame_addba_req *) (&Elem->Msg[0]);
1125 /* 2. Always send back ADDBA Response */
1126 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */
1127 if (NStatus != NDIS_STATUS_SUCCESS) {
1128 DBGPRINT(RT_DEBUG_TRACE,
1129 ("ACTION - PeerBAAction() allocate memory failed \n"));
1130 return;
1131 }
1132
1133 NdisZeroMemory(&ADDframe, sizeof(struct rt_frame_addba_rsp));
1134
1135 /* 2-1. Prepare ADDBA Response frame. */
1136 {
1137 if (ADHOC_ON(pAd))
1138 ActHeaderInit(pAd, &ADDframe.Hdr, pAddr,
1139 pAd->CurrentAddress,
1140 pAd->CommonCfg.Bssid);
1141 else
1142 ActHeaderInit(pAd, &ADDframe.Hdr, pAd->CommonCfg.Bssid,
1143 pAd->CurrentAddress, pAddr);
1144 }
1145
1146 ADDframe.Category = CATEGORY_BA;
1147 ADDframe.Action = ADDBA_RESP;
1148 ADDframe.Token = pAddreqFrame->Token;
1149 /* What is the Status code?? need to check. */
1150 ADDframe.StatusCode = Status;
1151 ADDframe.BaParm.BAPolicy = IMMED_BA;
1152 ADDframe.BaParm.AMSDUSupported = 0;
1153 ADDframe.BaParm.TID = pAddreqFrame->BaParm.TID;
1154 ADDframe.BaParm.BufSize =
1155 min(((u8)pAddreqFrame->BaParm.BufSize),
1156 (u8)pAd->CommonCfg.BACapability.field.RxBAWinLimit);
1157 if (ADDframe.BaParm.BufSize == 0) {
1158 ADDframe.BaParm.BufSize = 64;
1159 }
1160 ADDframe.TimeOutValue = 0; /*pAddreqFrame->TimeOutValue; */
1161
1162 *(u16 *) (&ADDframe.BaParm) =
1163 cpu2le16(*(u16 *) (&ADDframe.BaParm));
1164 ADDframe.StatusCode = cpu2le16(ADDframe.StatusCode);
1165 ADDframe.TimeOutValue = cpu2le16(ADDframe.TimeOutValue);
1166
1167 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1168 sizeof(struct rt_frame_addba_rsp), &ADDframe, END_OF_ARGS);
1169 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
1170 MlmeFreeMemory(pAd, pOutBuffer);
1171
1172 DBGPRINT(RT_DEBUG_TRACE,
1173 ("%s(%d): TID(%d), BufSize(%d) <== \n", __func__, Elem->Wcid,
1174 ADDframe.BaParm.TID, ADDframe.BaParm.BufSize));
1175}
1176
1177void PeerAddBARspAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
1178{
1179 /*u8 Idx, i; */
1180 /*u8 * pOutBuffer = NULL; */
1181 struct rt_frame_addba_rsp * pFrame = NULL;
1182 /*struct rt_ba_ori_entry *pBAEntry; */
1183
1184 /*ADDBA Response from unknown peer, ignore this. */
1185 if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
1186 return;
1187
1188 DBGPRINT(RT_DEBUG_TRACE, ("%s ==> Wcid(%d)\n", __func__, Elem->Wcid));
1189
1190 /*hex_dump("PeerAddBARspAction()", Elem->Msg, Elem->MsgLen); */
1191
1192 if (PeerAddBARspActionSanity(pAd, Elem->Msg, Elem->MsgLen)) {
1193 pFrame = (struct rt_frame_addba_rsp *) (&Elem->Msg[0]);
1194
1195 DBGPRINT(RT_DEBUG_TRACE,
1196 ("\t\t StatusCode = %d\n", pFrame->StatusCode));
1197 switch (pFrame->StatusCode) {
1198 case 0:
1199 /* I want a BAsession with this peer as an originator. */
1200 BAOriSessionAdd(pAd, &pAd->MacTab.Content[Elem->Wcid],
1201 pFrame);
1202 break;
1203 default:
1204 /* check status == USED ??? */
1205 BAOriSessionTearDown(pAd, Elem->Wcid,
1206 pFrame->BaParm.TID, TRUE, FALSE);
1207 break;
1208 }
1209 /* Rcv Decline StatusCode */
1210 if ((pFrame->StatusCode == 37)
1211 || ((pAd->OpMode == OPMODE_STA) && STA_TGN_WIFI_ON(pAd)
1212 && (pFrame->StatusCode != 0))
1213 ) {
1214 pAd->MacTab.Content[Elem->Wcid].BADeclineBitmap |=
1215 1 << pFrame->BaParm.TID;
1216 }
1217 }
1218}
1219
1220void PeerDelBAAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
1221{
1222 /*u8 Idx; */
1223 /*u8 * pOutBuffer = NULL; */
1224 struct rt_frame_delba_req * pDelFrame = NULL;
1225
1226 DBGPRINT(RT_DEBUG_TRACE, ("%s ==>\n", __func__));
1227 /*DELBA Request from unknown peer, ignore this. */
1228 if (PeerDelBAActionSanity(pAd, Elem->Wcid, Elem->Msg, Elem->MsgLen)) {
1229 pDelFrame = (struct rt_frame_delba_req *) (&Elem->Msg[0]);
1230 if (pDelFrame->DelbaParm.Initiator == ORIGINATOR) {
1231 DBGPRINT(RT_DEBUG_TRACE,
1232 ("BA - PeerDelBAAction----> ORIGINATOR\n"));
1233 BARecSessionTearDown(pAd, Elem->Wcid,
1234 pDelFrame->DelbaParm.TID, TRUE);
1235 } else {
1236 DBGPRINT(RT_DEBUG_TRACE,
1237 ("BA - PeerDelBAAction----> RECIPIENT, Reason = %d\n",
1238 pDelFrame->ReasonCode));
1239 /*hex_dump("DelBA Frame", pDelFrame, Elem->MsgLen); */
1240 BAOriSessionTearDown(pAd, Elem->Wcid,
1241 pDelFrame->DelbaParm.TID, TRUE,
1242 FALSE);
1243 }
1244 }
1245}
1246
1247BOOLEAN CntlEnqueueForRecv(struct rt_rtmp_adapter *pAd,
1248 unsigned long Wcid,
1249 unsigned long MsgLen, struct rt_frame_ba_req * pMsg)
1250{
1251 struct rt_frame_ba_req * pFrame = pMsg;
1252 /*PRTMP_REORDERBUF pBuffer; */
1253 /*PRTMP_REORDERBUF pDmaBuf; */
1254 struct rt_ba_rec_entry *pBAEntry;
1255 /*BOOLEAN Result; */
1256 unsigned long Idx;
1257 /*u8 NumRxPkt; */
1258 u8 TID; /*, i; */
1259
1260 TID = (u8)pFrame->BARControl.TID;
1261
1262 DBGPRINT(RT_DEBUG_TRACE,
1263 ("%s(): BAR-Wcid(%ld), Tid (%d)\n", __func__, Wcid, TID));
1264 /*hex_dump("BAR", (char *)pFrame, MsgLen); */
1265 /* Do nothing if the driver is starting halt state. */
1266 /* This might happen when timer already been fired before cancel timer with mlmehalt */
1267 if (RTMP_TEST_FLAG
1268 (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
1269 return FALSE;
1270
1271 /* First check the size, it MUST not exceed the mlme queue size */
1272 if (MsgLen > MGMT_DMA_BUFFER_SIZE) {
1273 DBGPRINT_ERR("CntlEnqueueForRecv: frame too large, size = %ld \n", MsgLen);
1274 return FALSE;
1275 } else if (MsgLen != sizeof(struct rt_frame_ba_req)) {
1276 DBGPRINT_ERR("CntlEnqueueForRecv: BlockAck Request frame length size = %ld incorrect\n", MsgLen);
1277 return FALSE;
1278 } else if (MsgLen != sizeof(struct rt_frame_ba_req)) {
1279 DBGPRINT_ERR("CntlEnqueueForRecv: BlockAck Request frame length size = %ld incorrect\n", MsgLen);
1280 return FALSE;
1281 }
1282
1283 if ((Wcid < MAX_LEN_OF_MAC_TABLE) && (TID < 8)) {
1284 /* if this receiving packet is from SA that is in our OriEntry. Since WCID <9 has direct mapping. no need search. */
1285 Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID];
1286 pBAEntry = &pAd->BATable.BARecEntry[Idx];
1287 } else {
1288 return FALSE;
1289 }
1290
1291 DBGPRINT(RT_DEBUG_TRACE,
1292 ("BAR(%ld) : Tid (%d) - %04x:%04x\n", Wcid, TID,
1293 pFrame->BAStartingSeq.field.StartSeq, pBAEntry->LastIndSeq));
1294
1295 if (SEQ_SMALLER
1296 (pBAEntry->LastIndSeq, pFrame->BAStartingSeq.field.StartSeq,
1297 MAXSEQ)) {
1298 /*DBGPRINT(RT_DEBUG_TRACE, ("BAR Seq = %x, LastIndSeq = %x\n", pFrame->BAStartingSeq.field.StartSeq, pBAEntry->LastIndSeq)); */
1299 ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry,
1300 pFrame->BAStartingSeq.field.
1301 StartSeq);
1302 pBAEntry->LastIndSeq =
1303 (pFrame->BAStartingSeq.field.StartSeq ==
1304 0) ? MAXSEQ : (pFrame->BAStartingSeq.field.StartSeq - 1);
1305 }
1306 /*ba_refresh_reordering_mpdus(pAd, pBAEntry); */
1307 return TRUE;
1308}
1309
1310/*
1311Description : Send PSMP Action frame If PSMP mode switches.
1312*/
1313void SendPSMPAction(struct rt_rtmp_adapter *pAd, u8 Wcid, u8 Psmp)
1314{
1315 u8 *pOutBuffer = NULL;
1316 int NStatus;
1317 /*unsigned long Idx; */
1318 struct rt_frame_psmp_action Frame;
1319 unsigned long FrameLen;
1320
1321 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */
1322 if (NStatus != NDIS_STATUS_SUCCESS) {
1323 DBGPRINT(RT_DEBUG_ERROR,
1324 ("BA - MlmeADDBAAction() allocate memory failed \n"));
1325 return;
1326 }
1327
1328 ActHeaderInit(pAd, &Frame.Hdr, pAd->CommonCfg.Bssid,
1329 pAd->CurrentAddress, pAd->MacTab.Content[Wcid].Addr);
1330
1331 Frame.Category = CATEGORY_HT;
1332 Frame.Action = SMPS_ACTION;
1333 switch (Psmp) {
1334 case MMPS_ENABLE:
1335#ifdef RT30xx
1336 if (IS_RT30xx(pAd)
1337 && (pAd->Antenna.field.RxPath > 1
1338 || pAd->Antenna.field.TxPath > 1)) {
1339 RTMP_ASIC_MMPS_DISABLE(pAd);
1340 }
1341#endif /* RT30xx // */
1342 Frame.Psmp = 0;
1343 break;
1344 case MMPS_DYNAMIC:
1345 Frame.Psmp = 3;
1346 break;
1347 case MMPS_STATIC:
1348#ifdef RT30xx
1349 if (IS_RT30xx(pAd)
1350 && (pAd->Antenna.field.RxPath > 1
1351 || pAd->Antenna.field.TxPath > 1)) {
1352 RTMP_ASIC_MMPS_ENABLE(pAd);
1353 }
1354#endif /* RT30xx // */
1355 Frame.Psmp = 1;
1356 break;
1357 }
1358 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1359 sizeof(struct rt_frame_psmp_action), &Frame, END_OF_ARGS);
1360 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
1361 MlmeFreeMemory(pAd, pOutBuffer);
1362 DBGPRINT(RT_DEBUG_ERROR, ("HT - SendPSMPAction( %d ) \n", Frame.Psmp));
1363}
1364
1365#define RADIO_MEASUREMENT_REQUEST_ACTION 0
1366
1367struct PACKED rt_beacon_request {
1368 u8 RegulatoryClass;
1369 u8 ChannelNumber;
1370 u16 RandomInterval;
1371 u16 MeasurementDuration;
1372 u8 MeasurementMode;
1373 u8 BSSID[MAC_ADDR_LEN];
1374 u8 ReportingCondition;
1375 u8 Threshold;
1376 u8 SSIDIE[2]; /* 2 byte */
1377};
1378
1379struct PACKED rt_measurement_req {
1380 u8 ID;
1381 u8 Length;
1382 u8 Token;
1383 u8 RequestMode;
1384 u8 Type;
1385};
1386
1387void convert_reordering_packet_to_preAMSDU_or_802_3_packet(struct rt_rtmp_adapter *pAd,
1388 struct rt_rx_blk *pRxBlk,
1389 u8
1390 FromWhichBSSID)
1391{
1392 void *pRxPkt;
1393 u8 Header802_3[LENGTH_802_3];
1394
1395 /* 1. get 802.3 Header */
1396 /* 2. remove LLC */
1397 /* a. pointer pRxBlk->pData to payload */
1398 /* b. modify pRxBlk->DataSize */
1399
1400 RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3);
1401
1402 ASSERT(pRxBlk->pRxPacket);
1403 pRxPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
1404
1405 SET_OS_PKT_NETDEV(pRxPkt, get_netdev_from_bssid(pAd, FromWhichBSSID));
1406 SET_OS_PKT_DATAPTR(pRxPkt, pRxBlk->pData);
1407 SET_OS_PKT_LEN(pRxPkt, pRxBlk->DataSize);
1408 SET_OS_PKT_DATATAIL(pRxPkt, pRxBlk->pData, pRxBlk->DataSize);
1409
1410 /* */
1411 /* copy 802.3 header, if necessary */
1412 /* */
1413 if (!RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU)) {
1414 {
1415#ifdef LINUX
1416 NdisMoveMemory(skb_push(pRxPkt, LENGTH_802_3),
1417 Header802_3, LENGTH_802_3);
1418#endif
1419 }
1420 }
1421}
1422
1423#define INDICATE_LEGACY_OR_AMSDU(_pAd, _pRxBlk, _fromWhichBSSID) \
1424 do \
1425 { \
1426 if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_AMSDU)) \
1427 { \
1428 Indicate_AMSDU_Packet(_pAd, _pRxBlk, _fromWhichBSSID); \
1429 } \
1430 else if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_EAP)) \
1431 { \
1432 Indicate_EAPOL_Packet(_pAd, _pRxBlk, _fromWhichBSSID); \
1433 } \
1434 else \
1435 { \
1436 Indicate_Legacy_Packet(_pAd, _pRxBlk, _fromWhichBSSID); \
1437 } \
1438 } while (0);
1439
1440static void ba_enqueue_reordering_packet(struct rt_rtmp_adapter *pAd,
1441 struct rt_ba_rec_entry *pBAEntry,
1442 struct rt_rx_blk *pRxBlk,
1443 u8 FromWhichBSSID)
1444{
1445 struct reordering_mpdu *mpdu_blk;
1446 u16 Sequence = (u16)pRxBlk->pHeader->Sequence;
1447
1448 mpdu_blk = ba_mpdu_blk_alloc(pAd);
1449 if ((mpdu_blk != NULL) && (!RX_BLK_TEST_FLAG(pRxBlk, fRX_EAP))) {
1450 /* Write RxD buffer address & allocated buffer length */
1451 NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
1452
1453 mpdu_blk->Sequence = Sequence;
1454
1455 mpdu_blk->bAMSDU = RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU);
1456
1457 convert_reordering_packet_to_preAMSDU_or_802_3_packet(pAd,
1458 pRxBlk,
1459 FromWhichBSSID);
1460
1461 STATS_INC_RX_PACKETS(pAd, FromWhichBSSID);
1462
1463 /* */
1464 /* it is necessary for reordering packet to record */
1465 /* which BSS it come from */
1466 /* */
1467 RTMP_SET_PACKET_IF(pRxBlk->pRxPacket, FromWhichBSSID);
1468
1469 mpdu_blk->pPacket = pRxBlk->pRxPacket;
1470
1471 if (ba_reordering_mpdu_insertsorted(&pBAEntry->list, mpdu_blk)
1472 == FALSE) {
1473 /* had been already within reordering list */
1474 /* don't indicate */
1475 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket,
1476 NDIS_STATUS_SUCCESS);
1477 ba_mpdu_blk_free(pAd, mpdu_blk);
1478 }
1479
1480 ASSERT((0 <= pBAEntry->list.qlen)
1481 && (pBAEntry->list.qlen <= pBAEntry->BAWinSize));
1482 NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
1483 } else {
1484 DBGPRINT(RT_DEBUG_ERROR,
1485 (" (%d) Can't allocate reordering mpdu blk\n",
1486 pBAEntry->list.qlen));
1487
1488 /*
1489 * flush all pending reordering mpdus
1490 * and receiving mpdu to upper layer
1491 * make tcp/ip to take care reordering mechanism
1492 */
1493 /*ba_refresh_reordering_mpdus(pAd, pBAEntry); */
1494 ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, Sequence);
1495
1496 pBAEntry->LastIndSeq = Sequence;
1497 INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID);
1498 }
1499}
1500
1501/*
1502 ==========================================================================
1503 Description:
1504 Indicate this packet to upper layer or put it into reordering buffer
1505
1506 Parametrs:
1507 pRxBlk : carry necessary packet info 802.11 format
1508 FromWhichBSSID : the packet received from which BSS
1509
1510 Return :
1511 none
1512
1513 Note :
1514 the packet queued into reordering buffer need to cover to 802.3 format
1515 or pre_AMSDU format
1516 ==========================================================================
1517 */
1518
1519void Indicate_AMPDU_Packet(struct rt_rtmp_adapter *pAd,
1520 struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID)
1521{
1522 u16 Idx;
1523 struct rt_ba_rec_entry *pBAEntry = NULL;
1524 u16 Sequence = pRxBlk->pHeader->Sequence;
1525 unsigned long Now32;
1526 u8 Wcid = pRxBlk->pRxWI->WirelessCliID;
1527 u8 TID = pRxBlk->pRxWI->TID;
1528
1529 if (!RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU)
1530 && (pRxBlk->DataSize > MAX_RX_PKT_LEN)) {
1531 /* release packet */
1532 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket,
1533 NDIS_STATUS_FAILURE);
1534 return;
1535 }
1536
1537 if (Wcid < MAX_LEN_OF_MAC_TABLE) {
1538 Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID];
1539 if (Idx == 0) {
1540 /* Rec BA Session had been torn down */
1541 INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID);
1542 return;
1543 }
1544 pBAEntry = &pAd->BATable.BARecEntry[Idx];
1545 } else {
1546 /* impossible ! */
1547 ASSERT(0);
1548 /* release packet */
1549 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket,
1550 NDIS_STATUS_FAILURE);
1551 return;
1552 }
1553
1554 ASSERT(pBAEntry);
1555
1556 /* update last rx time */
1557 NdisGetSystemUpTime(&Now32);
1558
1559 pBAEntry->rcvSeq = Sequence;
1560
1561 ba_flush_reordering_timeout_mpdus(pAd, pBAEntry, Now32);
1562 pBAEntry->LastIndSeqAtTimer = Now32;
1563
1564 /* */
1565 /* Reset Last Indicate Sequence */
1566 /* */
1567 if (pBAEntry->LastIndSeq == RESET_RCV_SEQ) {
1568 ASSERT((pBAEntry->list.qlen == 0)
1569 && (pBAEntry->list.next == NULL));
1570
1571 /* reset rcv sequence of BA session */
1572 pBAEntry->LastIndSeq = Sequence;
1573 pBAEntry->LastIndSeqAtTimer = Now32;
1574 INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID);
1575 return;
1576 }
1577
1578 /* */
1579 /* I. Check if in order. */
1580 /* */
1581 if (SEQ_STEPONE(Sequence, pBAEntry->LastIndSeq, MAXSEQ)) {
1582 u16 LastIndSeq;
1583
1584 pBAEntry->LastIndSeq = Sequence;
1585 INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID);
1586 LastIndSeq =
1587 ba_indicate_reordering_mpdus_in_order(pAd, pBAEntry,
1588 pBAEntry->LastIndSeq);
1589 if (LastIndSeq != RESET_RCV_SEQ) {
1590 pBAEntry->LastIndSeq = LastIndSeq;
1591 }
1592 pBAEntry->LastIndSeqAtTimer = Now32;
1593 }
1594 /* */
1595 /* II. Drop Duplicated Packet */
1596 /* */
1597 else if (Sequence == pBAEntry->LastIndSeq) {
1598
1599 /* drop and release packet */
1600 pBAEntry->nDropPacket++;
1601 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket,
1602 NDIS_STATUS_FAILURE);
1603 }
1604 /* */
1605 /* III. Drop Old Received Packet */
1606 /* */
1607 else if (SEQ_SMALLER(Sequence, pBAEntry->LastIndSeq, MAXSEQ)) {
1608
1609 /* drop and release packet */
1610 pBAEntry->nDropPacket++;
1611 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket,
1612 NDIS_STATUS_FAILURE);
1613 }
1614 /* */
1615 /* IV. Receive Sequence within Window Size */
1616 /* */
1617 else if (SEQ_SMALLER
1618 (Sequence,
1619 (((pBAEntry->LastIndSeq + pBAEntry->BAWinSize + 1)) & MAXSEQ),
1620 MAXSEQ)) {
1621 ba_enqueue_reordering_packet(pAd, pBAEntry, pRxBlk,
1622 FromWhichBSSID);
1623 }
1624 /* */
1625 /* V. Receive seq surpasses Win(lastseq + nMSDU). So refresh all reorder buffer */
1626 /* */
1627 else {
1628 long WinStartSeq, TmpSeq;
1629
1630 TmpSeq = Sequence - (pBAEntry->BAWinSize) - 1;
1631 if (TmpSeq < 0) {
1632 TmpSeq = (MAXSEQ + 1) + TmpSeq;
1633 }
1634 WinStartSeq = (TmpSeq + 1) & MAXSEQ;
1635 ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, WinStartSeq);
1636 pBAEntry->LastIndSeq = WinStartSeq; /*TmpSeq; */
1637
1638 pBAEntry->LastIndSeqAtTimer = Now32;
1639
1640 ba_enqueue_reordering_packet(pAd, pBAEntry, pRxBlk,
1641 FromWhichBSSID);
1642
1643 TmpSeq =
1644 ba_indicate_reordering_mpdus_in_order(pAd, pBAEntry,
1645 pBAEntry->LastIndSeq);
1646 if (TmpSeq != RESET_RCV_SEQ) {
1647 pBAEntry->LastIndSeq = TmpSeq;
1648 }
1649 }
1650}
diff --git a/drivers/staging/rt2860/common/cmm_aes.c b/drivers/staging/rt2860/common/cmm_aes.c
deleted file mode 100644
index d70d229a6e5..00000000000
--- a/drivers/staging/rt2860/common/cmm_aes.c
+++ /dev/null
@@ -1,1311 +0,0 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 cmm_aes.c
29
30 Abstract:
31
32 Revision History:
33 Who When What
34 -------- ---------- ----------------------------------------------
35 Paul Wu 02-25-02 Initial
36*/
37
38#include "../rt_config.h"
39
40struct aes_context {
41 u32 erk[64]; /* encryption round keys */
42 u32 drk[64]; /* decryption round keys */
43 int nr; /* number of rounds */
44};
45
46/*****************************/
47/******** SBOX Table *********/
48/*****************************/
49
50u8 SboxTable[256] = {
51 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
52 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
53 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
54 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
55 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
56 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
57 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
58 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
59 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
60 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
61 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
62 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
63 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
64 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
65 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
66 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
67 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
68 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
69 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
70 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
71 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
72 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
73 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
74 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
75 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
76 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
77 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
78 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
79 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
80 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
81 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
82 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
83};
84
85void xor_32(u8 *a, u8 *b, u8 *out)
86{
87 int i;
88
89 for (i = 0; i < 4; i++) {
90 out[i] = a[i] ^ b[i];
91 }
92}
93
94void xor_128(u8 *a, u8 *b, u8 *out)
95{
96 int i;
97
98 for (i = 0; i < 16; i++) {
99 out[i] = a[i] ^ b[i];
100 }
101}
102
103u8 RTMPCkipSbox(u8 a)
104{
105 return SboxTable[(int)a];
106}
107
108void next_key(u8 *key, int round)
109{
110 u8 rcon;
111 u8 sbox_key[4];
112 u8 rcon_table[12] = {
113 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
114 0x1b, 0x36, 0x36, 0x36
115 };
116
117 sbox_key[0] = RTMPCkipSbox(key[13]);
118 sbox_key[1] = RTMPCkipSbox(key[14]);
119 sbox_key[2] = RTMPCkipSbox(key[15]);
120 sbox_key[3] = RTMPCkipSbox(key[12]);
121
122 rcon = rcon_table[round];
123
124 xor_32(&key[0], sbox_key, &key[0]);
125 key[0] = key[0] ^ rcon;
126
127 xor_32(&key[4], &key[0], &key[4]);
128 xor_32(&key[8], &key[4], &key[8]);
129 xor_32(&key[12], &key[8], &key[12]);
130}
131
132void byte_sub(u8 *in, u8 *out)
133{
134 int i;
135
136 for (i = 0; i < 16; i++) {
137 out[i] = RTMPCkipSbox(in[i]);
138 }
139}
140
141/************************************/
142/* bitwise_xor() */
143/* A 128 bit, bitwise exclusive or */
144/************************************/
145
146void bitwise_xor(unsigned char *ina, unsigned char *inb, unsigned char *out)
147{
148 int i;
149 for (i = 0; i < 16; i++) {
150 out[i] = ina[i] ^ inb[i];
151 }
152}
153
154void shift_row(u8 *in, u8 *out)
155{
156 out[0] = in[0];
157 out[1] = in[5];
158 out[2] = in[10];
159 out[3] = in[15];
160 out[4] = in[4];
161 out[5] = in[9];
162 out[6] = in[14];
163 out[7] = in[3];
164 out[8] = in[8];
165 out[9] = in[13];
166 out[10] = in[2];
167 out[11] = in[7];
168 out[12] = in[12];
169 out[13] = in[1];
170 out[14] = in[6];
171 out[15] = in[11];
172}
173
174void mix_column(u8 *in, u8 *out)
175{
176 int i;
177 u8 add1b[4];
178 u8 add1bf7[4];
179 u8 rotl[4];
180 u8 swap_halfs[4];
181 u8 andf7[4];
182 u8 rotr[4];
183 u8 temp[4];
184 u8 tempb[4];
185
186 for (i = 0; i < 4; i++) {
187 if ((in[i] & 0x80) == 0x80)
188 add1b[i] = 0x1b;
189 else
190 add1b[i] = 0x00;
191 }
192
193 swap_halfs[0] = in[2]; /* Swap halfs */
194 swap_halfs[1] = in[3];
195 swap_halfs[2] = in[0];
196 swap_halfs[3] = in[1];
197
198 rotl[0] = in[3]; /* Rotate left 8 bits */
199 rotl[1] = in[0];
200 rotl[2] = in[1];
201 rotl[3] = in[2];
202
203 andf7[0] = in[0] & 0x7f;
204 andf7[1] = in[1] & 0x7f;
205 andf7[2] = in[2] & 0x7f;
206 andf7[3] = in[3] & 0x7f;
207
208 for (i = 3; i > 0; i--) { /* logical shift left 1 bit */
209 andf7[i] = andf7[i] << 1;
210 if ((andf7[i - 1] & 0x80) == 0x80) {
211 andf7[i] = (andf7[i] | 0x01);
212 }
213 }
214 andf7[0] = andf7[0] << 1;
215 andf7[0] = andf7[0] & 0xfe;
216
217 xor_32(add1b, andf7, add1bf7);
218
219 xor_32(in, add1bf7, rotr);
220
221 temp[0] = rotr[0]; /* Rotate right 8 bits */
222 rotr[0] = rotr[1];
223 rotr[1] = rotr[2];
224 rotr[2] = rotr[3];
225 rotr[3] = temp[0];
226
227 xor_32(add1bf7, rotr, temp);
228 xor_32(swap_halfs, rotl, tempb);
229 xor_32(temp, tempb, out);
230}
231
232/************************************************/
233/* construct_mic_header1() */
234/* Builds the first MIC header block from */
235/* header fields. */
236/************************************************/
237
238void construct_mic_header1(unsigned char *mic_header1,
239 int header_length, unsigned char *mpdu)
240{
241 mic_header1[0] = (unsigned char)((header_length - 2) / 256);
242 mic_header1[1] = (unsigned char)((header_length - 2) % 256);
243 mic_header1[2] = mpdu[0] & 0xcf; /* Mute CF poll & CF ack bits */
244 mic_header1[3] = mpdu[1] & 0xc7; /* Mute retry, more data and pwr mgt bits */
245 mic_header1[4] = mpdu[4]; /* A1 */
246 mic_header1[5] = mpdu[5];
247 mic_header1[6] = mpdu[6];
248 mic_header1[7] = mpdu[7];
249 mic_header1[8] = mpdu[8];
250 mic_header1[9] = mpdu[9];
251 mic_header1[10] = mpdu[10]; /* A2 */
252 mic_header1[11] = mpdu[11];
253 mic_header1[12] = mpdu[12];
254 mic_header1[13] = mpdu[13];
255 mic_header1[14] = mpdu[14];
256 mic_header1[15] = mpdu[15];
257}
258
259/************************************************/
260/* construct_mic_header2() */
261/* Builds the last MIC header block from */
262/* header fields. */
263/************************************************/
264
265void construct_mic_header2(unsigned char *mic_header2,
266 unsigned char *mpdu, int a4_exists, int qc_exists)
267{
268 int i;
269
270 for (i = 0; i < 16; i++)
271 mic_header2[i] = 0x00;
272
273 mic_header2[0] = mpdu[16]; /* A3 */
274 mic_header2[1] = mpdu[17];
275 mic_header2[2] = mpdu[18];
276 mic_header2[3] = mpdu[19];
277 mic_header2[4] = mpdu[20];
278 mic_header2[5] = mpdu[21];
279
280 /* In Sequence Control field, mute sequence numer bits (12-bit) */
281 mic_header2[6] = mpdu[22] & 0x0f; /* SC */
282 mic_header2[7] = 0x00; /* mpdu[23]; */
283
284 if ((!qc_exists) && a4_exists) {
285 for (i = 0; i < 6; i++)
286 mic_header2[8 + i] = mpdu[24 + i]; /* A4 */
287
288 }
289
290 if (qc_exists && (!a4_exists)) {
291 mic_header2[8] = mpdu[24] & 0x0f; /* mute bits 15 - 4 */
292 mic_header2[9] = mpdu[25] & 0x00;
293 }
294
295 if (qc_exists && a4_exists) {
296 for (i = 0; i < 6; i++)
297 mic_header2[8 + i] = mpdu[24 + i]; /* A4 */
298
299 mic_header2[14] = mpdu[30] & 0x0f;
300 mic_header2[15] = mpdu[31] & 0x00;
301 }
302}
303
304/************************************************/
305/* construct_mic_iv() */
306/* Builds the MIC IV from header fields and PN */
307/************************************************/
308
309void construct_mic_iv(unsigned char *mic_iv,
310 int qc_exists,
311 int a4_exists,
312 unsigned char *mpdu,
313 unsigned int payload_length, unsigned char *pn_vector)
314{
315 int i;
316
317 mic_iv[0] = 0x59;
318 if (qc_exists && a4_exists)
319 mic_iv[1] = mpdu[30] & 0x0f; /* QoS_TC */
320 if (qc_exists && !a4_exists)
321 mic_iv[1] = mpdu[24] & 0x0f; /* mute bits 7-4 */
322 if (!qc_exists)
323 mic_iv[1] = 0x00;
324 for (i = 2; i < 8; i++)
325 mic_iv[i] = mpdu[i + 8]; /* mic_iv[2:7] = A2[0:5] = mpdu[10:15] */
326#ifdef CONSISTENT_PN_ORDER
327 for (i = 8; i < 14; i++)
328 mic_iv[i] = pn_vector[i - 8]; /* mic_iv[8:13] = PN[0:5] */
329#else
330 for (i = 8; i < 14; i++)
331 mic_iv[i] = pn_vector[13 - i]; /* mic_iv[8:13] = PN[5:0] */
332#endif
333 mic_iv[14] = (unsigned char)(payload_length / 256);
334 mic_iv[15] = (unsigned char)(payload_length % 256);
335
336}
337
338/****************************************/
339/* aes128k128d() */
340/* Performs a 128 bit AES encrypt with */
341/* 128 bit data. */
342/****************************************/
343void aes128k128d(unsigned char *key, unsigned char *data,
344 unsigned char *ciphertext)
345{
346 int round;
347 int i;
348 unsigned char intermediatea[16];
349 unsigned char intermediateb[16];
350 unsigned char round_key[16];
351
352 for (i = 0; i < 16; i++)
353 round_key[i] = key[i];
354
355 for (round = 0; round < 11; round++) {
356 if (round == 0) {
357 xor_128(round_key, data, ciphertext);
358 next_key(round_key, round);
359 } else if (round == 10) {
360 byte_sub(ciphertext, intermediatea);
361 shift_row(intermediatea, intermediateb);
362 xor_128(intermediateb, round_key, ciphertext);
363 } else { /* 1 - 9 */
364
365 byte_sub(ciphertext, intermediatea);
366 shift_row(intermediatea, intermediateb);
367 mix_column(&intermediateb[0], &intermediatea[0]);
368 mix_column(&intermediateb[4], &intermediatea[4]);
369 mix_column(&intermediateb[8], &intermediatea[8]);
370 mix_column(&intermediateb[12], &intermediatea[12]);
371 xor_128(intermediatea, round_key, ciphertext);
372 next_key(round_key, round);
373 }
374 }
375
376}
377
378void construct_ctr_preload(unsigned char *ctr_preload,
379 int a4_exists,
380 int qc_exists,
381 unsigned char *mpdu, unsigned char *pn_vector, int c)
382{
383
384 int i = 0;
385 for (i = 0; i < 16; i++)
386 ctr_preload[i] = 0x00;
387 i = 0;
388
389 ctr_preload[0] = 0x01; /* flag */
390 if (qc_exists && a4_exists)
391 ctr_preload[1] = mpdu[30] & 0x0f; /* QoC_Control */
392 if (qc_exists && !a4_exists)
393 ctr_preload[1] = mpdu[24] & 0x0f;
394
395 for (i = 2; i < 8; i++)
396 ctr_preload[i] = mpdu[i + 8]; /* ctr_preload[2:7] = A2[0:5] = mpdu[10:15] */
397#ifdef CONSISTENT_PN_ORDER
398 for (i = 8; i < 14; i++)
399 ctr_preload[i] = pn_vector[i - 8]; /* ctr_preload[8:13] = PN[0:5] */
400#else
401 for (i = 8; i < 14; i++)
402 ctr_preload[i] = pn_vector[13 - i]; /* ctr_preload[8:13] = PN[5:0] */
403#endif
404 ctr_preload[14] = (unsigned char)(c / 256); /* Ctr */
405 ctr_preload[15] = (unsigned char)(c % 256);
406
407}
408
409BOOLEAN RTMPSoftDecryptAES(struct rt_rtmp_adapter *pAd,
410 u8 *pData,
411 unsigned long DataByteCnt, struct rt_cipher_key *pWpaKey)
412{
413 u8 KeyID;
414 u32 HeaderLen;
415 u8 PN[6];
416 u32 payload_len;
417 u32 num_blocks;
418 u32 payload_remainder;
419 u16 fc;
420 u8 fc0;
421 u8 fc1;
422 u32 frame_type;
423 u32 frame_subtype;
424 u32 from_ds;
425 u32 to_ds;
426 int a4_exists;
427 int qc_exists;
428 u8 aes_out[16];
429 int payload_index;
430 u32 i;
431 u8 ctr_preload[16];
432 u8 chain_buffer[16];
433 u8 padded_buffer[16];
434 u8 mic_iv[16];
435 u8 mic_header1[16];
436 u8 mic_header2[16];
437 u8 MIC[8];
438 u8 TrailMIC[8];
439
440 fc0 = *pData;
441 fc1 = *(pData + 1);
442
443 fc = *((u16 *)pData);
444
445 frame_type = ((fc0 >> 2) & 0x03);
446 frame_subtype = ((fc0 >> 4) & 0x0f);
447
448 from_ds = (fc1 & 0x2) >> 1;
449 to_ds = (fc1 & 0x1);
450
451 a4_exists = (from_ds & to_ds);
452 qc_exists = ((frame_subtype == 0x08) || /* Assumed QoS subtypes */
453 (frame_subtype == 0x09) || /* Likely to change. */
454 (frame_subtype == 0x0a) || (frame_subtype == 0x0b)
455 );
456
457 HeaderLen = 24;
458 if (a4_exists)
459 HeaderLen += 6;
460
461 KeyID = *((u8 *)(pData + HeaderLen + 3));
462 KeyID = KeyID >> 6;
463
464 if (pWpaKey[KeyID].KeyLen == 0) {
465 DBGPRINT(RT_DEBUG_TRACE,
466 ("RTMPSoftDecryptAES failed!(KeyID[%d] Length can not be 0)\n",
467 KeyID));
468 return FALSE;
469 }
470
471 PN[0] = *(pData + HeaderLen);
472 PN[1] = *(pData + HeaderLen + 1);
473 PN[2] = *(pData + HeaderLen + 4);
474 PN[3] = *(pData + HeaderLen + 5);
475 PN[4] = *(pData + HeaderLen + 6);
476 PN[5] = *(pData + HeaderLen + 7);
477
478 payload_len = DataByteCnt - HeaderLen - 8 - 8; /* 8 bytes for CCMP header , 8 bytes for MIC */
479 payload_remainder = (payload_len) % 16;
480 num_blocks = (payload_len) / 16;
481
482 /* Find start of payload */
483 payload_index = HeaderLen + 8; /*IV+EIV */
484
485 for (i = 0; i < num_blocks; i++) {
486 construct_ctr_preload(ctr_preload,
487 a4_exists, qc_exists, pData, PN, i + 1);
488
489 aes128k128d(pWpaKey[KeyID].Key, ctr_preload, aes_out);
490
491 bitwise_xor(aes_out, pData + payload_index, chain_buffer);
492 NdisMoveMemory(pData + payload_index - 8, chain_buffer, 16);
493 payload_index += 16;
494 }
495
496 /* */
497 /* If there is a short final block, then pad it */
498 /* encrypt it and copy the unpadded part back */
499 /* */
500 if (payload_remainder > 0) {
501 construct_ctr_preload(ctr_preload,
502 a4_exists,
503 qc_exists, pData, PN, num_blocks + 1);
504
505 NdisZeroMemory(padded_buffer, 16);
506 NdisMoveMemory(padded_buffer, pData + payload_index,
507 payload_remainder);
508
509 aes128k128d(pWpaKey[KeyID].Key, ctr_preload, aes_out);
510
511 bitwise_xor(aes_out, padded_buffer, chain_buffer);
512 NdisMoveMemory(pData + payload_index - 8, chain_buffer,
513 payload_remainder);
514 payload_index += payload_remainder;
515 }
516 /* */
517 /* Descrypt the MIC */
518 /* */
519 construct_ctr_preload(ctr_preload, a4_exists, qc_exists, pData, PN, 0);
520 NdisZeroMemory(padded_buffer, 16);
521 NdisMoveMemory(padded_buffer, pData + payload_index, 8);
522
523 aes128k128d(pWpaKey[KeyID].Key, ctr_preload, aes_out);
524
525 bitwise_xor(aes_out, padded_buffer, chain_buffer);
526
527 NdisMoveMemory(TrailMIC, chain_buffer, 8);
528
529 /* */
530 /* Calculate MIC */
531 /* */
532
533 /*Force the protected frame bit on */
534 *(pData + 1) = *(pData + 1) | 0x40;
535
536 /* Find start of payload */
537 /* Because the CCMP header has been removed */
538 payload_index = HeaderLen;
539
540 construct_mic_iv(mic_iv, qc_exists, a4_exists, pData, payload_len, PN);
541
542 construct_mic_header1(mic_header1, HeaderLen, pData);
543
544 construct_mic_header2(mic_header2, pData, a4_exists, qc_exists);
545
546 aes128k128d(pWpaKey[KeyID].Key, mic_iv, aes_out);
547 bitwise_xor(aes_out, mic_header1, chain_buffer);
548 aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
549 bitwise_xor(aes_out, mic_header2, chain_buffer);
550 aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
551
552 /* iterate through each 16 byte payload block */
553 for (i = 0; i < num_blocks; i++) {
554 bitwise_xor(aes_out, pData + payload_index, chain_buffer);
555 payload_index += 16;
556 aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
557 }
558
559 /* Add on the final payload block if it needs padding */
560 if (payload_remainder > 0) {
561 NdisZeroMemory(padded_buffer, 16);
562 NdisMoveMemory(padded_buffer, pData + payload_index,
563 payload_remainder);
564
565 bitwise_xor(aes_out, padded_buffer, chain_buffer);
566 aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
567 }
568 /* aes_out contains padded mic, discard most significant */
569 /* 8 bytes to generate 64 bit MIC */
570 for (i = 0; i < 8; i++)
571 MIC[i] = aes_out[i];
572
573 if (!NdisEqualMemory(MIC, TrailMIC, 8)) {
574 DBGPRINT(RT_DEBUG_ERROR, ("RTMPSoftDecryptAES, MIC Error !\n")); /*MIC error. */
575 return FALSE;
576 }
577
578 return TRUE;
579}
580
581/* ========================= AES En/Decryption ========================== */
582#ifndef uint8
583#define uint8 unsigned char
584#endif
585
586#ifndef uint32
587#define uint32 unsigned int
588#endif
589
590/* forward S-box */
591static uint32 FSb[256] = {
592 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
593 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
594 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
595 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
596 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
597 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
598 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
599 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
600 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
601 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
602 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
603 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
604 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
605 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
606 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
607 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
608 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
609 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
610 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
611 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
612 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
613 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
614 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
615 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
616 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
617 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
618 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
619 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
620 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
621 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
622 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
623 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
624};
625
626/* forward table */
627#define FT \
628\
629 V(C6,63,63,A5), V(F8,7C,7C,84), V(EE,77,77,99), V(F6,7B,7B,8D), \
630 V(FF,F2,F2,0D), V(D6,6B,6B,BD), V(DE,6F,6F,B1), V(91,C5,C5,54), \
631 V(60,30,30,50), V(02,01,01,03), V(CE,67,67,A9), V(56,2B,2B,7D), \
632 V(E7,FE,FE,19), V(B5,D7,D7,62), V(4D,AB,AB,E6), V(EC,76,76,9A), \
633 V(8F,CA,CA,45), V(1F,82,82,9D), V(89,C9,C9,40), V(FA,7D,7D,87), \
634 V(EF,FA,FA,15), V(B2,59,59,EB), V(8E,47,47,C9), V(FB,F0,F0,0B), \
635 V(41,AD,AD,EC), V(B3,D4,D4,67), V(5F,A2,A2,FD), V(45,AF,AF,EA), \
636 V(23,9C,9C,BF), V(53,A4,A4,F7), V(E4,72,72,96), V(9B,C0,C0,5B), \
637 V(75,B7,B7,C2), V(E1,FD,FD,1C), V(3D,93,93,AE), V(4C,26,26,6A), \
638 V(6C,36,36,5A), V(7E,3F,3F,41), V(F5,F7,F7,02), V(83,CC,CC,4F), \
639 V(68,34,34,5C), V(51,A5,A5,F4), V(D1,E5,E5,34), V(F9,F1,F1,08), \
640 V(E2,71,71,93), V(AB,D8,D8,73), V(62,31,31,53), V(2A,15,15,3F), \
641 V(08,04,04,0C), V(95,C7,C7,52), V(46,23,23,65), V(9D,C3,C3,5E), \
642 V(30,18,18,28), V(37,96,96,A1), V(0A,05,05,0F), V(2F,9A,9A,B5), \
643 V(0E,07,07,09), V(24,12,12,36), V(1B,80,80,9B), V(DF,E2,E2,3D), \
644 V(CD,EB,EB,26), V(4E,27,27,69), V(7F,B2,B2,CD), V(EA,75,75,9F), \
645 V(12,09,09,1B), V(1D,83,83,9E), V(58,2C,2C,74), V(34,1A,1A,2E), \
646 V(36,1B,1B,2D), V(DC,6E,6E,B2), V(B4,5A,5A,EE), V(5B,A0,A0,FB), \
647 V(A4,52,52,F6), V(76,3B,3B,4D), V(B7,D6,D6,61), V(7D,B3,B3,CE), \
648 V(52,29,29,7B), V(DD,E3,E3,3E), V(5E,2F,2F,71), V(13,84,84,97), \
649 V(A6,53,53,F5), V(B9,D1,D1,68), V(00,00,00,00), V(C1,ED,ED,2C), \
650 V(40,20,20,60), V(E3,FC,FC,1F), V(79,B1,B1,C8), V(B6,5B,5B,ED), \
651 V(D4,6A,6A,BE), V(8D,CB,CB,46), V(67,BE,BE,D9), V(72,39,39,4B), \
652 V(94,4A,4A,DE), V(98,4C,4C,D4), V(B0,58,58,E8), V(85,CF,CF,4A), \
653 V(BB,D0,D0,6B), V(C5,EF,EF,2A), V(4F,AA,AA,E5), V(ED,FB,FB,16), \
654 V(86,43,43,C5), V(9A,4D,4D,D7), V(66,33,33,55), V(11,85,85,94), \
655 V(8A,45,45,CF), V(E9,F9,F9,10), V(04,02,02,06), V(FE,7F,7F,81), \
656 V(A0,50,50,F0), V(78,3C,3C,44), V(25,9F,9F,BA), V(4B,A8,A8,E3), \
657 V(A2,51,51,F3), V(5D,A3,A3,FE), V(80,40,40,C0), V(05,8F,8F,8A), \
658 V(3F,92,92,AD), V(21,9D,9D,BC), V(70,38,38,48), V(F1,F5,F5,04), \
659 V(63,BC,BC,DF), V(77,B6,B6,C1), V(AF,DA,DA,75), V(42,21,21,63), \
660 V(20,10,10,30), V(E5,FF,FF,1A), V(FD,F3,F3,0E), V(BF,D2,D2,6D), \
661 V(81,CD,CD,4C), V(18,0C,0C,14), V(26,13,13,35), V(C3,EC,EC,2F), \
662 V(BE,5F,5F,E1), V(35,97,97,A2), V(88,44,44,CC), V(2E,17,17,39), \
663 V(93,C4,C4,57), V(55,A7,A7,F2), V(FC,7E,7E,82), V(7A,3D,3D,47), \
664 V(C8,64,64,AC), V(BA,5D,5D,E7), V(32,19,19,2B), V(E6,73,73,95), \
665 V(C0,60,60,A0), V(19,81,81,98), V(9E,4F,4F,D1), V(A3,DC,DC,7F), \
666 V(44,22,22,66), V(54,2A,2A,7E), V(3B,90,90,AB), V(0B,88,88,83), \
667 V(8C,46,46,CA), V(C7,EE,EE,29), V(6B,B8,B8,D3), V(28,14,14,3C), \
668 V(A7,DE,DE,79), V(BC,5E,5E,E2), V(16,0B,0B,1D), V(AD,DB,DB,76), \
669 V(DB,E0,E0,3B), V(64,32,32,56), V(74,3A,3A,4E), V(14,0A,0A,1E), \
670 V(92,49,49,DB), V(0C,06,06,0A), V(48,24,24,6C), V(B8,5C,5C,E4), \
671 V(9F,C2,C2,5D), V(BD,D3,D3,6E), V(43,AC,AC,EF), V(C4,62,62,A6), \
672 V(39,91,91,A8), V(31,95,95,A4), V(D3,E4,E4,37), V(F2,79,79,8B), \
673 V(D5,E7,E7,32), V(8B,C8,C8,43), V(6E,37,37,59), V(DA,6D,6D,B7), \
674 V(01,8D,8D,8C), V(B1,D5,D5,64), V(9C,4E,4E,D2), V(49,A9,A9,E0), \
675 V(D8,6C,6C,B4), V(AC,56,56,FA), V(F3,F4,F4,07), V(CF,EA,EA,25), \
676 V(CA,65,65,AF), V(F4,7A,7A,8E), V(47,AE,AE,E9), V(10,08,08,18), \
677 V(6F,BA,BA,D5), V(F0,78,78,88), V(4A,25,25,6F), V(5C,2E,2E,72), \
678 V(38,1C,1C,24), V(57,A6,A6,F1), V(73,B4,B4,C7), V(97,C6,C6,51), \
679 V(CB,E8,E8,23), V(A1,DD,DD,7C), V(E8,74,74,9C), V(3E,1F,1F,21), \
680 V(96,4B,4B,DD), V(61,BD,BD,DC), V(0D,8B,8B,86), V(0F,8A,8A,85), \
681 V(E0,70,70,90), V(7C,3E,3E,42), V(71,B5,B5,C4), V(CC,66,66,AA), \
682 V(90,48,48,D8), V(06,03,03,05), V(F7,F6,F6,01), V(1C,0E,0E,12), \
683 V(C2,61,61,A3), V(6A,35,35,5F), V(AE,57,57,F9), V(69,B9,B9,D0), \
684 V(17,86,86,91), V(99,C1,C1,58), V(3A,1D,1D,27), V(27,9E,9E,B9), \
685 V(D9,E1,E1,38), V(EB,F8,F8,13), V(2B,98,98,B3), V(22,11,11,33), \
686 V(D2,69,69,BB), V(A9,D9,D9,70), V(07,8E,8E,89), V(33,94,94,A7), \
687 V(2D,9B,9B,B6), V(3C,1E,1E,22), V(15,87,87,92), V(C9,E9,E9,20), \
688 V(87,CE,CE,49), V(AA,55,55,FF), V(50,28,28,78), V(A5,DF,DF,7A), \
689 V(03,8C,8C,8F), V(59,A1,A1,F8), V(09,89,89,80), V(1A,0D,0D,17), \
690 V(65,BF,BF,DA), V(D7,E6,E6,31), V(84,42,42,C6), V(D0,68,68,B8), \
691 V(82,41,41,C3), V(29,99,99,B0), V(5A,2D,2D,77), V(1E,0F,0F,11), \
692 V(7B,B0,B0,CB), V(A8,54,54,FC), V(6D,BB,BB,D6), V(2C,16,16,3A)
693
694#define V(a,b,c,d) 0x##a##b##c##d
695static uint32 FT0[256] = { FT };
696
697#undef V
698
699#define V(a,b,c,d) 0x##d##a##b##c
700static uint32 FT1[256] = { FT };
701
702#undef V
703
704#define V(a,b,c,d) 0x##c##d##a##b
705static uint32 FT2[256] = { FT };
706
707#undef V
708
709#define V(a,b,c,d) 0x##b##c##d##a
710static uint32 FT3[256] = { FT };
711
712#undef V
713
714#undef FT
715
716/* reverse S-box */
717
718static uint32 RSb[256] = {
719 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
720 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
721 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
722 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
723 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
724 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
725 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
726 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
727 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
728 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
729 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
730 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
731 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
732 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
733 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
734 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
735 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
736 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
737 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
738 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
739 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
740 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
741 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
742 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
743 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
744 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
745 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
746 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
747 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
748 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
749 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
750 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
751};
752
753/* reverse table */
754
755#define RT \
756\
757 V(51,F4,A7,50), V(7E,41,65,53), V(1A,17,A4,C3), V(3A,27,5E,96), \
758 V(3B,AB,6B,CB), V(1F,9D,45,F1), V(AC,FA,58,AB), V(4B,E3,03,93), \
759 V(20,30,FA,55), V(AD,76,6D,F6), V(88,CC,76,91), V(F5,02,4C,25), \
760 V(4F,E5,D7,FC), V(C5,2A,CB,D7), V(26,35,44,80), V(B5,62,A3,8F), \
761 V(DE,B1,5A,49), V(25,BA,1B,67), V(45,EA,0E,98), V(5D,FE,C0,E1), \
762 V(C3,2F,75,02), V(81,4C,F0,12), V(8D,46,97,A3), V(6B,D3,F9,C6), \
763 V(03,8F,5F,E7), V(15,92,9C,95), V(BF,6D,7A,EB), V(95,52,59,DA), \
764 V(D4,BE,83,2D), V(58,74,21,D3), V(49,E0,69,29), V(8E,C9,C8,44), \
765 V(75,C2,89,6A), V(F4,8E,79,78), V(99,58,3E,6B), V(27,B9,71,DD), \
766 V(BE,E1,4F,B6), V(F0,88,AD,17), V(C9,20,AC,66), V(7D,CE,3A,B4), \
767 V(63,DF,4A,18), V(E5,1A,31,82), V(97,51,33,60), V(62,53,7F,45), \
768 V(B1,64,77,E0), V(BB,6B,AE,84), V(FE,81,A0,1C), V(F9,08,2B,94), \
769 V(70,48,68,58), V(8F,45,FD,19), V(94,DE,6C,87), V(52,7B,F8,B7), \
770 V(AB,73,D3,23), V(72,4B,02,E2), V(E3,1F,8F,57), V(66,55,AB,2A), \
771 V(B2,EB,28,07), V(2F,B5,C2,03), V(86,C5,7B,9A), V(D3,37,08,A5), \
772 V(30,28,87,F2), V(23,BF,A5,B2), V(02,03,6A,BA), V(ED,16,82,5C), \
773 V(8A,CF,1C,2B), V(A7,79,B4,92), V(F3,07,F2,F0), V(4E,69,E2,A1), \
774 V(65,DA,F4,CD), V(06,05,BE,D5), V(D1,34,62,1F), V(C4,A6,FE,8A), \
775 V(34,2E,53,9D), V(A2,F3,55,A0), V(05,8A,E1,32), V(A4,F6,EB,75), \
776 V(0B,83,EC,39), V(40,60,EF,AA), V(5E,71,9F,06), V(BD,6E,10,51), \
777 V(3E,21,8A,F9), V(96,DD,06,3D), V(DD,3E,05,AE), V(4D,E6,BD,46), \
778 V(91,54,8D,B5), V(71,C4,5D,05), V(04,06,D4,6F), V(60,50,15,FF), \
779 V(19,98,FB,24), V(D6,BD,E9,97), V(89,40,43,CC), V(67,D9,9E,77), \
780 V(B0,E8,42,BD), V(07,89,8B,88), V(E7,19,5B,38), V(79,C8,EE,DB), \
781 V(A1,7C,0A,47), V(7C,42,0F,E9), V(F8,84,1E,C9), V(00,00,00,00), \
782 V(09,80,86,83), V(32,2B,ED,48), V(1E,11,70,AC), V(6C,5A,72,4E), \
783 V(FD,0E,FF,FB), V(0F,85,38,56), V(3D,AE,D5,1E), V(36,2D,39,27), \
784 V(0A,0F,D9,64), V(68,5C,A6,21), V(9B,5B,54,D1), V(24,36,2E,3A), \
785 V(0C,0A,67,B1), V(93,57,E7,0F), V(B4,EE,96,D2), V(1B,9B,91,9E), \
786 V(80,C0,C5,4F), V(61,DC,20,A2), V(5A,77,4B,69), V(1C,12,1A,16), \
787 V(E2,93,BA,0A), V(C0,A0,2A,E5), V(3C,22,E0,43), V(12,1B,17,1D), \
788 V(0E,09,0D,0B), V(F2,8B,C7,AD), V(2D,B6,A8,B9), V(14,1E,A9,C8), \
789 V(57,F1,19,85), V(AF,75,07,4C), V(EE,99,DD,BB), V(A3,7F,60,FD), \
790 V(F7,01,26,9F), V(5C,72,F5,BC), V(44,66,3B,C5), V(5B,FB,7E,34), \
791 V(8B,43,29,76), V(CB,23,C6,DC), V(B6,ED,FC,68), V(B8,E4,F1,63), \
792 V(D7,31,DC,CA), V(42,63,85,10), V(13,97,22,40), V(84,C6,11,20), \
793 V(85,4A,24,7D), V(D2,BB,3D,F8), V(AE,F9,32,11), V(C7,29,A1,6D), \
794 V(1D,9E,2F,4B), V(DC,B2,30,F3), V(0D,86,52,EC), V(77,C1,E3,D0), \
795 V(2B,B3,16,6C), V(A9,70,B9,99), V(11,94,48,FA), V(47,E9,64,22), \
796 V(A8,FC,8C,C4), V(A0,F0,3F,1A), V(56,7D,2C,D8), V(22,33,90,EF), \
797 V(87,49,4E,C7), V(D9,38,D1,C1), V(8C,CA,A2,FE), V(98,D4,0B,36), \
798 V(A6,F5,81,CF), V(A5,7A,DE,28), V(DA,B7,8E,26), V(3F,AD,BF,A4), \
799 V(2C,3A,9D,E4), V(50,78,92,0D), V(6A,5F,CC,9B), V(54,7E,46,62), \
800 V(F6,8D,13,C2), V(90,D8,B8,E8), V(2E,39,F7,5E), V(82,C3,AF,F5), \
801 V(9F,5D,80,BE), V(69,D0,93,7C), V(6F,D5,2D,A9), V(CF,25,12,B3), \
802 V(C8,AC,99,3B), V(10,18,7D,A7), V(E8,9C,63,6E), V(DB,3B,BB,7B), \
803 V(CD,26,78,09), V(6E,59,18,F4), V(EC,9A,B7,01), V(83,4F,9A,A8), \
804 V(E6,95,6E,65), V(AA,FF,E6,7E), V(21,BC,CF,08), V(EF,15,E8,E6), \
805 V(BA,E7,9B,D9), V(4A,6F,36,CE), V(EA,9F,09,D4), V(29,B0,7C,D6), \
806 V(31,A4,B2,AF), V(2A,3F,23,31), V(C6,A5,94,30), V(35,A2,66,C0), \
807 V(74,4E,BC,37), V(FC,82,CA,A6), V(E0,90,D0,B0), V(33,A7,D8,15), \
808 V(F1,04,98,4A), V(41,EC,DA,F7), V(7F,CD,50,0E), V(17,91,F6,2F), \
809 V(76,4D,D6,8D), V(43,EF,B0,4D), V(CC,AA,4D,54), V(E4,96,04,DF), \
810 V(9E,D1,B5,E3), V(4C,6A,88,1B), V(C1,2C,1F,B8), V(46,65,51,7F), \
811 V(9D,5E,EA,04), V(01,8C,35,5D), V(FA,87,74,73), V(FB,0B,41,2E), \
812 V(B3,67,1D,5A), V(92,DB,D2,52), V(E9,10,56,33), V(6D,D6,47,13), \
813 V(9A,D7,61,8C), V(37,A1,0C,7A), V(59,F8,14,8E), V(EB,13,3C,89), \
814 V(CE,A9,27,EE), V(B7,61,C9,35), V(E1,1C,E5,ED), V(7A,47,B1,3C), \
815 V(9C,D2,DF,59), V(55,F2,73,3F), V(18,14,CE,79), V(73,C7,37,BF), \
816 V(53,F7,CD,EA), V(5F,FD,AA,5B), V(DF,3D,6F,14), V(78,44,DB,86), \
817 V(CA,AF,F3,81), V(B9,68,C4,3E), V(38,24,34,2C), V(C2,A3,40,5F), \
818 V(16,1D,C3,72), V(BC,E2,25,0C), V(28,3C,49,8B), V(FF,0D,95,41), \
819 V(39,A8,01,71), V(08,0C,B3,DE), V(D8,B4,E4,9C), V(64,56,C1,90), \
820 V(7B,CB,84,61), V(D5,32,B6,70), V(48,6C,5C,74), V(D0,B8,57,42)
821
822#define V(a,b,c,d) 0x##a##b##c##d
823static uint32 RT0[256] = { RT };
824
825#undef V
826
827#define V(a,b,c,d) 0x##d##a##b##c
828static uint32 RT1[256] = { RT };
829
830#undef V
831
832#define V(a,b,c,d) 0x##c##d##a##b
833static uint32 RT2[256] = { RT };
834
835#undef V
836
837#define V(a,b,c,d) 0x##b##c##d##a
838static uint32 RT3[256] = { RT };
839
840#undef V
841
842#undef RT
843
844/* round constants */
845
846static uint32 RCON[10] = {
847 0x01000000, 0x02000000, 0x04000000, 0x08000000,
848 0x10000000, 0x20000000, 0x40000000, 0x80000000,
849 0x1B000000, 0x36000000
850};
851
852/* key schedule tables */
853
854static int KT_init = 1;
855
856static uint32 KT0[256];
857static uint32 KT1[256];
858static uint32 KT2[256];
859static uint32 KT3[256];
860
861/* platform-independent 32-bit integer manipulation macros */
862
863#define GET_UINT32(n,b,i) \
864{ \
865 (n) = ( (uint32) (b)[(i) ] << 24 ) \
866 | ( (uint32) (b)[(i) + 1] << 16 ) \
867 | ( (uint32) (b)[(i) + 2] << 8 ) \
868 | ( (uint32) (b)[(i) + 3] ); \
869}
870
871#define PUT_UINT32(n,b,i) \
872{ \
873 (b)[(i) ] = (uint8) ( (n) >> 24 ); \
874 (b)[(i) + 1] = (uint8) ( (n) >> 16 ); \
875 (b)[(i) + 2] = (uint8) ( (n) >> 8 ); \
876 (b)[(i) + 3] = (uint8) ( (n) ); \
877}
878
879int rt_aes_set_key(struct aes_context * ctx, uint8 * key, int nbits)
880{
881 int i;
882 uint32 *RK, *SK;
883
884 switch (nbits) {
885 case 128:
886 ctx->nr = 10;
887 break;
888 case 192:
889 ctx->nr = 12;
890 break;
891 case 256:
892 ctx->nr = 14;
893 break;
894 default:
895 return (1);
896 }
897
898 RK = (uint32 *) ctx->erk;
899
900 for (i = 0; i < (nbits >> 5); i++) {
901 GET_UINT32(RK[i], key, i * 4);
902 }
903
904 /* setup encryption round keys */
905
906 switch (nbits) {
907 case 128:
908
909 for (i = 0; i < 10; i++, RK += 4) {
910 RK[4] = RK[0] ^ RCON[i] ^
911 (FSb[(uint8) (RK[3] >> 16)] << 24) ^
912 (FSb[(uint8) (RK[3] >> 8)] << 16) ^
913 (FSb[(uint8) (RK[3])] << 8) ^
914 (FSb[(uint8) (RK[3] >> 24)]);
915
916 RK[5] = RK[1] ^ RK[4];
917 RK[6] = RK[2] ^ RK[5];
918 RK[7] = RK[3] ^ RK[6];
919 }
920 break;
921
922 case 192:
923
924 for (i = 0; i < 8; i++, RK += 6) {
925 RK[6] = RK[0] ^ RCON[i] ^
926 (FSb[(uint8) (RK[5] >> 16)] << 24) ^
927 (FSb[(uint8) (RK[5] >> 8)] << 16) ^
928 (FSb[(uint8) (RK[5])] << 8) ^
929 (FSb[(uint8) (RK[5] >> 24)]);
930
931 RK[7] = RK[1] ^ RK[6];
932 RK[8] = RK[2] ^ RK[7];
933 RK[9] = RK[3] ^ RK[8];
934 RK[10] = RK[4] ^ RK[9];
935 RK[11] = RK[5] ^ RK[10];
936 }
937 break;
938
939 case 256:
940
941 for (i = 0; i < 7; i++, RK += 8) {
942 RK[8] = RK[0] ^ RCON[i] ^
943 (FSb[(uint8) (RK[7] >> 16)] << 24) ^
944 (FSb[(uint8) (RK[7] >> 8)] << 16) ^
945 (FSb[(uint8) (RK[7])] << 8) ^
946 (FSb[(uint8) (RK[7] >> 24)]);
947
948 RK[9] = RK[1] ^ RK[8];
949 RK[10] = RK[2] ^ RK[9];
950 RK[11] = RK[3] ^ RK[10];
951
952 RK[12] = RK[4] ^
953 (FSb[(uint8) (RK[11] >> 24)] << 24) ^
954 (FSb[(uint8) (RK[11] >> 16)] << 16) ^
955 (FSb[(uint8) (RK[11] >> 8)] << 8) ^
956 (FSb[(uint8) (RK[11])]);
957
958 RK[13] = RK[5] ^ RK[12];
959 RK[14] = RK[6] ^ RK[13];
960 RK[15] = RK[7] ^ RK[14];
961 }
962 break;
963 }
964
965 /* setup decryption round keys */
966
967 if (KT_init) {
968 for (i = 0; i < 256; i++) {
969 KT0[i] = RT0[FSb[i]];
970 KT1[i] = RT1[FSb[i]];
971 KT2[i] = RT2[FSb[i]];
972 KT3[i] = RT3[FSb[i]];
973 }
974
975 KT_init = 0;
976 }
977
978 SK = (uint32 *) ctx->drk;
979
980 *SK++ = *RK++;
981 *SK++ = *RK++;
982 *SK++ = *RK++;
983 *SK++ = *RK++;
984
985 for (i = 1; i < ctx->nr; i++) {
986 RK -= 8;
987
988 *SK++ = KT0[(uint8) (*RK >> 24)] ^
989 KT1[(uint8) (*RK >> 16)] ^
990 KT2[(uint8) (*RK >> 8)] ^ KT3[(uint8) (*RK)];
991 RK++;
992
993 *SK++ = KT0[(uint8) (*RK >> 24)] ^
994 KT1[(uint8) (*RK >> 16)] ^
995 KT2[(uint8) (*RK >> 8)] ^ KT3[(uint8) (*RK)];
996 RK++;
997
998 *SK++ = KT0[(uint8) (*RK >> 24)] ^
999 KT1[(uint8) (*RK >> 16)] ^
1000 KT2[(uint8) (*RK >> 8)] ^ KT3[(uint8) (*RK)];
1001 RK++;
1002
1003 *SK++ = KT0[(uint8) (*RK >> 24)] ^
1004 KT1[(uint8) (*RK >> 16)] ^
1005 KT2[(uint8) (*RK >> 8)] ^ KT3[(uint8) (*RK)];
1006 RK++;
1007 }
1008
1009 RK -= 8;
1010
1011 *SK++ = *RK++;
1012 *SK++ = *RK++;
1013 *SK++ = *RK++;
1014 *SK++ = *RK++;
1015
1016 return (0);
1017}
1018
1019/* AES 128-bit block encryption routine */
1020
1021void rt_aes_encrypt(struct aes_context * ctx, uint8 input[16], uint8 output[16])
1022{
1023 uint32 *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
1024
1025 RK = (uint32 *) ctx->erk;
1026 GET_UINT32(X0, input, 0);
1027 X0 ^= RK[0];
1028 GET_UINT32(X1, input, 4);
1029 X1 ^= RK[1];
1030 GET_UINT32(X2, input, 8);
1031 X2 ^= RK[2];
1032 GET_UINT32(X3, input, 12);
1033 X3 ^= RK[3];
1034
1035#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
1036{ \
1037 RK += 4; \
1038 \
1039 X0 = RK[0] ^ FT0[ (uint8) ( Y0 >> 24 ) ] ^ \
1040 FT1[ (uint8) ( Y1 >> 16 ) ] ^ \
1041 FT2[ (uint8) ( Y2 >> 8 ) ] ^ \
1042 FT3[ (uint8) ( Y3 ) ]; \
1043 \
1044 X1 = RK[1] ^ FT0[ (uint8) ( Y1 >> 24 ) ] ^ \
1045 FT1[ (uint8) ( Y2 >> 16 ) ] ^ \
1046 FT2[ (uint8) ( Y3 >> 8 ) ] ^ \
1047 FT3[ (uint8) ( Y0 ) ]; \
1048 \
1049 X2 = RK[2] ^ FT0[ (uint8) ( Y2 >> 24 ) ] ^ \
1050 FT1[ (uint8) ( Y3 >> 16 ) ] ^ \
1051 FT2[ (uint8) ( Y0 >> 8 ) ] ^ \
1052 FT3[ (uint8) ( Y1 ) ]; \
1053 \
1054 X3 = RK[3] ^ FT0[ (uint8) ( Y3 >> 24 ) ] ^ \
1055 FT1[ (uint8) ( Y0 >> 16 ) ] ^ \
1056 FT2[ (uint8) ( Y1 >> 8 ) ] ^ \
1057 FT3[ (uint8) ( Y2 ) ]; \
1058}
1059
1060 AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 1 */
1061 AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 2 */
1062 AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 3 */
1063 AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 4 */
1064 AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 5 */
1065 AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 6 */
1066 AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 7 */
1067 AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 8 */
1068 AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 9 */
1069
1070 if (ctx->nr > 10) {
1071 AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 10 */
1072 AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 11 */
1073 }
1074
1075 if (ctx->nr > 12) {
1076 AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 12 */
1077 AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 13 */
1078 }
1079
1080 /* last round */
1081
1082 RK += 4;
1083
1084 X0 = RK[0] ^ (FSb[(uint8) (Y0 >> 24)] << 24) ^
1085 (FSb[(uint8) (Y1 >> 16)] << 16) ^
1086 (FSb[(uint8) (Y2 >> 8)] << 8) ^ (FSb[(uint8) (Y3)]);
1087
1088 X1 = RK[1] ^ (FSb[(uint8) (Y1 >> 24)] << 24) ^
1089 (FSb[(uint8) (Y2 >> 16)] << 16) ^
1090 (FSb[(uint8) (Y3 >> 8)] << 8) ^ (FSb[(uint8) (Y0)]);
1091
1092 X2 = RK[2] ^ (FSb[(uint8) (Y2 >> 24)] << 24) ^
1093 (FSb[(uint8) (Y3 >> 16)] << 16) ^
1094 (FSb[(uint8) (Y0 >> 8)] << 8) ^ (FSb[(uint8) (Y1)]);
1095
1096 X3 = RK[3] ^ (FSb[(uint8) (Y3 >> 24)] << 24) ^
1097 (FSb[(uint8) (Y0 >> 16)] << 16) ^
1098 (FSb[(uint8) (Y1 >> 8)] << 8) ^ (FSb[(uint8) (Y2)]);
1099
1100 PUT_UINT32(X0, output, 0);
1101 PUT_UINT32(X1, output, 4);
1102 PUT_UINT32(X2, output, 8);
1103 PUT_UINT32(X3, output, 12);
1104}
1105
1106/* AES 128-bit block decryption routine */
1107
1108void rt_aes_decrypt(struct aes_context * ctx, uint8 input[16], uint8 output[16])
1109{
1110 uint32 *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
1111
1112 RK = (uint32 *) ctx->drk;
1113
1114 GET_UINT32(X0, input, 0);
1115 X0 ^= RK[0];
1116 GET_UINT32(X1, input, 4);
1117 X1 ^= RK[1];
1118 GET_UINT32(X2, input, 8);
1119 X2 ^= RK[2];
1120 GET_UINT32(X3, input, 12);
1121 X3 ^= RK[3];
1122
1123#define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
1124{ \
1125 RK += 4; \
1126 \
1127 X0 = RK[0] ^ RT0[ (uint8) ( Y0 >> 24 ) ] ^ \
1128 RT1[ (uint8) ( Y3 >> 16 ) ] ^ \
1129 RT2[ (uint8) ( Y2 >> 8 ) ] ^ \
1130 RT3[ (uint8) ( Y1 ) ]; \
1131 \
1132 X1 = RK[1] ^ RT0[ (uint8) ( Y1 >> 24 ) ] ^ \
1133 RT1[ (uint8) ( Y0 >> 16 ) ] ^ \
1134 RT2[ (uint8) ( Y3 >> 8 ) ] ^ \
1135 RT3[ (uint8) ( Y2 ) ]; \
1136 \
1137 X2 = RK[2] ^ RT0[ (uint8) ( Y2 >> 24 ) ] ^ \
1138 RT1[ (uint8) ( Y1 >> 16 ) ] ^ \
1139 RT2[ (uint8) ( Y0 >> 8 ) ] ^ \
1140 RT3[ (uint8) ( Y3 ) ]; \
1141 \
1142 X3 = RK[3] ^ RT0[ (uint8) ( Y3 >> 24 ) ] ^ \
1143 RT1[ (uint8) ( Y2 >> 16 ) ] ^ \
1144 RT2[ (uint8) ( Y1 >> 8 ) ] ^ \
1145 RT3[ (uint8) ( Y0 ) ]; \
1146}
1147
1148 AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 1 */
1149 AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 2 */
1150 AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 3 */
1151 AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 4 */
1152 AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 5 */
1153 AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 6 */
1154 AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 7 */
1155 AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 8 */
1156 AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 9 */
1157
1158 if (ctx->nr > 10) {
1159 AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 10 */
1160 AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 11 */
1161 }
1162
1163 if (ctx->nr > 12) {
1164 AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 12 */
1165 AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 13 */
1166 }
1167
1168 /* last round */
1169
1170 RK += 4;
1171
1172 X0 = RK[0] ^ (RSb[(uint8) (Y0 >> 24)] << 24) ^
1173 (RSb[(uint8) (Y3 >> 16)] << 16) ^
1174 (RSb[(uint8) (Y2 >> 8)] << 8) ^ (RSb[(uint8) (Y1)]);
1175
1176 X1 = RK[1] ^ (RSb[(uint8) (Y1 >> 24)] << 24) ^
1177 (RSb[(uint8) (Y0 >> 16)] << 16) ^
1178 (RSb[(uint8) (Y3 >> 8)] << 8) ^ (RSb[(uint8) (Y2)]);
1179
1180 X2 = RK[2] ^ (RSb[(uint8) (Y2 >> 24)] << 24) ^
1181 (RSb[(uint8) (Y1 >> 16)] << 16) ^
1182 (RSb[(uint8) (Y0 >> 8)] << 8) ^ (RSb[(uint8) (Y3)]);
1183
1184 X3 = RK[3] ^ (RSb[(uint8) (Y3 >> 24)] << 24) ^
1185 (RSb[(uint8) (Y2 >> 16)] << 16) ^
1186 (RSb[(uint8) (Y1 >> 8)] << 8) ^ (RSb[(uint8) (Y0)]);
1187
1188 PUT_UINT32(X0, output, 0);
1189 PUT_UINT32(X1, output, 4);
1190 PUT_UINT32(X2, output, 8);
1191 PUT_UINT32(X3, output, 12);
1192}
1193
1194/*
1195 ==========================================================================
1196 Description:
1197 ENCRYPT AES GTK before sending in EAPOL frame.
1198 AES GTK length = 128 bit, so fix blocks for aes-key-wrap as 2 in this function.
1199 This function references to RFC 3394 for aes key wrap algorithm.
1200 Return:
1201 ==========================================================================
1202*/
1203void AES_GTK_KEY_WRAP(u8 * key,
1204 u8 * plaintext,
1205 u32 p_len, u8 * ciphertext)
1206{
1207 u8 A[8], BIN[16], BOUT[16];
1208 u8 R[512];
1209 int num_blocks = p_len / 8; /* unit:64bits */
1210 int i, j;
1211 struct aes_context aesctx;
1212 u8 xor;
1213
1214 rt_aes_set_key(&aesctx, key, 128);
1215
1216 /* Init IA */
1217 for (i = 0; i < 8; i++)
1218 A[i] = 0xa6;
1219
1220 /*Input plaintext */
1221 for (i = 0; i < num_blocks; i++) {
1222 for (j = 0; j < 8; j++)
1223 R[8 * (i + 1) + j] = plaintext[8 * i + j];
1224 }
1225
1226 /* Key Mix */
1227 for (j = 0; j < 6; j++) {
1228 for (i = 1; i <= num_blocks; i++) {
1229 /*phase 1 */
1230 NdisMoveMemory(BIN, A, 8);
1231 NdisMoveMemory(&BIN[8], &R[8 * i], 8);
1232 rt_aes_encrypt(&aesctx, BIN, BOUT);
1233
1234 NdisMoveMemory(A, &BOUT[0], 8);
1235 xor = num_blocks * j + i;
1236 A[7] = BOUT[7] ^ xor;
1237 NdisMoveMemory(&R[8 * i], &BOUT[8], 8);
1238 }
1239 }
1240
1241 /* Output ciphertext */
1242 NdisMoveMemory(ciphertext, A, 8);
1243
1244 for (i = 1; i <= num_blocks; i++) {
1245 for (j = 0; j < 8; j++)
1246 ciphertext[8 * i + j] = R[8 * i + j];
1247 }
1248}
1249
1250/*
1251 ========================================================================
1252
1253 Routine Description:
1254 Misc function to decrypt AES body
1255
1256 Arguments:
1257
1258 Return Value:
1259
1260 Note:
1261 This function references to RFC 3394 for aes key unwrap algorithm.
1262
1263 ========================================================================
1264*/
1265void AES_GTK_KEY_UNWRAP(u8 * key,
1266 u8 * plaintext,
1267 u32 c_len, u8 * ciphertext)
1268{
1269 u8 A[8], BIN[16], BOUT[16];
1270 u8 xor;
1271 int i, j;
1272 struct aes_context aesctx;
1273 u8 *R;
1274 int num_blocks = c_len / 8; /* unit:64bits */
1275
1276 os_alloc_mem(NULL, (u8 **) & R, 512);
1277
1278 if (R == NULL) {
1279 DBGPRINT(RT_DEBUG_ERROR,
1280 ("AES_GTK_KEY_UNWRAP: no memory!\n"));
1281 return;
1282 }
1283 /* End of if */
1284 /* Initialize */
1285 NdisMoveMemory(A, ciphertext, 8);
1286 /*Input plaintext */
1287 for (i = 0; i < (c_len - 8); i++) {
1288 R[i] = ciphertext[i + 8];
1289 }
1290
1291 rt_aes_set_key(&aesctx, key, 128);
1292
1293 for (j = 5; j >= 0; j--) {
1294 for (i = (num_blocks - 1); i > 0; i--) {
1295 xor = (num_blocks - 1) * j + i;
1296 NdisMoveMemory(BIN, A, 8);
1297 BIN[7] = A[7] ^ xor;
1298 NdisMoveMemory(&BIN[8], &R[(i - 1) * 8], 8);
1299 rt_aes_decrypt(&aesctx, BIN, BOUT);
1300 NdisMoveMemory(A, &BOUT[0], 8);
1301 NdisMoveMemory(&R[(i - 1) * 8], &BOUT[8], 8);
1302 }
1303 }
1304
1305 /* OUTPUT */
1306 for (i = 0; i < c_len; i++) {
1307 plaintext[i] = R[i];
1308 }
1309
1310 os_free_mem(NULL, R);
1311}
diff --git a/drivers/staging/rt2860/common/cmm_asic.c b/drivers/staging/rt2860/common/cmm_asic.c
deleted file mode 100644
index 4d77e83eb41..00000000000
--- a/drivers/staging/rt2860/common/cmm_asic.c
+++ /dev/null
@@ -1,2565 +0,0 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 cmm_asic.c
29
30 Abstract:
31 Functions used to communicate with ASIC
32
33 Revision History:
34 Who When What
35 -------- ---------- ----------------------------------------------
36*/
37
38#include "../rt_config.h"
39
40/* Reset the RFIC setting to new series */
41struct rt_rtmp_rf_regs RF2850RegTable[] = {
42/* ch R1 R2 R3(TX0~4=0) R4 */
43 {1, 0x98402ecc, 0x984c0786, 0x9816b455, 0x9800510b}
44 ,
45 {2, 0x98402ecc, 0x984c0786, 0x98168a55, 0x9800519f}
46 ,
47 {3, 0x98402ecc, 0x984c078a, 0x98168a55, 0x9800518b}
48 ,
49 {4, 0x98402ecc, 0x984c078a, 0x98168a55, 0x9800519f}
50 ,
51 {5, 0x98402ecc, 0x984c078e, 0x98168a55, 0x9800518b}
52 ,
53 {6, 0x98402ecc, 0x984c078e, 0x98168a55, 0x9800519f}
54 ,
55 {7, 0x98402ecc, 0x984c0792, 0x98168a55, 0x9800518b}
56 ,
57 {8, 0x98402ecc, 0x984c0792, 0x98168a55, 0x9800519f}
58 ,
59 {9, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800518b}
60 ,
61 {10, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800519f}
62 ,
63 {11, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800518b}
64 ,
65 {12, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800519f}
66 ,
67 {13, 0x98402ecc, 0x984c079e, 0x98168a55, 0x9800518b}
68 ,
69 {14, 0x98402ecc, 0x984c07a2, 0x98168a55, 0x98005193}
70 ,
71
72 /* 802.11 UNI / HyperLan 2 */
73 {36, 0x98402ecc, 0x984c099a, 0x98158a55, 0x980ed1a3}
74 ,
75 {38, 0x98402ecc, 0x984c099e, 0x98158a55, 0x980ed193}
76 ,
77 {40, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed183}
78 ,
79 {44, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed1a3}
80 ,
81 {46, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed18b}
82 ,
83 {48, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed19b}
84 ,
85 {52, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed193}
86 ,
87 {54, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed1a3}
88 ,
89 {56, 0x98402ec8, 0x984c068e, 0x98158a55, 0x980ed18b}
90 ,
91 {60, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed183}
92 ,
93 {62, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed193}
94 ,
95 {64, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed1a3}
96 , /* Plugfest#4, Day4, change RFR3 left4th 9->5. */
97
98 /* 802.11 HyperLan 2 */
99 {100, 0x98402ec8, 0x984c06b2, 0x98178a55, 0x980ed783}
100 ,
101
102 /* 2008.04.30 modified */
103 /* The system team has AN to improve the EVM value */
104 /* for channel 102 to 108 for the RT2850/RT2750 dual band solution. */
105 {102, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed793}
106 ,
107 {104, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed1a3}
108 ,
109 {108, 0x98402ecc, 0x985c0a32, 0x98578a55, 0x980ed193}
110 ,
111
112 {110, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed183}
113 ,
114 {112, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed19b}
115 ,
116 {116, 0x98402ecc, 0x984c0a3a, 0x98178a55, 0x980ed1a3}
117 ,
118 {118, 0x98402ecc, 0x984c0a3e, 0x98178a55, 0x980ed193}
119 ,
120 {120, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed183}
121 ,
122 {124, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed193}
123 ,
124 {126, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed15b}
125 , /* 0x980ed1bb->0x980ed15b required by Rory 20070927 */
126 {128, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed1a3}
127 ,
128 {132, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed18b}
129 ,
130 {134, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed193}
131 ,
132 {136, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed19b}
133 ,
134 {140, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed183}
135 ,
136
137 /* 802.11 UNII */
138 {149, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed1a7}
139 ,
140 {151, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed187}
141 ,
142 {153, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed18f}
143 ,
144 {157, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed19f}
145 ,
146 {159, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed1a7}
147 ,
148 {161, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed187}
149 ,
150 {165, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed197}
151 ,
152 {167, 0x98402ec4, 0x984c03d2, 0x98179855, 0x9815531f}
153 ,
154 {169, 0x98402ec4, 0x984c03d2, 0x98179855, 0x98155327}
155 ,
156 {171, 0x98402ec4, 0x984c03d6, 0x98179855, 0x98155307}
157 ,
158 {173, 0x98402ec4, 0x984c03d6, 0x98179855, 0x9815530f}
159 ,
160
161 /* Japan */
162 {184, 0x95002ccc, 0x9500491e, 0x9509be55, 0x950c0a0b}
163 ,
164 {188, 0x95002ccc, 0x95004922, 0x9509be55, 0x950c0a13}
165 ,
166 {192, 0x95002ccc, 0x95004926, 0x9509be55, 0x950c0a1b}
167 ,
168 {196, 0x95002ccc, 0x9500492a, 0x9509be55, 0x950c0a23}
169 ,
170 {208, 0x95002ccc, 0x9500493a, 0x9509be55, 0x950c0a13}
171 ,
172 {212, 0x95002ccc, 0x9500493e, 0x9509be55, 0x950c0a1b}
173 ,
174 {216, 0x95002ccc, 0x95004982, 0x9509be55, 0x950c0a23}
175 ,
176
177 /* still lack of MMAC(Japan) ch 34,38,42,46 */
178};
179
180u8 NUM_OF_2850_CHNL = (sizeof(RF2850RegTable) / sizeof(struct rt_rtmp_rf_regs));
181
182struct rt_frequency_item FreqItems3020[] = {
183 /**************************************************/
184 /* ISM : 2.4 to 2.483 GHz // */
185 /**************************************************/
186 /* 11g */
187 /**************************************************/
188 /*-CH---N-------R---K----------- */
189 {1, 241, 2, 2}
190 ,
191 {2, 241, 2, 7}
192 ,
193 {3, 242, 2, 2}
194 ,
195 {4, 242, 2, 7}
196 ,
197 {5, 243, 2, 2}
198 ,
199 {6, 243, 2, 7}
200 ,
201 {7, 244, 2, 2}
202 ,
203 {8, 244, 2, 7}
204 ,
205 {9, 245, 2, 2}
206 ,
207 {10, 245, 2, 7}
208 ,
209 {11, 246, 2, 2}
210 ,
211 {12, 246, 2, 7}
212 ,
213 {13, 247, 2, 2}
214 ,
215 {14, 248, 2, 4}
216 ,
217};
218
219u8 NUM_OF_3020_CHNL = (sizeof(FreqItems3020) / sizeof(struct rt_frequency_item));
220
221void AsicUpdateAutoFallBackTable(struct rt_rtmp_adapter *pAd, u8 *pRateTable)
222{
223 u8 i;
224 HT_FBK_CFG0_STRUC HtCfg0;
225 HT_FBK_CFG1_STRUC HtCfg1;
226 LG_FBK_CFG0_STRUC LgCfg0;
227 LG_FBK_CFG1_STRUC LgCfg1;
228 struct rt_rtmp_tx_rate_switch *pCurrTxRate, *pNextTxRate;
229
230 /* set to initial value */
231 HtCfg0.word = 0x65432100;
232 HtCfg1.word = 0xedcba988;
233 LgCfg0.word = 0xedcba988;
234 LgCfg1.word = 0x00002100;
235
236 pNextTxRate = (struct rt_rtmp_tx_rate_switch *) pRateTable + 1;
237 for (i = 1; i < *((u8 *)pRateTable); i++) {
238 pCurrTxRate = (struct rt_rtmp_tx_rate_switch *) pRateTable + 1 + i;
239 switch (pCurrTxRate->Mode) {
240 case 0: /*CCK */
241 break;
242 case 1: /*OFDM */
243 {
244 switch (pCurrTxRate->CurrMCS) {
245 case 0:
246 LgCfg0.field.OFDMMCS0FBK =
247 (pNextTxRate->Mode ==
248 MODE_OFDM) ? (pNextTxRate->
249 CurrMCS +
250 8) : pNextTxRate->
251 CurrMCS;
252 break;
253 case 1:
254 LgCfg0.field.OFDMMCS1FBK =
255 (pNextTxRate->Mode ==
256 MODE_OFDM) ? (pNextTxRate->
257 CurrMCS +
258 8) : pNextTxRate->
259 CurrMCS;
260 break;
261 case 2:
262 LgCfg0.field.OFDMMCS2FBK =
263 (pNextTxRate->Mode ==
264 MODE_OFDM) ? (pNextTxRate->
265 CurrMCS +
266 8) : pNextTxRate->
267 CurrMCS;
268 break;
269 case 3:
270 LgCfg0.field.OFDMMCS3FBK =
271 (pNextTxRate->Mode ==
272 MODE_OFDM) ? (pNextTxRate->
273 CurrMCS +
274 8) : pNextTxRate->
275 CurrMCS;
276 break;
277 case 4:
278 LgCfg0.field.OFDMMCS4FBK =
279 (pNextTxRate->Mode ==
280 MODE_OFDM) ? (pNextTxRate->
281 CurrMCS +
282 8) : pNextTxRate->
283 CurrMCS;
284 break;
285 case 5:
286 LgCfg0.field.OFDMMCS5FBK =
287 (pNextTxRate->Mode ==
288 MODE_OFDM) ? (pNextTxRate->
289 CurrMCS +
290 8) : pNextTxRate->
291 CurrMCS;
292 break;
293 case 6:
294 LgCfg0.field.OFDMMCS6FBK =
295 (pNextTxRate->Mode ==
296 MODE_OFDM) ? (pNextTxRate->
297 CurrMCS +
298 8) : pNextTxRate->
299 CurrMCS;
300 break;
301 case 7:
302 LgCfg0.field.OFDMMCS7FBK =
303 (pNextTxRate->Mode ==
304 MODE_OFDM) ? (pNextTxRate->
305 CurrMCS +
306 8) : pNextTxRate->
307 CurrMCS;
308 break;
309 }
310 }
311 break;
312 case 2: /*HT-MIX */
313 case 3: /*HT-GF */
314 {
315 if ((pNextTxRate->Mode >= MODE_HTMIX)
316 && (pCurrTxRate->CurrMCS !=
317 pNextTxRate->CurrMCS)) {
318 switch (pCurrTxRate->CurrMCS) {
319 case 0:
320 HtCfg0.field.HTMCS0FBK =
321 pNextTxRate->CurrMCS;
322 break;
323 case 1:
324 HtCfg0.field.HTMCS1FBK =
325 pNextTxRate->CurrMCS;
326 break;
327 case 2:
328 HtCfg0.field.HTMCS2FBK =
329 pNextTxRate->CurrMCS;
330 break;
331 case 3:
332 HtCfg0.field.HTMCS3FBK =
333 pNextTxRate->CurrMCS;
334 break;
335 case 4:
336 HtCfg0.field.HTMCS4FBK =
337 pNextTxRate->CurrMCS;
338 break;
339 case 5:
340 HtCfg0.field.HTMCS5FBK =
341 pNextTxRate->CurrMCS;
342 break;
343 case 6:
344 HtCfg0.field.HTMCS6FBK =
345 pNextTxRate->CurrMCS;
346 break;
347 case 7:
348 HtCfg0.field.HTMCS7FBK =
349 pNextTxRate->CurrMCS;
350 break;
351 case 8:
352 HtCfg1.field.HTMCS8FBK =
353 pNextTxRate->CurrMCS;
354 break;
355 case 9:
356 HtCfg1.field.HTMCS9FBK =
357 pNextTxRate->CurrMCS;
358 break;
359 case 10:
360 HtCfg1.field.HTMCS10FBK =
361 pNextTxRate->CurrMCS;
362 break;
363 case 11:
364 HtCfg1.field.HTMCS11FBK =
365 pNextTxRate->CurrMCS;
366 break;
367 case 12:
368 HtCfg1.field.HTMCS12FBK =
369 pNextTxRate->CurrMCS;
370 break;
371 case 13:
372 HtCfg1.field.HTMCS13FBK =
373 pNextTxRate->CurrMCS;
374 break;
375 case 14:
376 HtCfg1.field.HTMCS14FBK =
377 pNextTxRate->CurrMCS;
378 break;
379 case 15:
380 HtCfg1.field.HTMCS15FBK =
381 pNextTxRate->CurrMCS;
382 break;
383 default:
384 DBGPRINT(RT_DEBUG_ERROR,
385 ("AsicUpdateAutoFallBackTable: not support CurrMCS=%d\n",
386 pCurrTxRate->
387 CurrMCS));
388 }
389 }
390 }
391 break;
392 }
393
394 pNextTxRate = pCurrTxRate;
395 }
396
397 RTMP_IO_WRITE32(pAd, HT_FBK_CFG0, HtCfg0.word);
398 RTMP_IO_WRITE32(pAd, HT_FBK_CFG1, HtCfg1.word);
399 RTMP_IO_WRITE32(pAd, LG_FBK_CFG0, LgCfg0.word);
400 RTMP_IO_WRITE32(pAd, LG_FBK_CFG1, LgCfg1.word);
401}
402
403/*
404 ========================================================================
405
406 Routine Description:
407 Set MAC register value according operation mode.
408 OperationMode AND bNonGFExist are for MM and GF Proteciton.
409 If MM or GF mask is not set, those passing argument doesn't not take effect.
410
411 Operation mode meaning:
412 = 0 : Pure HT, no preotection.
413 = 0x01; there may be non-HT devices in both the control and extension channel, protection is optional in BSS.
414 = 0x10: No Transmission in 40M is protected.
415 = 0x11: Transmission in both 40M and 20M shall be protected
416 if (bNonGFExist)
417 we should choose not to use GF. But still set correct ASIC registers.
418 ========================================================================
419*/
420void AsicUpdateProtect(struct rt_rtmp_adapter *pAd,
421 u16 OperationMode,
422 u8 SetMask,
423 IN BOOLEAN bDisableBGProtect, IN BOOLEAN bNonGFExist)
424{
425 PROT_CFG_STRUC ProtCfg, ProtCfg4;
426 u32 Protect[6];
427 u16 offset;
428 u8 i;
429 u32 MacReg = 0;
430
431 if (!(pAd->CommonCfg.bHTProtect) && (OperationMode != 8)) {
432 return;
433 }
434
435 if (pAd->BATable.numDoneOriginator) {
436 /* */
437 /* enable the RTS/CTS to avoid channel collision */
438 /* */
439 SetMask = ALLN_SETPROTECT;
440 OperationMode = 8;
441 }
442 /* Config ASIC RTS threshold register */
443 RTMP_IO_READ32(pAd, TX_RTS_CFG, &MacReg);
444 MacReg &= 0xFF0000FF;
445 /* If the user want disable RtsThreshold and enable Amsdu/Ralink-Aggregation, set the RtsThreshold as 4096 */
446 if (((pAd->CommonCfg.BACapability.field.AmsduEnable) ||
447 (pAd->CommonCfg.bAggregationCapable == TRUE))
448 && pAd->CommonCfg.RtsThreshold == MAX_RTS_THRESHOLD) {
449 MacReg |= (0x1000 << 8);
450 } else {
451 MacReg |= (pAd->CommonCfg.RtsThreshold << 8);
452 }
453
454 RTMP_IO_WRITE32(pAd, TX_RTS_CFG, MacReg);
455
456 /* Initial common protection settings */
457 RTMPZeroMemory(Protect, sizeof(Protect));
458 ProtCfg4.word = 0;
459 ProtCfg.word = 0;
460 ProtCfg.field.TxopAllowGF40 = 1;
461 ProtCfg.field.TxopAllowGF20 = 1;
462 ProtCfg.field.TxopAllowMM40 = 1;
463 ProtCfg.field.TxopAllowMM20 = 1;
464 ProtCfg.field.TxopAllowOfdm = 1;
465 ProtCfg.field.TxopAllowCck = 1;
466 ProtCfg.field.RTSThEn = 1;
467 ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
468
469 /* update PHY mode and rate */
470 if (pAd->CommonCfg.Channel > 14)
471 ProtCfg.field.ProtectRate = 0x4000;
472 ProtCfg.field.ProtectRate |= pAd->CommonCfg.RtsRate;
473
474 /* Handle legacy(B/G) protection */
475 if (bDisableBGProtect) {
476 /*ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate; */
477 ProtCfg.field.ProtectCtrl = 0;
478 Protect[0] = ProtCfg.word;
479 Protect[1] = ProtCfg.word;
480 pAd->FlgCtsEnabled = 0; /* CTS-self is not used */
481 } else {
482 /*ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate; */
483 ProtCfg.field.ProtectCtrl = 0; /* CCK do not need to be protected */
484 Protect[0] = ProtCfg.word;
485 ProtCfg.field.ProtectCtrl = ASIC_CTS; /* OFDM needs using CCK to protect */
486 Protect[1] = ProtCfg.word;
487 pAd->FlgCtsEnabled = 1; /* CTS-self is used */
488 }
489
490 /* Decide HT frame protection. */
491 if ((SetMask & ALLN_SETPROTECT) != 0) {
492 switch (OperationMode) {
493 case 0x0:
494 /* NO PROTECT */
495 /* 1.All STAs in the BSS are 20/40 MHz HT */
496 /* 2. in ai 20/40MHz BSS */
497 /* 3. all STAs are 20MHz in a 20MHz BSS */
498 /* Pure HT. no protection. */
499
500 /* MM20_PROT_CFG */
501 /* Reserved (31:27) */
502 /* PROT_TXOP(25:20) -- 010111 */
503 /* PROT_NAV(19:18) -- 01 (Short NAV protection) */
504 /* PROT_CTRL(17:16) -- 00 (None) */
505 /* PROT_RATE(15:0) -- 0x4004 (OFDM 24M) */
506 Protect[2] = 0x01744004;
507
508 /* MM40_PROT_CFG */
509 /* Reserved (31:27) */
510 /* PROT_TXOP(25:20) -- 111111 */
511 /* PROT_NAV(19:18) -- 01 (Short NAV protection) */
512 /* PROT_CTRL(17:16) -- 00 (None) */
513 /* PROT_RATE(15:0) -- 0x4084 (duplicate OFDM 24M) */
514 Protect[3] = 0x03f44084;
515
516 /* CF20_PROT_CFG */
517 /* Reserved (31:27) */
518 /* PROT_TXOP(25:20) -- 010111 */
519 /* PROT_NAV(19:18) -- 01 (Short NAV protection) */
520 /* PROT_CTRL(17:16) -- 00 (None) */
521 /* PROT_RATE(15:0) -- 0x4004 (OFDM 24M) */
522 Protect[4] = 0x01744004;
523
524 /* CF40_PROT_CFG */
525 /* Reserved (31:27) */
526 /* PROT_TXOP(25:20) -- 111111 */
527 /* PROT_NAV(19:18) -- 01 (Short NAV protection) */
528 /* PROT_CTRL(17:16) -- 00 (None) */
529 /* PROT_RATE(15:0) -- 0x4084 (duplicate OFDM 24M) */
530 Protect[5] = 0x03f44084;
531
532 if (bNonGFExist) {
533 /* PROT_NAV(19:18) -- 01 (Short NAV protectiion) */
534 /* PROT_CTRL(17:16) -- 01 (RTS/CTS) */
535 Protect[4] = 0x01754004;
536 Protect[5] = 0x03f54084;
537 }
538 pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE;
539 break;
540
541 case 1:
542 /* This is "HT non-member protection mode." */
543 /* If there may be non-HT STAs my BSS */
544 ProtCfg.word = 0x01744004; /* PROT_CTRL(17:16) : 0 (None) */
545 ProtCfg4.word = 0x03f44084; /* duplicaet legacy 24M. BW set 1. */
546 if (OPSTATUS_TEST_FLAG
547 (pAd, fOP_STATUS_BG_PROTECTION_INUSED)) {
548 ProtCfg.word = 0x01740003; /*ERP use Protection bit is set, use protection rate at Clause 18.. */
549 ProtCfg4.word = 0x03f40003; /* Don't duplicate RTS/CTS in CCK mode. 0x03f40083; */
550 }
551 /*Assign Protection method for 20&40 MHz packets */
552 ProtCfg.field.ProtectCtrl = ASIC_RTS;
553 ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
554 ProtCfg4.field.ProtectCtrl = ASIC_RTS;
555 ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
556 Protect[2] = ProtCfg.word;
557 Protect[3] = ProtCfg4.word;
558 Protect[4] = ProtCfg.word;
559 Protect[5] = ProtCfg4.word;
560 pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
561 break;
562
563 case 2:
564 /* If only HT STAs are in BSS. at least one is 20MHz. Only protect 40MHz packets */
565 ProtCfg.word = 0x01744004; /* PROT_CTRL(17:16) : 0 (None) */
566 ProtCfg4.word = 0x03f44084; /* duplicaet legacy 24M. BW set 1. */
567
568 /*Assign Protection method for 40MHz packets */
569 ProtCfg4.field.ProtectCtrl = ASIC_RTS;
570 ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
571 Protect[2] = ProtCfg.word;
572 Protect[3] = ProtCfg4.word;
573 if (bNonGFExist) {
574 ProtCfg.field.ProtectCtrl = ASIC_RTS;
575 ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
576 }
577 Protect[4] = ProtCfg.word;
578 Protect[5] = ProtCfg4.word;
579
580 pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE;
581 break;
582
583 case 3:
584 /* HT mixed mode. PROTECT ALL! */
585 /* Assign Rate */
586 ProtCfg.word = 0x01744004; /*duplicaet legacy 24M. BW set 1. */
587 ProtCfg4.word = 0x03f44084;
588 /* both 20MHz and 40MHz are protected. Whether use RTS or CTS-to-self depends on the */
589 if (OPSTATUS_TEST_FLAG
590 (pAd, fOP_STATUS_BG_PROTECTION_INUSED)) {
591 ProtCfg.word = 0x01740003; /*ERP use Protection bit is set, use protection rate at Clause 18.. */
592 ProtCfg4.word = 0x03f40003; /* Don't duplicate RTS/CTS in CCK mode. 0x03f40083 */
593 }
594 /*Assign Protection method for 20&40 MHz packets */
595 ProtCfg.field.ProtectCtrl = ASIC_RTS;
596 ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
597 ProtCfg4.field.ProtectCtrl = ASIC_RTS;
598 ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
599 Protect[2] = ProtCfg.word;
600 Protect[3] = ProtCfg4.word;
601 Protect[4] = ProtCfg.word;
602 Protect[5] = ProtCfg4.word;
603 pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
604 break;
605
606 case 8:
607 /* Special on for Atheros problem n chip. */
608 Protect[2] = 0x01754004;
609 Protect[3] = 0x03f54084;
610 Protect[4] = 0x01754004;
611 Protect[5] = 0x03f54084;
612 pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
613 break;
614 }
615 }
616
617 offset = CCK_PROT_CFG;
618 for (i = 0; i < 6; i++) {
619 if ((SetMask & (1 << i))) {
620 RTMP_IO_WRITE32(pAd, offset + i * 4, Protect[i]);
621 }
622 }
623}
624
625/*
626 ==========================================================================
627 Description:
628
629 IRQL = PASSIVE_LEVEL
630 IRQL = DISPATCH_LEVEL
631
632 ==========================================================================
633 */
634void AsicSwitchChannel(struct rt_rtmp_adapter *pAd, u8 Channel, IN BOOLEAN bScan)
635{
636 unsigned long R2 = 0, R3 = DEFAULT_RF_TX_POWER, R4 = 0;
637 char TxPwer = 0, TxPwer2 = DEFAULT_RF_TX_POWER; /*Bbp94 = BBPR94_DEFAULT, TxPwer2 = DEFAULT_RF_TX_POWER; */
638 u8 index;
639 u32 Value = 0; /*BbpReg, Value; */
640 struct rt_rtmp_rf_regs *RFRegTable;
641 u8 RFValue;
642
643 RFValue = 0;
644 /* Search Tx power value */
645 /* We can't use ChannelList to search channel, since some central channl's txpowr doesn't list */
646 /* in ChannelList, so use TxPower array instead. */
647 /* */
648 for (index = 0; index < MAX_NUM_OF_CHANNELS; index++) {
649 if (Channel == pAd->TxPower[index].Channel) {
650 TxPwer = pAd->TxPower[index].Power;
651 TxPwer2 = pAd->TxPower[index].Power2;
652 break;
653 }
654 }
655
656 if (index == MAX_NUM_OF_CHANNELS) {
657 DBGPRINT(RT_DEBUG_ERROR,
658 ("AsicSwitchChannel: Can't find the Channel#%d \n",
659 Channel));
660 }
661#ifdef RT30xx
662 /* The RF programming sequence is difference between 3xxx and 2xxx */
663 if ((IS_RT3070(pAd) || IS_RT3090(pAd) || IS_RT3390(pAd))
664 && ((pAd->RfIcType == RFIC_3020) || (pAd->RfIcType == RFIC_2020)
665 || (pAd->RfIcType == RFIC_3021)
666 || (pAd->RfIcType == RFIC_3022))) {
667 /* modify by WY for Read RF Reg. error */
668
669 for (index = 0; index < NUM_OF_3020_CHNL; index++) {
670 if (Channel == FreqItems3020[index].Channel) {
671 /* Programming channel parameters */
672 RT30xxWriteRFRegister(pAd, RF_R02,
673 FreqItems3020[index].N);
674 RT30xxWriteRFRegister(pAd, RF_R03,
675 FreqItems3020[index].K);
676 RT30xxReadRFRegister(pAd, RF_R06, &RFValue);
677 RFValue =
678 (RFValue & 0xFC) | FreqItems3020[index].R;
679 RT30xxWriteRFRegister(pAd, RF_R06, RFValue);
680
681 /* Set Tx0 Power */
682 RT30xxReadRFRegister(pAd, RF_R12, &RFValue);
683 RFValue = (RFValue & 0xE0) | TxPwer;
684 RT30xxWriteRFRegister(pAd, RF_R12, RFValue);
685
686 /* Set Tx1 Power */
687 RT30xxReadRFRegister(pAd, RF_R13, &RFValue);
688 RFValue = (RFValue & 0xE0) | TxPwer2;
689 RT30xxWriteRFRegister(pAd, RF_R13, RFValue);
690
691 /* Tx/Rx Stream setting */
692 RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
693 /*if (IS_RT3090(pAd)) */
694 /* RFValue |= 0x01; // Enable RF block. */
695 RFValue &= 0x03; /*clear bit[7~2] */
696 if (pAd->Antenna.field.TxPath == 1)
697 RFValue |= 0xA0;
698 else if (pAd->Antenna.field.TxPath == 2)
699 RFValue |= 0x80;
700 if (pAd->Antenna.field.RxPath == 1)
701 RFValue |= 0x50;
702 else if (pAd->Antenna.field.RxPath == 2)
703 RFValue |= 0x40;
704 RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
705
706 /* Set RF offset */
707 RT30xxReadRFRegister(pAd, RF_R23, &RFValue);
708 RFValue = (RFValue & 0x80) | pAd->RfFreqOffset;
709 RT30xxWriteRFRegister(pAd, RF_R23, RFValue);
710
711 /* Set BW */
712 if (!bScan
713 && (pAd->CommonCfg.BBPCurrentBW == BW_40)) {
714 RFValue = pAd->Mlme.CaliBW40RfR24;
715 /*DISABLE_11N_CHECK(pAd); */
716 } else {
717 RFValue = pAd->Mlme.CaliBW20RfR24;
718 }
719 RT30xxWriteRFRegister(pAd, RF_R24, RFValue);
720 RT30xxWriteRFRegister(pAd, RF_R31, RFValue);
721
722 /* Enable RF tuning */
723 RT30xxReadRFRegister(pAd, RF_R07, &RFValue);
724 RFValue = RFValue | 0x1;
725 RT30xxWriteRFRegister(pAd, RF_R07, RFValue);
726
727 /* latch channel for future usage. */
728 pAd->LatchRfRegs.Channel = Channel;
729
730 DBGPRINT(RT_DEBUG_TRACE,
731 ("SwitchChannel#%d(RF=%d, Pwr0=%d, Pwr1=%d, %dT), N=0x%02X, K=0x%02X, R=0x%02X\n",
732 Channel, pAd->RfIcType, TxPwer,
733 TxPwer2, pAd->Antenna.field.TxPath,
734 FreqItems3020[index].N,
735 FreqItems3020[index].K,
736 FreqItems3020[index].R));
737
738 break;
739 }
740 }
741 } else
742#endif /* RT30xx // */
743 {
744 RFRegTable = RF2850RegTable;
745 switch (pAd->RfIcType) {
746 case RFIC_2820:
747 case RFIC_2850:
748 case RFIC_2720:
749 case RFIC_2750:
750
751 for (index = 0; index < NUM_OF_2850_CHNL; index++) {
752 if (Channel == RFRegTable[index].Channel) {
753 R2 = RFRegTable[index].R2;
754 if (pAd->Antenna.field.TxPath == 1) {
755 R2 |= 0x4000; /* If TXpath is 1, bit 14 = 1; */
756 }
757
758 if (pAd->Antenna.field.RxPath == 2) {
759 R2 |= 0x40; /* write 1 to off Rxpath. */
760 } else if (pAd->Antenna.field.RxPath ==
761 1) {
762 R2 |= 0x20040; /* write 1 to off RxPath */
763 }
764
765 if (Channel > 14) {
766 /* initialize R3, R4 */
767 R3 = (RFRegTable[index].
768 R3 & 0xffffc1ff);
769 R4 = (RFRegTable[index].
770 R4 & (~0x001f87c0)) |
771 (pAd->RfFreqOffset << 15);
772
773 /* 5G band power range: 0xF9~0X0F, TX0 Reg3 bit9/TX1 Reg4 bit6="0" means the TX power reduce 7dB */
774 /* R3 */
775 if ((TxPwer >= -7)
776 && (TxPwer < 0)) {
777 TxPwer = (7 + TxPwer);
778 TxPwer =
779 (TxPwer >
780 0xF) ? (0xF)
781 : (TxPwer);
782 R3 |= (TxPwer << 10);
783 DBGPRINT(RT_DEBUG_ERROR,
784 ("AsicSwitchChannel: TxPwer=%d \n",
785 TxPwer));
786 } else {
787 TxPwer =
788 (TxPwer >
789 0xF) ? (0xF)
790 : (TxPwer);
791 R3 |=
792 (TxPwer << 10) | (1
793 <<
794 9);
795 }
796
797 /* R4 */
798 if ((TxPwer2 >= -7)
799 && (TxPwer2 < 0)) {
800 TxPwer2 = (7 + TxPwer2);
801 TxPwer2 =
802 (TxPwer2 >
803 0xF) ? (0xF)
804 : (TxPwer2);
805 R4 |= (TxPwer2 << 7);
806 DBGPRINT(RT_DEBUG_ERROR,
807 ("AsicSwitchChannel: TxPwer2=%d \n",
808 TxPwer2));
809 } else {
810 TxPwer2 =
811 (TxPwer2 >
812 0xF) ? (0xF)
813 : (TxPwer2);
814 R4 |=
815 (TxPwer2 << 7) | (1
816 <<
817 6);
818 }
819 } else {
820 R3 = (RFRegTable[index].R3 & 0xffffc1ff) | (TxPwer << 9); /* set TX power0 */
821 R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->RfFreqOffset << 15) | (TxPwer2 << 6); /* Set freq Offset & TxPwr1 */
822 }
823
824 /* Based on BBP current mode before changing RF channel. */
825 if (!bScan
826 && (pAd->CommonCfg.BBPCurrentBW ==
827 BW_40)) {
828 R4 |= 0x200000;
829 }
830 /* Update variables */
831 pAd->LatchRfRegs.Channel = Channel;
832 pAd->LatchRfRegs.R1 =
833 RFRegTable[index].R1;
834 pAd->LatchRfRegs.R2 = R2;
835 pAd->LatchRfRegs.R3 = R3;
836 pAd->LatchRfRegs.R4 = R4;
837
838 /* Set RF value 1's set R3[bit2] = [0] */
839 RTMP_RF_IO_WRITE32(pAd,
840 pAd->LatchRfRegs.R1);
841 RTMP_RF_IO_WRITE32(pAd,
842 pAd->LatchRfRegs.R2);
843 RTMP_RF_IO_WRITE32(pAd,
844 (pAd->LatchRfRegs.
845 R3 & (~0x04)));
846 RTMP_RF_IO_WRITE32(pAd,
847 pAd->LatchRfRegs.R4);
848
849 RTMPusecDelay(200);
850
851 /* Set RF value 2's set R3[bit2] = [1] */
852 RTMP_RF_IO_WRITE32(pAd,
853 pAd->LatchRfRegs.R1);
854 RTMP_RF_IO_WRITE32(pAd,
855 pAd->LatchRfRegs.R2);
856 RTMP_RF_IO_WRITE32(pAd,
857 (pAd->LatchRfRegs.
858 R3 | 0x04));
859 RTMP_RF_IO_WRITE32(pAd,
860 pAd->LatchRfRegs.R4);
861
862 RTMPusecDelay(200);
863
864 /* Set RF value 3's set R3[bit2] = [0] */
865 RTMP_RF_IO_WRITE32(pAd,
866 pAd->LatchRfRegs.R1);
867 RTMP_RF_IO_WRITE32(pAd,
868 pAd->LatchRfRegs.R2);
869 RTMP_RF_IO_WRITE32(pAd,
870 (pAd->LatchRfRegs.
871 R3 & (~0x04)));
872 RTMP_RF_IO_WRITE32(pAd,
873 pAd->LatchRfRegs.R4);
874
875 break;
876 }
877 }
878 break;
879
880 default:
881 break;
882 }
883
884 DBGPRINT(RT_DEBUG_TRACE,
885 ("SwitchChannel#%d(RF=%d, Pwr0=%lu, Pwr1=%lu, %dT) to , R1=0x%08lx, R2=0x%08lx, R3=0x%08lx, R4=0x%08lx\n",
886 Channel, pAd->RfIcType, (R3 & 0x00003e00) >> 9,
887 (R4 & 0x000007c0) >> 6, pAd->Antenna.field.TxPath,
888 pAd->LatchRfRegs.R1, pAd->LatchRfRegs.R2,
889 pAd->LatchRfRegs.R3, pAd->LatchRfRegs.R4));
890 }
891
892 /* Change BBP setting during siwtch from a->g, g->a */
893 if (Channel <= 14) {
894 unsigned long TxPinCfg = 0x00050F0A; /*Gary 2007/08/09 0x050A0A */
895
896 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62,
897 (0x37 - GET_LNA_GAIN(pAd)));
898 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63,
899 (0x37 - GET_LNA_GAIN(pAd)));
900 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64,
901 (0x37 - GET_LNA_GAIN(pAd)));
902 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0); /*(0x44 - GET_LNA_GAIN(pAd))); // According the Rory's suggestion to solve the middle range issue. */
903 /*RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62); */
904
905 /* Rx High power VGA offset for LNA select */
906 if (pAd->NicConfig2.field.ExternalLNAForG) {
907 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62);
908 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46);
909 } else {
910 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x84);
911 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50);
912 }
913
914 /* 5G band selection PIN, bit1 and bit2 are complement */
915 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
916 Value &= (~0x6);
917 Value |= (0x04);
918 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
919
920 /* Turn off unused PA or LNA when only 1T or 1R */
921 if (pAd->Antenna.field.TxPath == 1) {
922 TxPinCfg &= 0xFFFFFFF3;
923 }
924 if (pAd->Antenna.field.RxPath == 1) {
925 TxPinCfg &= 0xFFFFF3FF;
926 }
927
928 RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
929
930#if defined(RT3090) || defined(RT3390)
931 /* PCIe PHY Transmit attenuation adjustment */
932 if (IS_RT3090A(pAd) || IS_RT3390(pAd)) {
933 TX_ATTENUATION_CTRL_STRUC TxAttenuationCtrl = {
934 .word = 0};
935
936 RTMP_IO_READ32(pAd, PCIE_PHY_TX_ATTENUATION_CTRL,
937 &TxAttenuationCtrl.word);
938
939 if (Channel == 14) /* Channel #14 */
940 {
941 TxAttenuationCtrl.field.PCIE_PHY_TX_ATTEN_EN = 1; /* Enable PCIe PHY Tx attenuation */
942 TxAttenuationCtrl.field.PCIE_PHY_TX_ATTEN_VALUE = 4; /* 9/16 full drive level */
943 } else /* Channel #1~#13 */
944 {
945 TxAttenuationCtrl.field.PCIE_PHY_TX_ATTEN_EN = 0; /* Disable PCIe PHY Tx attenuation */
946 TxAttenuationCtrl.field.PCIE_PHY_TX_ATTEN_VALUE = 0; /* n/a */
947 }
948
949 RTMP_IO_WRITE32(pAd, PCIE_PHY_TX_ATTENUATION_CTRL,
950 TxAttenuationCtrl.word);
951 }
952#endif
953 } else {
954 unsigned long TxPinCfg = 0x00050F05; /*Gary 2007/8/9 0x050505 */
955
956 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62,
957 (0x37 - GET_LNA_GAIN(pAd)));
958 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63,
959 (0x37 - GET_LNA_GAIN(pAd)));
960 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64,
961 (0x37 - GET_LNA_GAIN(pAd)));
962 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0); /*(0x44 - GET_LNA_GAIN(pAd))); // According the Rory's suggestion to solve the middle range issue. */
963 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0xF2);
964
965 /* Rx High power VGA offset for LNA select */
966 if (pAd->NicConfig2.field.ExternalLNAForA) {
967 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46);
968 } else {
969 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50);
970 }
971
972 /* 5G band selection PIN, bit1 and bit2 are complement */
973 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
974 Value &= (~0x6);
975 Value |= (0x02);
976 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
977
978 /* Turn off unused PA or LNA when only 1T or 1R */
979 if (pAd->Antenna.field.TxPath == 1) {
980 TxPinCfg &= 0xFFFFFFF3;
981 }
982 if (pAd->Antenna.field.RxPath == 1) {
983 TxPinCfg &= 0xFFFFF3FF;
984 }
985
986 RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
987
988 }
989
990 /* R66 should be set according to Channel and use 20MHz when scanning */
991 /*RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, (0x2E + GET_LNA_GAIN(pAd))); */
992 if (bScan)
993 RTMPSetAGCInitValue(pAd, BW_20);
994 else
995 RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW);
996
997 /* */
998 /* On 11A, We should delay and wait RF/BBP to be stable */
999 /* and the appropriate time should be 1000 micro seconds */
1000 /* 2005/06/05 - On 11G, We also need this delay time. Otherwise it's difficult to pass the WHQL. */
1001 /* */
1002 RTMPusecDelay(1000);
1003}
1004
1005void AsicResetBBPAgent(struct rt_rtmp_adapter *pAd)
1006{
1007 BBP_CSR_CFG_STRUC BbpCsr;
1008 DBGPRINT(RT_DEBUG_ERROR, ("Reset BBP Agent busy bit!\n"));
1009 /* Still need to find why BBP agent keeps busy, but in fact, hardware still function ok. Now clear busy first. */
1010 RTMP_IO_READ32(pAd, H2M_BBP_AGENT, &BbpCsr.word);
1011 BbpCsr.field.Busy = 0;
1012 RTMP_IO_WRITE32(pAd, H2M_BBP_AGENT, BbpCsr.word);
1013}
1014
1015/*
1016 ==========================================================================
1017 Description:
1018 This function is required for 2421 only, and should not be used during
1019 site survey. It's only required after NIC decided to stay at a channel
1020 for a longer period.
1021 When this function is called, it's always after AsicSwitchChannel().
1022
1023 IRQL = PASSIVE_LEVEL
1024 IRQL = DISPATCH_LEVEL
1025
1026 ==========================================================================
1027 */
1028void AsicLockChannel(struct rt_rtmp_adapter *pAd, u8 Channel)
1029{
1030}
1031
1032void AsicRfTuningExec(void *SystemSpecific1,
1033 void *FunctionContext,
1034 void *SystemSpecific2, void *SystemSpecific3)
1035{
1036}
1037
1038/*
1039 ==========================================================================
1040 Description:
1041 Gives CCK TX rate 2 more dB TX power.
1042 This routine works only in LINK UP in INFRASTRUCTURE mode.
1043
1044 calculate desired Tx power in RF R3.Tx0~5, should consider -
1045 0. if current radio is a noisy environment (pAd->DrsCounters.fNoisyEnvironment)
1046 1. TxPowerPercentage
1047 2. auto calibration based on TSSI feedback
1048 3. extra 2 db for CCK
1049 4. -10 db upon very-short distance (AvgRSSI >= -40db) to AP
1050
1051 NOTE: Since this routine requires the value of (pAd->DrsCounters.fNoisyEnvironment),
1052 it should be called AFTER MlmeDynamicTxRatSwitching()
1053 ==========================================================================
1054 */
1055void AsicAdjustTxPower(struct rt_rtmp_adapter *pAd)
1056{
1057 int i, j;
1058 char DeltaPwr = 0;
1059 BOOLEAN bAutoTxAgc = FALSE;
1060 u8 TssiRef, *pTssiMinusBoundary, *pTssiPlusBoundary, TxAgcStep;
1061 u8 BbpR1 = 0, BbpR49 = 0, idx;
1062 char *pTxAgcCompensate;
1063 unsigned long TxPwr[5];
1064 char Value;
1065 char Rssi = -127;
1066
1067 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) ||
1068#ifdef RTMP_MAC_PCI
1069 (pAd->bPCIclkOff == TRUE) ||
1070#endif /* RTMP_MAC_PCI // */
1071 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF) ||
1072 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
1073 return;
1074
1075 Rssi = RTMPMaxRssi(pAd,
1076 pAd->StaCfg.RssiSample.AvgRssi0,
1077 pAd->StaCfg.RssiSample.AvgRssi1,
1078 pAd->StaCfg.RssiSample.AvgRssi2);
1079
1080 if (pAd->CommonCfg.BBPCurrentBW == BW_40) {
1081 if (pAd->CommonCfg.CentralChannel > 14) {
1082 TxPwr[0] = pAd->Tx40MPwrCfgABand[0];
1083 TxPwr[1] = pAd->Tx40MPwrCfgABand[1];
1084 TxPwr[2] = pAd->Tx40MPwrCfgABand[2];
1085 TxPwr[3] = pAd->Tx40MPwrCfgABand[3];
1086 TxPwr[4] = pAd->Tx40MPwrCfgABand[4];
1087 } else {
1088 TxPwr[0] = pAd->Tx40MPwrCfgGBand[0];
1089 TxPwr[1] = pAd->Tx40MPwrCfgGBand[1];
1090 TxPwr[2] = pAd->Tx40MPwrCfgGBand[2];
1091 TxPwr[3] = pAd->Tx40MPwrCfgGBand[3];
1092 TxPwr[4] = pAd->Tx40MPwrCfgGBand[4];
1093 }
1094 } else {
1095 if (pAd->CommonCfg.Channel > 14) {
1096 TxPwr[0] = pAd->Tx20MPwrCfgABand[0];
1097 TxPwr[1] = pAd->Tx20MPwrCfgABand[1];
1098 TxPwr[2] = pAd->Tx20MPwrCfgABand[2];
1099 TxPwr[3] = pAd->Tx20MPwrCfgABand[3];
1100 TxPwr[4] = pAd->Tx20MPwrCfgABand[4];
1101 } else {
1102 TxPwr[0] = pAd->Tx20MPwrCfgGBand[0];
1103 TxPwr[1] = pAd->Tx20MPwrCfgGBand[1];
1104 TxPwr[2] = pAd->Tx20MPwrCfgGBand[2];
1105 TxPwr[3] = pAd->Tx20MPwrCfgGBand[3];
1106 TxPwr[4] = pAd->Tx20MPwrCfgGBand[4];
1107 }
1108 }
1109
1110 /* TX power compensation for temperature variation based on TSSI. try every 4 second */
1111 if (pAd->Mlme.OneSecPeriodicRound % 4 == 0) {
1112 if (pAd->CommonCfg.Channel <= 14) {
1113 /* bg channel */
1114 bAutoTxAgc = pAd->bAutoTxAgcG;
1115 TssiRef = pAd->TssiRefG;
1116 pTssiMinusBoundary = &pAd->TssiMinusBoundaryG[0];
1117 pTssiPlusBoundary = &pAd->TssiPlusBoundaryG[0];
1118 TxAgcStep = pAd->TxAgcStepG;
1119 pTxAgcCompensate = &pAd->TxAgcCompensateG;
1120 } else {
1121 /* a channel */
1122 bAutoTxAgc = pAd->bAutoTxAgcA;
1123 TssiRef = pAd->TssiRefA;
1124 pTssiMinusBoundary = &pAd->TssiMinusBoundaryA[0];
1125 pTssiPlusBoundary = &pAd->TssiPlusBoundaryA[0];
1126 TxAgcStep = pAd->TxAgcStepA;
1127 pTxAgcCompensate = &pAd->TxAgcCompensateA;
1128 }
1129
1130 if (bAutoTxAgc) {
1131 /* BbpR1 is unsigned char */
1132 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpR49);
1133
1134 /* (p) TssiPlusBoundaryG[0] = 0 = (m) TssiMinusBoundaryG[0] */
1135 /* compensate: +4 +3 +2 +1 0 -1 -2 -3 -4 * steps */
1136 /* step value is defined in pAd->TxAgcStepG for tx power value */
1137
1138 /* [4]+1+[4] p4 p3 p2 p1 o1 m1 m2 m3 m4 */
1139 /* ex: 0x00 0x15 0x25 0x45 0x88 0xA0 0xB5 0xD0 0xF0
1140 above value are examined in mass factory production */
1141 /* [4] [3] [2] [1] [0] [1] [2] [3] [4] */
1142
1143 /* plus (+) is 0x00 ~ 0x45, minus (-) is 0xa0 ~ 0xf0 */
1144 /* if value is between p1 ~ o1 or o1 ~ s1, no need to adjust tx power */
1145 /* if value is 0xa5, tx power will be -= TxAgcStep*(2-1) */
1146
1147 if (BbpR49 > pTssiMinusBoundary[1]) {
1148 /* Reading is larger than the reference value */
1149 /* check for how large we need to decrease the Tx power */
1150 for (idx = 1; idx < 5; idx++) {
1151 if (BbpR49 <= pTssiMinusBoundary[idx]) /* Found the range */
1152 break;
1153 }
1154 /* The index is the step we should decrease, idx = 0 means there is nothing to compensate */
1155/* if (R3 > (unsigned long)(TxAgcStep * (idx-1))) */
1156 *pTxAgcCompensate = -(TxAgcStep * (idx - 1));
1157/* else */
1158/* *pTxAgcCompensate = -((u8)R3); */
1159
1160 DeltaPwr += (*pTxAgcCompensate);
1161 DBGPRINT(RT_DEBUG_TRACE,
1162 ("-- Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = -%d\n",
1163 BbpR49, TssiRef, TxAgcStep, idx - 1));
1164 } else if (BbpR49 < pTssiPlusBoundary[1]) {
1165 /* Reading is smaller than the reference value */
1166 /* check for how large we need to increase the Tx power */
1167 for (idx = 1; idx < 5; idx++) {
1168 if (BbpR49 >= pTssiPlusBoundary[idx]) /* Found the range */
1169 break;
1170 }
1171 /* The index is the step we should increase, idx = 0 means there is nothing to compensate */
1172 *pTxAgcCompensate = TxAgcStep * (idx - 1);
1173 DeltaPwr += (*pTxAgcCompensate);
1174 DBGPRINT(RT_DEBUG_TRACE,
1175 ("++ Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
1176 BbpR49, TssiRef, TxAgcStep, idx - 1));
1177 } else {
1178 *pTxAgcCompensate = 0;
1179 DBGPRINT(RT_DEBUG_TRACE,
1180 (" Tx Power, BBP R49=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
1181 BbpR49, TssiRef, TxAgcStep, 0));
1182 }
1183 }
1184 } else {
1185 if (pAd->CommonCfg.Channel <= 14) {
1186 bAutoTxAgc = pAd->bAutoTxAgcG;
1187 pTxAgcCompensate = &pAd->TxAgcCompensateG;
1188 } else {
1189 bAutoTxAgc = pAd->bAutoTxAgcA;
1190 pTxAgcCompensate = &pAd->TxAgcCompensateA;
1191 }
1192
1193 if (bAutoTxAgc)
1194 DeltaPwr += (*pTxAgcCompensate);
1195 }
1196
1197 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpR1);
1198 BbpR1 &= 0xFC;
1199
1200 /* calculate delta power based on the percentage specified from UI */
1201 /* E2PROM setting is calibrated for maximum TX power (i.e. 100%) */
1202 /* We lower TX power here according to the percentage specified from UI */
1203 if (pAd->CommonCfg.TxPowerPercentage == 0xffffffff) /* AUTO TX POWER control */
1204 {
1205 {
1206 /* to patch high power issue with some APs, like Belkin N1. */
1207 if (Rssi > -35) {
1208 BbpR1 |= 0x02; /* DeltaPwr -= 12; */
1209 } else if (Rssi > -40) {
1210 BbpR1 |= 0x01; /* DeltaPwr -= 6; */
1211 } else;
1212 }
1213 } else if (pAd->CommonCfg.TxPowerPercentage > 90) /* 91 ~ 100% & AUTO, treat as 100% in terms of mW */
1214 ;
1215 else if (pAd->CommonCfg.TxPowerPercentage > 60) /* 61 ~ 90%, treat as 75% in terms of mW // DeltaPwr -= 1; */
1216 {
1217 DeltaPwr -= 1;
1218 } else if (pAd->CommonCfg.TxPowerPercentage > 30) /* 31 ~ 60%, treat as 50% in terms of mW // DeltaPwr -= 3; */
1219 {
1220 DeltaPwr -= 3;
1221 } else if (pAd->CommonCfg.TxPowerPercentage > 15) /* 16 ~ 30%, treat as 25% in terms of mW // DeltaPwr -= 6; */
1222 {
1223 BbpR1 |= 0x01;
1224 } else if (pAd->CommonCfg.TxPowerPercentage > 9) /* 10 ~ 15%, treat as 12.5% in terms of mW // DeltaPwr -= 9; */
1225 {
1226 BbpR1 |= 0x01;
1227 DeltaPwr -= 3;
1228 } else /* 0 ~ 9 %, treat as MIN(~3%) in terms of mW // DeltaPwr -= 12; */
1229 {
1230 BbpR1 |= 0x02;
1231 }
1232
1233 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpR1);
1234
1235 /* reset different new tx power for different TX rate */
1236 for (i = 0; i < 5; i++) {
1237 if (TxPwr[i] != 0xffffffff) {
1238 for (j = 0; j < 8; j++) {
1239 Value = (char)((TxPwr[i] >> j * 4) & 0x0F); /* 0 ~ 15 */
1240
1241 if ((Value + DeltaPwr) < 0) {
1242 Value = 0; /* min */
1243 } else if ((Value + DeltaPwr) > 0xF) {
1244 Value = 0xF; /* max */
1245 } else {
1246 Value += DeltaPwr; /* temperature compensation */
1247 }
1248
1249 /* fill new value to CSR offset */
1250 TxPwr[i] =
1251 (TxPwr[i] & ~(0x0000000F << j * 4)) | (Value
1252 << j
1253 * 4);
1254 }
1255
1256 /* write tx power value to CSR */
1257 /* TX_PWR_CFG_0 (8 tx rate) for TX power for OFDM 12M/18M
1258 TX power for OFDM 6M/9M
1259 TX power for CCK5.5M/11M
1260 TX power for CCK1M/2M */
1261 /* TX_PWR_CFG_1 ~ TX_PWR_CFG_4 */
1262 RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i * 4, TxPwr[i]);
1263 }
1264 }
1265
1266}
1267
1268/*
1269 ==========================================================================
1270 Description:
1271 put PHY to sleep here, and set next wakeup timer. PHY doesn't not wakeup
1272 automatically. Instead, MCU will issue a TwakeUpInterrupt to host after
1273 the wakeup timer timeout. Driver has to issue a separate command to wake
1274 PHY up.
1275
1276 IRQL = DISPATCH_LEVEL
1277
1278 ==========================================================================
1279 */
1280void AsicSleepThenAutoWakeup(struct rt_rtmp_adapter *pAd,
1281 u16 TbttNumToNextWakeUp)
1282{
1283 RTMP_STA_SLEEP_THEN_AUTO_WAKEUP(pAd, TbttNumToNextWakeUp);
1284}
1285
1286/*
1287 ==========================================================================
1288 Description:
1289 AsicForceWakeup() is used whenever manual wakeup is required
1290 AsicForceSleep() should only be used when not in INFRA BSS. When
1291 in INFRA BSS, we should use AsicSleepThenAutoWakeup() instead.
1292 ==========================================================================
1293 */
1294void AsicForceSleep(struct rt_rtmp_adapter *pAd)
1295{
1296
1297}
1298
1299/*
1300 ==========================================================================
1301 Description:
1302 AsicForceWakeup() is used whenever Twakeup timer (set via AsicSleepThenAutoWakeup)
1303 expired.
1304
1305 IRQL = PASSIVE_LEVEL
1306 IRQL = DISPATCH_LEVEL
1307 ==========================================================================
1308 */
1309void AsicForceWakeup(struct rt_rtmp_adapter *pAd, IN BOOLEAN bFromTx)
1310{
1311 DBGPRINT(RT_DEBUG_INFO, ("--> AsicForceWakeup \n"));
1312 RTMP_STA_FORCE_WAKEUP(pAd, bFromTx);
1313}
1314
1315/*
1316 ==========================================================================
1317 Description:
1318 Set My BSSID
1319
1320 IRQL = DISPATCH_LEVEL
1321
1322 ==========================================================================
1323 */
1324void AsicSetBssid(struct rt_rtmp_adapter *pAd, u8 *pBssid)
1325{
1326 unsigned long Addr4;
1327 DBGPRINT(RT_DEBUG_TRACE,
1328 ("==============> AsicSetBssid %x:%x:%x:%x:%x:%x\n", pBssid[0],
1329 pBssid[1], pBssid[2], pBssid[3], pBssid[4], pBssid[5]));
1330
1331 Addr4 = (unsigned long)(pBssid[0]) |
1332 (unsigned long)(pBssid[1] << 8) |
1333 (unsigned long)(pBssid[2] << 16) | (unsigned long)(pBssid[3] << 24);
1334 RTMP_IO_WRITE32(pAd, MAC_BSSID_DW0, Addr4);
1335
1336 Addr4 = 0;
1337 /* always one BSSID in STA mode */
1338 Addr4 = (unsigned long)(pBssid[4]) | (unsigned long)(pBssid[5] << 8);
1339
1340 RTMP_IO_WRITE32(pAd, MAC_BSSID_DW1, Addr4);
1341}
1342
1343void AsicSetMcastWC(struct rt_rtmp_adapter *pAd)
1344{
1345 struct rt_mac_table_entry *pEntry = &pAd->MacTab.Content[MCAST_WCID];
1346 u16 offset;
1347
1348 pEntry->Sst = SST_ASSOC;
1349 pEntry->Aid = MCAST_WCID; /* Softap supports 1 BSSID and use WCID=0 as multicast Wcid index */
1350 pEntry->PsMode = PWR_ACTIVE;
1351 pEntry->CurrTxRate = pAd->CommonCfg.MlmeRate;
1352 offset = MAC_WCID_BASE + BSS0Mcast_WCID * HW_WCID_ENTRY_SIZE;
1353}
1354
1355/*
1356 ==========================================================================
1357 Description:
1358
1359 IRQL = DISPATCH_LEVEL
1360
1361 ==========================================================================
1362 */
1363void AsicDelWcidTab(struct rt_rtmp_adapter *pAd, u8 Wcid)
1364{
1365 unsigned long Addr0 = 0x0, Addr1 = 0x0;
1366 unsigned long offset;
1367
1368 DBGPRINT(RT_DEBUG_TRACE, ("AsicDelWcidTab==>Wcid = 0x%x\n", Wcid));
1369 offset = MAC_WCID_BASE + Wcid * HW_WCID_ENTRY_SIZE;
1370 RTMP_IO_WRITE32(pAd, offset, Addr0);
1371 offset += 4;
1372 RTMP_IO_WRITE32(pAd, offset, Addr1);
1373}
1374
1375/*
1376 ==========================================================================
1377 Description:
1378
1379 IRQL = DISPATCH_LEVEL
1380
1381 ==========================================================================
1382 */
1383void AsicEnableRDG(struct rt_rtmp_adapter *pAd)
1384{
1385 TX_LINK_CFG_STRUC TxLinkCfg;
1386 u32 Data = 0;
1387
1388 RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word);
1389 TxLinkCfg.field.TxRDGEn = 1;
1390 RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word);
1391
1392 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1393 Data &= 0xFFFFFF00;
1394 Data |= 0x80;
1395 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1396
1397 /*OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED); */
1398}
1399
1400/*
1401 ==========================================================================
1402 Description:
1403
1404 IRQL = DISPATCH_LEVEL
1405
1406 ==========================================================================
1407 */
1408void AsicDisableRDG(struct rt_rtmp_adapter *pAd)
1409{
1410 TX_LINK_CFG_STRUC TxLinkCfg;
1411 u32 Data = 0;
1412
1413 RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word);
1414 TxLinkCfg.field.TxRDGEn = 0;
1415 RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word);
1416
1417 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1418
1419 Data &= 0xFFFFFF00;
1420 /*Data |= 0x20; */
1421#ifndef WIFI_TEST
1422 /*if ( pAd->CommonCfg.bEnableTxBurst ) */
1423 /* Data |= 0x60; // for performance issue not set the TXOP to 0 */
1424#endif
1425 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_DYNAMIC_BE_TXOP_ACTIVE)
1426 && (pAd->MacTab.fAnyStationMIMOPSDynamic == FALSE)
1427 ) {
1428 /* For CWC test, change txop from 0x30 to 0x20 in TxBurst mode */
1429 if (pAd->CommonCfg.bEnableTxBurst)
1430 Data |= 0x20;
1431 }
1432 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1433}
1434
1435/*
1436 ==========================================================================
1437 Description:
1438
1439 IRQL = PASSIVE_LEVEL
1440 IRQL = DISPATCH_LEVEL
1441
1442 ==========================================================================
1443 */
1444void AsicDisableSync(struct rt_rtmp_adapter *pAd)
1445{
1446 BCN_TIME_CFG_STRUC csr;
1447
1448 DBGPRINT(RT_DEBUG_TRACE, ("--->Disable TSF synchronization\n"));
1449
1450 /* 2003-12-20 disable TSF and TBTT while NIC in power-saving have side effect */
1451 /* that NIC will never wakes up because TSF stops and no more */
1452 /* TBTT interrupts */
1453 pAd->TbttTickCount = 0;
1454 RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
1455 csr.field.bBeaconGen = 0;
1456 csr.field.bTBTTEnable = 0;
1457 csr.field.TsfSyncMode = 0;
1458 csr.field.bTsfTicking = 0;
1459 RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
1460
1461}
1462
1463/*
1464 ==========================================================================
1465 Description:
1466
1467 IRQL = DISPATCH_LEVEL
1468
1469 ==========================================================================
1470 */
1471void AsicEnableBssSync(struct rt_rtmp_adapter *pAd)
1472{
1473 BCN_TIME_CFG_STRUC csr;
1474
1475 DBGPRINT(RT_DEBUG_TRACE, ("--->AsicEnableBssSync(INFRA mode)\n"));
1476
1477 RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
1478/* RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, 0x00000000); */
1479 {
1480 csr.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4; /* ASIC register in units of 1/16 TU */
1481 csr.field.bTsfTicking = 1;
1482 csr.field.TsfSyncMode = 1; /* sync TSF in INFRASTRUCTURE mode */
1483 csr.field.bBeaconGen = 0; /* do NOT generate BEACON */
1484 csr.field.bTBTTEnable = 1;
1485 }
1486 RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
1487}
1488
1489/*
1490 ==========================================================================
1491 Description:
1492 Note:
1493 BEACON frame in shared memory should be built ok before this routine
1494 can be called. Otherwise, a garbage frame maybe transmitted out every
1495 Beacon period.
1496
1497 IRQL = DISPATCH_LEVEL
1498
1499 ==========================================================================
1500 */
1501void AsicEnableIbssSync(struct rt_rtmp_adapter *pAd)
1502{
1503 BCN_TIME_CFG_STRUC csr9;
1504 u8 *ptr;
1505 u32 i;
1506
1507 DBGPRINT(RT_DEBUG_TRACE,
1508 ("--->AsicEnableIbssSync(ADHOC mode. MPDUtotalByteCount = %d)\n",
1509 pAd->BeaconTxWI.MPDUtotalByteCount));
1510
1511 RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr9.word);
1512 csr9.field.bBeaconGen = 0;
1513 csr9.field.bTBTTEnable = 0;
1514 csr9.field.bTsfTicking = 0;
1515 RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word);
1516
1517#ifdef RTMP_MAC_PCI
1518 /* move BEACON TXD and frame content to on-chip memory */
1519 ptr = (u8 *)& pAd->BeaconTxWI;
1520 for (i = 0; i < TXWI_SIZE; i += 4) /* 16-byte TXWI field */
1521 {
1522 u32 longptr =
1523 *ptr + (*(ptr + 1) << 8) + (*(ptr + 2) << 16) +
1524 (*(ptr + 3) << 24);
1525 RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + i, longptr);
1526 ptr += 4;
1527 }
1528
1529 /* start right after the 16-byte TXWI field */
1530 ptr = pAd->BeaconBuf;
1531 for (i = 0; i < pAd->BeaconTxWI.MPDUtotalByteCount; i += 4) {
1532 u32 longptr =
1533 *ptr + (*(ptr + 1) << 8) + (*(ptr + 2) << 16) +
1534 (*(ptr + 3) << 24);
1535 RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, longptr);
1536 ptr += 4;
1537 }
1538#endif /* RTMP_MAC_PCI // */
1539#ifdef RTMP_MAC_USB
1540 /* move BEACON TXD and frame content to on-chip memory */
1541 ptr = (u8 *)& pAd->BeaconTxWI;
1542 for (i = 0; i < TXWI_SIZE; i += 2) /* 16-byte TXWI field */
1543 {
1544 /*u32 longptr = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24); */
1545 /*RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + i, longptr); */
1546 RTUSBMultiWrite(pAd, HW_BEACON_BASE0 + i, ptr, 2);
1547 ptr += 2;
1548 }
1549
1550 /* start right after the 16-byte TXWI field */
1551 ptr = pAd->BeaconBuf;
1552 for (i = 0; i < pAd->BeaconTxWI.MPDUtotalByteCount; i += 2) {
1553 /*u32 longptr = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24); */
1554 /*RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, longptr); */
1555 RTUSBMultiWrite(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, ptr, 2);
1556 ptr += 2;
1557 }
1558#endif /* RTMP_MAC_USB // */
1559
1560 /* */
1561 /* For Wi-Fi faily generated beacons between participating stations. */
1562 /* Set TBTT phase adaptive adjustment step to 8us (default 16us) */
1563 /* don't change settings 2006-5- by Jerry */
1564 /*RTMP_IO_WRITE32(pAd, TBTT_SYNC_CFG, 0x00001010); */
1565
1566 /* start sending BEACON */
1567 csr9.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4; /* ASIC register in units of 1/16 TU */
1568 csr9.field.bTsfTicking = 1;
1569 csr9.field.TsfSyncMode = 2; /* sync TSF in IBSS mode */
1570 csr9.field.bTBTTEnable = 1;
1571 csr9.field.bBeaconGen = 1;
1572 RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word);
1573}
1574
1575/*
1576 ==========================================================================
1577 Description:
1578
1579 IRQL = PASSIVE_LEVEL
1580 IRQL = DISPATCH_LEVEL
1581
1582 ==========================================================================
1583 */
1584void AsicSetEdcaParm(struct rt_rtmp_adapter *pAd, struct rt_edca_parm *pEdcaParm)
1585{
1586 EDCA_AC_CFG_STRUC Ac0Cfg, Ac1Cfg, Ac2Cfg, Ac3Cfg;
1587 AC_TXOP_CSR0_STRUC csr0;
1588 AC_TXOP_CSR1_STRUC csr1;
1589 AIFSN_CSR_STRUC AifsnCsr;
1590 CWMIN_CSR_STRUC CwminCsr;
1591 CWMAX_CSR_STRUC CwmaxCsr;
1592 int i;
1593
1594 Ac0Cfg.word = 0;
1595 Ac1Cfg.word = 0;
1596 Ac2Cfg.word = 0;
1597 Ac3Cfg.word = 0;
1598 if ((pEdcaParm == NULL) || (pEdcaParm->bValid == FALSE)) {
1599 DBGPRINT(RT_DEBUG_TRACE, ("AsicSetEdcaParm\n"));
1600 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_WMM_INUSED);
1601 for (i = 0; i < MAX_LEN_OF_MAC_TABLE; i++) {
1602 if (pAd->MacTab.Content[i].ValidAsCLI
1603 || pAd->MacTab.Content[i].ValidAsApCli)
1604 CLIENT_STATUS_CLEAR_FLAG(&pAd->MacTab.
1605 Content[i],
1606 fCLIENT_STATUS_WMM_CAPABLE);
1607 }
1608
1609 /*======================================================== */
1610 /* MAC Register has a copy . */
1611 /*======================================================== */
1612/*#ifndef WIFI_TEST */
1613 if (pAd->CommonCfg.bEnableTxBurst) {
1614 /* For CWC test, change txop from 0x30 to 0x20 in TxBurst mode */
1615 Ac0Cfg.field.AcTxop = 0x20; /* Suggest by John for TxBurst in HT Mode */
1616 } else
1617 Ac0Cfg.field.AcTxop = 0; /* QID_AC_BE */
1618/*#else */
1619/* Ac0Cfg.field.AcTxop = 0; // QID_AC_BE */
1620/*#endif */
1621 Ac0Cfg.field.Cwmin = CW_MIN_IN_BITS;
1622 Ac0Cfg.field.Cwmax = CW_MAX_IN_BITS;
1623 Ac0Cfg.field.Aifsn = 2;
1624 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Ac0Cfg.word);
1625
1626 Ac1Cfg.field.AcTxop = 0; /* QID_AC_BK */
1627 Ac1Cfg.field.Cwmin = CW_MIN_IN_BITS;
1628 Ac1Cfg.field.Cwmax = CW_MAX_IN_BITS;
1629 Ac1Cfg.field.Aifsn = 2;
1630 RTMP_IO_WRITE32(pAd, EDCA_AC1_CFG, Ac1Cfg.word);
1631
1632 if (pAd->CommonCfg.PhyMode == PHY_11B) {
1633 Ac2Cfg.field.AcTxop = 192; /* AC_VI: 192*32us ~= 6ms */
1634 Ac3Cfg.field.AcTxop = 96; /* AC_VO: 96*32us ~= 3ms */
1635 } else {
1636 Ac2Cfg.field.AcTxop = 96; /* AC_VI: 96*32us ~= 3ms */
1637 Ac3Cfg.field.AcTxop = 48; /* AC_VO: 48*32us ~= 1.5ms */
1638 }
1639 Ac2Cfg.field.Cwmin = CW_MIN_IN_BITS;
1640 Ac2Cfg.field.Cwmax = CW_MAX_IN_BITS;
1641 Ac2Cfg.field.Aifsn = 2;
1642 RTMP_IO_WRITE32(pAd, EDCA_AC2_CFG, Ac2Cfg.word);
1643 Ac3Cfg.field.Cwmin = CW_MIN_IN_BITS;
1644 Ac3Cfg.field.Cwmax = CW_MAX_IN_BITS;
1645 Ac3Cfg.field.Aifsn = 2;
1646 RTMP_IO_WRITE32(pAd, EDCA_AC3_CFG, Ac3Cfg.word);
1647
1648 /*======================================================== */
1649 /* DMA Register has a copy too. */
1650 /*======================================================== */
1651 csr0.field.Ac0Txop = 0; /* QID_AC_BE */
1652 csr0.field.Ac1Txop = 0; /* QID_AC_BK */
1653 RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word);
1654 if (pAd->CommonCfg.PhyMode == PHY_11B) {
1655 csr1.field.Ac2Txop = 192; /* AC_VI: 192*32us ~= 6ms */
1656 csr1.field.Ac3Txop = 96; /* AC_VO: 96*32us ~= 3ms */
1657 } else {
1658 csr1.field.Ac2Txop = 96; /* AC_VI: 96*32us ~= 3ms */
1659 csr1.field.Ac3Txop = 48; /* AC_VO: 48*32us ~= 1.5ms */
1660 }
1661 RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr1.word);
1662
1663 CwminCsr.word = 0;
1664 CwminCsr.field.Cwmin0 = CW_MIN_IN_BITS;
1665 CwminCsr.field.Cwmin1 = CW_MIN_IN_BITS;
1666 CwminCsr.field.Cwmin2 = CW_MIN_IN_BITS;
1667 CwminCsr.field.Cwmin3 = CW_MIN_IN_BITS;
1668 RTMP_IO_WRITE32(pAd, WMM_CWMIN_CFG, CwminCsr.word);
1669
1670 CwmaxCsr.word = 0;
1671 CwmaxCsr.field.Cwmax0 = CW_MAX_IN_BITS;
1672 CwmaxCsr.field.Cwmax1 = CW_MAX_IN_BITS;
1673 CwmaxCsr.field.Cwmax2 = CW_MAX_IN_BITS;
1674 CwmaxCsr.field.Cwmax3 = CW_MAX_IN_BITS;
1675 RTMP_IO_WRITE32(pAd, WMM_CWMAX_CFG, CwmaxCsr.word);
1676
1677 RTMP_IO_WRITE32(pAd, WMM_AIFSN_CFG, 0x00002222);
1678
1679 NdisZeroMemory(&pAd->CommonCfg.APEdcaParm, sizeof(struct rt_edca_parm));
1680 } else {
1681 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_WMM_INUSED);
1682 /*======================================================== */
1683 /* MAC Register has a copy. */
1684 /*======================================================== */
1685 /* */
1686 /* Modify Cwmin/Cwmax/Txop on queue[QID_AC_VI], Recommend by Jerry 2005/07/27 */
1687 /* To degrade our VIDO Queue's throughput for WiFi WMM S3T07 Issue. */
1688 /* */
1689 /*pEdcaParm->Txop[QID_AC_VI] = pEdcaParm->Txop[QID_AC_VI] * 7 / 10; // rt2860c need this */
1690
1691 Ac0Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BE];
1692 Ac0Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_BE];
1693 Ac0Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_BE];
1694 Ac0Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BE]; /*+1; */
1695
1696 Ac1Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BK];
1697 Ac1Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_BK]; /*+2; */
1698 Ac1Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_BK];
1699 Ac1Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BK]; /*+1; */
1700
1701 Ac2Cfg.field.AcTxop = (pEdcaParm->Txop[QID_AC_VI] * 6) / 10;
1702 if (pAd->Antenna.field.TxPath == 1) {
1703 Ac2Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VI] + 1;
1704 Ac2Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VI] + 1;
1705 } else {
1706 Ac2Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VI];
1707 Ac2Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VI];
1708 }
1709 Ac2Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VI] + 1;
1710#ifdef RTMP_MAC_USB
1711 Ac2Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VI] + 3;
1712#endif /* RTMP_MAC_USB // */
1713
1714 {
1715 /* Tuning for Wi-Fi WMM S06 */
1716 if (pAd->CommonCfg.bWiFiTest &&
1717 pEdcaParm->Aifsn[QID_AC_VI] == 10)
1718 Ac2Cfg.field.Aifsn -= 1;
1719
1720 /* Tuning for TGn Wi-Fi 5.2.32 */
1721 /* STA TestBed changes in this item: conexant legacy sta ==> broadcom 11n sta */
1722 if (STA_TGN_WIFI_ON(pAd) &&
1723 pEdcaParm->Aifsn[QID_AC_VI] == 10) {
1724 Ac0Cfg.field.Aifsn = 3;
1725 Ac2Cfg.field.AcTxop = 5;
1726 }
1727#ifdef RT30xx
1728 if (pAd->RfIcType == RFIC_3020
1729 || pAd->RfIcType == RFIC_2020) {
1730 /* Tuning for WiFi WMM S3-T07: connexant legacy sta ==> broadcom 11n sta. */
1731 Ac2Cfg.field.Aifsn = 5;
1732 }
1733#endif /* RT30xx // */
1734 }
1735
1736 Ac3Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_VO];
1737 Ac3Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VO];
1738 Ac3Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VO];
1739 Ac3Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VO];
1740
1741/*#ifdef WIFI_TEST */
1742 if (pAd->CommonCfg.bWiFiTest) {
1743 if (Ac3Cfg.field.AcTxop == 102) {
1744 Ac0Cfg.field.AcTxop =
1745 pEdcaParm->Txop[QID_AC_BE] ? pEdcaParm->
1746 Txop[QID_AC_BE] : 10;
1747 Ac0Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BE] - 1; /* AIFSN must >= 1 */
1748 Ac1Cfg.field.AcTxop =
1749 pEdcaParm->Txop[QID_AC_BK];
1750 Ac1Cfg.field.Aifsn =
1751 pEdcaParm->Aifsn[QID_AC_BK];
1752 Ac2Cfg.field.AcTxop =
1753 pEdcaParm->Txop[QID_AC_VI];
1754 } /* End of if */
1755 }
1756/*#endif // WIFI_TEST // */
1757
1758 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Ac0Cfg.word);
1759 RTMP_IO_WRITE32(pAd, EDCA_AC1_CFG, Ac1Cfg.word);
1760 RTMP_IO_WRITE32(pAd, EDCA_AC2_CFG, Ac2Cfg.word);
1761 RTMP_IO_WRITE32(pAd, EDCA_AC3_CFG, Ac3Cfg.word);
1762
1763 /*======================================================== */
1764 /* DMA Register has a copy too. */
1765 /*======================================================== */
1766 csr0.field.Ac0Txop = Ac0Cfg.field.AcTxop;
1767 csr0.field.Ac1Txop = Ac1Cfg.field.AcTxop;
1768 RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word);
1769
1770 csr1.field.Ac2Txop = Ac2Cfg.field.AcTxop;
1771 csr1.field.Ac3Txop = Ac3Cfg.field.AcTxop;
1772 RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr1.word);
1773
1774 CwminCsr.word = 0;
1775 CwminCsr.field.Cwmin0 = pEdcaParm->Cwmin[QID_AC_BE];
1776 CwminCsr.field.Cwmin1 = pEdcaParm->Cwmin[QID_AC_BK];
1777 CwminCsr.field.Cwmin2 = pEdcaParm->Cwmin[QID_AC_VI];
1778 CwminCsr.field.Cwmin3 = pEdcaParm->Cwmin[QID_AC_VO] - 1; /*for TGn wifi test */
1779 RTMP_IO_WRITE32(pAd, WMM_CWMIN_CFG, CwminCsr.word);
1780
1781 CwmaxCsr.word = 0;
1782 CwmaxCsr.field.Cwmax0 = pEdcaParm->Cwmax[QID_AC_BE];
1783 CwmaxCsr.field.Cwmax1 = pEdcaParm->Cwmax[QID_AC_BK];
1784 CwmaxCsr.field.Cwmax2 = pEdcaParm->Cwmax[QID_AC_VI];
1785 CwmaxCsr.field.Cwmax3 = pEdcaParm->Cwmax[QID_AC_VO];
1786 RTMP_IO_WRITE32(pAd, WMM_CWMAX_CFG, CwmaxCsr.word);
1787
1788 AifsnCsr.word = 0;
1789 AifsnCsr.field.Aifsn0 = Ac0Cfg.field.Aifsn; /*pEdcaParm->Aifsn[QID_AC_BE]; */
1790 AifsnCsr.field.Aifsn1 = Ac1Cfg.field.Aifsn; /*pEdcaParm->Aifsn[QID_AC_BK]; */
1791 AifsnCsr.field.Aifsn2 = Ac2Cfg.field.Aifsn; /*pEdcaParm->Aifsn[QID_AC_VI]; */
1792
1793 {
1794 /* Tuning for Wi-Fi WMM S06 */
1795 if (pAd->CommonCfg.bWiFiTest &&
1796 pEdcaParm->Aifsn[QID_AC_VI] == 10)
1797 AifsnCsr.field.Aifsn2 = Ac2Cfg.field.Aifsn - 4;
1798
1799 /* Tuning for TGn Wi-Fi 5.2.32 */
1800 /* STA TestBed changes in this item: connexant legacy sta ==> broadcom 11n sta */
1801 if (STA_TGN_WIFI_ON(pAd) &&
1802 pEdcaParm->Aifsn[QID_AC_VI] == 10) {
1803 AifsnCsr.field.Aifsn0 = 3;
1804 AifsnCsr.field.Aifsn2 = 7;
1805 }
1806
1807 if (INFRA_ON(pAd))
1808 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.
1809 Content[BSSID_WCID],
1810 fCLIENT_STATUS_WMM_CAPABLE);
1811 }
1812
1813 {
1814 AifsnCsr.field.Aifsn3 = Ac3Cfg.field.Aifsn - 1; /*pEdcaParm->Aifsn[QID_AC_VO]; //for TGn wifi test */
1815#ifdef RT30xx
1816 /* TODO: Shiang, this modification also suitable for RT3052/RT3050 ??? */
1817 if (pAd->RfIcType == RFIC_3020
1818 || pAd->RfIcType == RFIC_2020) {
1819 AifsnCsr.field.Aifsn2 = 0x2; /*pEdcaParm->Aifsn[QID_AC_VI]; //for WiFi WMM S4-T04. */
1820 }
1821#endif /* RT30xx // */
1822 }
1823 RTMP_IO_WRITE32(pAd, WMM_AIFSN_CFG, AifsnCsr.word);
1824
1825 NdisMoveMemory(&pAd->CommonCfg.APEdcaParm, pEdcaParm,
1826 sizeof(struct rt_edca_parm));
1827 if (!ADHOC_ON(pAd)) {
1828 DBGPRINT(RT_DEBUG_TRACE,
1829 ("EDCA [#%d]: AIFSN CWmin CWmax TXOP(us) ACM\n",
1830 pEdcaParm->EdcaUpdateCount));
1831 DBGPRINT(RT_DEBUG_TRACE,
1832 (" AC_BE %2d %2d %2d %4d %d\n",
1833 pEdcaParm->Aifsn[0], pEdcaParm->Cwmin[0],
1834 pEdcaParm->Cwmax[0], pEdcaParm->Txop[0] << 5,
1835 pEdcaParm->bACM[0]));
1836 DBGPRINT(RT_DEBUG_TRACE,
1837 (" AC_BK %2d %2d %2d %4d %d\n",
1838 pEdcaParm->Aifsn[1], pEdcaParm->Cwmin[1],
1839 pEdcaParm->Cwmax[1], pEdcaParm->Txop[1] << 5,
1840 pEdcaParm->bACM[1]));
1841 DBGPRINT(RT_DEBUG_TRACE,
1842 (" AC_VI %2d %2d %2d %4d %d\n",
1843 pEdcaParm->Aifsn[2], pEdcaParm->Cwmin[2],
1844 pEdcaParm->Cwmax[2], pEdcaParm->Txop[2] << 5,
1845 pEdcaParm->bACM[2]));
1846 DBGPRINT(RT_DEBUG_TRACE,
1847 (" AC_VO %2d %2d %2d %4d %d\n",
1848 pEdcaParm->Aifsn[3], pEdcaParm->Cwmin[3],
1849 pEdcaParm->Cwmax[3], pEdcaParm->Txop[3] << 5,
1850 pEdcaParm->bACM[3]));
1851 }
1852 }
1853
1854}
1855
1856/*
1857 ==========================================================================
1858 Description:
1859
1860 IRQL = PASSIVE_LEVEL
1861 IRQL = DISPATCH_LEVEL
1862
1863 ==========================================================================
1864 */
1865void AsicSetSlotTime(struct rt_rtmp_adapter *pAd, IN BOOLEAN bUseShortSlotTime)
1866{
1867 unsigned long SlotTime;
1868 u32 RegValue = 0;
1869
1870 if (pAd->CommonCfg.Channel > 14)
1871 bUseShortSlotTime = TRUE;
1872
1873 if (bUseShortSlotTime
1874 && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED))
1875 return;
1876 else if ((!bUseShortSlotTime)
1877 && (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED)))
1878 return;
1879
1880 if (bUseShortSlotTime)
1881 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
1882 else
1883 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
1884
1885 SlotTime = (bUseShortSlotTime) ? 9 : 20;
1886
1887 {
1888 /* force using short SLOT time for FAE to demo performance when TxBurst is ON */
1889 if (((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
1890 && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED)))
1891 || ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE)
1892 && (pAd->CommonCfg.BACapability.field.Policy ==
1893 BA_NOTUSE))
1894 ) {
1895 /* In this case, we will think it is doing Wi-Fi test */
1896 /* And we will not set to short slot when bEnableTxBurst is TRUE. */
1897 } else if (pAd->CommonCfg.bEnableTxBurst) {
1898 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
1899 SlotTime = 9;
1900 }
1901 }
1902
1903 /* */
1904 /* For some reasons, always set it to short slot time. */
1905 /* */
1906 /* ToDo: Should consider capability with 11B */
1907 /* */
1908 {
1909 if (pAd->StaCfg.BssType == BSS_ADHOC) {
1910 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
1911 SlotTime = 20;
1912 }
1913 }
1914
1915 RTMP_IO_READ32(pAd, BKOFF_SLOT_CFG, &RegValue);
1916 RegValue = RegValue & 0xFFFFFF00;
1917
1918 RegValue |= SlotTime;
1919
1920 RTMP_IO_WRITE32(pAd, BKOFF_SLOT_CFG, RegValue);
1921}
1922
1923/*
1924 ========================================================================
1925 Description:
1926 Add Shared key information into ASIC.
1927 Update shared key, TxMic and RxMic to Asic Shared key table
1928 Update its cipherAlg to Asic Shared key Mode.
1929
1930 Return:
1931 ========================================================================
1932*/
1933void AsicAddSharedKeyEntry(struct rt_rtmp_adapter *pAd,
1934 u8 BssIndex,
1935 u8 KeyIdx,
1936 u8 CipherAlg,
1937 u8 *pKey, u8 *pTxMic, u8 *pRxMic)
1938{
1939 unsigned long offset; /*, csr0; */
1940 SHAREDKEY_MODE_STRUC csr1;
1941#ifdef RTMP_MAC_PCI
1942 int i;
1943#endif /* RTMP_MAC_PCI // */
1944
1945 DBGPRINT(RT_DEBUG_TRACE,
1946 ("AsicAddSharedKeyEntry BssIndex=%d, KeyIdx=%d\n", BssIndex,
1947 KeyIdx));
1948/*============================================================================================ */
1949
1950 DBGPRINT(RT_DEBUG_TRACE,
1951 ("AsicAddSharedKeyEntry: %s key #%d\n", CipherName[CipherAlg],
1952 BssIndex * 4 + KeyIdx));
1953 DBGPRINT_RAW(RT_DEBUG_TRACE,
1954 (" Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
1955 pKey[0], pKey[1], pKey[2], pKey[3], pKey[4],
1956 pKey[5], pKey[6], pKey[7], pKey[8], pKey[9],
1957 pKey[10], pKey[11], pKey[12], pKey[13], pKey[14],
1958 pKey[15]));
1959 if (pRxMic) {
1960 DBGPRINT_RAW(RT_DEBUG_TRACE,
1961 (" Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
1962 pRxMic[0], pRxMic[1], pRxMic[2], pRxMic[3],
1963 pRxMic[4], pRxMic[5], pRxMic[6], pRxMic[7]));
1964 }
1965 if (pTxMic) {
1966 DBGPRINT_RAW(RT_DEBUG_TRACE,
1967 (" Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
1968 pTxMic[0], pTxMic[1], pTxMic[2], pTxMic[3],
1969 pTxMic[4], pTxMic[5], pTxMic[6], pTxMic[7]));
1970 }
1971/*============================================================================================ */
1972 /* */
1973 /* fill key material - key + TX MIC + RX MIC */
1974 /* */
1975#ifdef RTMP_MAC_PCI
1976 offset =
1977 SHARED_KEY_TABLE_BASE + (4 * BssIndex + KeyIdx) * HW_KEY_ENTRY_SIZE;
1978 for (i = 0; i < MAX_LEN_OF_SHARE_KEY; i++) {
1979 RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
1980 }
1981
1982 offset += MAX_LEN_OF_SHARE_KEY;
1983 if (pTxMic) {
1984 for (i = 0; i < 8; i++) {
1985 RTMP_IO_WRITE8(pAd, offset + i, pTxMic[i]);
1986 }
1987 }
1988
1989 offset += 8;
1990 if (pRxMic) {
1991 for (i = 0; i < 8; i++) {
1992 RTMP_IO_WRITE8(pAd, offset + i, pRxMic[i]);
1993 }
1994 }
1995#endif /* RTMP_MAC_PCI // */
1996#ifdef RTMP_MAC_USB
1997 {
1998 offset =
1999 SHARED_KEY_TABLE_BASE + (4 * BssIndex +
2000 KeyIdx) * HW_KEY_ENTRY_SIZE;
2001 RTUSBMultiWrite(pAd, offset, pKey, MAX_LEN_OF_SHARE_KEY);
2002
2003 offset += MAX_LEN_OF_SHARE_KEY;
2004 if (pTxMic) {
2005 RTUSBMultiWrite(pAd, offset, pTxMic, 8);
2006 }
2007
2008 offset += 8;
2009 if (pRxMic) {
2010 RTUSBMultiWrite(pAd, offset, pRxMic, 8);
2011 }
2012 }
2013#endif /* RTMP_MAC_USB // */
2014
2015 /* */
2016 /* Update cipher algorithm. WSTA always use BSS0 */
2017 /* */
2018 RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2),
2019 &csr1.word);
2020 DBGPRINT(RT_DEBUG_TRACE,
2021 ("Read: SHARED_KEY_MODE_BASE at this Bss[%d] KeyIdx[%d]= 0x%x \n",
2022 BssIndex, KeyIdx, csr1.word));
2023 if ((BssIndex % 2) == 0) {
2024 if (KeyIdx == 0)
2025 csr1.field.Bss0Key0CipherAlg = CipherAlg;
2026 else if (KeyIdx == 1)
2027 csr1.field.Bss0Key1CipherAlg = CipherAlg;
2028 else if (KeyIdx == 2)
2029 csr1.field.Bss0Key2CipherAlg = CipherAlg;
2030 else
2031 csr1.field.Bss0Key3CipherAlg = CipherAlg;
2032 } else {
2033 if (KeyIdx == 0)
2034 csr1.field.Bss1Key0CipherAlg = CipherAlg;
2035 else if (KeyIdx == 1)
2036 csr1.field.Bss1Key1CipherAlg = CipherAlg;
2037 else if (KeyIdx == 2)
2038 csr1.field.Bss1Key2CipherAlg = CipherAlg;
2039 else
2040 csr1.field.Bss1Key3CipherAlg = CipherAlg;
2041 }
2042 DBGPRINT(RT_DEBUG_TRACE,
2043 ("Write: SHARED_KEY_MODE_BASE at this Bss[%d] = 0x%x \n",
2044 BssIndex, csr1.word));
2045 RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2),
2046 csr1.word);
2047
2048}
2049
2050/* IRQL = DISPATCH_LEVEL */
2051void AsicRemoveSharedKeyEntry(struct rt_rtmp_adapter *pAd,
2052 u8 BssIndex, u8 KeyIdx)
2053{
2054 /*unsigned long SecCsr0; */
2055 SHAREDKEY_MODE_STRUC csr1;
2056
2057 DBGPRINT(RT_DEBUG_TRACE,
2058 ("AsicRemoveSharedKeyEntry: #%d \n", BssIndex * 4 + KeyIdx));
2059
2060 RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2),
2061 &csr1.word);
2062 if ((BssIndex % 2) == 0) {
2063 if (KeyIdx == 0)
2064 csr1.field.Bss0Key0CipherAlg = 0;
2065 else if (KeyIdx == 1)
2066 csr1.field.Bss0Key1CipherAlg = 0;
2067 else if (KeyIdx == 2)
2068 csr1.field.Bss0Key2CipherAlg = 0;
2069 else
2070 csr1.field.Bss0Key3CipherAlg = 0;
2071 } else {
2072 if (KeyIdx == 0)
2073 csr1.field.Bss1Key0CipherAlg = 0;
2074 else if (KeyIdx == 1)
2075 csr1.field.Bss1Key1CipherAlg = 0;
2076 else if (KeyIdx == 2)
2077 csr1.field.Bss1Key2CipherAlg = 0;
2078 else
2079 csr1.field.Bss1Key3CipherAlg = 0;
2080 }
2081 DBGPRINT(RT_DEBUG_TRACE,
2082 ("Write: SHARED_KEY_MODE_BASE at this Bss[%d] = 0x%x \n",
2083 BssIndex, csr1.word));
2084 RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2),
2085 csr1.word);
2086 ASSERT(BssIndex < 4);
2087 ASSERT(KeyIdx < 4);
2088
2089}
2090
2091void AsicUpdateWCIDAttribute(struct rt_rtmp_adapter *pAd,
2092 u16 WCID,
2093 u8 BssIndex,
2094 u8 CipherAlg,
2095 IN BOOLEAN bUsePairewiseKeyTable)
2096{
2097 unsigned long WCIDAttri = 0, offset;
2098
2099 /* */
2100 /* Update WCID attribute. */
2101 /* Only TxKey could update WCID attribute. */
2102 /* */
2103 offset = MAC_WCID_ATTRIBUTE_BASE + (WCID * HW_WCID_ATTRI_SIZE);
2104 WCIDAttri =
2105 (BssIndex << 4) | (CipherAlg << 1) | (bUsePairewiseKeyTable);
2106 RTMP_IO_WRITE32(pAd, offset, WCIDAttri);
2107}
2108
2109void AsicUpdateWCIDIVEIV(struct rt_rtmp_adapter *pAd,
2110 u16 WCID, unsigned long uIV, unsigned long uEIV)
2111{
2112 unsigned long offset;
2113
2114 offset = MAC_IVEIV_TABLE_BASE + (WCID * HW_IVEIV_ENTRY_SIZE);
2115
2116 RTMP_IO_WRITE32(pAd, offset, uIV);
2117 RTMP_IO_WRITE32(pAd, offset + 4, uEIV);
2118}
2119
2120void AsicUpdateRxWCIDTable(struct rt_rtmp_adapter *pAd,
2121 u16 WCID, u8 *pAddr)
2122{
2123 unsigned long offset;
2124 unsigned long Addr;
2125
2126 offset = MAC_WCID_BASE + (WCID * HW_WCID_ENTRY_SIZE);
2127 Addr = pAddr[0] + (pAddr[1] << 8) + (pAddr[2] << 16) + (pAddr[3] << 24);
2128 RTMP_IO_WRITE32(pAd, offset, Addr);
2129 Addr = pAddr[4] + (pAddr[5] << 8);
2130 RTMP_IO_WRITE32(pAd, offset + 4, Addr);
2131}
2132
2133/*
2134 ========================================================================
2135
2136 Routine Description:
2137 Set Cipher Key, Cipher algorithm, IV/EIV to Asic
2138
2139 Arguments:
2140 pAd Pointer to our adapter
2141 WCID WCID Entry number.
2142 BssIndex BSSID index, station or none multiple BSSID support
2143 this value should be 0.
2144 KeyIdx This KeyIdx will set to IV's KeyID if bTxKey enabled
2145 pCipherKey Pointer to Cipher Key.
2146 bUsePairewiseKeyTable TRUE means saved the key in SharedKey table,
2147 otherwise PairewiseKey table
2148 bTxKey This is the transmit key if enabled.
2149
2150 Return Value:
2151 None
2152
2153 Note:
2154 This routine will set the relative key stuff to Asic including WCID attribute,
2155 Cipher Key, Cipher algorithm and IV/EIV.
2156
2157 IV/EIV will be update if this CipherKey is the transmission key because
2158 ASIC will base on IV's KeyID value to select Cipher Key.
2159
2160 If bTxKey sets to FALSE, this is not the TX key, but it could be
2161 RX key
2162
2163 For AP mode bTxKey must be always set to TRUE.
2164 ========================================================================
2165*/
2166void AsicAddKeyEntry(struct rt_rtmp_adapter *pAd,
2167 u16 WCID,
2168 u8 BssIndex,
2169 u8 KeyIdx,
2170 struct rt_cipher_key *pCipherKey,
2171 IN BOOLEAN bUsePairewiseKeyTable, IN BOOLEAN bTxKey)
2172{
2173 unsigned long offset;
2174/* unsigned long WCIDAttri = 0; */
2175 u8 IV4 = 0;
2176 u8 *pKey = pCipherKey->Key;
2177/* unsigned long KeyLen = pCipherKey->KeyLen; */
2178 u8 *pTxMic = pCipherKey->TxMic;
2179 u8 *pRxMic = pCipherKey->RxMic;
2180 u8 *pTxtsc = pCipherKey->TxTsc;
2181 u8 CipherAlg = pCipherKey->CipherAlg;
2182 SHAREDKEY_MODE_STRUC csr1;
2183#ifdef RTMP_MAC_PCI
2184 u8 i;
2185#endif /* RTMP_MAC_PCI // */
2186
2187/* ASSERT(KeyLen <= MAX_LEN_OF_PEER_KEY); */
2188
2189 DBGPRINT(RT_DEBUG_TRACE, ("==> AsicAddKeyEntry\n"));
2190 /* */
2191 /* 1.) decide key table offset */
2192 /* */
2193 if (bUsePairewiseKeyTable)
2194 offset = PAIRWISE_KEY_TABLE_BASE + (WCID * HW_KEY_ENTRY_SIZE);
2195 else
2196 offset =
2197 SHARED_KEY_TABLE_BASE + (4 * BssIndex +
2198 KeyIdx) * HW_KEY_ENTRY_SIZE;
2199
2200 /* */
2201 /* 2.) Set Key to Asic */
2202 /* */
2203 /*for (i = 0; i < KeyLen; i++) */
2204#ifdef RTMP_MAC_PCI
2205 for (i = 0; i < MAX_LEN_OF_PEER_KEY; i++) {
2206 RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
2207 }
2208 offset += MAX_LEN_OF_PEER_KEY;
2209
2210 /* */
2211 /* 3.) Set MIC key if available */
2212 /* */
2213 if (pTxMic) {
2214 for (i = 0; i < 8; i++) {
2215 RTMP_IO_WRITE8(pAd, offset + i, pTxMic[i]);
2216 }
2217 }
2218 offset += LEN_TKIP_TXMICK;
2219
2220 if (pRxMic) {
2221 for (i = 0; i < 8; i++) {
2222 RTMP_IO_WRITE8(pAd, offset + i, pRxMic[i]);
2223 }
2224 }
2225#endif /* RTMP_MAC_PCI // */
2226#ifdef RTMP_MAC_USB
2227 RTUSBMultiWrite(pAd, offset, pKey, MAX_LEN_OF_PEER_KEY);
2228 offset += MAX_LEN_OF_PEER_KEY;
2229
2230 /* */
2231 /* 3.) Set MIC key if available */
2232 /* */
2233 if (pTxMic) {
2234 RTUSBMultiWrite(pAd, offset, pTxMic, 8);
2235 }
2236 offset += LEN_TKIP_TXMICK;
2237
2238 if (pRxMic) {
2239 RTUSBMultiWrite(pAd, offset, pRxMic, 8);
2240 }
2241#endif /* RTMP_MAC_USB // */
2242
2243 /* */
2244 /* 4.) Modify IV/EIV if needs */
2245 /* This will force Asic to use this key ID by setting IV. */
2246 /* */
2247 if (bTxKey) {
2248#ifdef RTMP_MAC_PCI
2249 offset = MAC_IVEIV_TABLE_BASE + (WCID * HW_IVEIV_ENTRY_SIZE);
2250 /* */
2251 /* Write IV */
2252 /* */
2253 RTMP_IO_WRITE8(pAd, offset, pTxtsc[1]);
2254 RTMP_IO_WRITE8(pAd, offset + 1, ((pTxtsc[1] | 0x20) & 0x7f));
2255 RTMP_IO_WRITE8(pAd, offset + 2, pTxtsc[0]);
2256
2257 IV4 = (KeyIdx << 6);
2258 if ((CipherAlg == CIPHER_TKIP)
2259 || (CipherAlg == CIPHER_TKIP_NO_MIC)
2260 || (CipherAlg == CIPHER_AES))
2261 IV4 |= 0x20; /* turn on extension bit means EIV existence */
2262
2263 RTMP_IO_WRITE8(pAd, offset + 3, IV4);
2264
2265 /* */
2266 /* Write EIV */
2267 /* */
2268 offset += 4;
2269 for (i = 0; i < 4; i++) {
2270 RTMP_IO_WRITE8(pAd, offset + i, pTxtsc[i + 2]);
2271 }
2272#endif /* RTMP_MAC_PCI // */
2273#ifdef RTMP_MAC_USB
2274 u32 tmpVal;
2275
2276 /* */
2277 /* Write IV */
2278 /* */
2279 IV4 = (KeyIdx << 6);
2280 if ((CipherAlg == CIPHER_TKIP)
2281 || (CipherAlg == CIPHER_TKIP_NO_MIC)
2282 || (CipherAlg == CIPHER_AES))
2283 IV4 |= 0x20; /* turn on extension bit means EIV existence */
2284
2285 tmpVal =
2286 pTxtsc[1] + (((pTxtsc[1] | 0x20) & 0x7f) << 8) +
2287 (pTxtsc[0] << 16) + (IV4 << 24);
2288 RTMP_IO_WRITE32(pAd, offset, tmpVal);
2289
2290 /* */
2291 /* Write EIV */
2292 /* */
2293 offset += 4;
2294 RTMP_IO_WRITE32(pAd, offset, *(u32 *)& pCipherKey->TxTsc[2]);
2295#endif /* RTMP_MAC_USB // */
2296
2297 AsicUpdateWCIDAttribute(pAd, WCID, BssIndex, CipherAlg,
2298 bUsePairewiseKeyTable);
2299 }
2300
2301 if (!bUsePairewiseKeyTable) {
2302 /* */
2303 /* Only update the shared key security mode */
2304 /* */
2305 RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2),
2306 &csr1.word);
2307 if ((BssIndex % 2) == 0) {
2308 if (KeyIdx == 0)
2309 csr1.field.Bss0Key0CipherAlg = CipherAlg;
2310 else if (KeyIdx == 1)
2311 csr1.field.Bss0Key1CipherAlg = CipherAlg;
2312 else if (KeyIdx == 2)
2313 csr1.field.Bss0Key2CipherAlg = CipherAlg;
2314 else
2315 csr1.field.Bss0Key3CipherAlg = CipherAlg;
2316 } else {
2317 if (KeyIdx == 0)
2318 csr1.field.Bss1Key0CipherAlg = CipherAlg;
2319 else if (KeyIdx == 1)
2320 csr1.field.Bss1Key1CipherAlg = CipherAlg;
2321 else if (KeyIdx == 2)
2322 csr1.field.Bss1Key2CipherAlg = CipherAlg;
2323 else
2324 csr1.field.Bss1Key3CipherAlg = CipherAlg;
2325 }
2326 RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2),
2327 csr1.word);
2328 }
2329
2330 DBGPRINT(RT_DEBUG_TRACE, ("<== AsicAddKeyEntry\n"));
2331}
2332
2333/*
2334 ========================================================================
2335 Description:
2336 Add Pair-wise key material into ASIC.
2337 Update pairwise key, TxMic and RxMic to Asic Pair-wise key table
2338
2339 Return:
2340 ========================================================================
2341*/
2342void AsicAddPairwiseKeyEntry(struct rt_rtmp_adapter *pAd,
2343 u8 *pAddr,
2344 u8 WCID, struct rt_cipher_key *pCipherKey)
2345{
2346 int i;
2347 unsigned long offset;
2348 u8 *pKey = pCipherKey->Key;
2349 u8 *pTxMic = pCipherKey->TxMic;
2350 u8 *pRxMic = pCipherKey->RxMic;
2351#ifdef DBG
2352 u8 CipherAlg = pCipherKey->CipherAlg;
2353#endif /* DBG // */
2354
2355 /* EKEY */
2356 offset = PAIRWISE_KEY_TABLE_BASE + (WCID * HW_KEY_ENTRY_SIZE);
2357#ifdef RTMP_MAC_PCI
2358 for (i = 0; i < MAX_LEN_OF_PEER_KEY; i++) {
2359 RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
2360 }
2361#endif /* RTMP_MAC_PCI // */
2362#ifdef RTMP_MAC_USB
2363 RTUSBMultiWrite(pAd, offset, &pCipherKey->Key[0], MAX_LEN_OF_PEER_KEY);
2364#endif /* RTMP_MAC_USB // */
2365 for (i = 0; i < MAX_LEN_OF_PEER_KEY; i += 4) {
2366 u32 Value;
2367 RTMP_IO_READ32(pAd, offset + i, &Value);
2368 }
2369
2370 offset += MAX_LEN_OF_PEER_KEY;
2371
2372 /* MIC KEY */
2373 if (pTxMic) {
2374#ifdef RTMP_MAC_PCI
2375 for (i = 0; i < 8; i++) {
2376 RTMP_IO_WRITE8(pAd, offset + i, pTxMic[i]);
2377 }
2378#endif /* RTMP_MAC_PCI // */
2379#ifdef RTMP_MAC_USB
2380 RTUSBMultiWrite(pAd, offset, &pCipherKey->TxMic[0], 8);
2381#endif /* RTMP_MAC_USB // */
2382 }
2383 offset += 8;
2384 if (pRxMic) {
2385#ifdef RTMP_MAC_PCI
2386 for (i = 0; i < 8; i++) {
2387 RTMP_IO_WRITE8(pAd, offset + i, pRxMic[i]);
2388 }
2389#endif /* RTMP_MAC_PCI // */
2390#ifdef RTMP_MAC_USB
2391 RTUSBMultiWrite(pAd, offset, &pCipherKey->RxMic[0], 8);
2392#endif /* RTMP_MAC_USB // */
2393 }
2394
2395 DBGPRINT(RT_DEBUG_TRACE,
2396 ("AsicAddPairwiseKeyEntry: WCID #%d Alg=%s\n", WCID,
2397 CipherName[CipherAlg]));
2398 DBGPRINT(RT_DEBUG_TRACE,
2399 (" Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
2400 pKey[0], pKey[1], pKey[2], pKey[3], pKey[4], pKey[5],
2401 pKey[6], pKey[7], pKey[8], pKey[9], pKey[10], pKey[11],
2402 pKey[12], pKey[13], pKey[14], pKey[15]));
2403 if (pRxMic) {
2404 DBGPRINT(RT_DEBUG_TRACE,
2405 (" Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
2406 pRxMic[0], pRxMic[1], pRxMic[2], pRxMic[3],
2407 pRxMic[4], pRxMic[5], pRxMic[6], pRxMic[7]));
2408 }
2409 if (pTxMic) {
2410 DBGPRINT(RT_DEBUG_TRACE,
2411 (" Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
2412 pTxMic[0], pTxMic[1], pTxMic[2], pTxMic[3],
2413 pTxMic[4], pTxMic[5], pTxMic[6], pTxMic[7]));
2414 }
2415}
2416
2417/*
2418 ========================================================================
2419 Description:
2420 Remove Pair-wise key material from ASIC.
2421
2422 Return:
2423 ========================================================================
2424*/
2425void AsicRemovePairwiseKeyEntry(struct rt_rtmp_adapter *pAd,
2426 u8 BssIdx, u8 Wcid)
2427{
2428 unsigned long WCIDAttri;
2429 u16 offset;
2430
2431 /* re-set the entry's WCID attribute as OPEN-NONE. */
2432 offset = MAC_WCID_ATTRIBUTE_BASE + (Wcid * HW_WCID_ATTRI_SIZE);
2433 WCIDAttri = (BssIdx << 4) | PAIRWISEKEYTABLE;
2434 RTMP_IO_WRITE32(pAd, offset, WCIDAttri);
2435}
2436
2437BOOLEAN AsicSendCommandToMcu(struct rt_rtmp_adapter *pAd,
2438 u8 Command,
2439 u8 Token, u8 Arg0, u8 Arg1)
2440{
2441
2442 if (pAd->chipOps.sendCommandToMcu)
2443 pAd->chipOps.sendCommandToMcu(pAd, Command, Token, Arg0, Arg1);
2444
2445 return TRUE;
2446}
2447
2448void AsicSetRxAnt(struct rt_rtmp_adapter *pAd, u8 Ant)
2449{
2450#ifdef RT30xx
2451 /* RT3572 ATE need not to do this. */
2452 RT30xxSetRxAnt(pAd, Ant);
2453#endif /* RT30xx // */
2454}
2455
2456void AsicTurnOffRFClk(struct rt_rtmp_adapter *pAd, u8 Channel)
2457{
2458 if (pAd->chipOps.AsicRfTurnOff) {
2459 pAd->chipOps.AsicRfTurnOff(pAd);
2460 } else {
2461 /* RF R2 bit 18 = 0 */
2462 u32 R1 = 0, R2 = 0, R3 = 0;
2463 u8 index;
2464 struct rt_rtmp_rf_regs *RFRegTable;
2465
2466 RFRegTable = RF2850RegTable;
2467
2468 switch (pAd->RfIcType) {
2469 case RFIC_2820:
2470 case RFIC_2850:
2471 case RFIC_2720:
2472 case RFIC_2750:
2473
2474 for (index = 0; index < NUM_OF_2850_CHNL; index++) {
2475 if (Channel == RFRegTable[index].Channel) {
2476 R1 = RFRegTable[index].R1 & 0xffffdfff;
2477 R2 = RFRegTable[index].R2 & 0xfffbffff;
2478 R3 = RFRegTable[index].R3 & 0xfff3ffff;
2479
2480 RTMP_RF_IO_WRITE32(pAd, R1);
2481 RTMP_RF_IO_WRITE32(pAd, R2);
2482
2483 /* Program R1b13 to 1, R3/b18,19 to 0, R2b18 to 0. */
2484 /* Set RF R2 bit18=0, R3 bit[18:19]=0 */
2485 /*if (pAd->StaCfg.bRadio == FALSE) */
2486 if (1) {
2487 RTMP_RF_IO_WRITE32(pAd, R3);
2488
2489 DBGPRINT(RT_DEBUG_TRACE,
2490 ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x, R3 = 0x%08x \n",
2491 Channel,
2492 pAd->RfIcType, R2,
2493 R3));
2494 } else
2495 DBGPRINT(RT_DEBUG_TRACE,
2496 ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x \n",
2497 Channel,
2498 pAd->RfIcType, R2));
2499 break;
2500 }
2501 }
2502 break;
2503
2504 default:
2505 break;
2506 }
2507 }
2508}
2509
2510void AsicTurnOnRFClk(struct rt_rtmp_adapter *pAd, u8 Channel)
2511{
2512 /* RF R2 bit 18 = 0 */
2513 u32 R1 = 0, R2 = 0, R3 = 0;
2514 u8 index;
2515 struct rt_rtmp_rf_regs *RFRegTable;
2516
2517#ifdef PCIE_PS_SUPPORT
2518 /* The RF programming sequence is difference between 3xxx and 2xxx */
2519 if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))) {
2520 return;
2521 }
2522#endif /* PCIE_PS_SUPPORT // */
2523
2524 RFRegTable = RF2850RegTable;
2525
2526 switch (pAd->RfIcType) {
2527 case RFIC_2820:
2528 case RFIC_2850:
2529 case RFIC_2720:
2530 case RFIC_2750:
2531
2532 for (index = 0; index < NUM_OF_2850_CHNL; index++) {
2533 if (Channel == RFRegTable[index].Channel) {
2534 R3 = pAd->LatchRfRegs.R3;
2535 R3 &= 0xfff3ffff;
2536 R3 |= 0x00080000;
2537 RTMP_RF_IO_WRITE32(pAd, R3);
2538
2539 R1 = RFRegTable[index].R1;
2540 RTMP_RF_IO_WRITE32(pAd, R1);
2541
2542 R2 = RFRegTable[index].R2;
2543 if (pAd->Antenna.field.TxPath == 1) {
2544 R2 |= 0x4000; /* If TXpath is 1, bit 14 = 1; */
2545 }
2546
2547 if (pAd->Antenna.field.RxPath == 2) {
2548 R2 |= 0x40; /* write 1 to off Rxpath. */
2549 } else if (pAd->Antenna.field.RxPath == 1) {
2550 R2 |= 0x20040; /* write 1 to off RxPath */
2551 }
2552 RTMP_RF_IO_WRITE32(pAd, R2);
2553
2554 break;
2555 }
2556 }
2557 break;
2558
2559 default:
2560 break;
2561 }
2562
2563 DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOnRFClk#%d(RF=%d, ) , R2=0x%08x\n",
2564 Channel, pAd->RfIcType, R2));
2565}
diff --git a/drivers/staging/rt2860/common/cmm_cfg.c b/drivers/staging/rt2860/common/cmm_cfg.c
deleted file mode 100644
index 727f7992925..00000000000
--- a/drivers/staging/rt2860/common/cmm_cfg.c
+++ /dev/null
@@ -1,258 +0,0 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 cmm_cfg.c
29
30 Abstract:
31 Ralink WiFi Driver configuration related subroutines
32
33 Revision History:
34 Who When What
35 --------- ---------- ----------------------------------------------
36*/
37
38#include "../rt_config.h"
39
40char *GetPhyMode(int Mode)
41{
42 switch (Mode) {
43 case MODE_CCK:
44 return "CCK";
45
46 case MODE_OFDM:
47 return "OFDM";
48 case MODE_HTMIX:
49 return "HTMIX";
50
51 case MODE_HTGREENFIELD:
52 return "GREEN";
53 default:
54 return "N/A";
55 }
56}
57
58char *GetBW(int BW)
59{
60 switch (BW) {
61 case BW_10:
62 return "10M";
63
64 case BW_20:
65 return "20M";
66 case BW_40:
67 return "40M";
68 default:
69 return "N/A";
70 }
71}
72
73/*
74 ==========================================================================
75 Description:
76 Set Country Region to pAd->CommonCfg.CountryRegion.
77 This command will not work, if the field of CountryRegion in eeprom is programmed.
78
79 Return:
80 TRUE if all parameters are OK, FALSE otherwise
81 ==========================================================================
82*/
83int RT_CfgSetCountryRegion(struct rt_rtmp_adapter *pAd, char *arg, int band)
84{
85 long region, regionMax;
86 u8 *pCountryRegion;
87
88 region = simple_strtol(arg, 0, 10);
89
90 if (band == BAND_24G) {
91 pCountryRegion = &pAd->CommonCfg.CountryRegion;
92 regionMax = REGION_MAXIMUM_BG_BAND;
93 } else {
94 pCountryRegion = &pAd->CommonCfg.CountryRegionForABand;
95 regionMax = REGION_MAXIMUM_A_BAND;
96 }
97
98 /* TODO: Is it neccesay for following check??? */
99 /* Country can be set only when EEPROM not programmed */
100 if (*pCountryRegion & 0x80) {
101 DBGPRINT(RT_DEBUG_ERROR,
102 ("CfgSetCountryRegion():CountryRegion in eeprom was programmed\n"));
103 return FALSE;
104 }
105
106 if ((region >= 0) && (region <= REGION_MAXIMUM_BG_BAND)) {
107 *pCountryRegion = (u8)region;
108 } else if ((region == REGION_31_BG_BAND) && (band == BAND_24G)) {
109 *pCountryRegion = (u8)region;
110 } else {
111 DBGPRINT(RT_DEBUG_ERROR,
112 ("CfgSetCountryRegion():region(%ld) out of range!\n",
113 region));
114 return FALSE;
115 }
116
117 return TRUE;
118
119}
120
121/*
122 ==========================================================================
123 Description:
124 Set Wireless Mode
125 Return:
126 TRUE if all parameters are OK, FALSE otherwise
127 ==========================================================================
128*/
129int RT_CfgSetWirelessMode(struct rt_rtmp_adapter *pAd, char *arg)
130{
131 int MaxPhyMode = PHY_11G;
132 long WirelessMode;
133
134 MaxPhyMode = PHY_11N_5G;
135
136 WirelessMode = simple_strtol(arg, 0, 10);
137 if (WirelessMode <= MaxPhyMode) {
138 pAd->CommonCfg.PhyMode = WirelessMode;
139 return TRUE;
140 }
141
142 return FALSE;
143
144}
145
146int RT_CfgSetShortSlot(struct rt_rtmp_adapter *pAd, char *arg)
147{
148 long ShortSlot;
149
150 ShortSlot = simple_strtol(arg, 0, 10);
151
152 if (ShortSlot == 1)
153 pAd->CommonCfg.bUseShortSlotTime = TRUE;
154 else if (ShortSlot == 0)
155 pAd->CommonCfg.bUseShortSlotTime = FALSE;
156 else
157 return FALSE; /*Invalid argument */
158
159 return TRUE;
160}
161
162/*
163 ==========================================================================
164 Description:
165 Set WEP KEY base on KeyIdx
166 Return:
167 TRUE if all parameters are OK, FALSE otherwise
168 ==========================================================================
169*/
170int RT_CfgSetWepKey(struct rt_rtmp_adapter *pAd,
171 char *keyString,
172 struct rt_cipher_key *pSharedKey, int keyIdx)
173{
174 int KeyLen;
175 int i;
176 u8 CipherAlg = CIPHER_NONE;
177 BOOLEAN bKeyIsHex = FALSE;
178
179 /* TODO: Shall we do memset for the original key info?? */
180 memset(pSharedKey, 0, sizeof(struct rt_cipher_key));
181 KeyLen = strlen(keyString);
182 switch (KeyLen) {
183 case 5: /*wep 40 Ascii type */
184 case 13: /*wep 104 Ascii type */
185 bKeyIsHex = FALSE;
186 pSharedKey->KeyLen = KeyLen;
187 NdisMoveMemory(pSharedKey->Key, keyString, KeyLen);
188 break;
189
190 case 10: /*wep 40 Hex type */
191 case 26: /*wep 104 Hex type */
192 for (i = 0; i < KeyLen; i++) {
193 if (!isxdigit(*(keyString + i)))
194 return FALSE; /*Not Hex value; */
195 }
196 bKeyIsHex = TRUE;
197 pSharedKey->KeyLen = KeyLen / 2;
198 AtoH(keyString, pSharedKey->Key, pSharedKey->KeyLen);
199 break;
200
201 default: /*Invalid argument */
202 DBGPRINT(RT_DEBUG_TRACE,
203 ("RT_CfgSetWepKey(keyIdx=%d):Invalid argument (arg=%s)\n",
204 keyIdx, keyString));
205 return FALSE;
206 }
207
208 pSharedKey->CipherAlg = ((KeyLen % 5) ? CIPHER_WEP128 : CIPHER_WEP64);
209 DBGPRINT(RT_DEBUG_TRACE,
210 ("RT_CfgSetWepKey:(KeyIdx=%d,type=%s, Alg=%s)\n", keyIdx,
211 (bKeyIsHex == FALSE ? "Ascii" : "Hex"),
212 CipherName[CipherAlg]));
213
214 return TRUE;
215}
216
217/*
218 ==========================================================================
219 Description:
220 Set WPA PSK key
221
222 Arguments:
223 pAdapter Pointer to our adapter
224 keyString WPA pre-shared key string
225 pHashStr String used for password hash function
226 hashStrLen Length of the hash string
227 pPMKBuf Output buffer of WPAPSK key
228
229 Return:
230 TRUE if all parameters are OK, FALSE otherwise
231 ==========================================================================
232*/
233int RT_CfgSetWPAPSKKey(struct rt_rtmp_adapter *pAd,
234 char *keyString,
235 u8 * pHashStr,
236 int hashStrLen, u8 *pPMKBuf)
237{
238 int keyLen;
239 u8 keyMaterial[40];
240
241 keyLen = strlen(keyString);
242 if ((keyLen < 8) || (keyLen > 64)) {
243 DBGPRINT(RT_DEBUG_TRACE,
244 ("WPAPSK Key length(%d) error, required 8 ~ 64 characters!(keyStr=%s)\n",
245 keyLen, keyString));
246 return FALSE;
247 }
248
249 memset(pPMKBuf, 0, 32);
250 if (keyLen == 64) {
251 AtoH(keyString, pPMKBuf, 32);
252 } else {
253 PasswordHash(keyString, pHashStr, hashStrLen, keyMaterial);
254 NdisMoveMemory(pPMKBuf, keyMaterial, 32);
255 }
256
257 return TRUE;
258}
diff --git a/drivers/staging/rt2860/common/cmm_data.c b/drivers/staging/rt2860/common/cmm_data.c
deleted file mode 100644
index 33799e1449a..00000000000
--- a/drivers/staging/rt2860/common/cmm_data.c
+++ /dev/null
@@ -1,2361 +0,0 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26*/
27
28#include "../rt_config.h"
29
30u8 SNAP_802_1H[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
31u8 SNAP_BRIDGE_TUNNEL[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
32
33/* Add Cisco Aironet SNAP heade for CCX2 support */
34u8 SNAP_AIRONET[] = { 0xaa, 0xaa, 0x03, 0x00, 0x40, 0x96, 0x00, 0x00 };
35u8 CKIP_LLC_SNAP[] = { 0xaa, 0xaa, 0x03, 0x00, 0x40, 0x96, 0x00, 0x02 };
36u8 EAPOL_LLC_SNAP[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8e };
37u8 EAPOL[] = { 0x88, 0x8e };
38u8 TPID[] = { 0x81, 0x00 }; /* VLAN related */
39
40u8 IPX[] = { 0x81, 0x37 };
41u8 APPLE_TALK[] = { 0x80, 0xf3 };
42
43u8 RateIdToPlcpSignal[12] = {
44 0, /* RATE_1 */ 1, /* RATE_2 */ 2, /* RATE_5_5 */ 3, /* RATE_11 *//* see BBP spec */
45 11, /* RATE_6 */ 15, /* RATE_9 */ 10, /* RATE_12 */ 14, /* RATE_18 *//* see IEEE802.11a-1999 p.14 */
46 9, /* RATE_24 */ 13, /* RATE_36 */ 8, /* RATE_48 */ 12 /* RATE_54 */
47}; /* see IEEE802.11a-1999 p.14 */
48
49u8 OfdmSignalToRateId[16] = {
50 RATE_54, RATE_54, RATE_54, RATE_54, /* OFDM PLCP Signal = 0, 1, 2, 3 respectively */
51 RATE_54, RATE_54, RATE_54, RATE_54, /* OFDM PLCP Signal = 4, 5, 6, 7 respectively */
52 RATE_48, RATE_24, RATE_12, RATE_6, /* OFDM PLCP Signal = 8, 9, 10, 11 respectively */
53 RATE_54, RATE_36, RATE_18, RATE_9, /* OFDM PLCP Signal = 12, 13, 14, 15 respectively */
54};
55
56u8 OfdmRateToRxwiMCS[12] = {
57 0, 0, 0, 0,
58 0, 1, 2, 3, /* OFDM rate 6,9,12,18 = rxwi mcs 0,1,2,3 */
59 4, 5, 6, 7, /* OFDM rate 24,36,48,54 = rxwi mcs 4,5,6,7 */
60};
61
62u8 RxwiMCSToOfdmRate[12] = {
63 RATE_6, RATE_9, RATE_12, RATE_18,
64 RATE_24, RATE_36, RATE_48, RATE_54, /* OFDM rate 6,9,12,18 = rxwi mcs 0,1,2,3 */
65 4, 5, 6, 7, /* OFDM rate 24,36,48,54 = rxwi mcs 4,5,6,7 */
66};
67
68char *MCSToMbps[] =
69 { "1Mbps", "2Mbps", "5.5Mbps", "11Mbps", "06Mbps", "09Mbps", "12Mbps",
70"18Mbps", "24Mbps", "36Mbps", "48Mbps", "54Mbps", "MM-0", "MM-1", "MM-2", "MM-3",
71"MM-4", "MM-5", "MM-6", "MM-7", "MM-8", "MM-9", "MM-10", "MM-11", "MM-12", "MM-13",
72"MM-14", "MM-15", "MM-32", "ee1", "ee2", "ee3" };
73
74u8 default_cwmin[] =
75 { CW_MIN_IN_BITS, CW_MIN_IN_BITS, CW_MIN_IN_BITS - 1, CW_MIN_IN_BITS - 2 };
76/*u8 default_cwmax[]={CW_MAX_IN_BITS, CW_MAX_IN_BITS, CW_MIN_IN_BITS, CW_MIN_IN_BITS-1}; */
77u8 default_sta_aifsn[] = { 3, 7, 2, 2 };
78
79u8 MapUserPriorityToAccessCategory[8] =
80 { QID_AC_BE, QID_AC_BK, QID_AC_BK, QID_AC_BE, QID_AC_VI, QID_AC_VI,
81QID_AC_VO, QID_AC_VO };
82
83/*
84 ========================================================================
85
86 Routine Description:
87 API for MLME to transmit management frame to AP (BSS Mode)
88 or station (IBSS Mode)
89
90 Arguments:
91 pAd Pointer to our adapter
92 pData Pointer to the outgoing 802.11 frame
93 Length Size of outgoing management frame
94
95 Return Value:
96 NDIS_STATUS_FAILURE
97 NDIS_STATUS_PENDING
98 NDIS_STATUS_SUCCESS
99
100 IRQL = PASSIVE_LEVEL
101 IRQL = DISPATCH_LEVEL
102
103 Note:
104
105 ========================================================================
106*/
107int MiniportMMRequest(struct rt_rtmp_adapter *pAd,
108 u8 QueIdx, u8 *pData, u32 Length)
109{
110 void *pPacket;
111 int Status = NDIS_STATUS_SUCCESS;
112 unsigned long FreeNum;
113 u8 rtmpHwHdr[TXINFO_SIZE + TXWI_SIZE]; /*RTMP_HW_HDR_LEN]; */
114#ifdef RTMP_MAC_PCI
115 unsigned long IrqFlags = 0;
116 u8 IrqState;
117#endif /* RTMP_MAC_PCI // */
118 BOOLEAN bUseDataQ = FALSE;
119 int retryCnt = 0;
120
121 ASSERT(Length <= MGMT_DMA_BUFFER_SIZE);
122
123 if ((QueIdx & MGMT_USE_QUEUE_FLAG) == MGMT_USE_QUEUE_FLAG) {
124 bUseDataQ = TRUE;
125 QueIdx &= (~MGMT_USE_QUEUE_FLAG);
126 }
127#ifdef RTMP_MAC_PCI
128 /* 2860C use Tx Ring */
129 IrqState = pAd->irq_disabled;
130 if (pAd->MACVersion == 0x28600100) {
131 QueIdx = (bUseDataQ == TRUE ? QueIdx : 3);
132 bUseDataQ = TRUE;
133 }
134 if (bUseDataQ && (!IrqState))
135 RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
136#endif /* RTMP_MAC_PCI // */
137
138 do {
139 /* Reset is in progress, stop immediately */
140 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
141 RTMP_TEST_FLAG(pAd,
142 fRTMP_ADAPTER_HALT_IN_PROGRESS |
143 fRTMP_ADAPTER_NIC_NOT_EXIST)
144 || !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP)) {
145 Status = NDIS_STATUS_FAILURE;
146 break;
147 }
148 /* Check Free priority queue */
149 /* Since we use PBF Queue2 for management frame. Its corresponding DMA ring should be using TxRing. */
150#ifdef RTMP_MAC_PCI
151 if (bUseDataQ) {
152 retryCnt = MAX_DATAMM_RETRY;
153 /* free Tx(QueIdx) resources */
154 RTMPFreeTXDUponTxDmaDone(pAd, QueIdx);
155 FreeNum = GET_TXRING_FREENO(pAd, QueIdx);
156 } else
157#endif /* RTMP_MAC_PCI // */
158 {
159 FreeNum = GET_MGMTRING_FREENO(pAd);
160 }
161
162 if ((FreeNum > 0)) {
163 /* We need to reserve space for rtmp hardware header. i.e., TxWI for RT2860 and TxInfo+TxWI for RT2870 */
164 NdisZeroMemory(&rtmpHwHdr, (TXINFO_SIZE + TXWI_SIZE));
165 Status =
166 RTMPAllocateNdisPacket(pAd, &pPacket,
167 (u8 *)& rtmpHwHdr,
168 (TXINFO_SIZE + TXWI_SIZE),
169 pData, Length);
170 if (Status != NDIS_STATUS_SUCCESS) {
171 DBGPRINT(RT_DEBUG_WARN,
172 ("MiniportMMRequest (error:: can't allocate NDIS PACKET)\n"));
173 break;
174 }
175 /*pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK; */
176 /*pAd->CommonCfg.MlmeRate = RATE_2; */
177
178#ifdef RTMP_MAC_PCI
179 if (bUseDataQ) {
180 Status =
181 MlmeDataHardTransmit(pAd, QueIdx, pPacket);
182 retryCnt--;
183 } else
184#endif /* RTMP_MAC_PCI // */
185 Status = MlmeHardTransmit(pAd, QueIdx, pPacket);
186 if (Status == NDIS_STATUS_SUCCESS)
187 retryCnt = 0;
188 else
189 RTMPFreeNdisPacket(pAd, pPacket);
190 } else {
191 pAd->RalinkCounters.MgmtRingFullCount++;
192#ifdef RTMP_MAC_PCI
193 if (bUseDataQ) {
194 retryCnt--;
195 DBGPRINT(RT_DEBUG_TRACE,
196 ("retryCnt %d\n", retryCnt));
197 if (retryCnt == 0) {
198 DBGPRINT(RT_DEBUG_ERROR,
199 ("Qidx(%d), not enough space in DataRing, MgmtRingFullCount=%ld!\n",
200 QueIdx,
201 pAd->RalinkCounters.
202 MgmtRingFullCount));
203 }
204 }
205#endif /* RTMP_MAC_PCI // */
206 DBGPRINT(RT_DEBUG_ERROR,
207 ("Qidx(%d), not enough space in MgmtRing, MgmtRingFullCount=%ld!\n",
208 QueIdx,
209 pAd->RalinkCounters.MgmtRingFullCount));
210 }
211 } while (retryCnt > 0);
212
213#ifdef RTMP_MAC_PCI
214 if (bUseDataQ && (!IrqState))
215 RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
216#endif /* RTMP_MAC_PCI // */
217
218 return Status;
219}
220
221/*
222 ========================================================================
223
224 Routine Description:
225 Copy frame from waiting queue into relative ring buffer and set
226 appropriate ASIC register to kick hardware transmit function
227
228 Arguments:
229 pAd Pointer to our adapter
230 pBuffer Pointer to memory of outgoing frame
231 Length Size of outgoing management frame
232
233 Return Value:
234 NDIS_STATUS_FAILURE
235 NDIS_STATUS_PENDING
236 NDIS_STATUS_SUCCESS
237
238 IRQL = PASSIVE_LEVEL
239 IRQL = DISPATCH_LEVEL
240
241 Note:
242
243 ========================================================================
244*/
245int MlmeHardTransmit(struct rt_rtmp_adapter *pAd,
246 u8 QueIdx, void *pPacket)
247{
248 struct rt_packet_info PacketInfo;
249 u8 *pSrcBufVA;
250 u32 SrcBufLen;
251 struct rt_header_802_11 * pHeader_802_11;
252
253 if ((pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)
254 ) {
255 return NDIS_STATUS_FAILURE;
256 }
257
258 RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
259 if (pSrcBufVA == NULL)
260 return NDIS_STATUS_FAILURE;
261
262 pHeader_802_11 = (struct rt_header_802_11 *) (pSrcBufVA + TXINFO_SIZE + TXWI_SIZE);
263
264#ifdef RTMP_MAC_PCI
265 if (pAd->MACVersion == 0x28600100)
266 return MlmeHardTransmitTxRing(pAd, QueIdx, pPacket);
267 else
268#endif /* RTMP_MAC_PCI // */
269 return MlmeHardTransmitMgmtRing(pAd, QueIdx, pPacket);
270
271}
272
273int MlmeHardTransmitMgmtRing(struct rt_rtmp_adapter *pAd,
274 u8 QueIdx, void *pPacket)
275{
276 struct rt_packet_info PacketInfo;
277 u8 *pSrcBufVA;
278 u32 SrcBufLen;
279 struct rt_header_802_11 * pHeader_802_11;
280 BOOLEAN bAckRequired, bInsertTimestamp;
281 u8 MlmeRate;
282 struct rt_txwi * pFirstTxWI;
283 struct rt_mac_table_entry *pMacEntry = NULL;
284 u8 PID;
285
286 RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
287
288 /* Make sure MGMT ring resource won't be used by other threads */
289 RTMP_SEM_LOCK(&pAd->MgmtRingLock);
290 if (pSrcBufVA == NULL) {
291 /* The buffer shouldn't be NULL */
292 RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);
293 return NDIS_STATUS_FAILURE;
294 }
295
296 {
297 /* outgoing frame always wakeup PHY to prevent frame lost */
298 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
299 AsicForceWakeup(pAd, TRUE);
300 }
301
302 pFirstTxWI = (struct rt_txwi *) (pSrcBufVA + TXINFO_SIZE);
303 pHeader_802_11 = (struct rt_header_802_11 *) (pSrcBufVA + TXINFO_SIZE + TXWI_SIZE); /*TXWI_SIZE); */
304
305 if (pHeader_802_11->Addr1[0] & 0x01) {
306 MlmeRate = pAd->CommonCfg.BasicMlmeRate;
307 } else {
308 MlmeRate = pAd->CommonCfg.MlmeRate;
309 }
310
311 /* Verify Mlme rate for a / g bands. */
312 if ((pAd->LatchRfRegs.Channel > 14) && (MlmeRate < RATE_6)) /* 11A band */
313 MlmeRate = RATE_6;
314
315 if ((pHeader_802_11->FC.Type == BTYPE_DATA) &&
316 (pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL)) {
317 pMacEntry = MacTableLookup(pAd, pHeader_802_11->Addr1);
318 }
319
320 {
321 /* Fixed W52 with Activity scan issue in ABG_MIXED and ABGN_MIXED mode. */
322 if (pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED
323 || pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED) {
324 if (pAd->LatchRfRegs.Channel > 14)
325 pAd->CommonCfg.MlmeTransmit.field.MODE = 1;
326 else
327 pAd->CommonCfg.MlmeTransmit.field.MODE = 0;
328 }
329 }
330
331 /* */
332 /* Should not be hard code to set PwrMgmt to 0 (PWR_ACTIVE) */
333 /* Snice it's been set to 0 while on MgtMacHeaderInit */
334 /* By the way this will cause frame to be send on PWR_SAVE failed. */
335 /* */
336 pHeader_802_11->FC.PwrMgmt = PWR_ACTIVE; /* (pAd->StaCfg.Psm == PWR_SAVE); */
337
338 /* */
339 /* In WMM-UAPSD, mlme frame should be set psm as power saving but probe request frame */
340 /* Data-Null packets also pass through MMRequest in RT2860, however, we hope control the psm bit to pass APSD */
341/* if ((pHeader_802_11->FC.Type != BTYPE_DATA) && (pHeader_802_11->FC.Type != BTYPE_CNTL)) */
342 {
343 if ((pHeader_802_11->FC.SubType == SUBTYPE_ACTION) ||
344 ((pHeader_802_11->FC.Type == BTYPE_DATA) &&
345 ((pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL) ||
346 (pHeader_802_11->FC.SubType == SUBTYPE_NULL_FUNC)))) {
347 if (pAd->StaCfg.Psm == PWR_SAVE)
348 pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
349 else
350 pHeader_802_11->FC.PwrMgmt =
351 pAd->CommonCfg.bAPSDForcePowerSave;
352 }
353 }
354
355 bInsertTimestamp = FALSE;
356 if (pHeader_802_11->FC.Type == BTYPE_CNTL) /* must be PS-POLL */
357 {
358 /*Set PM bit in ps-poll, to fix WLK 1.2 PowerSaveMode_ext failure issue. */
359 if ((pAd->OpMode == OPMODE_STA)
360 && (pHeader_802_11->FC.SubType == SUBTYPE_PS_POLL)) {
361 pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
362 }
363 bAckRequired = FALSE;
364 } else /* BTYPE_MGMT or BTYPE_DATA(must be NULL frame) */
365 {
366 /*pAd->Sequence++; */
367 /*pHeader_802_11->Sequence = pAd->Sequence; */
368
369 if (pHeader_802_11->Addr1[0] & 0x01) /* MULTICAST, BROADCAST */
370 {
371 bAckRequired = FALSE;
372 pHeader_802_11->Duration = 0;
373 } else {
374 bAckRequired = TRUE;
375 pHeader_802_11->Duration =
376 RTMPCalcDuration(pAd, MlmeRate, 14);
377 if ((pHeader_802_11->FC.SubType == SUBTYPE_PROBE_RSP)
378 && (pHeader_802_11->FC.Type == BTYPE_MGMT)) {
379 bInsertTimestamp = TRUE;
380 bAckRequired = FALSE; /* Disable ACK to prevent retry 0x1f for Probe Response */
381 } else
382 if ((pHeader_802_11->FC.SubType ==
383 SUBTYPE_PROBE_REQ)
384 && (pHeader_802_11->FC.Type == BTYPE_MGMT)) {
385 bAckRequired = FALSE; /* Disable ACK to prevent retry 0x1f for Probe Request */
386 }
387 }
388 }
389
390 pHeader_802_11->Sequence = pAd->Sequence++;
391 if (pAd->Sequence > 0xfff)
392 pAd->Sequence = 0;
393
394 /* Before radar detection done, mgmt frame can not be sent but probe req */
395 /* Because we need to use probe req to trigger driver to send probe req in passive scan */
396 if ((pHeader_802_11->FC.SubType != SUBTYPE_PROBE_REQ)
397 && (pAd->CommonCfg.bIEEE80211H == 1)
398 && (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)) {
399 DBGPRINT(RT_DEBUG_ERROR,
400 ("MlmeHardTransmit --> radar detect not in normal mode!\n"));
401/* if (!IrqState) */
402 RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);
403 return (NDIS_STATUS_FAILURE);
404 }
405
406 /* */
407 /* fill scatter-and-gather buffer list into TXD. Internally created NDIS PACKET */
408 /* should always has only one physical buffer, and the whole frame size equals */
409 /* to the first scatter buffer size */
410 /* */
411
412 /* Initialize TX Descriptor */
413 /* For inter-frame gap, the number is for this frame and next frame */
414 /* For MLME rate, we will fix as 2Mb to match other vendor's implement */
415/* pAd->CommonCfg.MlmeTransmit.field.MODE = 1; */
416
417/* management frame doesn't need encryption. so use RESERVED_WCID no matter u are sending to specific wcid or not. */
418 PID = PID_MGMT;
419
420 if (pMacEntry == NULL) {
421 RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, bInsertTimestamp,
422 FALSE, bAckRequired, FALSE, 0, RESERVED_WCID,
423 (SrcBufLen - TXINFO_SIZE - TXWI_SIZE), PID, 0,
424 (u8)pAd->CommonCfg.MlmeTransmit.field.MCS,
425 IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
426 } else {
427 /* dont use low rate to send QoS Null data frame */
428 RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE,
429 bInsertTimestamp, FALSE, bAckRequired, FALSE,
430 0, pMacEntry->Aid,
431 (SrcBufLen - TXINFO_SIZE - TXWI_SIZE),
432 pMacEntry->MaxHTPhyMode.field.MCS, 0,
433 (u8)pMacEntry->MaxHTPhyMode.field.MCS,
434 IFS_BACKOFF, FALSE, &pMacEntry->MaxHTPhyMode);
435 }
436
437 /* Now do hardware-depened kick out. */
438 HAL_KickOutMgmtTx(pAd, QueIdx, pPacket, pSrcBufVA, SrcBufLen);
439
440 /* Make sure to release MGMT ring resource */
441/* if (!IrqState) */
442 RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);
443 return NDIS_STATUS_SUCCESS;
444}
445
446/********************************************************************************
447
448 New DeQueue Procedures.
449
450 ********************************************************************************/
451
452#define DEQUEUE_LOCK(lock, bIntContext, IrqFlags) \
453 do{ \
454 if (bIntContext == FALSE) \
455 RTMP_IRQ_LOCK((lock), IrqFlags); \
456 }while(0)
457
458#define DEQUEUE_UNLOCK(lock, bIntContext, IrqFlags) \
459 do{ \
460 if (bIntContext == FALSE) \
461 RTMP_IRQ_UNLOCK((lock), IrqFlags); \
462 }while(0)
463
464/*
465 ========================================================================
466 Tx Path design algorithm:
467 Basically, we divide the packets into four types, Broadcast/Multicast, 11N Rate(AMPDU, AMSDU, Normal), B/G Rate(ARALINK, Normal),
468 Specific Packet Type. Following show the classification rule and policy for each kinds of packets.
469 Classification Rule=>
470 Multicast: (*addr1 & 0x01) == 0x01
471 Specific : bDHCPFrame, bARPFrame, bEAPOLFrame, etc.
472 11N Rate : If peer support HT
473 (1).AMPDU -- If TXBA is negotiated.
474 (2).AMSDU -- If AMSDU is capable for both peer and ourself.
475 *). AMSDU can embedded in a AMPDU, but now we didn't support it.
476 (3).Normal -- Other packets which send as 11n rate.
477
478 B/G Rate : If peer is b/g only.
479 (1).ARALINK-- If both of peer/us supprot Ralink proprietary Aggregation and the TxRate is large than RATE_6
480 (2).Normal -- Other packets which send as b/g rate.
481 Fragment:
482 The packet must be unicast, NOT A-RALINK, NOT A-MSDU, NOT 11n, then can consider about fragment.
483
484 Classified Packet Handle Rule=>
485 Multicast:
486 No ACK, //pTxBlk->bAckRequired = FALSE;
487 No WMM, //pTxBlk->bWMM = FALSE;
488 No piggyback, //pTxBlk->bPiggyBack = FALSE;
489 Force LowRate, //pTxBlk->bForceLowRate = TRUE;
490 Specific : Basically, for specific packet, we should handle it specifically, but now all specific packets are use
491 the same policy to handle it.
492 Force LowRate, //pTxBlk->bForceLowRate = TRUE;
493
494 11N Rate :
495 No piggyback, //pTxBlk->bPiggyBack = FALSE;
496
497 (1).AMSDU
498 pTxBlk->bWMM = TRUE;
499 (2).AMPDU
500 pTxBlk->bWMM = TRUE;
501 (3).Normal
502
503 B/G Rate :
504 (1).ARALINK
505
506 (2).Normal
507 ========================================================================
508*/
509static u8 TxPktClassification(struct rt_rtmp_adapter *pAd, void *pPacket)
510{
511 u8 TxFrameType = TX_UNKOWN_FRAME;
512 u8 Wcid;
513 struct rt_mac_table_entry *pMacEntry = NULL;
514 BOOLEAN bHTRate = FALSE;
515
516 Wcid = RTMP_GET_PACKET_WCID(pPacket);
517 if (Wcid == MCAST_WCID) { /* Handle for RA is Broadcast/Multicast Address. */
518 return TX_MCAST_FRAME;
519 }
520 /* Handle for unicast packets */
521 pMacEntry = &pAd->MacTab.Content[Wcid];
522 if (RTMP_GET_PACKET_LOWRATE(pPacket)) { /* It's a specific packet need to force low rate, i.e., bDHCPFrame, bEAPOLFrame, bWAIFrame */
523 TxFrameType = TX_LEGACY_FRAME;
524 } else if (IS_HT_RATE(pMacEntry)) { /* it's a 11n capable packet */
525
526 /* Depends on HTPhyMode to check if the peer support the HTRate transmission. */
527 /* Currently didn't support A-MSDU embedded in A-MPDU */
528 bHTRate = TRUE;
529 if (RTMP_GET_PACKET_MOREDATA(pPacket)
530 || (pMacEntry->PsMode == PWR_SAVE))
531 TxFrameType = TX_LEGACY_FRAME;
532 else if ((pMacEntry->
533 TXBAbitmap & (1 << (RTMP_GET_PACKET_UP(pPacket)))) !=
534 0)
535 return TX_AMPDU_FRAME;
536 else if (CLIENT_STATUS_TEST_FLAG
537 (pMacEntry, fCLIENT_STATUS_AMSDU_INUSED))
538 return TX_AMSDU_FRAME;
539 else
540 TxFrameType = TX_LEGACY_FRAME;
541 } else { /* it's a legacy b/g packet. */
542 if ((CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE) && pAd->CommonCfg.bAggregationCapable) && (RTMP_GET_PACKET_TXRATE(pPacket) >= RATE_6) && (!(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE)))) { /* if peer support Ralink Aggregation, we use it. */
543 TxFrameType = TX_RALINK_FRAME;
544 } else {
545 TxFrameType = TX_LEGACY_FRAME;
546 }
547 }
548
549 /* Currently, our fragment only support when a unicast packet send as NOT-ARALINK, NOT-AMSDU and NOT-AMPDU. */
550 if ((RTMP_GET_PACKET_FRAGMENTS(pPacket) > 1)
551 && (TxFrameType == TX_LEGACY_FRAME))
552 TxFrameType = TX_FRAG_FRAME;
553
554 return TxFrameType;
555}
556
557BOOLEAN RTMP_FillTxBlkInfo(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk)
558{
559 struct rt_packet_info PacketInfo;
560 void *pPacket;
561 struct rt_mac_table_entry *pMacEntry = NULL;
562
563 pPacket = pTxBlk->pPacket;
564 RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pTxBlk->pSrcBufHeader,
565 &pTxBlk->SrcBufLen);
566
567 pTxBlk->Wcid = RTMP_GET_PACKET_WCID(pPacket);
568 pTxBlk->apidx = RTMP_GET_PACKET_IF(pPacket);
569 pTxBlk->UserPriority = RTMP_GET_PACKET_UP(pPacket);
570 pTxBlk->FrameGap = IFS_HTTXOP; /* ASIC determine Frame Gap */
571
572 if (RTMP_GET_PACKET_CLEAR_EAP_FRAME(pTxBlk->pPacket))
573 TX_BLK_SET_FLAG(pTxBlk, fTX_bClearEAPFrame);
574 else
575 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bClearEAPFrame);
576
577 /* Default to clear this flag */
578 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bForceNonQoS);
579
580 if (pTxBlk->Wcid == MCAST_WCID) {
581 pTxBlk->pMacEntry = NULL;
582 {
583 pTxBlk->pTransmit =
584 &pAd->MacTab.Content[MCAST_WCID].HTPhyMode;
585 }
586
587 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired); /* AckRequired = FALSE, when broadcast packet in Adhoc mode. */
588 /*TX_BLK_SET_FLAG(pTxBlk, fTX_bForceLowRate); */
589 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAllowFrag);
590 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bWMM);
591 if (RTMP_GET_PACKET_MOREDATA(pPacket)) {
592 TX_BLK_SET_FLAG(pTxBlk, fTX_bMoreData);
593 }
594
595 } else {
596 pTxBlk->pMacEntry = &pAd->MacTab.Content[pTxBlk->Wcid];
597 pTxBlk->pTransmit = &pTxBlk->pMacEntry->HTPhyMode;
598
599 pMacEntry = pTxBlk->pMacEntry;
600
601 /* For all unicast packets, need Ack unless the Ack Policy is not set as NORMAL_ACK. */
602 if (pAd->CommonCfg.AckPolicy[pTxBlk->QueIdx] != NORMAL_ACK)
603 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired);
604 else
605 TX_BLK_SET_FLAG(pTxBlk, fTX_bAckRequired);
606
607 if ((pAd->OpMode == OPMODE_STA) &&
608 (ADHOC_ON(pAd)) &&
609 (RX_FILTER_TEST_FLAG(pAd, fRX_FILTER_ACCEPT_PROMISCUOUS))) {
610 if (pAd->CommonCfg.PSPXlink)
611 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired);
612 }
613
614 {
615 {
616
617 /* If support WMM, enable it. */
618 if (OPSTATUS_TEST_FLAG
619 (pAd, fOP_STATUS_WMM_INUSED)
620 && CLIENT_STATUS_TEST_FLAG(pMacEntry,
621 fCLIENT_STATUS_WMM_CAPABLE))
622 TX_BLK_SET_FLAG(pTxBlk, fTX_bWMM);
623
624/* if (pAd->StaCfg.bAutoTxRateSwitch) */
625/* TX_BLK_SET_FLAG(pTxBlk, fTX_AutoRateSwitch); */
626 }
627 }
628
629 if (pTxBlk->TxFrameType == TX_LEGACY_FRAME) {
630 if ((RTMP_GET_PACKET_LOWRATE(pPacket)) || ((pAd->OpMode == OPMODE_AP) && (pMacEntry->MaxHTPhyMode.field.MODE == MODE_CCK) && (pMacEntry->MaxHTPhyMode.field.MCS == RATE_1))) { /* Specific packet, i.e., bDHCPFrame, bEAPOLFrame, bWAIFrame, need force low rate. */
631 pTxBlk->pTransmit =
632 &pAd->MacTab.Content[MCAST_WCID].HTPhyMode;
633
634 /* Modify the WMM bit for ICV issue. If we have a packet with EOSP field need to set as 1, how to handle it??? */
635 if (IS_HT_STA(pTxBlk->pMacEntry) &&
636 (CLIENT_STATUS_TEST_FLAG
637 (pMacEntry, fCLIENT_STATUS_RALINK_CHIPSET))
638 && ((pAd->CommonCfg.bRdg == TRUE)
639 && CLIENT_STATUS_TEST_FLAG(pMacEntry,
640 fCLIENT_STATUS_RDG_CAPABLE)))
641 {
642 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bWMM);
643 TX_BLK_SET_FLAG(pTxBlk,
644 fTX_bForceNonQoS);
645 }
646 }
647
648 if ((IS_HT_RATE(pMacEntry) == FALSE) && (CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE))) { /* Currently piggy-back only support when peer is operate in b/g mode. */
649 TX_BLK_SET_FLAG(pTxBlk, fTX_bPiggyBack);
650 }
651
652 if (RTMP_GET_PACKET_MOREDATA(pPacket)) {
653 TX_BLK_SET_FLAG(pTxBlk, fTX_bMoreData);
654 }
655 } else if (pTxBlk->TxFrameType == TX_FRAG_FRAME) {
656 TX_BLK_SET_FLAG(pTxBlk, fTX_bAllowFrag);
657 }
658
659 pMacEntry->DebugTxCount++;
660 }
661
662 return TRUE;
663}
664
665BOOLEAN CanDoAggregateTransmit(struct rt_rtmp_adapter *pAd,
666 char * pPacket, struct rt_tx_blk *pTxBlk)
667{
668
669 /*DBGPRINT(RT_DEBUG_TRACE, ("Check if can do aggregation! TxFrameType=%d!\n", pTxBlk->TxFrameType)); */
670
671 if (RTMP_GET_PACKET_WCID(pPacket) == MCAST_WCID)
672 return FALSE;
673
674 if (RTMP_GET_PACKET_DHCP(pPacket) ||
675 RTMP_GET_PACKET_EAPOL(pPacket) || RTMP_GET_PACKET_WAI(pPacket))
676 return FALSE;
677
678 if ((pTxBlk->TxFrameType == TX_AMSDU_FRAME) && ((pTxBlk->TotalFrameLen + GET_OS_PKT_LEN(pPacket)) > (RX_BUFFER_AGGRESIZE - 100))) { /* For AMSDU, allow the packets with total length < max-amsdu size */
679 return FALSE;
680 }
681
682 if ((pTxBlk->TxFrameType == TX_RALINK_FRAME) && (pTxBlk->TxPacketList.Number == 2)) { /* For RALINK-Aggregation, allow two frames in one batch. */
683 return FALSE;
684 }
685
686 if ((INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA)) /* must be unicast to AP */
687 return TRUE;
688 else
689 return FALSE;
690
691}
692
693/*
694 ========================================================================
695
696 Routine Description:
697 To do the enqueue operation and extract the first item of waiting
698 list. If a number of available shared memory segments could meet
699 the request of extracted item, the extracted item will be fragmented
700 into shared memory segments.
701
702 Arguments:
703 pAd Pointer to our adapter
704 pQueue Pointer to Waiting Queue
705
706 Return Value:
707 None
708
709 IRQL = DISPATCH_LEVEL
710
711 Note:
712
713 ========================================================================
714*/
715void RTMPDeQueuePacket(struct rt_rtmp_adapter *pAd, IN BOOLEAN bIntContext, u8 QIdx, /* BulkOutPipeId */
716 u8 Max_Tx_Packets)
717{
718 struct rt_queue_entry *pEntry = NULL;
719 void *pPacket;
720 int Status = NDIS_STATUS_SUCCESS;
721 u8 Count = 0;
722 struct rt_queue_header *pQueue;
723 unsigned long FreeNumber[NUM_OF_TX_RING];
724 u8 QueIdx, sQIdx, eQIdx;
725 unsigned long IrqFlags = 0;
726 BOOLEAN hasTxDesc = FALSE;
727 struct rt_tx_blk TxBlk;
728 struct rt_tx_blk *pTxBlk;
729
730 if (QIdx == NUM_OF_TX_RING) {
731 sQIdx = 0;
732 eQIdx = 3; /* 4 ACs, start from 0. */
733 } else {
734 sQIdx = eQIdx = QIdx;
735 }
736
737 for (QueIdx = sQIdx; QueIdx <= eQIdx; QueIdx++) {
738 Count = 0;
739
740 RTMP_START_DEQUEUE(pAd, QueIdx, IrqFlags);
741
742 while (1) {
743 if ((RTMP_TEST_FLAG
744 (pAd,
745 (fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS |
746 fRTMP_ADAPTER_RADIO_OFF |
747 fRTMP_ADAPTER_RESET_IN_PROGRESS |
748 fRTMP_ADAPTER_HALT_IN_PROGRESS |
749 fRTMP_ADAPTER_NIC_NOT_EXIST)))) {
750 RTMP_STOP_DEQUEUE(pAd, QueIdx, IrqFlags);
751 return;
752 }
753
754 if (Count >= Max_Tx_Packets)
755 break;
756
757 DEQUEUE_LOCK(&pAd->irq_lock, bIntContext, IrqFlags);
758 if (&pAd->TxSwQueue[QueIdx] == NULL) {
759 DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext,
760 IrqFlags);
761 break;
762 }
763#ifdef RTMP_MAC_PCI
764 FreeNumber[QueIdx] = GET_TXRING_FREENO(pAd, QueIdx);
765
766 if (FreeNumber[QueIdx] <= 5) {
767 /* free Tx(QueIdx) resources */
768 RTMPFreeTXDUponTxDmaDone(pAd, QueIdx);
769 FreeNumber[QueIdx] =
770 GET_TXRING_FREENO(pAd, QueIdx);
771 }
772#endif /* RTMP_MAC_PCI // */
773
774 /* probe the Queue Head */
775 pQueue = &pAd->TxSwQueue[QueIdx];
776 pEntry = pQueue->Head;
777 if (pEntry == NULL) {
778 DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext,
779 IrqFlags);
780 break;
781 }
782
783 pTxBlk = &TxBlk;
784 NdisZeroMemory((u8 *)pTxBlk, sizeof(struct rt_tx_blk));
785 /*InitializeQueueHeader(&pTxBlk->TxPacketList); // Didn't need it because we already memzero it. */
786 pTxBlk->QueIdx = QueIdx;
787
788 pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
789
790 /* Early check to make sure we have enoguh Tx Resource. */
791 hasTxDesc =
792 RTMP_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk,
793 FreeNumber[QueIdx],
794 pPacket);
795 if (!hasTxDesc) {
796 pAd->PrivateInfo.TxRingFullCnt++;
797
798 DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext,
799 IrqFlags);
800
801 break;
802 }
803
804 pTxBlk->TxFrameType = TxPktClassification(pAd, pPacket);
805 pEntry = RemoveHeadQueue(pQueue);
806 pTxBlk->TotalFrameNum++;
807 pTxBlk->TotalFragNum += RTMP_GET_PACKET_FRAGMENTS(pPacket); /* The real fragment number maybe vary */
808 pTxBlk->TotalFrameLen += GET_OS_PKT_LEN(pPacket);
809 pTxBlk->pPacket = pPacket;
810 InsertTailQueue(&pTxBlk->TxPacketList,
811 PACKET_TO_QUEUE_ENTRY(pPacket));
812
813 if (pTxBlk->TxFrameType == TX_RALINK_FRAME
814 || pTxBlk->TxFrameType == TX_AMSDU_FRAME) {
815 /* Enhance SW Aggregation Mechanism */
816 if (NEED_QUEUE_BACK_FOR_AGG
817 (pAd, QueIdx, FreeNumber[QueIdx],
818 pTxBlk->TxFrameType)) {
819 InsertHeadQueue(pQueue,
820 PACKET_TO_QUEUE_ENTRY
821 (pPacket));
822 DEQUEUE_UNLOCK(&pAd->irq_lock,
823 bIntContext, IrqFlags);
824 break;
825 }
826
827 do {
828 pEntry = pQueue->Head;
829 if (pEntry == NULL)
830 break;
831
832 /* For TX_AMSDU_FRAME/TX_RALINK_FRAME, Need to check if next pakcet can do aggregation. */
833 pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
834 FreeNumber[QueIdx] =
835 GET_TXRING_FREENO(pAd, QueIdx);
836 hasTxDesc =
837 RTMP_HAS_ENOUGH_FREE_DESC(pAd,
838 pTxBlk,
839 FreeNumber
840 [QueIdx],
841 pPacket);
842 if ((hasTxDesc == FALSE)
843 ||
844 (CanDoAggregateTransmit
845 (pAd, pPacket, pTxBlk) == FALSE))
846 break;
847
848 /*Remove the packet from the TxSwQueue and insert into pTxBlk */
849 pEntry = RemoveHeadQueue(pQueue);
850 ASSERT(pEntry);
851 pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
852 pTxBlk->TotalFrameNum++;
853 pTxBlk->TotalFragNum += RTMP_GET_PACKET_FRAGMENTS(pPacket); /* The real fragment number maybe vary */
854 pTxBlk->TotalFrameLen +=
855 GET_OS_PKT_LEN(pPacket);
856 InsertTailQueue(&pTxBlk->TxPacketList,
857 PACKET_TO_QUEUE_ENTRY
858 (pPacket));
859 } while (1);
860
861 if (pTxBlk->TxPacketList.Number == 1)
862 pTxBlk->TxFrameType = TX_LEGACY_FRAME;
863 }
864#ifdef RTMP_MAC_USB
865 DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
866#endif /* RTMP_MAC_USB // */
867 Count += pTxBlk->TxPacketList.Number;
868
869 /* Do HardTransmit now. */
870 Status = STAHardTransmit(pAd, pTxBlk, QueIdx);
871
872#ifdef RTMP_MAC_PCI
873 DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
874 /* static rate also need NICUpdateFifoStaCounters() function. */
875 /*if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)) */
876 NICUpdateFifoStaCounters(pAd);
877#endif /* RTMP_MAC_PCI // */
878
879 }
880
881 RTMP_STOP_DEQUEUE(pAd, QueIdx, IrqFlags);
882
883#ifdef RTMP_MAC_USB
884 if (!hasTxDesc)
885 RTUSBKickBulkOut(pAd);
886#endif /* RTMP_MAC_USB // */
887 }
888
889}
890
891/*
892 ========================================================================
893
894 Routine Description:
895 Calculates the duration which is required to transmit out frames
896 with given size and specified rate.
897
898 Arguments:
899 pAd Pointer to our adapter
900 Rate Transmit rate
901 Size Frame size in units of byte
902
903 Return Value:
904 Duration number in units of usec
905
906 IRQL = PASSIVE_LEVEL
907 IRQL = DISPATCH_LEVEL
908
909 Note:
910
911 ========================================================================
912*/
913u16 RTMPCalcDuration(struct rt_rtmp_adapter *pAd, u8 Rate, unsigned long Size)
914{
915 unsigned long Duration = 0;
916
917 if (Rate < RATE_FIRST_OFDM_RATE) /* CCK */
918 {
919 if ((Rate > RATE_1)
920 && OPSTATUS_TEST_FLAG(pAd,
921 fOP_STATUS_SHORT_PREAMBLE_INUSED))
922 Duration = 96; /* 72+24 preamble+plcp */
923 else
924 Duration = 192; /* 144+48 preamble+plcp */
925
926 Duration += (u16)((Size << 4) / RateIdTo500Kbps[Rate]);
927 if ((Size << 4) % RateIdTo500Kbps[Rate])
928 Duration++;
929 } else if (Rate <= RATE_LAST_OFDM_RATE) /* OFDM rates */
930 {
931 Duration = 20 + 6; /* 16+4 preamble+plcp + Signal Extension */
932 Duration +=
933 4 * (u16)((11 + Size * 4) / RateIdTo500Kbps[Rate]);
934 if ((11 + Size * 4) % RateIdTo500Kbps[Rate])
935 Duration += 4;
936 } else /*mimo rate */
937 {
938 Duration = 20 + 6; /* 16+4 preamble+plcp + Signal Extension */
939 }
940
941 return (u16)Duration;
942}
943
944/*
945 ========================================================================
946
947 Routine Description:
948 Calculates the duration which is required to transmit out frames
949 with given size and specified rate.
950
951 Arguments:
952 pTxWI Pointer to head of each MPDU to HW.
953 Ack Setting for Ack requirement bit
954 Fragment Setting for Fragment bit
955 RetryMode Setting for retry mode
956 Ifs Setting for IFS gap
957 Rate Setting for transmit rate
958 Service Setting for service
959 Length Frame length
960 TxPreamble Short or Long preamble when using CCK rates
961 QueIdx - 0-3, according to 802.11e/d4.4 June/2003
962
963 Return Value:
964 None
965
966 IRQL = PASSIVE_LEVEL
967 IRQL = DISPATCH_LEVEL
968
969 See also : BASmartHardTransmit() !
970
971 ========================================================================
972*/
973void RTMPWriteTxWI(struct rt_rtmp_adapter *pAd, struct rt_txwi * pOutTxWI, IN BOOLEAN FRAG, IN BOOLEAN CFACK, IN BOOLEAN InsTimestamp, IN BOOLEAN AMPDU, IN BOOLEAN Ack, IN BOOLEAN NSeq, /* HW new a sequence. */
974 u8 BASize,
975 u8 WCID,
976 unsigned long Length,
977 u8 PID,
978 u8 TID,
979 u8 TxRate,
980 u8 Txopmode,
981 IN BOOLEAN CfAck, IN HTTRANSMIT_SETTING * pTransmit)
982{
983 struct rt_mac_table_entry *pMac = NULL;
984 struct rt_txwi TxWI;
985 struct rt_txwi * pTxWI;
986
987 if (WCID < MAX_LEN_OF_MAC_TABLE)
988 pMac = &pAd->MacTab.Content[WCID];
989
990 /* */
991 /* Always use Long preamble before verifiation short preamble functionality works well. */
992 /* Todo: remove the following line if short preamble functionality works */
993 /* */
994 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
995 NdisZeroMemory(&TxWI, TXWI_SIZE);
996 pTxWI = &TxWI;
997
998 pTxWI->FRAG = FRAG;
999
1000 pTxWI->CFACK = CFACK;
1001 pTxWI->TS = InsTimestamp;
1002 pTxWI->AMPDU = AMPDU;
1003 pTxWI->ACK = Ack;
1004 pTxWI->txop = Txopmode;
1005
1006 pTxWI->NSEQ = NSeq;
1007 /* John tune the performace with Intel Client in 20 MHz performance */
1008 BASize = pAd->CommonCfg.TxBASize;
1009 if (pAd->MACVersion == 0x28720200) {
1010 if (BASize > 13)
1011 BASize = 13;
1012 } else {
1013 if (BASize > 7)
1014 BASize = 7;
1015 }
1016 pTxWI->BAWinSize = BASize;
1017 pTxWI->ShortGI = pTransmit->field.ShortGI;
1018 pTxWI->STBC = pTransmit->field.STBC;
1019
1020 pTxWI->WirelessCliID = WCID;
1021 pTxWI->MPDUtotalByteCount = Length;
1022 pTxWI->PacketId = PID;
1023
1024 /* If CCK or OFDM, BW must be 20 */
1025 pTxWI->BW =
1026 (pTransmit->field.MODE <=
1027 MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
1028
1029 pTxWI->MCS = pTransmit->field.MCS;
1030 pTxWI->PHYMODE = pTransmit->field.MODE;
1031 pTxWI->CFACK = CfAck;
1032
1033 if (pMac) {
1034 if (pAd->CommonCfg.bMIMOPSEnable) {
1035 if ((pMac->MmpsMode == MMPS_DYNAMIC)
1036 && (pTransmit->field.MCS > 7)) {
1037 /* Dynamic MIMO Power Save Mode */
1038 pTxWI->MIMOps = 1;
1039 } else if (pMac->MmpsMode == MMPS_STATIC) {
1040 /* Static MIMO Power Save Mode */
1041 if (pTransmit->field.MODE >= MODE_HTMIX
1042 && pTransmit->field.MCS > 7) {
1043 pTxWI->MCS = 7;
1044 pTxWI->MIMOps = 0;
1045 }
1046 }
1047 }
1048 /*pTxWI->MIMOps = (pMac->PsMode == PWR_MMPS)? 1:0; */
1049 if (pMac->bIAmBadAtheros
1050 && (pMac->WepStatus != Ndis802_11WEPDisabled)) {
1051 pTxWI->MpduDensity = 7;
1052 } else {
1053 pTxWI->MpduDensity = pMac->MpduDensity;
1054 }
1055 }
1056
1057 pTxWI->PacketId = pTxWI->MCS;
1058 NdisMoveMemory(pOutTxWI, &TxWI, sizeof(struct rt_txwi));
1059}
1060
1061void RTMPWriteTxWI_Data(struct rt_rtmp_adapter *pAd,
1062 struct rt_txwi * pTxWI, struct rt_tx_blk *pTxBlk)
1063{
1064 HTTRANSMIT_SETTING *pTransmit;
1065 struct rt_mac_table_entry *pMacEntry;
1066 u8 BASize;
1067
1068 ASSERT(pTxWI);
1069
1070 pTransmit = pTxBlk->pTransmit;
1071 pMacEntry = pTxBlk->pMacEntry;
1072
1073 /* */
1074 /* Always use Long preamble before verifiation short preamble functionality works well. */
1075 /* Todo: remove the following line if short preamble functionality works */
1076 /* */
1077 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
1078 NdisZeroMemory(pTxWI, TXWI_SIZE);
1079
1080 pTxWI->FRAG = TX_BLK_TEST_FLAG(pTxBlk, fTX_bAllowFrag);
1081 pTxWI->ACK = TX_BLK_TEST_FLAG(pTxBlk, fTX_bAckRequired);
1082 pTxWI->txop = pTxBlk->FrameGap;
1083
1084 pTxWI->WirelessCliID = pTxBlk->Wcid;
1085
1086 pTxWI->MPDUtotalByteCount = pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
1087 pTxWI->CFACK = TX_BLK_TEST_FLAG(pTxBlk, fTX_bPiggyBack);
1088
1089 /* If CCK or OFDM, BW must be 20 */
1090 pTxWI->BW =
1091 (pTransmit->field.MODE <=
1092 MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
1093 pTxWI->AMPDU = ((pTxBlk->TxFrameType == TX_AMPDU_FRAME) ? TRUE : FALSE);
1094
1095 /* John tune the performace with Intel Client in 20 MHz performance */
1096 BASize = pAd->CommonCfg.TxBASize;
1097 if ((pTxBlk->TxFrameType == TX_AMPDU_FRAME) && (pMacEntry)) {
1098 u8 RABAOriIdx = 0; /*The RA's BA Originator table index. */
1099
1100 RABAOriIdx =
1101 pTxBlk->pMacEntry->BAOriWcidArray[pTxBlk->UserPriority];
1102 BASize = pAd->BATable.BAOriEntry[RABAOriIdx].BAWinSize;
1103 }
1104
1105 pTxWI->TxBF = pTransmit->field.TxBF;
1106 pTxWI->BAWinSize = BASize;
1107 pTxWI->ShortGI = pTransmit->field.ShortGI;
1108 pTxWI->STBC = pTransmit->field.STBC;
1109
1110 pTxWI->MCS = pTransmit->field.MCS;
1111 pTxWI->PHYMODE = pTransmit->field.MODE;
1112
1113 if (pMacEntry) {
1114 if ((pMacEntry->MmpsMode == MMPS_DYNAMIC)
1115 && (pTransmit->field.MCS > 7)) {
1116 /* Dynamic MIMO Power Save Mode */
1117 pTxWI->MIMOps = 1;
1118 } else if (pMacEntry->MmpsMode == MMPS_STATIC) {
1119 /* Static MIMO Power Save Mode */
1120 if (pTransmit->field.MODE >= MODE_HTMIX
1121 && pTransmit->field.MCS > 7) {
1122 pTxWI->MCS = 7;
1123 pTxWI->MIMOps = 0;
1124 }
1125 }
1126
1127 if (pMacEntry->bIAmBadAtheros
1128 && (pMacEntry->WepStatus != Ndis802_11WEPDisabled)) {
1129 pTxWI->MpduDensity = 7;
1130 } else {
1131 pTxWI->MpduDensity = pMacEntry->MpduDensity;
1132 }
1133 }
1134
1135 /* for rate adapation */
1136 pTxWI->PacketId = pTxWI->MCS;
1137}
1138
1139void RTMPWriteTxWI_Cache(struct rt_rtmp_adapter *pAd,
1140 struct rt_txwi * pTxWI, struct rt_tx_blk *pTxBlk)
1141{
1142 PHTTRANSMIT_SETTING /*pTxHTPhyMode, */ pTransmit;
1143 struct rt_mac_table_entry *pMacEntry;
1144
1145 /* */
1146 /* update TXWI */
1147 /* */
1148 pMacEntry = pTxBlk->pMacEntry;
1149 pTransmit = pTxBlk->pTransmit;
1150
1151 /*if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)) */
1152 /*if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pMacEntry)) */
1153 /*if (TX_BLK_TEST_FLAG(pTxBlk, fTX_AutoRateSwitch)) */
1154 if (pMacEntry->bAutoTxRateSwitch) {
1155 pTxWI->txop = IFS_HTTXOP;
1156
1157 /* If CCK or OFDM, BW must be 20 */
1158 pTxWI->BW =
1159 (pTransmit->field.MODE <=
1160 MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
1161 pTxWI->ShortGI = pTransmit->field.ShortGI;
1162 pTxWI->STBC = pTransmit->field.STBC;
1163
1164 pTxWI->MCS = pTransmit->field.MCS;
1165 pTxWI->PHYMODE = pTransmit->field.MODE;
1166
1167 /* set PID for TxRateSwitching */
1168 pTxWI->PacketId = pTransmit->field.MCS;
1169 }
1170
1171 pTxWI->AMPDU = ((pMacEntry->NoBADataCountDown == 0) ? TRUE : FALSE);
1172 pTxWI->MIMOps = 0;
1173
1174 if (pAd->CommonCfg.bMIMOPSEnable) {
1175 /* MIMO Power Save Mode */
1176 if ((pMacEntry->MmpsMode == MMPS_DYNAMIC)
1177 && (pTransmit->field.MCS > 7)) {
1178 /* Dynamic MIMO Power Save Mode */
1179 pTxWI->MIMOps = 1;
1180 } else if (pMacEntry->MmpsMode == MMPS_STATIC) {
1181 /* Static MIMO Power Save Mode */
1182 if ((pTransmit->field.MODE >= MODE_HTMIX)
1183 && (pTransmit->field.MCS > 7)) {
1184 pTxWI->MCS = 7;
1185 pTxWI->MIMOps = 0;
1186 }
1187 }
1188 }
1189
1190 pTxWI->MPDUtotalByteCount = pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
1191
1192}
1193
1194/* should be called only when - */
1195/* 1. MEADIA_CONNECTED */
1196/* 2. AGGREGATION_IN_USED */
1197/* 3. Fragmentation not in used */
1198/* 4. either no previous frame (pPrevAddr1=NULL) .OR. previoud frame is aggregatible */
1199BOOLEAN TxFrameIsAggregatible(struct rt_rtmp_adapter *pAd,
1200 u8 *pPrevAddr1, u8 *p8023hdr)
1201{
1202
1203 /* can't aggregate EAPOL (802.1x) frame */
1204 if ((p8023hdr[12] == 0x88) && (p8023hdr[13] == 0x8e))
1205 return FALSE;
1206
1207 /* can't aggregate multicast/broadcast frame */
1208 if (p8023hdr[0] & 0x01)
1209 return FALSE;
1210
1211 if (INFRA_ON(pAd)) /* must be unicast to AP */
1212 return TRUE;
1213 else if ((pPrevAddr1 == NULL) || MAC_ADDR_EQUAL(pPrevAddr1, p8023hdr)) /* unicast to same STA */
1214 return TRUE;
1215 else
1216 return FALSE;
1217}
1218
1219/*
1220 ========================================================================
1221
1222 Routine Description:
1223 Check the MSDU Aggregation policy
1224 1.HT aggregation is A-MSDU
1225 2.legaacy rate aggregation is software aggregation by Ralink.
1226
1227 Arguments:
1228
1229 Return Value:
1230
1231 Note:
1232
1233 ========================================================================
1234*/
1235BOOLEAN PeerIsAggreOn(struct rt_rtmp_adapter *pAd,
1236 unsigned long TxRate, struct rt_mac_table_entry *pMacEntry)
1237{
1238 unsigned long AFlags =
1239 (fCLIENT_STATUS_AMSDU_INUSED | fCLIENT_STATUS_AGGREGATION_CAPABLE);
1240
1241 if (pMacEntry != NULL && CLIENT_STATUS_TEST_FLAG(pMacEntry, AFlags)) {
1242 if (pMacEntry->HTPhyMode.field.MODE >= MODE_HTMIX) {
1243 return TRUE;
1244 }
1245#ifdef AGGREGATION_SUPPORT
1246 if (TxRate >= RATE_6 && pAd->CommonCfg.bAggregationCapable && (!(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE)))) { /* legacy Ralink Aggregation support */
1247 return TRUE;
1248 }
1249#endif /* AGGREGATION_SUPPORT // */
1250 }
1251
1252 return FALSE;
1253
1254}
1255
1256/*
1257 ========================================================================
1258
1259 Routine Description:
1260 Check and fine the packet waiting in SW queue with highest priority
1261
1262 Arguments:
1263 pAd Pointer to our adapter
1264
1265 Return Value:
1266 pQueue Pointer to Waiting Queue
1267
1268 IRQL = DISPATCH_LEVEL
1269
1270 Note:
1271
1272 ========================================================================
1273*/
1274struct rt_queue_header *RTMPCheckTxSwQueue(struct rt_rtmp_adapter *pAd, u8 *pQueIdx)
1275{
1276
1277 unsigned long Number;
1278 /* 2004-11-15 to be removed. test aggregation only */
1279/* if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED)) && (*pNumber < 2)) */
1280/* return NULL; */
1281
1282 Number = pAd->TxSwQueue[QID_AC_BK].Number
1283 + pAd->TxSwQueue[QID_AC_BE].Number
1284 + pAd->TxSwQueue[QID_AC_VI].Number
1285 + pAd->TxSwQueue[QID_AC_VO].Number;
1286
1287 if (pAd->TxSwQueue[QID_AC_VO].Head != NULL) {
1288 *pQueIdx = QID_AC_VO;
1289 return (&pAd->TxSwQueue[QID_AC_VO]);
1290 } else if (pAd->TxSwQueue[QID_AC_VI].Head != NULL) {
1291 *pQueIdx = QID_AC_VI;
1292 return (&pAd->TxSwQueue[QID_AC_VI]);
1293 } else if (pAd->TxSwQueue[QID_AC_BE].Head != NULL) {
1294 *pQueIdx = QID_AC_BE;
1295 return (&pAd->TxSwQueue[QID_AC_BE]);
1296 } else if (pAd->TxSwQueue[QID_AC_BK].Head != NULL) {
1297 *pQueIdx = QID_AC_BK;
1298 return (&pAd->TxSwQueue[QID_AC_BK]);
1299 }
1300 /* No packet pending in Tx Sw queue */
1301 *pQueIdx = QID_AC_BK;
1302
1303 return (NULL);
1304}
1305
1306/*
1307 ========================================================================
1308
1309 Routine Description:
1310 Suspend MSDU transmission
1311
1312 Arguments:
1313 pAd Pointer to our adapter
1314
1315 Return Value:
1316 None
1317
1318 Note:
1319
1320 ========================================================================
1321*/
1322void RTMPSuspendMsduTransmission(struct rt_rtmp_adapter *pAd)
1323{
1324 DBGPRINT(RT_DEBUG_TRACE, ("SCANNING, suspend MSDU transmission ...\n"));
1325
1326 /* */
1327 /* Before BSS_SCAN_IN_PROGRESS, we need to keep Current R66 value and */
1328 /* use Lowbound as R66 value on ScanNextChannel(...) */
1329 /* */
1330 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66,
1331 &pAd->BbpTuning.R66CurrentValue);
1332
1333 /* set BBP_R66 to 0x30/0x40 when scanning (AsicSwitchChannel will set R66 according to channel when scanning) */
1334 /*RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, (0x26 + GET_LNA_GAIN(pAd))); */
1335 RTMPSetAGCInitValue(pAd, BW_20);
1336
1337 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
1338 /*RTMP_IO_WRITE32(pAd, TX_CNTL_CSR, 0x000f0000); // abort all TX rings */
1339}
1340
1341/*
1342 ========================================================================
1343
1344 Routine Description:
1345 Resume MSDU transmission
1346
1347 Arguments:
1348 pAd Pointer to our adapter
1349
1350 Return Value:
1351 None
1352
1353 IRQL = DISPATCH_LEVEL
1354
1355 Note:
1356
1357 ========================================================================
1358*/
1359void RTMPResumeMsduTransmission(struct rt_rtmp_adapter *pAd)
1360{
1361/* u8 IrqState; */
1362
1363 DBGPRINT(RT_DEBUG_TRACE, ("SCAN done, resume MSDU transmission ...\n"));
1364
1365 /* After finish BSS_SCAN_IN_PROGRESS, we need to restore Current R66 value */
1366 /* R66 should not be 0 */
1367 if (pAd->BbpTuning.R66CurrentValue == 0) {
1368 pAd->BbpTuning.R66CurrentValue = 0x38;
1369 DBGPRINT_ERR("RTMPResumeMsduTransmission, R66CurrentValue=0...\n");
1370 }
1371
1372 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66,
1373 pAd->BbpTuning.R66CurrentValue);
1374
1375 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
1376/* sample, for IRQ LOCK to SEM LOCK */
1377/* IrqState = pAd->irq_disabled; */
1378/* if (IrqState) */
1379/* RTMPDeQueuePacket(pAd, TRUE, NUM_OF_TX_RING, MAX_TX_PROCESS); */
1380/* else */
1381 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1382}
1383
1384u32 deaggregate_AMSDU_announce(struct rt_rtmp_adapter *pAd,
1385 void *pPacket,
1386 u8 *pData, unsigned long DataSize)
1387{
1388 u16 PayloadSize;
1389 u16 SubFrameSize;
1390 struct rt_header_802_3 * pAMSDUsubheader;
1391 u32 nMSDU;
1392 u8 Header802_3[14];
1393
1394 u8 *pPayload, *pDA, *pSA, *pRemovedLLCSNAP;
1395 void *pClonePacket;
1396
1397 nMSDU = 0;
1398
1399 while (DataSize > LENGTH_802_3) {
1400
1401 nMSDU++;
1402
1403 /*hex_dump("subheader", pData, 64); */
1404 pAMSDUsubheader = (struct rt_header_802_3 *) pData;
1405 /*pData += LENGTH_802_3; */
1406 PayloadSize =
1407 pAMSDUsubheader->Octet[1] +
1408 (pAMSDUsubheader->Octet[0] << 8);
1409 SubFrameSize = PayloadSize + LENGTH_802_3;
1410
1411 if ((DataSize < SubFrameSize) || (PayloadSize > 1518)) {
1412 break;
1413 }
1414 /*DBGPRINT(RT_DEBUG_TRACE,("%d subframe: Size = %d\n", nMSDU, PayloadSize)); */
1415
1416 pPayload = pData + LENGTH_802_3;
1417 pDA = pData;
1418 pSA = pData + MAC_ADDR_LEN;
1419
1420 /* convert to 802.3 header */
1421 CONVERT_TO_802_3(Header802_3, pDA, pSA, pPayload, PayloadSize,
1422 pRemovedLLCSNAP);
1423
1424 if ((Header802_3[12] == 0x88) && (Header802_3[13] == 0x8E)) {
1425 /* avoid local heap overflow, use dyanamic allocation */
1426 struct rt_mlme_queue_elem *Elem =
1427 kmalloc(sizeof(struct rt_mlme_queue_elem),
1428 MEM_ALLOC_FLAG);
1429 if (Elem != NULL) {
1430 memmove(Elem->Msg +
1431 (LENGTH_802_11 + LENGTH_802_1_H),
1432 pPayload, PayloadSize);
1433 Elem->MsgLen =
1434 LENGTH_802_11 + LENGTH_802_1_H +
1435 PayloadSize;
1436 /*WpaEAPOLKeyAction(pAd, Elem); */
1437 REPORT_MGMT_FRAME_TO_MLME(pAd, BSSID_WCID,
1438 Elem->Msg,
1439 Elem->MsgLen, 0, 0, 0,
1440 0);
1441 kfree(Elem);
1442 }
1443 }
1444
1445 {
1446 if (pRemovedLLCSNAP) {
1447 pPayload -= LENGTH_802_3;
1448 PayloadSize += LENGTH_802_3;
1449 NdisMoveMemory(pPayload, &Header802_3[0],
1450 LENGTH_802_3);
1451 }
1452 }
1453
1454 pClonePacket = ClonePacket(pAd, pPacket, pPayload, PayloadSize);
1455 if (pClonePacket) {
1456 ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pClonePacket,
1457 RTMP_GET_PACKET_IF
1458 (pPacket));
1459 }
1460
1461 /* A-MSDU has padding to multiple of 4 including subframe header. */
1462 /* align SubFrameSize up to multiple of 4 */
1463 SubFrameSize = (SubFrameSize + 3) & (~0x3);
1464
1465 if (SubFrameSize > 1528 || SubFrameSize < 32) {
1466 break;
1467 }
1468
1469 if (DataSize > SubFrameSize) {
1470 pData += SubFrameSize;
1471 DataSize -= SubFrameSize;
1472 } else {
1473 /* end of A-MSDU */
1474 DataSize = 0;
1475 }
1476 }
1477
1478 /* finally release original rx packet */
1479 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
1480
1481 return nMSDU;
1482}
1483
1484u32 BA_Reorder_AMSDU_Announce(struct rt_rtmp_adapter *pAd, void *pPacket)
1485{
1486 u8 *pData;
1487 u16 DataSize;
1488 u32 nMSDU = 0;
1489
1490 pData = (u8 *)GET_OS_PKT_DATAPTR(pPacket);
1491 DataSize = (u16)GET_OS_PKT_LEN(pPacket);
1492
1493 nMSDU = deaggregate_AMSDU_announce(pAd, pPacket, pData, DataSize);
1494
1495 return nMSDU;
1496}
1497
1498/*
1499 ==========================================================================
1500 Description:
1501 Look up the MAC address in the MAC table. Return NULL if not found.
1502 Return:
1503 pEntry - pointer to the MAC entry; NULL is not found
1504 ==========================================================================
1505*/
1506struct rt_mac_table_entry *MacTableLookup(struct rt_rtmp_adapter *pAd, u8 *pAddr)
1507{
1508 unsigned long HashIdx;
1509 struct rt_mac_table_entry *pEntry = NULL;
1510
1511 HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
1512 pEntry = pAd->MacTab.Hash[HashIdx];
1513
1514 while (pEntry
1515 && (pEntry->ValidAsCLI || pEntry->ValidAsWDS
1516 || pEntry->ValidAsApCli || pEntry->ValidAsMesh)) {
1517 if (MAC_ADDR_EQUAL(pEntry->Addr, pAddr)) {
1518 break;
1519 } else
1520 pEntry = pEntry->pNext;
1521 }
1522
1523 return pEntry;
1524}
1525
1526struct rt_mac_table_entry *MacTableInsertEntry(struct rt_rtmp_adapter *pAd,
1527 u8 *pAddr,
1528 u8 apidx, IN BOOLEAN CleanAll)
1529{
1530 u8 HashIdx;
1531 int i, FirstWcid;
1532 struct rt_mac_table_entry *pEntry = NULL, *pCurrEntry;
1533/* u16 offset; */
1534/* unsigned long addr; */
1535
1536 /* if FULL, return */
1537 if (pAd->MacTab.Size >= MAX_LEN_OF_MAC_TABLE)
1538 return NULL;
1539
1540 FirstWcid = 1;
1541
1542 if (pAd->StaCfg.BssType == BSS_INFRA)
1543 FirstWcid = 2;
1544
1545 /* allocate one MAC entry */
1546 NdisAcquireSpinLock(&pAd->MacTabLock);
1547 for (i = FirstWcid; i < MAX_LEN_OF_MAC_TABLE; i++) /* skip entry#0 so that "entry index == AID" for fast lookup */
1548 {
1549 /* pick up the first available vacancy */
1550 if ((pAd->MacTab.Content[i].ValidAsCLI == FALSE) &&
1551 (pAd->MacTab.Content[i].ValidAsWDS == FALSE) &&
1552 (pAd->MacTab.Content[i].ValidAsApCli == FALSE) &&
1553 (pAd->MacTab.Content[i].ValidAsMesh == FALSE)
1554 ) {
1555 pEntry = &pAd->MacTab.Content[i];
1556 if (CleanAll == TRUE) {
1557 pEntry->MaxSupportedRate = RATE_11;
1558 pEntry->CurrTxRate = RATE_11;
1559 NdisZeroMemory(pEntry, sizeof(struct rt_mac_table_entry));
1560 pEntry->PairwiseKey.KeyLen = 0;
1561 pEntry->PairwiseKey.CipherAlg = CIPHER_NONE;
1562 }
1563 {
1564 {
1565 pEntry->ValidAsCLI = TRUE;
1566 pEntry->ValidAsWDS = FALSE;
1567 pEntry->ValidAsApCli = FALSE;
1568 pEntry->ValidAsMesh = FALSE;
1569 pEntry->ValidAsDls = FALSE;
1570 }
1571 }
1572
1573 pEntry->bIAmBadAtheros = FALSE;
1574 pEntry->pAd = pAd;
1575 pEntry->CMTimerRunning = FALSE;
1576 pEntry->EnqueueEapolStartTimerRunning =
1577 EAPOL_START_DISABLE;
1578 pEntry->RSNIE_Len = 0;
1579 NdisZeroMemory(pEntry->R_Counter,
1580 sizeof(pEntry->R_Counter));
1581 pEntry->ReTryCounter = PEER_MSG1_RETRY_TIMER_CTR;
1582
1583 if (pEntry->ValidAsMesh)
1584 pEntry->apidx =
1585 (apidx - MIN_NET_DEVICE_FOR_MESH);
1586 else if (pEntry->ValidAsApCli)
1587 pEntry->apidx =
1588 (apidx - MIN_NET_DEVICE_FOR_APCLI);
1589 else if (pEntry->ValidAsWDS)
1590 pEntry->apidx =
1591 (apidx - MIN_NET_DEVICE_FOR_WDS);
1592 else
1593 pEntry->apidx = apidx;
1594
1595 {
1596 {
1597 pEntry->AuthMode = pAd->StaCfg.AuthMode;
1598 pEntry->WepStatus =
1599 pAd->StaCfg.WepStatus;
1600 pEntry->PrivacyFilter =
1601 Ndis802_11PrivFilterAcceptAll;
1602#ifdef RTMP_MAC_PCI
1603 AsicRemovePairwiseKeyEntry(pAd,
1604 pEntry->
1605 apidx,
1606 (u8)i);
1607#endif /* RTMP_MAC_PCI // */
1608 }
1609 }
1610
1611 pEntry->GTKState = REKEY_NEGOTIATING;
1612 pEntry->PairwiseKey.KeyLen = 0;
1613 pEntry->PairwiseKey.CipherAlg = CIPHER_NONE;
1614 pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED;
1615
1616 pEntry->PMKID_CacheIdx = ENTRY_NOT_FOUND;
1617 COPY_MAC_ADDR(pEntry->Addr, pAddr);
1618 pEntry->Sst = SST_NOT_AUTH;
1619 pEntry->AuthState = AS_NOT_AUTH;
1620 pEntry->Aid = (u16)i; /*0; */
1621 pEntry->CapabilityInfo = 0;
1622 pEntry->PsMode = PWR_ACTIVE;
1623 pEntry->PsQIdleCount = 0;
1624 pEntry->NoDataIdleCount = 0;
1625 pEntry->AssocDeadLine = MAC_TABLE_ASSOC_TIMEOUT;
1626 pEntry->ContinueTxFailCnt = 0;
1627 InitializeQueueHeader(&pEntry->PsQueue);
1628
1629 pAd->MacTab.Size++;
1630 /* Add this entry into ASIC RX WCID search table */
1631 RTMP_STA_ENTRY_ADD(pAd, pEntry);
1632
1633 DBGPRINT(RT_DEBUG_TRACE,
1634 ("MacTableInsertEntry - allocate entry #%d, Total= %d\n",
1635 i, pAd->MacTab.Size));
1636 break;
1637 }
1638 }
1639
1640 /* add this MAC entry into HASH table */
1641 if (pEntry) {
1642 HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
1643 if (pAd->MacTab.Hash[HashIdx] == NULL) {
1644 pAd->MacTab.Hash[HashIdx] = pEntry;
1645 } else {
1646 pCurrEntry = pAd->MacTab.Hash[HashIdx];
1647 while (pCurrEntry->pNext != NULL)
1648 pCurrEntry = pCurrEntry->pNext;
1649 pCurrEntry->pNext = pEntry;
1650 }
1651 }
1652
1653 NdisReleaseSpinLock(&pAd->MacTabLock);
1654 return pEntry;
1655}
1656
1657/*
1658 ==========================================================================
1659 Description:
1660 Delete a specified client from MAC table
1661 ==========================================================================
1662 */
1663BOOLEAN MacTableDeleteEntry(struct rt_rtmp_adapter *pAd,
1664 u16 wcid, u8 *pAddr)
1665{
1666 u16 HashIdx;
1667 struct rt_mac_table_entry *pEntry, *pPrevEntry, *pProbeEntry;
1668 BOOLEAN Cancelled;
1669 /*u16 offset; // unused variable */
1670 /*u8 j; // unused variable */
1671
1672 if (wcid >= MAX_LEN_OF_MAC_TABLE)
1673 return FALSE;
1674
1675 NdisAcquireSpinLock(&pAd->MacTabLock);
1676
1677 HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
1678 /*pEntry = pAd->MacTab.Hash[HashIdx]; */
1679 pEntry = &pAd->MacTab.Content[wcid];
1680
1681 if (pEntry
1682 && (pEntry->ValidAsCLI || pEntry->ValidAsApCli || pEntry->ValidAsWDS
1683 || pEntry->ValidAsMesh)) {
1684 if (MAC_ADDR_EQUAL(pEntry->Addr, pAddr)) {
1685
1686 /* Delete this entry from ASIC on-chip WCID Table */
1687 RTMP_STA_ENTRY_MAC_RESET(pAd, wcid);
1688
1689 /* free resources of BA */
1690 BASessionTearDownALL(pAd, pEntry->Aid);
1691
1692 pPrevEntry = NULL;
1693 pProbeEntry = pAd->MacTab.Hash[HashIdx];
1694 ASSERT(pProbeEntry);
1695
1696 /* update Hash list */
1697 do {
1698 if (pProbeEntry == pEntry) {
1699 if (pPrevEntry == NULL) {
1700 pAd->MacTab.Hash[HashIdx] =
1701 pEntry->pNext;
1702 } else {
1703 pPrevEntry->pNext =
1704 pEntry->pNext;
1705 }
1706 break;
1707 }
1708
1709 pPrevEntry = pProbeEntry;
1710 pProbeEntry = pProbeEntry->pNext;
1711 } while (pProbeEntry);
1712
1713 /* not found ! */
1714 ASSERT(pProbeEntry != NULL);
1715
1716 RTMP_STA_ENTRY_KEY_DEL(pAd, BSS0, wcid);
1717
1718 if (pEntry->EnqueueEapolStartTimerRunning !=
1719 EAPOL_START_DISABLE) {
1720 RTMPCancelTimer(&pEntry->
1721 EnqueueStartForPSKTimer,
1722 &Cancelled);
1723 pEntry->EnqueueEapolStartTimerRunning =
1724 EAPOL_START_DISABLE;
1725 }
1726
1727 NdisZeroMemory(pEntry, sizeof(struct rt_mac_table_entry));
1728 pAd->MacTab.Size--;
1729 DBGPRINT(RT_DEBUG_TRACE,
1730 ("MacTableDeleteEntry1 - Total= %d\n",
1731 pAd->MacTab.Size));
1732 } else {
1733 DBGPRINT(RT_DEBUG_OFF,
1734 ("\n%s: Impossible Wcid = %d !\n",
1735 __func__, wcid));
1736 }
1737 }
1738
1739 NdisReleaseSpinLock(&pAd->MacTabLock);
1740
1741 /*Reset operating mode when no Sta. */
1742 if (pAd->MacTab.Size == 0) {
1743 pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode = 0;
1744 RTMP_UPDATE_PROTECT(pAd); /* edit by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet */
1745 }
1746
1747 return TRUE;
1748}
1749
1750/*
1751 ==========================================================================
1752 Description:
1753 This routine reset the entire MAC table. All packets pending in
1754 the power-saving queues are freed here.
1755 ==========================================================================
1756 */
1757void MacTableReset(struct rt_rtmp_adapter *pAd)
1758{
1759 int i;
1760
1761 DBGPRINT(RT_DEBUG_TRACE, ("MacTableReset\n"));
1762 /*NdisAcquireSpinLock(&pAd->MacTabLock); */
1763
1764 for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++) {
1765#ifdef RTMP_MAC_PCI
1766 RTMP_STA_ENTRY_MAC_RESET(pAd, i);
1767#endif /* RTMP_MAC_PCI // */
1768 if (pAd->MacTab.Content[i].ValidAsCLI == TRUE) {
1769
1770 /* free resources of BA */
1771 BASessionTearDownALL(pAd, i);
1772
1773 pAd->MacTab.Content[i].ValidAsCLI = FALSE;
1774
1775#ifdef RTMP_MAC_USB
1776 NdisZeroMemory(pAd->MacTab.Content[i].Addr, 6);
1777 RTMP_STA_ENTRY_MAC_RESET(pAd, i);
1778#endif /* RTMP_MAC_USB // */
1779
1780 /*AsicDelWcidTab(pAd, i); */
1781 }
1782 }
1783
1784 return;
1785}
1786
1787/*
1788 ==========================================================================
1789 Description:
1790
1791 IRQL = DISPATCH_LEVEL
1792
1793 ==========================================================================
1794*/
1795void AssocParmFill(struct rt_rtmp_adapter *pAd,
1796 struct rt_mlme_assoc_req *AssocReq,
1797 u8 *pAddr,
1798 u16 CapabilityInfo,
1799 unsigned long Timeout, u16 ListenIntv)
1800{
1801 COPY_MAC_ADDR(AssocReq->Addr, pAddr);
1802 /* Add mask to support 802.11b mode only */
1803 AssocReq->CapabilityInfo = CapabilityInfo & SUPPORTED_CAPABILITY_INFO; /* not cf-pollable, not cf-poll-request */
1804 AssocReq->Timeout = Timeout;
1805 AssocReq->ListenIntv = ListenIntv;
1806}
1807
1808/*
1809 ==========================================================================
1810 Description:
1811
1812 IRQL = DISPATCH_LEVEL
1813
1814 ==========================================================================
1815*/
1816void DisassocParmFill(struct rt_rtmp_adapter *pAd,
1817 struct rt_mlme_disassoc_req *DisassocReq,
1818 u8 *pAddr, u16 Reason)
1819{
1820 COPY_MAC_ADDR(DisassocReq->Addr, pAddr);
1821 DisassocReq->Reason = Reason;
1822}
1823
1824/*
1825 ========================================================================
1826
1827 Routine Description:
1828 Check the out going frame, if this is an DHCP or ARP datagram
1829 will be duplicate another frame at low data rate transmit.
1830
1831 Arguments:
1832 pAd Pointer to our adapter
1833 pPacket Pointer to outgoing Ndis frame
1834
1835 Return Value:
1836 TRUE To be duplicate at Low data rate transmit. (1mb)
1837 FALSE Do nothing.
1838
1839 IRQL = DISPATCH_LEVEL
1840
1841 Note:
1842
1843 MAC header + IP Header + UDP Header
1844 14 Bytes 20 Bytes
1845
1846 UDP Header
1847 00|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|
1848 Source Port
1849 16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|
1850 Destination Port
1851
1852 port 0x43 means Bootstrap Protocol, server.
1853 Port 0x44 means Bootstrap Protocol, client.
1854
1855 ========================================================================
1856*/
1857
1858BOOLEAN RTMPCheckDHCPFrame(struct rt_rtmp_adapter *pAd, void *pPacket)
1859{
1860 struct rt_packet_info PacketInfo;
1861 unsigned long NumberOfBytesRead = 0;
1862 unsigned long CurrentOffset = 0;
1863 void *pVirtualAddress = NULL;
1864 u32 NdisBufferLength;
1865 u8 *pSrc;
1866 u16 Protocol;
1867 u8 ByteOffset36 = 0;
1868 u8 ByteOffset38 = 0;
1869 BOOLEAN ReadFirstParm = TRUE;
1870
1871 RTMP_QueryPacketInfo(pPacket, &PacketInfo, (u8 **) & pVirtualAddress,
1872 &NdisBufferLength);
1873
1874 NumberOfBytesRead += NdisBufferLength;
1875 pSrc = (u8 *)pVirtualAddress;
1876 Protocol = *(pSrc + 12) * 256 + *(pSrc + 13);
1877
1878 /* */
1879 /* Check DHCP & BOOTP protocol */
1880 /* */
1881 while (NumberOfBytesRead <= PacketInfo.TotalPacketLength) {
1882 if ((NumberOfBytesRead >= 35) && (ReadFirstParm == TRUE)) {
1883 CurrentOffset =
1884 35 - (NumberOfBytesRead - NdisBufferLength);
1885 ByteOffset36 = *(pSrc + CurrentOffset);
1886 ReadFirstParm = FALSE;
1887 }
1888
1889 if (NumberOfBytesRead >= 37) {
1890 CurrentOffset =
1891 37 - (NumberOfBytesRead - NdisBufferLength);
1892 ByteOffset38 = *(pSrc + CurrentOffset);
1893 /*End of Read */
1894 break;
1895 }
1896 return FALSE;
1897 }
1898
1899 /* Check for DHCP & BOOTP protocol */
1900 if ((ByteOffset36 != 0x44) || (ByteOffset38 != 0x43)) {
1901 /* */
1902 /* 2054 (hex 0806) for ARP datagrams */
1903 /* if this packet is not ARP datagrams, then do nothing */
1904 /* ARP datagrams will also be duplicate at 1mb broadcast frames */
1905 /* */
1906 if (Protocol != 0x0806)
1907 return FALSE;
1908 }
1909
1910 return TRUE;
1911}
1912
1913BOOLEAN RTMPCheckEtherType(struct rt_rtmp_adapter *pAd, void *pPacket)
1914{
1915 u16 TypeLen;
1916 u8 Byte0, Byte1;
1917 u8 *pSrcBuf;
1918 u32 pktLen;
1919 u16 srcPort, dstPort;
1920 BOOLEAN status = TRUE;
1921
1922 pSrcBuf = GET_OS_PKT_DATAPTR(pPacket);
1923 pktLen = GET_OS_PKT_LEN(pPacket);
1924
1925 ASSERT(pSrcBuf);
1926
1927 RTMP_SET_PACKET_SPECIFIC(pPacket, 0);
1928
1929 /* get Ethernet protocol field */
1930 TypeLen = (pSrcBuf[12] << 8) | pSrcBuf[13];
1931
1932 pSrcBuf += LENGTH_802_3; /* Skip the Ethernet Header. */
1933
1934 if (TypeLen <= 1500) { /* 802.3, 802.3 LLC */
1935 /*
1936 DestMAC(6) + SrcMAC(6) + Length(2) +
1937 DSAP(1) + SSAP(1) + Control(1) +
1938 if the DSAP = 0xAA, SSAP=0xAA, Contorl = 0x03, it has a 5-bytes SNAP header.
1939 => + SNAP (5, OriginationID(3) + etherType(2))
1940 */
1941 if (pSrcBuf[0] == 0xAA && pSrcBuf[1] == 0xAA
1942 && pSrcBuf[2] == 0x03) {
1943 Sniff2BytesFromNdisBuffer((char *)pSrcBuf, 6,
1944 &Byte0, &Byte1);
1945 RTMP_SET_PACKET_LLCSNAP(pPacket, 1);
1946 TypeLen = (u16)((Byte0 << 8) + Byte1);
1947 pSrcBuf += 8; /* Skip this LLC/SNAP header */
1948 } else {
1949 /*It just has 3-byte LLC header, maybe a legacy ether type frame. we didn't handle it. */
1950 }
1951 }
1952 /* If it's a VLAN packet, get the real Type/Length field. */
1953 if (TypeLen == 0x8100) {
1954 /* 0x8100 means VLAN packets */
1955
1956 /* Dest. MAC Address (6-bytes) +
1957 Source MAC Address (6-bytes) +
1958 Length/Type = 802.1Q Tag Type (2-byte) +
1959 Tag Control Information (2-bytes) +
1960 Length / Type (2-bytes) +
1961 data payload (0-n bytes) +
1962 Pad (0-p bytes) +
1963 Frame Check Sequence (4-bytes) */
1964
1965 RTMP_SET_PACKET_VLAN(pPacket, 1);
1966 Sniff2BytesFromNdisBuffer((char *)pSrcBuf, 2, &Byte0,
1967 &Byte1);
1968 TypeLen = (u16)((Byte0 << 8) + Byte1);
1969
1970 pSrcBuf += 4; /* Skip the VLAN Header. */
1971 }
1972
1973 switch (TypeLen) {
1974 case 0x0800:
1975 {
1976 ASSERT((pktLen > 34));
1977 if (*(pSrcBuf + 9) == 0x11) { /* udp packet */
1978 ASSERT((pktLen > 34)); /* 14 for ethernet header, 20 for IP header */
1979
1980 pSrcBuf += 20; /* Skip the IP header */
1981 srcPort =
1982 OS_NTOHS(get_unaligned
1983 ((u16 *)(pSrcBuf)));
1984 dstPort =
1985 OS_NTOHS(get_unaligned
1986 ((u16 *)(pSrcBuf + 2)));
1987
1988 if ((srcPort == 0x44 && dstPort == 0x43) || (srcPort == 0x43 && dstPort == 0x44)) { /*It's a BOOTP/DHCP packet */
1989 RTMP_SET_PACKET_DHCP(pPacket, 1);
1990 }
1991 }
1992 }
1993 break;
1994 case 0x0806:
1995 {
1996 /*ARP Packet. */
1997 RTMP_SET_PACKET_DHCP(pPacket, 1);
1998 }
1999 break;
2000 case 0x888e:
2001 {
2002 /* EAPOL Packet. */
2003 RTMP_SET_PACKET_EAPOL(pPacket, 1);
2004 }
2005 break;
2006 default:
2007 status = FALSE;
2008 break;
2009 }
2010
2011 return status;
2012
2013}
2014
2015void Update_Rssi_Sample(struct rt_rtmp_adapter *pAd,
2016 struct rt_rssi_sample *pRssi, struct rt_rxwi * pRxWI)
2017{
2018 char rssi0 = pRxWI->RSSI0;
2019 char rssi1 = pRxWI->RSSI1;
2020 char rssi2 = pRxWI->RSSI2;
2021
2022 if (rssi0 != 0) {
2023 pRssi->LastRssi0 = ConvertToRssi(pAd, (char)rssi0, RSSI_0);
2024 pRssi->AvgRssi0X8 =
2025 (pRssi->AvgRssi0X8 - pRssi->AvgRssi0) + pRssi->LastRssi0;
2026 pRssi->AvgRssi0 = pRssi->AvgRssi0X8 >> 3;
2027 }
2028
2029 if (rssi1 != 0) {
2030 pRssi->LastRssi1 = ConvertToRssi(pAd, (char)rssi1, RSSI_1);
2031 pRssi->AvgRssi1X8 =
2032 (pRssi->AvgRssi1X8 - pRssi->AvgRssi1) + pRssi->LastRssi1;
2033 pRssi->AvgRssi1 = pRssi->AvgRssi1X8 >> 3;
2034 }
2035
2036 if (rssi2 != 0) {
2037 pRssi->LastRssi2 = ConvertToRssi(pAd, (char)rssi2, RSSI_2);
2038 pRssi->AvgRssi2X8 =
2039 (pRssi->AvgRssi2X8 - pRssi->AvgRssi2) + pRssi->LastRssi2;
2040 pRssi->AvgRssi2 = pRssi->AvgRssi2X8 >> 3;
2041 }
2042}
2043
2044/* Normal legacy Rx packet indication */
2045void Indicate_Legacy_Packet(struct rt_rtmp_adapter *pAd,
2046 struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID)
2047{
2048 void *pRxPacket = pRxBlk->pRxPacket;
2049 u8 Header802_3[LENGTH_802_3];
2050
2051 /* 1. get 802.3 Header */
2052 /* 2. remove LLC */
2053 /* a. pointer pRxBlk->pData to payload */
2054 /* b. modify pRxBlk->DataSize */
2055 RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3);
2056
2057 if (pRxBlk->DataSize > MAX_RX_PKT_LEN) {
2058
2059 /* release packet */
2060 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
2061 return;
2062 }
2063
2064 STATS_INC_RX_PACKETS(pAd, FromWhichBSSID);
2065
2066#ifdef RTMP_MAC_USB
2067 if (pAd->CommonCfg.bDisableReordering == 0) {
2068 struct rt_ba_rec_entry *pBAEntry;
2069 unsigned long Now32;
2070 u8 Wcid = pRxBlk->pRxWI->WirelessCliID;
2071 u8 TID = pRxBlk->pRxWI->TID;
2072 u16 Idx;
2073
2074#define REORDERING_PACKET_TIMEOUT ((100 * OS_HZ)/1000) /* system ticks -- 100 ms */
2075
2076 if (Wcid < MAX_LEN_OF_MAC_TABLE) {
2077 Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID];
2078 if (Idx != 0) {
2079 pBAEntry = &pAd->BATable.BARecEntry[Idx];
2080 /* update last rx time */
2081 NdisGetSystemUpTime(&Now32);
2082 if ((pBAEntry->list.qlen > 0) &&
2083 RTMP_TIME_AFTER((unsigned long)Now32,
2084 (unsigned long)(pBAEntry->
2085 LastIndSeqAtTimer
2086 +
2087 (REORDERING_PACKET_TIMEOUT)))
2088 ) {
2089 DBGPRINT(RT_DEBUG_OFF,
2090 ("Indicate_Legacy_Packet():flush reordering_timeout_mpdus! RxWI->Flags=%d, pRxWI.TID=%d, RxD->AMPDU=%d!\n",
2091 pRxBlk->Flags,
2092 pRxBlk->pRxWI->TID,
2093 pRxBlk->RxD.AMPDU));
2094 hex_dump("Dump the legacy Packet:",
2095 GET_OS_PKT_DATAPTR(pRxBlk->
2096 pRxPacket),
2097 64);
2098 ba_flush_reordering_timeout_mpdus(pAd,
2099 pBAEntry,
2100 Now32);
2101 }
2102 }
2103 }
2104 }
2105#endif /* RTMP_MAC_USB // */
2106
2107 wlan_802_11_to_802_3_packet(pAd, pRxBlk, Header802_3, FromWhichBSSID);
2108
2109 /* */
2110 /* pass this 802.3 packet to upper layer or forward this packet to WM directly */
2111 /* */
2112 ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pRxPacket, FromWhichBSSID);
2113}
2114
2115/* Normal, AMPDU or AMSDU */
2116void CmmRxnonRalinkFrameIndicate(struct rt_rtmp_adapter *pAd,
2117 struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID)
2118{
2119 if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMPDU)
2120 && (pAd->CommonCfg.bDisableReordering == 0)) {
2121 Indicate_AMPDU_Packet(pAd, pRxBlk, FromWhichBSSID);
2122 } else {
2123 if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU)) {
2124 /* handle A-MSDU */
2125 Indicate_AMSDU_Packet(pAd, pRxBlk, FromWhichBSSID);
2126 } else {
2127 Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID);
2128 }
2129 }
2130}
2131
2132void CmmRxRalinkFrameIndicate(struct rt_rtmp_adapter *pAd,
2133 struct rt_mac_table_entry *pEntry,
2134 struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID)
2135{
2136 u8 Header802_3[LENGTH_802_3];
2137 u16 Msdu2Size;
2138 u16 Payload1Size, Payload2Size;
2139 u8 *pData2;
2140 void *pPacket2 = NULL;
2141
2142 Msdu2Size = *(pRxBlk->pData) + (*(pRxBlk->pData + 1) << 8);
2143
2144 if ((Msdu2Size <= 1536) && (Msdu2Size < pRxBlk->DataSize)) {
2145 /* skip two byte MSDU2 len */
2146 pRxBlk->pData += 2;
2147 pRxBlk->DataSize -= 2;
2148 } else {
2149 /* release packet */
2150 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket,
2151 NDIS_STATUS_FAILURE);
2152 return;
2153 }
2154
2155 /* get 802.3 Header and remove LLC */
2156 RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3);
2157
2158 ASSERT(pRxBlk->pRxPacket);
2159
2160 /* Ralink Aggregation frame */
2161 pAd->RalinkCounters.OneSecRxAggregationCount++;
2162 Payload1Size = pRxBlk->DataSize - Msdu2Size;
2163 Payload2Size = Msdu2Size - LENGTH_802_3;
2164
2165 pData2 = pRxBlk->pData + Payload1Size + LENGTH_802_3;
2166
2167 pPacket2 =
2168 duplicate_pkt(pAd, (pData2 - LENGTH_802_3), LENGTH_802_3, pData2,
2169 Payload2Size, FromWhichBSSID);
2170
2171 if (!pPacket2) {
2172 /* release packet */
2173 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket,
2174 NDIS_STATUS_FAILURE);
2175 return;
2176 }
2177 /* update payload size of 1st packet */
2178 pRxBlk->DataSize = Payload1Size;
2179 wlan_802_11_to_802_3_packet(pAd, pRxBlk, Header802_3, FromWhichBSSID);
2180
2181 ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pRxBlk->pRxPacket,
2182 FromWhichBSSID);
2183
2184 if (pPacket2) {
2185 ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pPacket2, FromWhichBSSID);
2186 }
2187}
2188
2189#define RESET_FRAGFRAME(_fragFrame) \
2190 { \
2191 _fragFrame.RxSize = 0; \
2192 _fragFrame.Sequence = 0; \
2193 _fragFrame.LastFrag = 0; \
2194 _fragFrame.Flags = 0; \
2195 }
2196
2197void *RTMPDeFragmentDataFrame(struct rt_rtmp_adapter *pAd, struct rt_rx_blk *pRxBlk)
2198{
2199 struct rt_header_802_11 * pHeader = pRxBlk->pHeader;
2200 void *pRxPacket = pRxBlk->pRxPacket;
2201 u8 *pData = pRxBlk->pData;
2202 u16 DataSize = pRxBlk->DataSize;
2203 void *pRetPacket = NULL;
2204 u8 *pFragBuffer = NULL;
2205 BOOLEAN bReassDone = FALSE;
2206 u8 HeaderRoom = 0;
2207
2208 ASSERT(pHeader);
2209
2210 HeaderRoom = pData - (u8 *) pHeader;
2211
2212 /* Re-assemble the fragmented packets */
2213 if (pHeader->Frag == 0) /* Frag. Number is 0 : First frag or only one pkt */
2214 {
2215 /* the first pkt of fragment, record it. */
2216 if (pHeader->FC.MoreFrag) {
2217 ASSERT(pAd->FragFrame.pFragPacket);
2218 pFragBuffer =
2219 GET_OS_PKT_DATAPTR(pAd->FragFrame.pFragPacket);
2220 pAd->FragFrame.RxSize = DataSize + HeaderRoom;
2221 NdisMoveMemory(pFragBuffer, pHeader,
2222 pAd->FragFrame.RxSize);
2223 pAd->FragFrame.Sequence = pHeader->Sequence;
2224 pAd->FragFrame.LastFrag = pHeader->Frag; /* Should be 0 */
2225 ASSERT(pAd->FragFrame.LastFrag == 0);
2226 goto done; /* end of processing this frame */
2227 }
2228 } else /*Middle & End of fragment */
2229 {
2230 if ((pHeader->Sequence != pAd->FragFrame.Sequence) ||
2231 (pHeader->Frag != (pAd->FragFrame.LastFrag + 1))) {
2232 /* Fragment is not the same sequence or out of fragment number order */
2233 /* Reset Fragment control blk */
2234 RESET_FRAGFRAME(pAd->FragFrame);
2235 DBGPRINT(RT_DEBUG_ERROR,
2236 ("Fragment is not the same sequence or out of fragment number order.\n"));
2237 goto done; /* give up this frame */
2238 } else if ((pAd->FragFrame.RxSize + DataSize) > MAX_FRAME_SIZE) {
2239 /* Fragment frame is too large, it exeeds the maximum frame size. */
2240 /* Reset Fragment control blk */
2241 RESET_FRAGFRAME(pAd->FragFrame);
2242 DBGPRINT(RT_DEBUG_ERROR,
2243 ("Fragment frame is too large, it exeeds the maximum frame size.\n"));
2244 goto done; /* give up this frame */
2245 }
2246 /* */
2247 /* Broadcom AP(BCM94704AGR) will send out LLC in fragment's packet, LLC only can accpet at first fragment. */
2248 /* In this case, we will dropt it. */
2249 /* */
2250 if (NdisEqualMemory(pData, SNAP_802_1H, sizeof(SNAP_802_1H))) {
2251 DBGPRINT(RT_DEBUG_ERROR,
2252 ("Find another LLC at Middle or End fragment(SN=%d, Frag=%d)\n",
2253 pHeader->Sequence, pHeader->Frag));
2254 goto done; /* give up this frame */
2255 }
2256
2257 pFragBuffer = GET_OS_PKT_DATAPTR(pAd->FragFrame.pFragPacket);
2258
2259 /* concatenate this fragment into the re-assembly buffer */
2260 NdisMoveMemory((pFragBuffer + pAd->FragFrame.RxSize), pData,
2261 DataSize);
2262 pAd->FragFrame.RxSize += DataSize;
2263 pAd->FragFrame.LastFrag = pHeader->Frag; /* Update fragment number */
2264
2265 /* Last fragment */
2266 if (pHeader->FC.MoreFrag == FALSE) {
2267 bReassDone = TRUE;
2268 }
2269 }
2270
2271done:
2272 /* always release rx fragmented packet */
2273 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
2274
2275 /* return defragmented packet if packet is reassembled completely */
2276 /* otherwise return NULL */
2277 if (bReassDone) {
2278 void *pNewFragPacket;
2279
2280 /* allocate a new packet buffer for fragment */
2281 pNewFragPacket =
2282 RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE);
2283 if (pNewFragPacket) {
2284 /* update RxBlk */
2285 pRetPacket = pAd->FragFrame.pFragPacket;
2286 pAd->FragFrame.pFragPacket = pNewFragPacket;
2287 pRxBlk->pHeader =
2288 (struct rt_header_802_11 *) GET_OS_PKT_DATAPTR(pRetPacket);
2289 pRxBlk->pData = (u8 *) pRxBlk->pHeader + HeaderRoom;
2290 pRxBlk->DataSize = pAd->FragFrame.RxSize - HeaderRoom;
2291 pRxBlk->pRxPacket = pRetPacket;
2292 } else {
2293 RESET_FRAGFRAME(pAd->FragFrame);
2294 }
2295 }
2296
2297 return pRetPacket;
2298}
2299
2300void Indicate_AMSDU_Packet(struct rt_rtmp_adapter *pAd,
2301 struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID)
2302{
2303 u32 nMSDU;
2304
2305 update_os_packet_info(pAd, pRxBlk, FromWhichBSSID);
2306 RTMP_SET_PACKET_IF(pRxBlk->pRxPacket, FromWhichBSSID);
2307 nMSDU =
2308 deaggregate_AMSDU_announce(pAd, pRxBlk->pRxPacket, pRxBlk->pData,
2309 pRxBlk->DataSize);
2310}
2311
2312void Indicate_EAPOL_Packet(struct rt_rtmp_adapter *pAd,
2313 struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID)
2314{
2315 struct rt_mac_table_entry *pEntry = NULL;
2316
2317 {
2318 pEntry = &pAd->MacTab.Content[BSSID_WCID];
2319 STARxEAPOLFrameIndicate(pAd, pEntry, pRxBlk, FromWhichBSSID);
2320 return;
2321 }
2322
2323 if (pEntry == NULL) {
2324 DBGPRINT(RT_DEBUG_WARN,
2325 ("Indicate_EAPOL_Packet: drop and release the invalid packet.\n"));
2326 /* release packet */
2327 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket,
2328 NDIS_STATUS_FAILURE);
2329 return;
2330 }
2331}
2332
2333#define BCN_TBTT_OFFSET 64 /*defer 64 us */
2334void ReSyncBeaconTime(struct rt_rtmp_adapter *pAd)
2335{
2336
2337 u32 Offset;
2338
2339 Offset = (pAd->TbttTickCount) % (BCN_TBTT_OFFSET);
2340
2341 pAd->TbttTickCount++;
2342
2343 /* */
2344 /* The updated BeaconInterval Value will affect Beacon Interval after two TBTT */
2345 /* beacasue the original BeaconInterval had been loaded into next TBTT_TIMER */
2346 /* */
2347 if (Offset == (BCN_TBTT_OFFSET - 2)) {
2348 BCN_TIME_CFG_STRUC csr;
2349 RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
2350 csr.field.BeaconInterval = (pAd->CommonCfg.BeaconPeriod << 4) - 1; /* ASIC register in units of 1/16 TU = 64us */
2351 RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
2352 } else {
2353 if (Offset == (BCN_TBTT_OFFSET - 1)) {
2354 BCN_TIME_CFG_STRUC csr;
2355
2356 RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
2357 csr.field.BeaconInterval = (pAd->CommonCfg.BeaconPeriod) << 4; /* ASIC register in units of 1/16 TU */
2358 RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
2359 }
2360 }
2361}
diff --git a/drivers/staging/rt2860/common/cmm_data_pci.c b/drivers/staging/rt2860/common/cmm_data_pci.c
deleted file mode 100644
index bef0bbd8cef..00000000000
--- a/drivers/staging/rt2860/common/cmm_data_pci.c
+++ /dev/null
@@ -1,1096 +0,0 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26 */
27
28/*
29 All functions in this file must be PCI-depended, or you should out your function
30 in other files.
31
32*/
33#include "../rt_config.h"
34
35u16 RtmpPCI_WriteTxResource(struct rt_rtmp_adapter *pAd,
36 struct rt_tx_blk *pTxBlk,
37 IN BOOLEAN bIsLast, u16 * FreeNumber)
38{
39
40 u8 *pDMAHeaderBufVA;
41 u16 TxIdx, RetTxIdx;
42 struct rt_txd * pTxD;
43 u32 BufBasePaLow;
44 struct rt_rtmp_tx_ring *pTxRing;
45 u16 hwHeaderLen;
46
47 /* */
48 /* get Tx Ring Resource */
49 /* */
50 pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
51 TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx;
52 pDMAHeaderBufVA = (u8 *)pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
53 BufBasePaLow =
54 RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
55
56 /* copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer */
57 if (pTxBlk->TxFrameType == TX_AMSDU_FRAME) {
58 /*hwHeaderLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD, 4)+LENGTH_AMSDU_SUBFRAMEHEAD; */
59 hwHeaderLen =
60 pTxBlk->MpduHeaderLen - LENGTH_AMSDU_SUBFRAMEHEAD +
61 pTxBlk->HdrPadLen + LENGTH_AMSDU_SUBFRAMEHEAD;
62 } else {
63 /*hwHeaderLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4); */
64 hwHeaderLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
65 }
66 NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf,
67 TXINFO_SIZE + TXWI_SIZE + hwHeaderLen);
68
69 pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket;
70 pTxRing->Cell[TxIdx].pNextNdisPacket = NULL;
71
72 /* */
73 /* build Tx Descriptor */
74 /* */
75
76 pTxD = (struct rt_txd *) pTxRing->Cell[TxIdx].AllocVa;
77 NdisZeroMemory(pTxD, TXD_SIZE);
78
79 pTxD->SDPtr0 = BufBasePaLow;
80 pTxD->SDLen0 = TXINFO_SIZE + TXWI_SIZE + hwHeaderLen; /* include padding */
81 pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE);
82 pTxD->SDLen1 = pTxBlk->SrcBufLen;
83 pTxD->LastSec0 = 0;
84 pTxD->LastSec1 = (bIsLast) ? 1 : 0;
85
86 RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);
87
88 RetTxIdx = TxIdx;
89 /* */
90 /* Update Tx index */
91 /* */
92 INC_RING_INDEX(TxIdx, TX_RING_SIZE);
93 pTxRing->TxCpuIdx = TxIdx;
94
95 *FreeNumber -= 1;
96
97 return RetTxIdx;
98}
99
100u16 RtmpPCI_WriteSingleTxResource(struct rt_rtmp_adapter *pAd,
101 struct rt_tx_blk *pTxBlk,
102 IN BOOLEAN bIsLast,
103 u16 * FreeNumber)
104{
105
106 u8 *pDMAHeaderBufVA;
107 u16 TxIdx, RetTxIdx;
108 struct rt_txd * pTxD;
109 u32 BufBasePaLow;
110 struct rt_rtmp_tx_ring *pTxRing;
111 u16 hwHeaderLen;
112
113 /* */
114 /* get Tx Ring Resource */
115 /* */
116 pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
117 TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx;
118 pDMAHeaderBufVA = (u8 *)pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
119 BufBasePaLow =
120 RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
121
122 /* copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer */
123 /*hwHeaderLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4); */
124 hwHeaderLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
125
126 NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf,
127 TXINFO_SIZE + TXWI_SIZE + hwHeaderLen);
128
129 pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket;
130 pTxRing->Cell[TxIdx].pNextNdisPacket = NULL;
131
132 /* */
133 /* build Tx Descriptor */
134 /* */
135 pTxD = (struct rt_txd *) pTxRing->Cell[TxIdx].AllocVa;
136 NdisZeroMemory(pTxD, TXD_SIZE);
137
138 pTxD->SDPtr0 = BufBasePaLow;
139 pTxD->SDLen0 = TXINFO_SIZE + TXWI_SIZE + hwHeaderLen; /* include padding */
140 pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE);
141 pTxD->SDLen1 = pTxBlk->SrcBufLen;
142 pTxD->LastSec0 = 0;
143 pTxD->LastSec1 = (bIsLast) ? 1 : 0;
144
145 RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);
146
147 RetTxIdx = TxIdx;
148 /* */
149 /* Update Tx index */
150 /* */
151 INC_RING_INDEX(TxIdx, TX_RING_SIZE);
152 pTxRing->TxCpuIdx = TxIdx;
153
154 *FreeNumber -= 1;
155
156 return RetTxIdx;
157}
158
159u16 RtmpPCI_WriteMultiTxResource(struct rt_rtmp_adapter *pAd,
160 struct rt_tx_blk *pTxBlk,
161 u8 frameNum, u16 * FreeNumber)
162{
163 BOOLEAN bIsLast;
164 u8 *pDMAHeaderBufVA;
165 u16 TxIdx, RetTxIdx;
166 struct rt_txd * pTxD;
167 u32 BufBasePaLow;
168 struct rt_rtmp_tx_ring *pTxRing;
169 u16 hwHdrLen;
170 u32 firstDMALen;
171
172 bIsLast = ((frameNum == (pTxBlk->TotalFrameNum - 1)) ? 1 : 0);
173
174 /* */
175 /* get Tx Ring Resource */
176 /* */
177 pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
178 TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx;
179 pDMAHeaderBufVA = (u8 *)pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
180 BufBasePaLow =
181 RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
182
183 if (frameNum == 0) {
184 /* copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer */
185 if (pTxBlk->TxFrameType == TX_AMSDU_FRAME)
186 /*hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD, 4)+LENGTH_AMSDU_SUBFRAMEHEAD; */
187 hwHdrLen =
188 pTxBlk->MpduHeaderLen - LENGTH_AMSDU_SUBFRAMEHEAD +
189 pTxBlk->HdrPadLen + LENGTH_AMSDU_SUBFRAMEHEAD;
190 else if (pTxBlk->TxFrameType == TX_RALINK_FRAME)
191 /*hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_ARALINK_HEADER_FIELD, 4)+LENGTH_ARALINK_HEADER_FIELD; */
192 hwHdrLen =
193 pTxBlk->MpduHeaderLen -
194 LENGTH_ARALINK_HEADER_FIELD + pTxBlk->HdrPadLen +
195 LENGTH_ARALINK_HEADER_FIELD;
196 else
197 /*hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4); */
198 hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
199
200 firstDMALen = TXINFO_SIZE + TXWI_SIZE + hwHdrLen;
201 } else {
202 firstDMALen = pTxBlk->MpduHeaderLen;
203 }
204
205 NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf, firstDMALen);
206
207 pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket;
208 pTxRing->Cell[TxIdx].pNextNdisPacket = NULL;
209
210 /* */
211 /* build Tx Descriptor */
212 /* */
213 pTxD = (struct rt_txd *) pTxRing->Cell[TxIdx].AllocVa;
214 NdisZeroMemory(pTxD, TXD_SIZE);
215
216 pTxD->SDPtr0 = BufBasePaLow;
217 pTxD->SDLen0 = firstDMALen; /* include padding */
218 pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE);
219 pTxD->SDLen1 = pTxBlk->SrcBufLen;
220 pTxD->LastSec0 = 0;
221 pTxD->LastSec1 = (bIsLast) ? 1 : 0;
222
223 RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);
224
225 RetTxIdx = TxIdx;
226 /* */
227 /* Update Tx index */
228 /* */
229 INC_RING_INDEX(TxIdx, TX_RING_SIZE);
230 pTxRing->TxCpuIdx = TxIdx;
231
232 *FreeNumber -= 1;
233
234 return RetTxIdx;
235
236}
237
238void RtmpPCI_FinalWriteTxResource(struct rt_rtmp_adapter *pAd,
239 struct rt_tx_blk *pTxBlk,
240 u16 totalMPDUSize, u16 FirstTxIdx)
241{
242
243 struct rt_txwi * pTxWI;
244 struct rt_rtmp_tx_ring *pTxRing;
245
246 /* */
247 /* get Tx Ring Resource */
248 /* */
249 pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
250 pTxWI = (struct rt_txwi *) pTxRing->Cell[FirstTxIdx].DmaBuf.AllocVa;
251 pTxWI->MPDUtotalByteCount = totalMPDUSize;
252
253}
254
255void RtmpPCIDataLastTxIdx(struct rt_rtmp_adapter *pAd,
256 u8 QueIdx, u16 LastTxIdx)
257{
258 struct rt_txd * pTxD;
259 struct rt_rtmp_tx_ring *pTxRing;
260
261 /* */
262 /* get Tx Ring Resource */
263 /* */
264 pTxRing = &pAd->TxRing[QueIdx];
265
266 /* */
267 /* build Tx Descriptor */
268 /* */
269 pTxD = (struct rt_txd *) pTxRing->Cell[LastTxIdx].AllocVa;
270
271 pTxD->LastSec1 = 1;
272
273}
274
275u16 RtmpPCI_WriteFragTxResource(struct rt_rtmp_adapter *pAd,
276 struct rt_tx_blk *pTxBlk,
277 u8 fragNum, u16 * FreeNumber)
278{
279 u8 *pDMAHeaderBufVA;
280 u16 TxIdx, RetTxIdx;
281 struct rt_txd * pTxD;
282 u32 BufBasePaLow;
283 struct rt_rtmp_tx_ring *pTxRing;
284 u16 hwHeaderLen;
285 u32 firstDMALen;
286
287 /* */
288 /* Get Tx Ring Resource */
289 /* */
290 pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
291 TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx;
292 pDMAHeaderBufVA = (u8 *)pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
293 BufBasePaLow =
294 RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
295
296 /* */
297 /* Copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer */
298 /* */
299 /*hwHeaderLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4); */
300 hwHeaderLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
301
302 firstDMALen = TXINFO_SIZE + TXWI_SIZE + hwHeaderLen;
303 NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf, firstDMALen);
304
305 /* */
306 /* Build Tx Descriptor */
307 /* */
308 pTxD = (struct rt_txd *) pTxRing->Cell[TxIdx].AllocVa;
309 NdisZeroMemory(pTxD, TXD_SIZE);
310
311 if (fragNum == pTxBlk->TotalFragNum) {
312 pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket;
313 pTxRing->Cell[TxIdx].pNextNdisPacket = NULL;
314 }
315
316 pTxD->SDPtr0 = BufBasePaLow;
317 pTxD->SDLen0 = firstDMALen; /* include padding */
318 pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE);
319 pTxD->SDLen1 = pTxBlk->SrcBufLen;
320 pTxD->LastSec0 = 0;
321 pTxD->LastSec1 = 1;
322
323 RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);
324
325 RetTxIdx = TxIdx;
326 pTxBlk->Priv += pTxBlk->SrcBufLen;
327
328 /* */
329 /* Update Tx index */
330 /* */
331 INC_RING_INDEX(TxIdx, TX_RING_SIZE);
332 pTxRing->TxCpuIdx = TxIdx;
333
334 *FreeNumber -= 1;
335
336 return RetTxIdx;
337
338}
339
340/*
341 Must be run in Interrupt context
342 This function handle PCI specific TxDesc and cpu index update and kick the packet out.
343 */
344int RtmpPCIMgmtKickOut(struct rt_rtmp_adapter *pAd,
345 u8 QueIdx,
346 void *pPacket,
347 u8 *pSrcBufVA, u32 SrcBufLen)
348{
349 struct rt_txd * pTxD;
350 unsigned long SwIdx = pAd->MgmtRing.TxCpuIdx;
351
352 pTxD = (struct rt_txd *) pAd->MgmtRing.Cell[SwIdx].AllocVa;
353
354 pAd->MgmtRing.Cell[SwIdx].pNdisPacket = pPacket;
355 pAd->MgmtRing.Cell[SwIdx].pNextNdisPacket = NULL;
356
357 RTMPWriteTxDescriptor(pAd, pTxD, TRUE, FIFO_MGMT);
358 pTxD->LastSec0 = 1;
359 pTxD->LastSec1 = 1;
360 pTxD->DMADONE = 0;
361 pTxD->SDLen1 = 0;
362 pTxD->SDPtr0 =
363 PCI_MAP_SINGLE(pAd, pSrcBufVA, SrcBufLen, 0, PCI_DMA_TODEVICE);
364 pTxD->SDLen0 = SrcBufLen;
365
366/*================================================================== */
367/* DBGPRINT_RAW(RT_DEBUG_TRACE, ("MLMEHardTransmit\n"));
368 for (i = 0; i < (TXWI_SIZE+24); i++)
369 {
370
371 DBGPRINT_RAW(RT_DEBUG_TRACE, ("%x:", *(pSrcBufVA+i)));
372 if ( i%4 == 3)
373 DBGPRINT_RAW(RT_DEBUG_TRACE, (" :: "));
374 if ( i%16 == 15)
375 DBGPRINT_RAW(RT_DEBUG_TRACE, ("\n "));
376 }
377 DBGPRINT_RAW(RT_DEBUG_TRACE, ("\n "));*/
378/*======================================================================= */
379
380 pAd->RalinkCounters.KickTxCount++;
381 pAd->RalinkCounters.OneSecTxDoneCount++;
382
383 /* Increase TX_CTX_IDX, but write to register later. */
384 INC_RING_INDEX(pAd->MgmtRing.TxCpuIdx, MGMT_RING_SIZE);
385
386 RTMP_IO_WRITE32(pAd, TX_MGMTCTX_IDX, pAd->MgmtRing.TxCpuIdx);
387
388 return 0;
389}
390
391/*
392 ========================================================================
393
394 Routine Description:
395 Check Rx descriptor, return NDIS_STATUS_FAILURE if any error dound
396
397 Arguments:
398 pRxD Pointer to the Rx descriptor
399
400 Return Value:
401 NDIS_STATUS_SUCCESS No err
402 NDIS_STATUS_FAILURE Error
403
404 Note:
405
406 ========================================================================
407*/
408int RTMPCheckRxError(struct rt_rtmp_adapter *pAd,
409 struct rt_header_802_11 * pHeader,
410 struct rt_rxwi * pRxWI, IN PRT28XX_RXD_STRUC pRxD)
411{
412 struct rt_cipher_key *pWpaKey;
413 int dBm;
414
415 /* Phy errors & CRC errors */
416 if ( /*(pRxD->PhyErr) || */ (pRxD->Crc)) {
417 /* Check RSSI for Noise Hist statistic collection. */
418 dBm = (int)(pRxWI->RSSI0) - pAd->BbpRssiToDbmDelta;
419 if (dBm <= -87)
420 pAd->StaCfg.RPIDensity[0] += 1;
421 else if (dBm <= -82)
422 pAd->StaCfg.RPIDensity[1] += 1;
423 else if (dBm <= -77)
424 pAd->StaCfg.RPIDensity[2] += 1;
425 else if (dBm <= -72)
426 pAd->StaCfg.RPIDensity[3] += 1;
427 else if (dBm <= -67)
428 pAd->StaCfg.RPIDensity[4] += 1;
429 else if (dBm <= -62)
430 pAd->StaCfg.RPIDensity[5] += 1;
431 else if (dBm <= -57)
432 pAd->StaCfg.RPIDensity[6] += 1;
433 else if (dBm > -57)
434 pAd->StaCfg.RPIDensity[7] += 1;
435
436 return (NDIS_STATUS_FAILURE);
437 }
438 /* Add Rx size to channel load counter, we should ignore error counts */
439 pAd->StaCfg.CLBusyBytes += (pRxD->SDL0 + 14);
440
441 /* Drop ToDs promiscuous frame, it is opened due to CCX 2 channel load statistics */
442 if (pHeader != NULL) {
443 if (pHeader->FC.ToDs) {
444 return (NDIS_STATUS_FAILURE);
445 }
446 }
447 /* Drop not U2M frames, can't's drop here because we will drop beacon in this case */
448 /* I am kind of doubting the U2M bit operation */
449 /* if (pRxD->U2M == 0) */
450 /* return(NDIS_STATUS_FAILURE); */
451
452 /* drop decyption fail frame */
453 if (pRxD->CipherErr) {
454 if (pRxD->CipherErr == 2) {
455 DBGPRINT_RAW(RT_DEBUG_TRACE,
456 ("pRxD ERROR: ICV ok but MICErr "));
457 } else if (pRxD->CipherErr == 1) {
458 DBGPRINT_RAW(RT_DEBUG_TRACE, ("pRxD ERROR: ICV Err "));
459 } else if (pRxD->CipherErr == 3)
460 DBGPRINT_RAW(RT_DEBUG_TRACE,
461 ("pRxD ERROR: Key not valid "));
462
463 if (((pRxD->CipherErr & 1) == 1)
464 && pAd->CommonCfg.bWirelessEvent && INFRA_ON(pAd))
465 RTMPSendWirelessEvent(pAd, IW_ICV_ERROR_EVENT_FLAG,
466 pAd->MacTab.Content[BSSID_WCID].
467 Addr, BSS0, 0);
468
469 DBGPRINT_RAW(RT_DEBUG_TRACE,
470 (" %d (len=%d, Mcast=%d, MyBss=%d, Wcid=%d, KeyId=%d)\n",
471 pRxD->CipherErr, pRxD->SDL0,
472 pRxD->Mcast | pRxD->Bcast, pRxD->MyBss,
473 pRxWI->WirelessCliID,
474/* CipherName[pRxD->CipherAlg], */
475 pRxWI->KeyIndex));
476
477 /* */
478 /* MIC Error */
479 /* */
480 if (pRxD->CipherErr == 2) {
481 pWpaKey = &pAd->SharedKey[BSS0][pRxWI->KeyIndex];
482 if (pAd->StaCfg.WpaSupplicantUP)
483 WpaSendMicFailureToWpaSupplicant(pAd,
484 (pWpaKey->
485 Type ==
486 PAIRWISEKEY) ?
487 TRUE : FALSE);
488 else
489 RTMPReportMicError(pAd, pWpaKey);
490
491 if (((pRxD->CipherErr & 2) == 2)
492 && pAd->CommonCfg.bWirelessEvent && INFRA_ON(pAd))
493 RTMPSendWirelessEvent(pAd,
494 IW_MIC_ERROR_EVENT_FLAG,
495 pAd->MacTab.
496 Content[BSSID_WCID].Addr,
497 BSS0, 0);
498
499 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Rx MIC Value error\n"));
500 }
501
502 if (pHeader == NULL)
503 return (NDIS_STATUS_SUCCESS);
504 /*if ((pRxD->CipherAlg == CIPHER_AES) &&
505 (pHeader->Sequence == pAd->FragFrame.Sequence))
506 {
507 //
508 // Acceptable since the First FragFrame no CipherErr problem.
509 //
510 return(NDIS_STATUS_SUCCESS);
511 } */
512
513 return (NDIS_STATUS_FAILURE);
514 }
515
516 return (NDIS_STATUS_SUCCESS);
517}
518
519BOOLEAN RTMPFreeTXDUponTxDmaDone(struct rt_rtmp_adapter *pAd, u8 QueIdx)
520{
521 struct rt_rtmp_tx_ring *pTxRing;
522 struct rt_txd * pTxD;
523 void *pPacket;
524 u8 FREE = 0;
525 struct rt_txd TxD, *pOriTxD;
526 /*unsigned long IrqFlags; */
527 BOOLEAN bReschedule = FALSE;
528
529 ASSERT(QueIdx < NUM_OF_TX_RING);
530 pTxRing = &pAd->TxRing[QueIdx];
531
532 RTMP_IO_READ32(pAd, TX_DTX_IDX0 + QueIdx * RINGREG_DIFF,
533 &pTxRing->TxDmaIdx);
534 while (pTxRing->TxSwFreeIdx != pTxRing->TxDmaIdx) {
535/* RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags); */
536
537 /* static rate also need NICUpdateFifoStaCounters() function. */
538 /*if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)) */
539 NICUpdateFifoStaCounters(pAd);
540
541 /* Note : If (pAd->ate.bQATxStart == TRUE), we will never reach here. */
542 FREE++;
543 pTxD =
544 (struct rt_txd *) (pTxRing->Cell[pTxRing->TxSwFreeIdx].AllocVa);
545 pOriTxD = pTxD;
546 NdisMoveMemory(&TxD, pTxD, sizeof(struct rt_txd));
547 pTxD = &TxD;
548
549 pTxD->DMADONE = 0;
550
551 {
552 pPacket =
553 pTxRing->Cell[pTxRing->TxSwFreeIdx].pNdisPacket;
554 if (pPacket) {
555 PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1,
556 pTxD->SDLen1,
557 PCI_DMA_TODEVICE);
558 RELEASE_NDIS_PACKET(pAd, pPacket,
559 NDIS_STATUS_SUCCESS);
560 }
561 /*Always assign pNdisPacket as NULL after clear */
562 pTxRing->Cell[pTxRing->TxSwFreeIdx].pNdisPacket = NULL;
563
564 pPacket =
565 pTxRing->Cell[pTxRing->TxSwFreeIdx].pNextNdisPacket;
566
567 ASSERT(pPacket == NULL);
568 if (pPacket) {
569 PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1,
570 pTxD->SDLen1,
571 PCI_DMA_TODEVICE);
572 RELEASE_NDIS_PACKET(pAd, pPacket,
573 NDIS_STATUS_SUCCESS);
574 }
575 /*Always assign pNextNdisPacket as NULL after clear */
576 pTxRing->Cell[pTxRing->TxSwFreeIdx].pNextNdisPacket =
577 NULL;
578 }
579
580 pAd->RalinkCounters.TransmittedByteCount +=
581 (pTxD->SDLen1 + pTxD->SDLen0);
582 pAd->RalinkCounters.OneSecDmaDoneCount[QueIdx]++;
583 INC_RING_INDEX(pTxRing->TxSwFreeIdx, TX_RING_SIZE);
584 /* get tx_tdx_idx again */
585 RTMP_IO_READ32(pAd, TX_DTX_IDX0 + QueIdx * RINGREG_DIFF,
586 &pTxRing->TxDmaIdx);
587 NdisMoveMemory(pOriTxD, pTxD, sizeof(struct rt_txd));
588
589/* RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags); */
590 }
591
592 return bReschedule;
593
594}
595
596/*
597 ========================================================================
598
599 Routine Description:
600 Process TX Rings DMA Done interrupt, running in DPC level
601
602 Arguments:
603 Adapter Pointer to our adapter
604
605 Return Value:
606 None
607
608 IRQL = DISPATCH_LEVEL
609
610 ========================================================================
611*/
612BOOLEAN RTMPHandleTxRingDmaDoneInterrupt(struct rt_rtmp_adapter *pAd,
613 INT_SOURCE_CSR_STRUC TxRingBitmap)
614{
615/* u8 Count = 0; */
616 unsigned long IrqFlags;
617 BOOLEAN bReschedule = FALSE;
618
619 /* Make sure Tx ring resource won't be used by other threads */
620 /*NdisAcquireSpinLock(&pAd->TxRingLock); */
621
622 RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
623
624 if (TxRingBitmap.field.Ac0DmaDone)
625 bReschedule = RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_BE);
626
627 if (TxRingBitmap.field.Ac3DmaDone)
628 bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_VO);
629
630 if (TxRingBitmap.field.Ac2DmaDone)
631 bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_VI);
632
633 if (TxRingBitmap.field.Ac1DmaDone)
634 bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_BK);
635
636 /* Make sure to release Tx ring resource */
637 /*NdisReleaseSpinLock(&pAd->TxRingLock); */
638 RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
639
640 /* Dequeue outgoing frames from TxSwQueue[] and process it */
641 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
642
643 return bReschedule;
644}
645
646/*
647 ========================================================================
648
649 Routine Description:
650 Process MGMT ring DMA done interrupt, running in DPC level
651
652 Arguments:
653 pAd Pointer to our adapter
654
655 Return Value:
656 None
657
658 IRQL = DISPATCH_LEVEL
659
660 Note:
661
662 ========================================================================
663*/
664void RTMPHandleMgmtRingDmaDoneInterrupt(struct rt_rtmp_adapter *pAd)
665{
666 struct rt_txd * pTxD;
667 void *pPacket;
668/* int i; */
669 u8 FREE = 0;
670 struct rt_rtmp_mgmt_ring *pMgmtRing = &pAd->MgmtRing;
671
672 NdisAcquireSpinLock(&pAd->MgmtRingLock);
673
674 RTMP_IO_READ32(pAd, TX_MGMTDTX_IDX, &pMgmtRing->TxDmaIdx);
675 while (pMgmtRing->TxSwFreeIdx != pMgmtRing->TxDmaIdx) {
676 FREE++;
677 pTxD =
678 (struct rt_txd *) (pMgmtRing->Cell[pAd->MgmtRing.TxSwFreeIdx].
679 AllocVa);
680 pTxD->DMADONE = 0;
681 pPacket = pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNdisPacket;
682
683 if (pPacket) {
684 PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0,
685 PCI_DMA_TODEVICE);
686 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
687 }
688 pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNdisPacket = NULL;
689
690 pPacket =
691 pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNextNdisPacket;
692 if (pPacket) {
693 PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1,
694 PCI_DMA_TODEVICE);
695 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
696 }
697 pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNextNdisPacket = NULL;
698 INC_RING_INDEX(pMgmtRing->TxSwFreeIdx, MGMT_RING_SIZE);
699
700 }
701 NdisReleaseSpinLock(&pAd->MgmtRingLock);
702
703}
704
705/*
706 ========================================================================
707
708 Routine Description:
709 Arguments:
710 Adapter Pointer to our adapter. Dequeue all power safe delayed braodcast frames after beacon.
711
712 IRQL = DISPATCH_LEVEL
713
714 ========================================================================
715*/
716void RTMPHandleTBTTInterrupt(struct rt_rtmp_adapter *pAd)
717{
718 {
719 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) {
720 }
721 }
722}
723
724/*
725 ========================================================================
726
727 Routine Description:
728 Arguments:
729 pAd Pointer to our adapter. Rewrite beacon content before next send-out.
730
731 IRQL = DISPATCH_LEVEL
732
733 ========================================================================
734*/
735void RTMPHandlePreTBTTInterrupt(struct rt_rtmp_adapter *pAd)
736{
737 {
738 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) {
739 DBGPRINT(RT_DEBUG_TRACE,
740 ("RTMPHandlePreTBTTInterrupt...\n"));
741 }
742 }
743
744}
745
746void RTMPHandleRxCoherentInterrupt(struct rt_rtmp_adapter *pAd)
747{
748 WPDMA_GLO_CFG_STRUC GloCfg;
749
750 if (pAd == NULL) {
751 DBGPRINT(RT_DEBUG_TRACE, ("====> pAd is NULL, return.\n"));
752 return;
753 }
754
755 DBGPRINT(RT_DEBUG_TRACE, ("==> RTMPHandleRxCoherentInterrupt \n"));
756
757 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
758
759 GloCfg.field.EnTXWriteBackDDONE = 0;
760 GloCfg.field.EnableRxDMA = 0;
761 GloCfg.field.EnableTxDMA = 0;
762 RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
763
764 RTMPRingCleanUp(pAd, QID_AC_BE);
765 RTMPRingCleanUp(pAd, QID_AC_BK);
766 RTMPRingCleanUp(pAd, QID_AC_VI);
767 RTMPRingCleanUp(pAd, QID_AC_VO);
768 RTMPRingCleanUp(pAd, QID_MGMT);
769 RTMPRingCleanUp(pAd, QID_RX);
770
771 RTMPEnableRxTx(pAd);
772
773 DBGPRINT(RT_DEBUG_TRACE, ("<== RTMPHandleRxCoherentInterrupt \n"));
774}
775
776void *GetPacketFromRxRing(struct rt_rtmp_adapter *pAd,
777 OUT PRT28XX_RXD_STRUC pSaveRxD,
778 OUT BOOLEAN * pbReschedule,
779 IN u32 * pRxPending)
780{
781 struct rt_rxd * pRxD;
782 void *pRxPacket = NULL;
783 void *pNewPacket;
784 void *AllocVa;
785 dma_addr_t AllocPa;
786 BOOLEAN bReschedule = FALSE;
787 struct rt_rtmp_dmacb *pRxCell;
788
789 RTMP_SEM_LOCK(&pAd->RxRingLock);
790
791 if (*pRxPending == 0) {
792 /* Get how may packets had been received */
793 RTMP_IO_READ32(pAd, RX_DRX_IDX, &pAd->RxRing.RxDmaIdx);
794
795 if (pAd->RxRing.RxSwReadIdx == pAd->RxRing.RxDmaIdx) {
796 /* no more rx packets */
797 bReschedule = FALSE;
798 goto done;
799 }
800 /* get rx pending count */
801 if (pAd->RxRing.RxDmaIdx > pAd->RxRing.RxSwReadIdx)
802 *pRxPending =
803 pAd->RxRing.RxDmaIdx - pAd->RxRing.RxSwReadIdx;
804 else
805 *pRxPending =
806 pAd->RxRing.RxDmaIdx + RX_RING_SIZE -
807 pAd->RxRing.RxSwReadIdx;
808
809 }
810
811 pRxCell = &pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx];
812
813 /* Point to Rx indexed rx ring descriptor */
814 pRxD = (struct rt_rxd *) pRxCell->AllocVa;
815
816 if (pRxD->DDONE == 0) {
817 *pRxPending = 0;
818 /* DMAIndx had done but DDONE bit not ready */
819 bReschedule = TRUE;
820 goto done;
821 }
822
823 /* return rx descriptor */
824 NdisMoveMemory(pSaveRxD, pRxD, RXD_SIZE);
825
826 pNewPacket =
827 RTMP_AllocateRxPacketBuffer(pAd, RX_BUFFER_AGGRESIZE, FALSE,
828 &AllocVa, &AllocPa);
829
830 if (pNewPacket) {
831 /* unmap the rx buffer */
832 PCI_UNMAP_SINGLE(pAd, pRxCell->DmaBuf.AllocPa,
833 pRxCell->DmaBuf.AllocSize, PCI_DMA_FROMDEVICE);
834 pRxPacket = pRxCell->pNdisPacket;
835
836 pRxCell->DmaBuf.AllocSize = RX_BUFFER_AGGRESIZE;
837 pRxCell->pNdisPacket = (void *)pNewPacket;
838 pRxCell->DmaBuf.AllocVa = AllocVa;
839 pRxCell->DmaBuf.AllocPa = AllocPa;
840 /* update SDP0 to new buffer of rx packet */
841 pRxD->SDP0 = AllocPa;
842 } else {
843 /*DBGPRINT(RT_DEBUG_TRACE,("No Rx Buffer\n")); */
844 pRxPacket = NULL;
845 bReschedule = TRUE;
846 }
847
848 pRxD->DDONE = 0;
849
850 /* had handled one rx packet */
851 *pRxPending = *pRxPending - 1;
852
853 /* update rx descriptor and kick rx */
854 INC_RING_INDEX(pAd->RxRing.RxSwReadIdx, RX_RING_SIZE);
855
856 pAd->RxRing.RxCpuIdx =
857 (pAd->RxRing.RxSwReadIdx ==
858 0) ? (RX_RING_SIZE - 1) : (pAd->RxRing.RxSwReadIdx - 1);
859 RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx);
860
861done:
862 RTMP_SEM_UNLOCK(&pAd->RxRingLock);
863 *pbReschedule = bReschedule;
864 return pRxPacket;
865}
866
867int MlmeHardTransmitTxRing(struct rt_rtmp_adapter *pAd,
868 u8 QueIdx, void *pPacket)
869{
870 struct rt_packet_info PacketInfo;
871 u8 *pSrcBufVA;
872 u32 SrcBufLen;
873 struct rt_txd * pTxD;
874 struct rt_header_802_11 * pHeader_802_11;
875 BOOLEAN bAckRequired, bInsertTimestamp;
876 unsigned long SrcBufPA;
877 /*u8 TxBufIdx; */
878 u8 MlmeRate;
879 unsigned long SwIdx = pAd->TxRing[QueIdx].TxCpuIdx;
880 struct rt_txwi * pFirstTxWI;
881 /*unsigned long i; */
882 /*HTTRANSMIT_SETTING MlmeTransmit; //Rate for this MGMT frame. */
883 unsigned long FreeNum;
884 struct rt_mac_table_entry *pMacEntry = NULL;
885
886 RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
887
888 if (pSrcBufVA == NULL) {
889 /* The buffer shouldn't be NULL */
890 return NDIS_STATUS_FAILURE;
891 }
892 /* Make sure MGMT ring resource won't be used by other threads */
893 /*NdisAcquireSpinLock(&pAd->TxRingLock); */
894
895 FreeNum = GET_TXRING_FREENO(pAd, QueIdx);
896
897 if (FreeNum == 0) {
898 /*NdisReleaseSpinLock(&pAd->TxRingLock); */
899 return NDIS_STATUS_FAILURE;
900 }
901
902 SwIdx = pAd->TxRing[QueIdx].TxCpuIdx;
903
904 pTxD = (struct rt_txd *) pAd->TxRing[QueIdx].Cell[SwIdx].AllocVa;
905
906 if (pAd->TxRing[QueIdx].Cell[SwIdx].pNdisPacket) {
907 DBGPRINT(RT_DEBUG_OFF, ("MlmeHardTransmit Error\n"));
908 /*NdisReleaseSpinLock(&pAd->TxRingLock); */
909 return NDIS_STATUS_FAILURE;
910 }
911
912 {
913 /* outgoing frame always wakeup PHY to prevent frame lost */
914 /* if (pAd->StaCfg.Psm == PWR_SAVE) */
915 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
916 AsicForceWakeup(pAd, TRUE);
917 }
918 pFirstTxWI = (struct rt_txwi *) pSrcBufVA;
919
920 pHeader_802_11 = (struct rt_header_802_11 *) (pSrcBufVA + TXWI_SIZE);
921 if (pHeader_802_11->Addr1[0] & 0x01) {
922 MlmeRate = pAd->CommonCfg.BasicMlmeRate;
923 } else {
924 MlmeRate = pAd->CommonCfg.MlmeRate;
925 }
926
927 if ((pHeader_802_11->FC.Type == BTYPE_DATA) &&
928 (pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL)) {
929 pMacEntry = MacTableLookup(pAd, pHeader_802_11->Addr1);
930 }
931 /* Verify Mlme rate for a / g bands. */
932 if ((pAd->LatchRfRegs.Channel > 14) && (MlmeRate < RATE_6)) /* 11A band */
933 MlmeRate = RATE_6;
934
935 /* */
936 /* Should not be hard code to set PwrMgmt to 0 (PWR_ACTIVE) */
937 /* Snice it's been set to 0 while on MgtMacHeaderInit */
938 /* By the way this will cause frame to be send on PWR_SAVE failed. */
939 /* */
940 /* */
941 /* In WMM-UAPSD, mlme frame should be set psm as power saving but probe request frame */
942 /* Data-Null packets also pass through MMRequest in RT2860, however, we hope control the psm bit to pass APSD */
943 if (pHeader_802_11->FC.Type != BTYPE_DATA) {
944 if ((pHeader_802_11->FC.SubType == SUBTYPE_PROBE_REQ)
945 || !(pAd->CommonCfg.bAPSDCapable
946 && pAd->CommonCfg.APEdcaParm.bAPSDCapable)) {
947 pHeader_802_11->FC.PwrMgmt = PWR_ACTIVE;
948 } else {
949 pHeader_802_11->FC.PwrMgmt =
950 pAd->CommonCfg.bAPSDForcePowerSave;
951 }
952 }
953
954 bInsertTimestamp = FALSE;
955 if (pHeader_802_11->FC.Type == BTYPE_CNTL) /* must be PS-POLL */
956 {
957 bAckRequired = FALSE;
958 } else /* BTYPE_MGMT or BTYPE_DATA(must be NULL frame) */
959 {
960 if (pHeader_802_11->Addr1[0] & 0x01) /* MULTICAST, BROADCAST */
961 {
962 bAckRequired = FALSE;
963 pHeader_802_11->Duration = 0;
964 } else {
965 bAckRequired = TRUE;
966 pHeader_802_11->Duration =
967 RTMPCalcDuration(pAd, MlmeRate, 14);
968 if (pHeader_802_11->FC.SubType == SUBTYPE_PROBE_RSP) {
969 bInsertTimestamp = TRUE;
970 }
971 }
972 }
973 pHeader_802_11->Sequence = pAd->Sequence++;
974 if (pAd->Sequence > 0xfff)
975 pAd->Sequence = 0;
976 /* Before radar detection done, mgmt frame can not be sent but probe req */
977 /* Because we need to use probe req to trigger driver to send probe req in passive scan */
978 if ((pHeader_802_11->FC.SubType != SUBTYPE_PROBE_REQ)
979 && (pAd->CommonCfg.bIEEE80211H == 1)
980 && (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)) {
981 DBGPRINT(RT_DEBUG_ERROR,
982 ("MlmeHardTransmit --> radar detect not in normal mode!\n"));
983 /*NdisReleaseSpinLock(&pAd->TxRingLock); */
984 return (NDIS_STATUS_FAILURE);
985 }
986 /* */
987 /* fill scatter-and-gather buffer list into TXD. Internally created NDIS PACKET */
988 /* should always has only one ohysical buffer, and the whole frame size equals */
989 /* to the first scatter buffer size */
990 /* */
991
992 /* Initialize TX Descriptor */
993 /* For inter-frame gap, the number is for this frame and next frame */
994 /* For MLME rate, we will fix as 2Mb to match other vendor's implement */
995/* pAd->CommonCfg.MlmeTransmit.field.MODE = 1; */
996
997/* management frame doesn't need encryption. so use RESERVED_WCID no matter u are sending to specific wcid or not. */
998 /* Only beacon use Nseq=TRUE. So here we use Nseq=FALSE. */
999 if (pMacEntry == NULL) {
1000 RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, bInsertTimestamp,
1001 FALSE, bAckRequired, FALSE, 0, RESERVED_WCID,
1002 (SrcBufLen - TXWI_SIZE), PID_MGMT, 0,
1003 (u8)pAd->CommonCfg.MlmeTransmit.field.MCS,
1004 IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
1005 } else {
1006 RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE,
1007 bInsertTimestamp, FALSE, bAckRequired, FALSE,
1008 0, pMacEntry->Aid, (SrcBufLen - TXWI_SIZE),
1009 pMacEntry->MaxHTPhyMode.field.MCS, 0,
1010 (u8)pMacEntry->MaxHTPhyMode.field.MCS,
1011 IFS_BACKOFF, FALSE, &pMacEntry->MaxHTPhyMode);
1012 }
1013
1014 pAd->TxRing[QueIdx].Cell[SwIdx].pNdisPacket = pPacket;
1015 pAd->TxRing[QueIdx].Cell[SwIdx].pNextNdisPacket = NULL;
1016/* pFirstTxWI->MPDUtotalByteCount = SrcBufLen - TXWI_SIZE; */
1017 SrcBufPA =
1018 PCI_MAP_SINGLE(pAd, pSrcBufVA, SrcBufLen, 0, PCI_DMA_TODEVICE);
1019
1020 RTMPWriteTxDescriptor(pAd, pTxD, TRUE, FIFO_EDCA);
1021 pTxD->LastSec0 = 1;
1022 pTxD->LastSec1 = 1;
1023 pTxD->SDLen0 = SrcBufLen;
1024 pTxD->SDLen1 = 0;
1025 pTxD->SDPtr0 = SrcBufPA;
1026 pTxD->DMADONE = 0;
1027
1028 pAd->RalinkCounters.KickTxCount++;
1029 pAd->RalinkCounters.OneSecTxDoneCount++;
1030
1031 /* Increase TX_CTX_IDX, but write to register later. */
1032 INC_RING_INDEX(pAd->TxRing[QueIdx].TxCpuIdx, TX_RING_SIZE);
1033
1034 RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + QueIdx * 0x10,
1035 pAd->TxRing[QueIdx].TxCpuIdx);
1036
1037 /* Make sure to release MGMT ring resource */
1038/* NdisReleaseSpinLock(&pAd->TxRingLock); */
1039
1040 return NDIS_STATUS_SUCCESS;
1041}
1042
1043int MlmeDataHardTransmit(struct rt_rtmp_adapter *pAd,
1044 u8 QueIdx, void *pPacket)
1045{
1046 if ((pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)
1047 ) {
1048 return NDIS_STATUS_FAILURE;
1049 }
1050
1051 return MlmeHardTransmitTxRing(pAd, QueIdx, pPacket);
1052}
1053
1054/*
1055 ========================================================================
1056
1057 Routine Description:
1058 Calculates the duration which is required to transmit out frames
1059 with given size and specified rate.
1060
1061 Arguments:
1062 pTxD Pointer to transmit descriptor
1063 Ack Setting for Ack requirement bit
1064 Fragment Setting for Fragment bit
1065 RetryMode Setting for retry mode
1066 Ifs Setting for IFS gap
1067 Rate Setting for transmit rate
1068 Service Setting for service
1069 Length Frame length
1070 TxPreamble Short or Long preamble when using CCK rates
1071 QueIdx - 0-3, according to 802.11e/d4.4 June/2003
1072
1073 Return Value:
1074 None
1075
1076 IRQL = PASSIVE_LEVEL
1077 IRQL = DISPATCH_LEVEL
1078
1079 ========================================================================
1080*/
1081void RTMPWriteTxDescriptor(struct rt_rtmp_adapter *pAd,
1082 struct rt_txd * pTxD,
1083 IN BOOLEAN bWIV, u8 QueueSEL)
1084{
1085 /* */
1086 /* Always use Long preamble before verifiation short preamble functionality works well. */
1087 /* Todo: remove the following line if short preamble functionality works */
1088 /* */
1089 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
1090
1091 pTxD->WIV = (bWIV) ? 1 : 0;
1092 pTxD->QSEL = (QueueSEL);
1093 /*RT2860c?? fixed using EDCA queue for test... We doubt Queue1 has problem. 2006-09-26 Jan */
1094 /*pTxD->QSEL= FIFO_EDCA; */
1095 pTxD->DMADONE = 0;
1096}
diff --git a/drivers/staging/rt2860/common/cmm_data_usb.c b/drivers/staging/rt2860/common/cmm_data_usb.c
deleted file mode 100644
index 5637857ae9e..00000000000
--- a/drivers/staging/rt2860/common/cmm_data_usb.c
+++ /dev/null
@@ -1,951 +0,0 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26*/
27
28/*
29 All functions in this file must be USB-depended, or you should out your function
30 in other files.
31
32*/
33
34#ifdef RTMP_MAC_USB
35
36#include "../rt_config.h"
37
38/*
39 We can do copy the frame into pTxContext when match following conditions.
40 =>
41 =>
42 =>
43*/
44static inline int RtmpUSBCanDoWrite(struct rt_rtmp_adapter *pAd,
45 u8 QueIdx,
46 struct rt_ht_tx_context *pHTTXContext)
47{
48 int canWrite = NDIS_STATUS_RESOURCES;
49
50 if (((pHTTXContext->CurWritePosition) <
51 pHTTXContext->NextBulkOutPosition)
52 && (pHTTXContext->CurWritePosition + LOCAL_TXBUF_SIZE) >
53 pHTTXContext->NextBulkOutPosition) {
54 DBGPRINT(RT_DEBUG_ERROR, ("RtmpUSBCanDoWrite c1!\n"));
55 RTUSB_SET_BULK_FLAG(pAd,
56 (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx));
57 } else if ((pHTTXContext->CurWritePosition == 8)
58 && (pHTTXContext->NextBulkOutPosition < LOCAL_TXBUF_SIZE)) {
59 DBGPRINT(RT_DEBUG_ERROR, ("RtmpUSBCanDoWrite c2!\n"));
60 RTUSB_SET_BULK_FLAG(pAd,
61 (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx));
62 } else if (pHTTXContext->bCurWriting == TRUE) {
63 DBGPRINT(RT_DEBUG_ERROR, ("RtmpUSBCanDoWrite c3!\n"));
64 } else {
65 canWrite = NDIS_STATUS_SUCCESS;
66 }
67
68 return canWrite;
69}
70
71u16 RtmpUSB_WriteSubTxResource(struct rt_rtmp_adapter *pAd,
72 struct rt_tx_blk *pTxBlk,
73 IN BOOLEAN bIsLast, u16 * FreeNumber)
74{
75
76 /* Dummy function. Should be removed in the future. */
77 return 0;
78
79}
80
81u16 RtmpUSB_WriteFragTxResource(struct rt_rtmp_adapter *pAd,
82 struct rt_tx_blk *pTxBlk,
83 u8 fragNum, u16 * FreeNumber)
84{
85 struct rt_ht_tx_context *pHTTXContext;
86 u16 hwHdrLen; /* The hwHdrLen consist of 802.11 header length plus the header padding length. */
87 u32 fillOffset;
88 struct rt_txinfo *pTxInfo;
89 struct rt_txwi *pTxWI;
90 u8 *pWirelessPacket = NULL;
91 u8 QueIdx;
92 int Status;
93 unsigned long IrqFlags;
94 u32 USBDMApktLen = 0, DMAHdrLen, padding;
95 BOOLEAN TxQLastRound = FALSE;
96
97 /* */
98 /* get Tx Ring Resource & Dma Buffer address */
99 /* */
100 QueIdx = pTxBlk->QueIdx;
101 pHTTXContext = &pAd->TxContext[QueIdx];
102
103 RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
104
105 pHTTXContext = &pAd->TxContext[QueIdx];
106 fillOffset = pHTTXContext->CurWritePosition;
107
108 if (fragNum == 0) {
109 /* Check if we have enough space for this bulk-out batch. */
110 Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext);
111 if (Status == NDIS_STATUS_SUCCESS) {
112 pHTTXContext->bCurWriting = TRUE;
113
114 /* Reserve space for 8 bytes padding. */
115 if ((pHTTXContext->ENextBulkOutPosition ==
116 pHTTXContext->CurWritePosition)) {
117 pHTTXContext->ENextBulkOutPosition += 8;
118 pHTTXContext->CurWritePosition += 8;
119 fillOffset += 8;
120 }
121 pTxBlk->Priv = 0;
122 pHTTXContext->CurWriteRealPos =
123 pHTTXContext->CurWritePosition;
124 } else {
125 RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx],
126 IrqFlags);
127
128 RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket,
129 NDIS_STATUS_FAILURE);
130 return (Status);
131 }
132 } else {
133 /* For sub-sequent frames of this bulk-out batch. Just copy it to our bulk-out buffer. */
134 Status =
135 ((pHTTXContext->bCurWriting ==
136 TRUE) ? NDIS_STATUS_SUCCESS : NDIS_STATUS_FAILURE);
137 if (Status == NDIS_STATUS_SUCCESS) {
138 fillOffset += pTxBlk->Priv;
139 } else {
140 RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx],
141 IrqFlags);
142
143 RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket,
144 NDIS_STATUS_FAILURE);
145 return (Status);
146 }
147 }
148
149 NdisZeroMemory((u8 *)(&pTxBlk->HeaderBuf[0]), TXINFO_SIZE);
150 pTxInfo = (struct rt_txinfo *)(&pTxBlk->HeaderBuf[0]);
151 pTxWI = (struct rt_txwi *) (&pTxBlk->HeaderBuf[TXINFO_SIZE]);
152
153 pWirelessPacket =
154 &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset];
155
156 /* copy TXWI + WLAN Header + LLC into DMA Header Buffer */
157 /*hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4); */
158 hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
159
160 /* Build our URB for USBD */
161 DMAHdrLen = TXWI_SIZE + hwHdrLen;
162 USBDMApktLen = DMAHdrLen + pTxBlk->SrcBufLen;
163 padding = (4 - (USBDMApktLen % 4)) & 0x03; /* round up to 4 byte alignment */
164 USBDMApktLen += padding;
165
166 pTxBlk->Priv += (TXINFO_SIZE + USBDMApktLen);
167
168 /* For TxInfo, the length of USBDMApktLen = TXWI_SIZE + 802.11 header + payload */
169 RTMPWriteTxInfo(pAd, pTxInfo, (u16)(USBDMApktLen), FALSE, FIFO_EDCA,
170 FALSE /*NextValid */ , FALSE);
171
172 if (fragNum == pTxBlk->TotalFragNum) {
173 pTxInfo->USBDMATxburst = 0;
174 if ((pHTTXContext->CurWritePosition + pTxBlk->Priv + 3906) >
175 MAX_TXBULK_LIMIT) {
176 pTxInfo->SwUseLastRound = 1;
177 TxQLastRound = TRUE;
178 }
179 } else {
180 pTxInfo->USBDMATxburst = 1;
181 }
182
183 NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf,
184 TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
185 pWirelessPacket += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
186 pHTTXContext->CurWriteRealPos += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
187
188 RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
189
190 NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen);
191
192 /* Zero the last padding. */
193 pWirelessPacket += pTxBlk->SrcBufLen;
194 NdisZeroMemory(pWirelessPacket, padding + 8);
195
196 if (fragNum == pTxBlk->TotalFragNum) {
197 RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
198
199 /* Update the pHTTXContext->CurWritePosition. 3906 used to prevent the NextBulkOut is a A-RALINK/A-MSDU Frame. */
200 pHTTXContext->CurWritePosition += pTxBlk->Priv;
201 if (TxQLastRound == TRUE)
202 pHTTXContext->CurWritePosition = 8;
203 pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
204
205 /* Finally, set bCurWriting as FALSE */
206 pHTTXContext->bCurWriting = FALSE;
207
208 RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
209
210 /* succeed and release the skb buffer */
211 RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS);
212 }
213
214 return (Status);
215
216}
217
218u16 RtmpUSB_WriteSingleTxResource(struct rt_rtmp_adapter *pAd,
219 struct rt_tx_blk *pTxBlk,
220 IN BOOLEAN bIsLast,
221 u16 * FreeNumber)
222{
223 struct rt_ht_tx_context *pHTTXContext;
224 u16 hwHdrLen;
225 u32 fillOffset;
226 struct rt_txinfo *pTxInfo;
227 struct rt_txwi *pTxWI;
228 u8 *pWirelessPacket;
229 u8 QueIdx;
230 unsigned long IrqFlags;
231 int Status;
232 u32 USBDMApktLen = 0, DMAHdrLen, padding;
233 BOOLEAN bTxQLastRound = FALSE;
234
235 /* For USB, didn't need PCI_MAP_SINGLE() */
236 /*SrcBufPA = PCI_MAP_SINGLE(pAd, (char *) pTxBlk->pSrcBufData, pTxBlk->SrcBufLen, PCI_DMA_TODEVICE); */
237
238 /* */
239 /* get Tx Ring Resource & Dma Buffer address */
240 /* */
241 QueIdx = pTxBlk->QueIdx;
242
243 RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
244 pHTTXContext = &pAd->TxContext[QueIdx];
245 fillOffset = pHTTXContext->CurWritePosition;
246
247 /* Check ring full. */
248 Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext);
249 if (Status == NDIS_STATUS_SUCCESS) {
250 pHTTXContext->bCurWriting = TRUE;
251
252 pTxInfo = (struct rt_txinfo *)(&pTxBlk->HeaderBuf[0]);
253 pTxWI = (struct rt_txwi *) (&pTxBlk->HeaderBuf[TXINFO_SIZE]);
254
255 /* Reserve space for 8 bytes padding. */
256 if ((pHTTXContext->ENextBulkOutPosition ==
257 pHTTXContext->CurWritePosition)) {
258 pHTTXContext->ENextBulkOutPosition += 8;
259 pHTTXContext->CurWritePosition += 8;
260 fillOffset += 8;
261 }
262 pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
263
264 pWirelessPacket =
265 &pHTTXContext->TransferBuffer->field.
266 WirelessPacket[fillOffset];
267
268 /* copy TXWI + WLAN Header + LLC into DMA Header Buffer */
269 /*hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4); */
270 hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
271
272 /* Build our URB for USBD */
273 DMAHdrLen = TXWI_SIZE + hwHdrLen;
274 USBDMApktLen = DMAHdrLen + pTxBlk->SrcBufLen;
275 padding = (4 - (USBDMApktLen % 4)) & 0x03; /* round up to 4 byte alignment */
276 USBDMApktLen += padding;
277
278 pTxBlk->Priv = (TXINFO_SIZE + USBDMApktLen);
279
280 /* For TxInfo, the length of USBDMApktLen = TXWI_SIZE + 802.11 header + payload */
281 RTMPWriteTxInfo(pAd, pTxInfo, (u16)(USBDMApktLen), FALSE,
282 FIFO_EDCA, FALSE /*NextValid */ , FALSE);
283
284 if ((pHTTXContext->CurWritePosition + 3906 + pTxBlk->Priv) >
285 MAX_TXBULK_LIMIT) {
286 pTxInfo->SwUseLastRound = 1;
287 bTxQLastRound = TRUE;
288 }
289 NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf,
290 TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
291 pWirelessPacket += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
292
293 /* We unlock it here to prevent the first 8 bytes maybe over-writed issue. */
294 /* 1. First we got CurWritePosition but the first 8 bytes still not write to the pTxcontext. */
295 /* 2. An interrupt break our routine and handle bulk-out complete. */
296 /* 3. In the bulk-out compllete, it need to do another bulk-out, */
297 /* if the ENextBulkOutPosition is just the same as CurWritePosition, it will save the first 8 bytes from CurWritePosition, */
298 /* but the payload still not copyed. the pTxContext->SavedPad[] will save as allzero. and set the bCopyPad = TRUE. */
299 /* 4. Interrupt complete. */
300 /* 5. Our interrupted routine go back and fill the first 8 bytes to pTxContext. */
301 /* 6. Next time when do bulk-out, it found the bCopyPad==TRUE and will copy the SavedPad[] to pTxContext->NextBulkOutPosition. */
302 /* and the packet will wrong. */
303 pHTTXContext->CurWriteRealPos +=
304 (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
305 RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
306
307 NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData,
308 pTxBlk->SrcBufLen);
309 pWirelessPacket += pTxBlk->SrcBufLen;
310 NdisZeroMemory(pWirelessPacket, padding + 8);
311
312 RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
313
314 pHTTXContext->CurWritePosition += pTxBlk->Priv;
315 if (bTxQLastRound)
316 pHTTXContext->CurWritePosition = 8;
317 pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
318
319 pHTTXContext->bCurWriting = FALSE;
320 }
321
322 RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
323
324 /* succeed and release the skb buffer */
325 RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS);
326
327 return (Status);
328
329}
330
331u16 RtmpUSB_WriteMultiTxResource(struct rt_rtmp_adapter *pAd,
332 struct rt_tx_blk *pTxBlk,
333 u8 frameNum, u16 * FreeNumber)
334{
335 struct rt_ht_tx_context *pHTTXContext;
336 u16 hwHdrLen; /* The hwHdrLen consist of 802.11 header length plus the header padding length. */
337 u32 fillOffset;
338 struct rt_txinfo *pTxInfo;
339 struct rt_txwi *pTxWI;
340 u8 *pWirelessPacket = NULL;
341 u8 QueIdx;
342 int Status;
343 unsigned long IrqFlags;
344 /*u32 USBDMApktLen = 0, DMAHdrLen, padding; */
345
346 /* */
347 /* get Tx Ring Resource & Dma Buffer address */
348 /* */
349 QueIdx = pTxBlk->QueIdx;
350 pHTTXContext = &pAd->TxContext[QueIdx];
351
352 RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
353
354 if (frameNum == 0) {
355 /* Check if we have enough space for this bulk-out batch. */
356 Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext);
357 if (Status == NDIS_STATUS_SUCCESS) {
358 pHTTXContext->bCurWriting = TRUE;
359
360 pTxInfo = (struct rt_txinfo *)(&pTxBlk->HeaderBuf[0]);
361 pTxWI = (struct rt_txwi *) (&pTxBlk->HeaderBuf[TXINFO_SIZE]);
362
363 /* Reserve space for 8 bytes padding. */
364 if ((pHTTXContext->ENextBulkOutPosition ==
365 pHTTXContext->CurWritePosition)) {
366
367 pHTTXContext->CurWritePosition += 8;
368 pHTTXContext->ENextBulkOutPosition += 8;
369 }
370 fillOffset = pHTTXContext->CurWritePosition;
371 pHTTXContext->CurWriteRealPos =
372 pHTTXContext->CurWritePosition;
373
374 pWirelessPacket =
375 &pHTTXContext->TransferBuffer->field.
376 WirelessPacket[fillOffset];
377
378 /* */
379 /* Copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer */
380 /* */
381 if (pTxBlk->TxFrameType == TX_AMSDU_FRAME)
382 /*hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD, 4)+LENGTH_AMSDU_SUBFRAMEHEAD; */
383 hwHdrLen =
384 pTxBlk->MpduHeaderLen -
385 LENGTH_AMSDU_SUBFRAMEHEAD +
386 pTxBlk->HdrPadLen +
387 LENGTH_AMSDU_SUBFRAMEHEAD;
388 else if (pTxBlk->TxFrameType == TX_RALINK_FRAME)
389 /*hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_ARALINK_HEADER_FIELD, 4)+LENGTH_ARALINK_HEADER_FIELD; */
390 hwHdrLen =
391 pTxBlk->MpduHeaderLen -
392 LENGTH_ARALINK_HEADER_FIELD +
393 pTxBlk->HdrPadLen +
394 LENGTH_ARALINK_HEADER_FIELD;
395 else
396 /*hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4); */
397 hwHdrLen =
398 pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
399
400 /* Update the pTxBlk->Priv. */
401 pTxBlk->Priv = TXINFO_SIZE + TXWI_SIZE + hwHdrLen;
402
403 /* pTxInfo->USBDMApktLen now just a temp value and will to correct latter. */
404 RTMPWriteTxInfo(pAd, pTxInfo, (u16)(pTxBlk->Priv),
405 FALSE, FIFO_EDCA, FALSE /*NextValid */ ,
406 FALSE);
407
408 /* Copy it. */
409 NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf,
410 pTxBlk->Priv);
411 pHTTXContext->CurWriteRealPos += pTxBlk->Priv;
412 pWirelessPacket += pTxBlk->Priv;
413 }
414 } else { /* For sub-sequent frames of this bulk-out batch. Just copy it to our bulk-out buffer. */
415
416 Status =
417 ((pHTTXContext->bCurWriting ==
418 TRUE) ? NDIS_STATUS_SUCCESS : NDIS_STATUS_FAILURE);
419 if (Status == NDIS_STATUS_SUCCESS) {
420 fillOffset =
421 (pHTTXContext->CurWritePosition + pTxBlk->Priv);
422 pWirelessPacket =
423 &pHTTXContext->TransferBuffer->field.
424 WirelessPacket[fillOffset];
425
426 /*hwHdrLen = pTxBlk->MpduHeaderLen; */
427 NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf,
428 pTxBlk->MpduHeaderLen);
429 pWirelessPacket += (pTxBlk->MpduHeaderLen);
430 pTxBlk->Priv += pTxBlk->MpduHeaderLen;
431 } else { /* It should not happened now unless we are going to shutdown. */
432 DBGPRINT(RT_DEBUG_ERROR,
433 ("WriteMultiTxResource():bCurWriting is FALSE when handle sub-sequent frames.\n"));
434 Status = NDIS_STATUS_FAILURE;
435 }
436 }
437
438 /* We unlock it here to prevent the first 8 bytes maybe over-write issue. */
439 /* 1. First we got CurWritePosition but the first 8 bytes still not write to the pTxContext. */
440 /* 2. An interrupt break our routine and handle bulk-out complete. */
441 /* 3. In the bulk-out compllete, it need to do another bulk-out, */
442 /* if the ENextBulkOutPosition is just the same as CurWritePosition, it will save the first 8 bytes from CurWritePosition, */
443 /* but the payload still not copyed. the pTxContext->SavedPad[] will save as allzero. and set the bCopyPad = TRUE. */
444 /* 4. Interrupt complete. */
445 /* 5. Our interrupted routine go back and fill the first 8 bytes to pTxContext. */
446 /* 6. Next time when do bulk-out, it found the bCopyPad==TRUE and will copy the SavedPad[] to pTxContext->NextBulkOutPosition. */
447 /* and the packet will wrong. */
448 RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
449
450 if (Status != NDIS_STATUS_SUCCESS) {
451 DBGPRINT(RT_DEBUG_ERROR,
452 ("WriteMultiTxResource: CWPos = %ld, NBOutPos = %ld.\n",
453 pHTTXContext->CurWritePosition,
454 pHTTXContext->NextBulkOutPosition));
455 goto done;
456 }
457 /* Copy the frame content into DMA buffer and update the pTxBlk->Priv */
458 NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen);
459 pWirelessPacket += pTxBlk->SrcBufLen;
460 pTxBlk->Priv += pTxBlk->SrcBufLen;
461
462done:
463 /* Release the skb buffer here */
464 RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS);
465
466 return (Status);
467
468}
469
470void RtmpUSB_FinalWriteTxResource(struct rt_rtmp_adapter *pAd,
471 struct rt_tx_blk *pTxBlk,
472 u16 totalMPDUSize, u16 TxIdx)
473{
474 u8 QueIdx;
475 struct rt_ht_tx_context *pHTTXContext;
476 u32 fillOffset;
477 struct rt_txinfo *pTxInfo;
478 struct rt_txwi *pTxWI;
479 u32 USBDMApktLen, padding;
480 unsigned long IrqFlags;
481 u8 *pWirelessPacket;
482
483 QueIdx = pTxBlk->QueIdx;
484 pHTTXContext = &pAd->TxContext[QueIdx];
485
486 RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
487
488 if (pHTTXContext->bCurWriting == TRUE) {
489 fillOffset = pHTTXContext->CurWritePosition;
490 if (((pHTTXContext->ENextBulkOutPosition ==
491 pHTTXContext->CurWritePosition)
492 || ((pHTTXContext->ENextBulkOutPosition - 8) ==
493 pHTTXContext->CurWritePosition))
494 && (pHTTXContext->bCopySavePad == TRUE))
495 pWirelessPacket = (u8 *)(&pHTTXContext->SavedPad[0]);
496 else
497 pWirelessPacket =
498 (u8 *)(&pHTTXContext->TransferBuffer->field.
499 WirelessPacket[fillOffset]);
500
501 /* */
502 /* Update TxInfo->USBDMApktLen , */
503 /* the length = TXWI_SIZE + 802.11_hdr + 802.11_hdr_pad + payload_of_all_batch_frames + Bulk-Out-padding */
504 /* */
505 pTxInfo = (struct rt_txinfo *)(pWirelessPacket);
506
507 /* Calculate the bulk-out padding */
508 USBDMApktLen = pTxBlk->Priv - TXINFO_SIZE;
509 padding = (4 - (USBDMApktLen % 4)) & 0x03; /* round up to 4 byte alignment */
510 USBDMApktLen += padding;
511
512 pTxInfo->USBDMATxPktLen = USBDMApktLen;
513
514 /* */
515 /* Update TXWI->MPDUtotalByteCount , */
516 /* the length = 802.11 header + payload_of_all_batch_frames */
517 pTxWI = (struct rt_txwi *) (pWirelessPacket + TXINFO_SIZE);
518 pTxWI->MPDUtotalByteCount = totalMPDUSize;
519
520 /* */
521 /* Update the pHTTXContext->CurWritePosition */
522 /* */
523 pHTTXContext->CurWritePosition += (TXINFO_SIZE + USBDMApktLen);
524 if ((pHTTXContext->CurWritePosition + 3906) > MAX_TXBULK_LIMIT) { /* Add 3906 for prevent the NextBulkOut packet size is a A-RALINK/A-MSDU Frame. */
525 pHTTXContext->CurWritePosition = 8;
526 pTxInfo->SwUseLastRound = 1;
527 }
528 pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
529
530 /* */
531 /* Zero the last padding. */
532 /* */
533 pWirelessPacket =
534 (&pHTTXContext->TransferBuffer->field.
535 WirelessPacket[fillOffset + pTxBlk->Priv]);
536 NdisZeroMemory(pWirelessPacket, padding + 8);
537
538 /* Finally, set bCurWriting as FALSE */
539 pHTTXContext->bCurWriting = FALSE;
540
541 } else { /* It should not happened now unless we are going to shutdown. */
542 DBGPRINT(RT_DEBUG_ERROR,
543 ("FinalWriteTxResource():bCurWriting is FALSE when handle last frames.\n"));
544 }
545
546 RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
547
548}
549
550void RtmpUSBDataLastTxIdx(struct rt_rtmp_adapter *pAd,
551 u8 QueIdx, u16 TxIdx)
552{
553 /* DO nothing for USB. */
554}
555
556/*
557 When can do bulk-out:
558 1. TxSwFreeIdx < TX_RING_SIZE;
559 It means has at least one Ring entity is ready for bulk-out, kick it out.
560 2. If TxSwFreeIdx == TX_RING_SIZE
561 Check if the CurWriting flag is FALSE, if it's FALSE, we can do kick out.
562
563*/
564void RtmpUSBDataKickOut(struct rt_rtmp_adapter *pAd,
565 struct rt_tx_blk *pTxBlk, u8 QueIdx)
566{
567 RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx));
568 RTUSBKickBulkOut(pAd);
569
570}
571
572/*
573 Must be run in Interrupt context
574 This function handle RT2870 specific TxDesc and cpu index update and kick the packet out.
575 */
576int RtmpUSBMgmtKickOut(struct rt_rtmp_adapter *pAd,
577 u8 QueIdx,
578 void *pPacket,
579 u8 *pSrcBufVA, u32 SrcBufLen)
580{
581 struct rt_txinfo *pTxInfo;
582 unsigned long BulkOutSize;
583 u8 padLen;
584 u8 *pDest;
585 unsigned long SwIdx = pAd->MgmtRing.TxCpuIdx;
586 struct rt_tx_context *pMLMEContext =
587 (struct rt_tx_context *)pAd->MgmtRing.Cell[SwIdx].AllocVa;
588 unsigned long IrqFlags;
589
590 pTxInfo = (struct rt_txinfo *)(pSrcBufVA);
591
592 /* Build our URB for USBD */
593 BulkOutSize = SrcBufLen;
594 BulkOutSize = (BulkOutSize + 3) & (~3);
595 RTMPWriteTxInfo(pAd, pTxInfo, (u16)(BulkOutSize - TXINFO_SIZE),
596 TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
597
598 BulkOutSize += 4; /* Always add 4 extra bytes at every packet. */
599
600 /* If BulkOutSize is multiple of BulkOutMaxPacketSize, add extra 4 bytes again. */
601 if ((BulkOutSize % pAd->BulkOutMaxPacketSize) == 0)
602 BulkOutSize += 4;
603
604 padLen = BulkOutSize - SrcBufLen;
605 ASSERT((padLen <= RTMP_PKT_TAIL_PADDING));
606
607 /* Now memzero all extra padding bytes. */
608 pDest = (u8 *)(pSrcBufVA + SrcBufLen);
609 skb_put(GET_OS_PKT_TYPE(pPacket), padLen);
610 NdisZeroMemory(pDest, padLen);
611
612 RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags);
613
614 pAd->MgmtRing.Cell[pAd->MgmtRing.TxCpuIdx].pNdisPacket = pPacket;
615 pMLMEContext->TransferBuffer =
616 (struct rt_tx_buffer *)(GET_OS_PKT_DATAPTR(pPacket));
617
618 /* Length in TxInfo should be 8 less than bulkout size. */
619 pMLMEContext->BulkOutSize = BulkOutSize;
620 pMLMEContext->InUse = TRUE;
621 pMLMEContext->bWaitingBulkOut = TRUE;
622
623 /*for debug */
624 /*hex_dump("RtmpUSBMgmtKickOut", &pMLMEContext->TransferBuffer->field.WirelessPacket[0], (pMLMEContext->BulkOutSize > 16 ? 16 : pMLMEContext->BulkOutSize)); */
625
626 /*pAd->RalinkCounters.KickTxCount++; */
627 /*pAd->RalinkCounters.OneSecTxDoneCount++; */
628
629 /*if (pAd->MgmtRing.TxSwFreeIdx == MGMT_RING_SIZE) */
630 /* needKickOut = TRUE; */
631
632 /* Decrease the TxSwFreeIdx and Increase the TX_CTX_IDX */
633 pAd->MgmtRing.TxSwFreeIdx--;
634 INC_RING_INDEX(pAd->MgmtRing.TxCpuIdx, MGMT_RING_SIZE);
635
636 RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags);
637
638 RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
639 /*if (needKickOut) */
640 RTUSBKickBulkOut(pAd);
641
642 return 0;
643}
644
645void RtmpUSBNullFrameKickOut(struct rt_rtmp_adapter *pAd,
646 u8 QueIdx,
647 u8 * pNullFrame, u32 frameLen)
648{
649 if (pAd->NullContext.InUse == FALSE) {
650 struct rt_tx_context *pNullContext;
651 struct rt_txinfo *pTxInfo;
652 struct rt_txwi * pTxWI;
653 u8 *pWirelessPkt;
654
655 pNullContext = &(pAd->NullContext);
656
657 /* Set the in use bit */
658 pNullContext->InUse = TRUE;
659 pWirelessPkt =
660 (u8 *)& pNullContext->TransferBuffer->field.
661 WirelessPacket[0];
662
663 RTMPZeroMemory(&pWirelessPkt[0], 100);
664 pTxInfo = (struct rt_txinfo *)& pWirelessPkt[0];
665 RTMPWriteTxInfo(pAd, pTxInfo,
666 (u16)(sizeof(struct rt_header_802_11) + TXWI_SIZE),
667 TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
668 pTxInfo->QSEL = FIFO_EDCA;
669 pTxWI = (struct rt_txwi *) & pWirelessPkt[TXINFO_SIZE];
670 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE,
671 FALSE, 0, BSSID_WCID, (sizeof(struct rt_header_802_11)), 0,
672 0, (u8)pAd->CommonCfg.MlmeTransmit.field.MCS,
673 IFS_HTTXOP, FALSE, &pAd->CommonCfg.MlmeTransmit);
674
675 RTMPMoveMemory(&pWirelessPkt[TXWI_SIZE + TXINFO_SIZE],
676 &pAd->NullFrame, sizeof(struct rt_header_802_11));
677 pAd->NullContext.BulkOutSize =
678 TXINFO_SIZE + TXWI_SIZE + sizeof(pAd->NullFrame) + 4;
679
680 /* Fill out frame length information for global Bulk out arbitor */
681 /*pNullContext->BulkOutSize = TransferBufferLength; */
682 DBGPRINT(RT_DEBUG_TRACE,
683 ("SYNC - send NULL Frame @%d Mbps...\n",
684 RateIdToMbps[pAd->CommonCfg.TxRate]));
685 RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL);
686
687 /* Kick bulk out */
688 RTUSBKickBulkOut(pAd);
689 }
690
691}
692
693/*
694========================================================================
695Routine Description:
696 Get a received packet.
697
698Arguments:
699 pAd device control block
700 pSaveRxD receive descriptor information
701 *pbReschedule need reschedule flag
702 *pRxPending pending received packet flag
703
704Return Value:
705 the received packet
706
707Note:
708========================================================================
709*/
710void *GetPacketFromRxRing(struct rt_rtmp_adapter *pAd,
711 OUT PRT28XX_RXD_STRUC pSaveRxD,
712 OUT BOOLEAN * pbReschedule,
713 IN u32 * pRxPending)
714{
715 struct rt_rx_context *pRxContext;
716 void *pSkb;
717 u8 *pData;
718 unsigned long ThisFrameLen;
719 unsigned long RxBufferLength;
720 struct rt_rxwi * pRxWI;
721
722 pRxContext = &pAd->RxContext[pAd->NextRxBulkInReadIndex];
723 if ((pRxContext->Readable == FALSE) || (pRxContext->InUse == TRUE))
724 return NULL;
725
726 RxBufferLength = pRxContext->BulkInOffset - pAd->ReadPosition;
727 if (RxBufferLength <
728 (RT2870_RXDMALEN_FIELD_SIZE + sizeof(struct rt_rxwi) +
729 sizeof(struct rt_rxinfo))) {
730 goto label_null;
731 }
732
733 pData = &pRxContext->TransferBuffer[pAd->ReadPosition]; /* 4KB */
734 /* The RXDMA field is 4 bytes, now just use the first 2 bytes. The Length including the (RXWI + MSDU + Padding) */
735 ThisFrameLen = *pData + (*(pData + 1) << 8);
736 if (ThisFrameLen == 0) {
737 DBGPRINT(RT_DEBUG_TRACE,
738 ("BIRIdx(%d): RXDMALen is zero.[%ld], BulkInBufLen = %ld)\n",
739 pAd->NextRxBulkInReadIndex, ThisFrameLen,
740 pRxContext->BulkInOffset));
741 goto label_null;
742 }
743 if ((ThisFrameLen & 0x3) != 0) {
744 DBGPRINT(RT_DEBUG_ERROR,
745 ("BIRIdx(%d): RXDMALen not multiple of 4.[%ld], BulkInBufLen = %ld)\n",
746 pAd->NextRxBulkInReadIndex, ThisFrameLen,
747 pRxContext->BulkInOffset));
748 goto label_null;
749 }
750
751 if ((ThisFrameLen + 8) > RxBufferLength) /* 8 for (RT2870_RXDMALEN_FIELD_SIZE + sizeof(struct rt_rxinfo)) */
752 {
753 DBGPRINT(RT_DEBUG_TRACE,
754 ("BIRIdx(%d):FrameLen(0x%lx) outranges. BulkInLen=0x%lx, remaining RxBufLen=0x%lx, ReadPos=0x%lx\n",
755 pAd->NextRxBulkInReadIndex, ThisFrameLen,
756 pRxContext->BulkInOffset, RxBufferLength,
757 pAd->ReadPosition));
758
759 /* error frame. finish this loop */
760 goto label_null;
761 }
762 /* skip USB frame length field */
763 pData += RT2870_RXDMALEN_FIELD_SIZE;
764 pRxWI = (struct rt_rxwi *) pData;
765 if (pRxWI->MPDUtotalByteCount > ThisFrameLen) {
766 DBGPRINT(RT_DEBUG_ERROR,
767 ("%s():pRxWIMPDUtotalByteCount(%d) large than RxDMALen(%ld)\n",
768 __FUNCTION__, pRxWI->MPDUtotalByteCount,
769 ThisFrameLen));
770 goto label_null;
771 }
772 /* allocate a rx packet */
773 pSkb = dev_alloc_skb(ThisFrameLen);
774 if (pSkb == NULL) {
775 DBGPRINT(RT_DEBUG_ERROR,
776 ("%s():Cannot Allocate sk buffer for this Bulk-In buffer!\n",
777 __FUNCTION__));
778 goto label_null;
779 }
780 /* copy the rx packet */
781 memcpy(skb_put(pSkb, ThisFrameLen), pData, ThisFrameLen);
782 RTPKT_TO_OSPKT(pSkb)->dev = get_netdev_from_bssid(pAd, BSS0);
783 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pSkb), PKTSRC_NDIS);
784
785 /* copy RxD */
786 *pSaveRxD = *(struct rt_rxinfo *) (pData + ThisFrameLen);
787
788 /* update next packet read position. */
789 pAd->ReadPosition += (ThisFrameLen + RT2870_RXDMALEN_FIELD_SIZE + RXINFO_SIZE); /* 8 for (RT2870_RXDMALEN_FIELD_SIZE + sizeof(struct rt_rxinfo)) */
790
791 return pSkb;
792
793label_null:
794
795 return NULL;
796}
797
798/*
799 ========================================================================
800
801 Routine Description:
802 Check Rx descriptor, return NDIS_STATUS_FAILURE if any error dound
803
804 Arguments:
805 pRxD Pointer to the Rx descriptor
806
807 Return Value:
808 NDIS_STATUS_SUCCESS No err
809 NDIS_STATUS_FAILURE Error
810
811 Note:
812
813 ========================================================================
814*/
815int RTMPCheckRxError(struct rt_rtmp_adapter *pAd,
816 struct rt_header_802_11 * pHeader,
817 struct rt_rxwi * pRxWI, IN PRT28XX_RXD_STRUC pRxINFO)
818{
819 struct rt_cipher_key *pWpaKey;
820 int dBm;
821
822 if (pAd->bPromiscuous == TRUE)
823 return (NDIS_STATUS_SUCCESS);
824 if (pRxINFO == NULL)
825 return (NDIS_STATUS_FAILURE);
826
827 /* Phy errors & CRC errors */
828 if (pRxINFO->Crc) {
829 /* Check RSSI for Noise Hist statistic collection. */
830 dBm = (int)(pRxWI->RSSI0) - pAd->BbpRssiToDbmDelta;
831 if (dBm <= -87)
832 pAd->StaCfg.RPIDensity[0] += 1;
833 else if (dBm <= -82)
834 pAd->StaCfg.RPIDensity[1] += 1;
835 else if (dBm <= -77)
836 pAd->StaCfg.RPIDensity[2] += 1;
837 else if (dBm <= -72)
838 pAd->StaCfg.RPIDensity[3] += 1;
839 else if (dBm <= -67)
840 pAd->StaCfg.RPIDensity[4] += 1;
841 else if (dBm <= -62)
842 pAd->StaCfg.RPIDensity[5] += 1;
843 else if (dBm <= -57)
844 pAd->StaCfg.RPIDensity[6] += 1;
845 else if (dBm > -57)
846 pAd->StaCfg.RPIDensity[7] += 1;
847
848 return (NDIS_STATUS_FAILURE);
849 }
850 /* Add Rx size to channel load counter, we should ignore error counts */
851 pAd->StaCfg.CLBusyBytes += (pRxWI->MPDUtotalByteCount + 14);
852
853 /* Drop ToDs promiscuous frame, it is opened due to CCX 2 channel load statistics */
854 if (pHeader->FC.ToDs) {
855 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Err;FC.ToDs\n"));
856 return NDIS_STATUS_FAILURE;
857 }
858 /* Paul 04-03 for OFDM Rx length issue */
859 if (pRxWI->MPDUtotalByteCount > MAX_AGGREGATION_SIZE) {
860 DBGPRINT_RAW(RT_DEBUG_ERROR, ("received packet too long\n"));
861 return NDIS_STATUS_FAILURE;
862 }
863 /* Drop not U2M frames, can't's drop here because we will drop beacon in this case */
864 /* I am kind of doubting the U2M bit operation */
865 /* if (pRxD->U2M == 0) */
866 /* return(NDIS_STATUS_FAILURE); */
867
868 /* drop decyption fail frame */
869 if (pRxINFO->Decrypted && pRxINFO->CipherErr) {
870
871 if (((pRxINFO->CipherErr & 1) == 1)
872 && pAd->CommonCfg.bWirelessEvent && INFRA_ON(pAd))
873 RTMPSendWirelessEvent(pAd, IW_ICV_ERROR_EVENT_FLAG,
874 pAd->MacTab.Content[BSSID_WCID].
875 Addr, BSS0, 0);
876
877 if (((pRxINFO->CipherErr & 2) == 2)
878 && pAd->CommonCfg.bWirelessEvent && INFRA_ON(pAd))
879 RTMPSendWirelessEvent(pAd, IW_MIC_ERROR_EVENT_FLAG,
880 pAd->MacTab.Content[BSSID_WCID].
881 Addr, BSS0, 0);
882 /* */
883 /* MIC Error */
884 /* */
885 if ((pRxINFO->CipherErr == 2) && pRxINFO->MyBss) {
886 pWpaKey = &pAd->SharedKey[BSS0][pRxWI->KeyIndex];
887 RTMPReportMicError(pAd, pWpaKey);
888 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Rx MIC Value error\n"));
889 }
890
891 if (pRxINFO->Decrypted &&
892 (pAd->SharedKey[BSS0][pRxWI->KeyIndex].CipherAlg ==
893 CIPHER_AES)
894 && (pHeader->Sequence == pAd->FragFrame.Sequence)) {
895 /* */
896 /* Acceptable since the First FragFrame no CipherErr problem. */
897 /* */
898 return (NDIS_STATUS_SUCCESS);
899 }
900
901 return (NDIS_STATUS_FAILURE);
902 }
903
904 return (NDIS_STATUS_SUCCESS);
905}
906
907void RtmpUsbStaAsicForceWakeupTimeout(void *SystemSpecific1,
908 void *FunctionContext,
909 void *SystemSpecific2,
910 void *SystemSpecific3)
911{
912 struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext;
913
914 if (pAd && pAd->Mlme.AutoWakeupTimerRunning) {
915 AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02);
916
917 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
918 pAd->Mlme.AutoWakeupTimerRunning = FALSE;
919 }
920}
921
922void RT28xxUsbStaAsicForceWakeup(struct rt_rtmp_adapter *pAd, IN BOOLEAN bFromTx)
923{
924 BOOLEAN Canceled;
925
926 if (pAd->Mlme.AutoWakeupTimerRunning)
927 RTMPCancelTimer(&pAd->Mlme.AutoWakeupTimer, &Canceled);
928
929 AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02);
930
931 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
932}
933
934void RT28xxUsbStaAsicSleepThenAutoWakeup(struct rt_rtmp_adapter *pAd,
935 u16 TbttNumToNextWakeUp)
936{
937
938 /* we have decided to SLEEP, so at least do it for a BEACON period. */
939 if (TbttNumToNextWakeUp == 0)
940 TbttNumToNextWakeUp = 1;
941
942 RTMPSetTimer(&pAd->Mlme.AutoWakeupTimer, AUTO_WAKEUP_TIMEOUT);
943 pAd->Mlme.AutoWakeupTimerRunning = TRUE;
944
945 AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02); /* send POWER-SAVE command to MCU. Timeout 40us. */
946
947 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_DOZE);
948
949}
950
951#endif /* RTMP_MAC_USB // */
diff --git a/drivers/staging/rt2860/common/cmm_info.c b/drivers/staging/rt2860/common/cmm_info.c
deleted file mode 100644
index 25302e8363b..00000000000
--- a/drivers/staging/rt2860/common/cmm_info.c
+++ /dev/null
@@ -1,955 +0,0 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26 */
27
28#include <linux/sched.h>
29#include "../rt_config.h"
30
31/*
32 ========================================================================
33
34 Routine Description:
35 Remove WPA Key process
36
37 Arguments:
38 pAd Pointer to our adapter
39 pBuf Pointer to the where the key stored
40
41 Return Value:
42 NDIS_SUCCESS Add key successfully
43
44 IRQL = DISPATCH_LEVEL
45
46 Note:
47
48 ========================================================================
49*/
50void RTMPSetDesiredRates(struct rt_rtmp_adapter *pAdapter, long Rates)
51{
52 NDIS_802_11_RATES aryRates;
53
54 memset(&aryRates, 0x00, sizeof(NDIS_802_11_RATES));
55 switch (pAdapter->CommonCfg.PhyMode) {
56 case PHY_11A: /* A only */
57 switch (Rates) {
58 case 6000000: /*6M */
59 aryRates[0] = 0x0c; /* 6M */
60 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
61 MCS_0;
62 break;
63 case 9000000: /*9M */
64 aryRates[0] = 0x12; /* 9M */
65 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
66 MCS_1;
67 break;
68 case 12000000: /*12M */
69 aryRates[0] = 0x18; /* 12M */
70 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
71 MCS_2;
72 break;
73 case 18000000: /*18M */
74 aryRates[0] = 0x24; /* 18M */
75 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
76 MCS_3;
77 break;
78 case 24000000: /*24M */
79 aryRates[0] = 0x30; /* 24M */
80 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
81 MCS_4;
82 break;
83 case 36000000: /*36M */
84 aryRates[0] = 0x48; /* 36M */
85 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
86 MCS_5;
87 break;
88 case 48000000: /*48M */
89 aryRates[0] = 0x60; /* 48M */
90 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
91 MCS_6;
92 break;
93 case 54000000: /*54M */
94 aryRates[0] = 0x6c; /* 54M */
95 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
96 MCS_7;
97 break;
98 case -1: /*Auto */
99 default:
100 aryRates[0] = 0x6c; /* 54Mbps */
101 aryRates[1] = 0x60; /* 48Mbps */
102 aryRates[2] = 0x48; /* 36Mbps */
103 aryRates[3] = 0x30; /* 24Mbps */
104 aryRates[4] = 0x24; /* 18M */
105 aryRates[5] = 0x18; /* 12M */
106 aryRates[6] = 0x12; /* 9M */
107 aryRates[7] = 0x0c; /* 6M */
108 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
109 MCS_AUTO;
110 break;
111 }
112 break;
113 case PHY_11BG_MIXED: /* B/G Mixed */
114 case PHY_11B: /* B only */
115 case PHY_11ABG_MIXED: /* A/B/G Mixed */
116 default:
117 switch (Rates) {
118 case 1000000: /*1M */
119 aryRates[0] = 0x02;
120 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
121 MCS_0;
122 break;
123 case 2000000: /*2M */
124 aryRates[0] = 0x04;
125 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
126 MCS_1;
127 break;
128 case 5000000: /*5.5M */
129 aryRates[0] = 0x0b; /* 5.5M */
130 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
131 MCS_2;
132 break;
133 case 11000000: /*11M */
134 aryRates[0] = 0x16; /* 11M */
135 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
136 MCS_3;
137 break;
138 case 6000000: /*6M */
139 aryRates[0] = 0x0c; /* 6M */
140 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
141 MCS_0;
142 break;
143 case 9000000: /*9M */
144 aryRates[0] = 0x12; /* 9M */
145 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
146 MCS_1;
147 break;
148 case 12000000: /*12M */
149 aryRates[0] = 0x18; /* 12M */
150 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
151 MCS_2;
152 break;
153 case 18000000: /*18M */
154 aryRates[0] = 0x24; /* 18M */
155 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
156 MCS_3;
157 break;
158 case 24000000: /*24M */
159 aryRates[0] = 0x30; /* 24M */
160 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
161 MCS_4;
162 break;
163 case 36000000: /*36M */
164 aryRates[0] = 0x48; /* 36M */
165 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
166 MCS_5;
167 break;
168 case 48000000: /*48M */
169 aryRates[0] = 0x60; /* 48M */
170 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
171 MCS_6;
172 break;
173 case 54000000: /*54M */
174 aryRates[0] = 0x6c; /* 54M */
175 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
176 MCS_7;
177 break;
178 case -1: /*Auto */
179 default:
180 if (pAdapter->CommonCfg.PhyMode == PHY_11B) { /*B Only */
181 aryRates[0] = 0x16; /* 11Mbps */
182 aryRates[1] = 0x0b; /* 5.5Mbps */
183 aryRates[2] = 0x04; /* 2Mbps */
184 aryRates[3] = 0x02; /* 1Mbps */
185 } else { /*(B/G) Mixed or (A/B/G) Mixed */
186 aryRates[0] = 0x6c; /* 54Mbps */
187 aryRates[1] = 0x60; /* 48Mbps */
188 aryRates[2] = 0x48; /* 36Mbps */
189 aryRates[3] = 0x30; /* 24Mbps */
190 aryRates[4] = 0x16; /* 11Mbps */
191 aryRates[5] = 0x0b; /* 5.5Mbps */
192 aryRates[6] = 0x04; /* 2Mbps */
193 aryRates[7] = 0x02; /* 1Mbps */
194 }
195 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
196 MCS_AUTO;
197 break;
198 }
199 break;
200 }
201
202 NdisZeroMemory(pAdapter->CommonCfg.DesireRate,
203 MAX_LEN_OF_SUPPORTED_RATES);
204 NdisMoveMemory(pAdapter->CommonCfg.DesireRate, &aryRates,
205 sizeof(NDIS_802_11_RATES));
206 DBGPRINT(RT_DEBUG_TRACE,
207 (" RTMPSetDesiredRates (%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x)\n",
208 pAdapter->CommonCfg.DesireRate[0],
209 pAdapter->CommonCfg.DesireRate[1],
210 pAdapter->CommonCfg.DesireRate[2],
211 pAdapter->CommonCfg.DesireRate[3],
212 pAdapter->CommonCfg.DesireRate[4],
213 pAdapter->CommonCfg.DesireRate[5],
214 pAdapter->CommonCfg.DesireRate[6],
215 pAdapter->CommonCfg.DesireRate[7]));
216 /* Changing DesiredRate may affect the MAX TX rate we used to TX frames out */
217 MlmeUpdateTxRates(pAdapter, FALSE, 0);
218}
219
220/*
221 ========================================================================
222
223 Routine Description:
224 Remove All WPA Keys
225
226 Arguments:
227 pAd Pointer to our adapter
228
229 Return Value:
230 None
231
232 IRQL = DISPATCH_LEVEL
233
234 Note:
235
236 ========================================================================
237*/
238void RTMPWPARemoveAllKeys(struct rt_rtmp_adapter *pAd)
239{
240
241 u8 i;
242
243 DBGPRINT(RT_DEBUG_TRACE,
244 ("RTMPWPARemoveAllKeys(AuthMode=%d, WepStatus=%d)\n",
245 pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus));
246 RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
247 /* For WEP/CKIP, there is no need to remove it, since WinXP won't set it again after */
248 /* Link up. And it will be replaced if user changed it. */
249 if (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
250 return;
251
252 /* For WPA-None, there is no need to remove it, since WinXP won't set it again after */
253 /* Link up. And it will be replaced if user changed it. */
254 if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
255 return;
256
257 /* set BSSID wcid entry of the Pair-wise Key table as no-security mode */
258 AsicRemovePairwiseKeyEntry(pAd, BSS0, BSSID_WCID);
259
260 /* set all shared key mode as no-security. */
261 for (i = 0; i < SHARE_KEY_NUM; i++) {
262 DBGPRINT(RT_DEBUG_TRACE,
263 ("remove %s key #%d\n",
264 CipherName[pAd->SharedKey[BSS0][i].CipherAlg], i));
265 NdisZeroMemory(&pAd->SharedKey[BSS0][i], sizeof(struct rt_cipher_key));
266
267 AsicRemoveSharedKeyEntry(pAd, BSS0, i);
268 }
269 RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
270}
271
272/*
273 ========================================================================
274
275 Routine Description:
276 As STA's BSSID is a WC too, it uses shared key table.
277 This function write correct unicast TX key to ASIC WCID.
278 And we still make a copy in our MacTab.Content[BSSID_WCID].PairwiseKey.
279 Caller guarantee TKIP/AES always has keyidx = 0. (pairwise key)
280 Caller guarantee WEP calls this function when set Txkey, default key index=0~3.
281
282 Arguments:
283 pAd Pointer to our adapter
284 pKey Pointer to the where the key stored
285
286 Return Value:
287 NDIS_SUCCESS Add key successfully
288
289 IRQL = DISPATCH_LEVEL
290
291 Note:
292
293 ========================================================================
294*/
295/*
296 ========================================================================
297 Routine Description:
298 Change NIC PHY mode. Re-association may be necessary. possible settings
299 include - PHY_11B, PHY_11BG_MIXED, PHY_11A, and PHY_11ABG_MIXED
300
301 Arguments:
302 pAd - Pointer to our adapter
303 phymode -
304
305 IRQL = PASSIVE_LEVEL
306 IRQL = DISPATCH_LEVEL
307
308 ========================================================================
309*/
310void RTMPSetPhyMode(struct rt_rtmp_adapter *pAd, unsigned long phymode)
311{
312 int i;
313 /* the selected phymode must be supported by the RF IC encoded in E2PROM */
314
315 /* if no change, do nothing */
316 /* bug fix
317 if (pAd->CommonCfg.PhyMode == phymode)
318 return;
319 */
320 pAd->CommonCfg.PhyMode = (u8)phymode;
321
322 DBGPRINT(RT_DEBUG_TRACE,
323 ("RTMPSetPhyMode : PhyMode=%d, channel=%d \n",
324 pAd->CommonCfg.PhyMode, pAd->CommonCfg.Channel));
325
326 BuildChannelList(pAd);
327
328 /* sanity check user setting */
329 for (i = 0; i < pAd->ChannelListNum; i++) {
330 if (pAd->CommonCfg.Channel == pAd->ChannelList[i].Channel)
331 break;
332 }
333
334 if (i == pAd->ChannelListNum) {
335 pAd->CommonCfg.Channel = FirstChannel(pAd);
336 DBGPRINT(RT_DEBUG_ERROR,
337 ("RTMPSetPhyMode: channel is out of range, use first channel=%d \n",
338 pAd->CommonCfg.Channel));
339 }
340
341 NdisZeroMemory(pAd->CommonCfg.SupRate, MAX_LEN_OF_SUPPORTED_RATES);
342 NdisZeroMemory(pAd->CommonCfg.ExtRate, MAX_LEN_OF_SUPPORTED_RATES);
343 NdisZeroMemory(pAd->CommonCfg.DesireRate, MAX_LEN_OF_SUPPORTED_RATES);
344 switch (phymode) {
345 case PHY_11B:
346 pAd->CommonCfg.SupRate[0] = 0x82; /* 1 mbps, in units of 0.5 Mbps, basic rate */
347 pAd->CommonCfg.SupRate[1] = 0x84; /* 2 mbps, in units of 0.5 Mbps, basic rate */
348 pAd->CommonCfg.SupRate[2] = 0x8B; /* 5.5 mbps, in units of 0.5 Mbps, basic rate */
349 pAd->CommonCfg.SupRate[3] = 0x96; /* 11 mbps, in units of 0.5 Mbps, basic rate */
350 pAd->CommonCfg.SupRateLen = 4;
351 pAd->CommonCfg.ExtRateLen = 0;
352 pAd->CommonCfg.DesireRate[0] = 2; /* 1 mbps, in units of 0.5 Mbps */
353 pAd->CommonCfg.DesireRate[1] = 4; /* 2 mbps, in units of 0.5 Mbps */
354 pAd->CommonCfg.DesireRate[2] = 11; /* 5.5 mbps, in units of 0.5 Mbps */
355 pAd->CommonCfg.DesireRate[3] = 22; /* 11 mbps, in units of 0.5 Mbps */
356 /*pAd->CommonCfg.HTPhyMode.field.MODE = MODE_CCK; // This MODE is only FYI. not use */
357 break;
358
359 case PHY_11G:
360 case PHY_11BG_MIXED:
361 case PHY_11ABG_MIXED:
362 case PHY_11N_2_4G:
363 case PHY_11ABGN_MIXED:
364 case PHY_11BGN_MIXED:
365 case PHY_11GN_MIXED:
366 pAd->CommonCfg.SupRate[0] = 0x82; /* 1 mbps, in units of 0.5 Mbps, basic rate */
367 pAd->CommonCfg.SupRate[1] = 0x84; /* 2 mbps, in units of 0.5 Mbps, basic rate */
368 pAd->CommonCfg.SupRate[2] = 0x8B; /* 5.5 mbps, in units of 0.5 Mbps, basic rate */
369 pAd->CommonCfg.SupRate[3] = 0x96; /* 11 mbps, in units of 0.5 Mbps, basic rate */
370 pAd->CommonCfg.SupRate[4] = 0x12; /* 9 mbps, in units of 0.5 Mbps */
371 pAd->CommonCfg.SupRate[5] = 0x24; /* 18 mbps, in units of 0.5 Mbps */
372 pAd->CommonCfg.SupRate[6] = 0x48; /* 36 mbps, in units of 0.5 Mbps */
373 pAd->CommonCfg.SupRate[7] = 0x6c; /* 54 mbps, in units of 0.5 Mbps */
374 pAd->CommonCfg.SupRateLen = 8;
375 pAd->CommonCfg.ExtRate[0] = 0x0C; /* 6 mbps, in units of 0.5 Mbps */
376 pAd->CommonCfg.ExtRate[1] = 0x18; /* 12 mbps, in units of 0.5 Mbps */
377 pAd->CommonCfg.ExtRate[2] = 0x30; /* 24 mbps, in units of 0.5 Mbps */
378 pAd->CommonCfg.ExtRate[3] = 0x60; /* 48 mbps, in units of 0.5 Mbps */
379 pAd->CommonCfg.ExtRateLen = 4;
380 pAd->CommonCfg.DesireRate[0] = 2; /* 1 mbps, in units of 0.5 Mbps */
381 pAd->CommonCfg.DesireRate[1] = 4; /* 2 mbps, in units of 0.5 Mbps */
382 pAd->CommonCfg.DesireRate[2] = 11; /* 5.5 mbps, in units of 0.5 Mbps */
383 pAd->CommonCfg.DesireRate[3] = 22; /* 11 mbps, in units of 0.5 Mbps */
384 pAd->CommonCfg.DesireRate[4] = 12; /* 6 mbps, in units of 0.5 Mbps */
385 pAd->CommonCfg.DesireRate[5] = 18; /* 9 mbps, in units of 0.5 Mbps */
386 pAd->CommonCfg.DesireRate[6] = 24; /* 12 mbps, in units of 0.5 Mbps */
387 pAd->CommonCfg.DesireRate[7] = 36; /* 18 mbps, in units of 0.5 Mbps */
388 pAd->CommonCfg.DesireRate[8] = 48; /* 24 mbps, in units of 0.5 Mbps */
389 pAd->CommonCfg.DesireRate[9] = 72; /* 36 mbps, in units of 0.5 Mbps */
390 pAd->CommonCfg.DesireRate[10] = 96; /* 48 mbps, in units of 0.5 Mbps */
391 pAd->CommonCfg.DesireRate[11] = 108; /* 54 mbps, in units of 0.5 Mbps */
392 break;
393
394 case PHY_11A:
395 case PHY_11AN_MIXED:
396 case PHY_11AGN_MIXED:
397 case PHY_11N_5G:
398 pAd->CommonCfg.SupRate[0] = 0x8C; /* 6 mbps, in units of 0.5 Mbps, basic rate */
399 pAd->CommonCfg.SupRate[1] = 0x12; /* 9 mbps, in units of 0.5 Mbps */
400 pAd->CommonCfg.SupRate[2] = 0x98; /* 12 mbps, in units of 0.5 Mbps, basic rate */
401 pAd->CommonCfg.SupRate[3] = 0x24; /* 18 mbps, in units of 0.5 Mbps */
402 pAd->CommonCfg.SupRate[4] = 0xb0; /* 24 mbps, in units of 0.5 Mbps, basic rate */
403 pAd->CommonCfg.SupRate[5] = 0x48; /* 36 mbps, in units of 0.5 Mbps */
404 pAd->CommonCfg.SupRate[6] = 0x60; /* 48 mbps, in units of 0.5 Mbps */
405 pAd->CommonCfg.SupRate[7] = 0x6c; /* 54 mbps, in units of 0.5 Mbps */
406 pAd->CommonCfg.SupRateLen = 8;
407 pAd->CommonCfg.ExtRateLen = 0;
408 pAd->CommonCfg.DesireRate[0] = 12; /* 6 mbps, in units of 0.5 Mbps */
409 pAd->CommonCfg.DesireRate[1] = 18; /* 9 mbps, in units of 0.5 Mbps */
410 pAd->CommonCfg.DesireRate[2] = 24; /* 12 mbps, in units of 0.5 Mbps */
411 pAd->CommonCfg.DesireRate[3] = 36; /* 18 mbps, in units of 0.5 Mbps */
412 pAd->CommonCfg.DesireRate[4] = 48; /* 24 mbps, in units of 0.5 Mbps */
413 pAd->CommonCfg.DesireRate[5] = 72; /* 36 mbps, in units of 0.5 Mbps */
414 pAd->CommonCfg.DesireRate[6] = 96; /* 48 mbps, in units of 0.5 Mbps */
415 pAd->CommonCfg.DesireRate[7] = 108; /* 54 mbps, in units of 0.5 Mbps */
416 /*pAd->CommonCfg.HTPhyMode.field.MODE = MODE_OFDM; // This MODE is only FYI. not use */
417 break;
418
419 default:
420 break;
421 }
422
423 pAd->CommonCfg.BandState = UNKNOWN_BAND;
424}
425
426/*
427 ========================================================================
428 Routine Description:
429 Caller ensures we has 802.11n support.
430 Calls at setting HT from AP/STASetinformation
431
432 Arguments:
433 pAd - Pointer to our adapter
434 phymode -
435
436 ========================================================================
437*/
438void RTMPSetHT(struct rt_rtmp_adapter *pAd, struct rt_oid_set_ht_phymode *pHTPhyMode)
439{
440 /*unsigned long *pmcs; */
441 u32 Value = 0;
442 u8 BBPValue = 0;
443 u8 BBP3Value = 0;
444 u8 RxStream = pAd->CommonCfg.RxStream;
445
446 DBGPRINT(RT_DEBUG_TRACE,
447 ("RTMPSetHT : HT_mode(%d), ExtOffset(%d), MCS(%d), BW(%d), STBC(%d), SHORTGI(%d)\n",
448 pHTPhyMode->HtMode, pHTPhyMode->ExtOffset, pHTPhyMode->MCS,
449 pHTPhyMode->BW, pHTPhyMode->STBC, pHTPhyMode->SHORTGI));
450
451 /* Don't zero supportedHyPhy structure. */
452 RTMPZeroMemory(&pAd->CommonCfg.HtCapability,
453 sizeof(pAd->CommonCfg.HtCapability));
454 RTMPZeroMemory(&pAd->CommonCfg.AddHTInfo,
455 sizeof(pAd->CommonCfg.AddHTInfo));
456 RTMPZeroMemory(&pAd->CommonCfg.NewExtChanOffset,
457 sizeof(pAd->CommonCfg.NewExtChanOffset));
458 RTMPZeroMemory(&pAd->CommonCfg.DesiredHtPhy,
459 sizeof(pAd->CommonCfg.DesiredHtPhy));
460
461 if (pAd->CommonCfg.bRdg) {
462 pAd->CommonCfg.HtCapability.ExtHtCapInfo.PlusHTC = 1;
463 pAd->CommonCfg.HtCapability.ExtHtCapInfo.RDGSupport = 1;
464 } else {
465 pAd->CommonCfg.HtCapability.ExtHtCapInfo.PlusHTC = 0;
466 pAd->CommonCfg.HtCapability.ExtHtCapInfo.RDGSupport = 0;
467 }
468
469 pAd->CommonCfg.HtCapability.HtCapParm.MaxRAmpduFactor = 3;
470 pAd->CommonCfg.DesiredHtPhy.MaxRAmpduFactor = 3;
471
472 DBGPRINT(RT_DEBUG_TRACE,
473 ("RTMPSetHT : RxBAWinLimit = %d\n",
474 pAd->CommonCfg.BACapability.field.RxBAWinLimit));
475
476 /* Mimo power save, A-MSDU size, */
477 pAd->CommonCfg.DesiredHtPhy.AmsduEnable =
478 (u16)pAd->CommonCfg.BACapability.field.AmsduEnable;
479 pAd->CommonCfg.DesiredHtPhy.AmsduSize =
480 (u8)pAd->CommonCfg.BACapability.field.AmsduSize;
481 pAd->CommonCfg.DesiredHtPhy.MimoPs =
482 (u8)pAd->CommonCfg.BACapability.field.MMPSmode;
483 pAd->CommonCfg.DesiredHtPhy.MpduDensity =
484 (u8)pAd->CommonCfg.BACapability.field.MpduDensity;
485
486 pAd->CommonCfg.HtCapability.HtCapInfo.AMsduSize =
487 (u16)pAd->CommonCfg.BACapability.field.AmsduSize;
488 pAd->CommonCfg.HtCapability.HtCapInfo.MimoPs =
489 (u16)pAd->CommonCfg.BACapability.field.MMPSmode;
490 pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity =
491 (u8)pAd->CommonCfg.BACapability.field.MpduDensity;
492
493 DBGPRINT(RT_DEBUG_TRACE,
494 ("RTMPSetHT : AMsduSize = %d, MimoPs = %d, MpduDensity = %d, MaxRAmpduFactor = %d\n",
495 pAd->CommonCfg.DesiredHtPhy.AmsduSize,
496 pAd->CommonCfg.DesiredHtPhy.MimoPs,
497 pAd->CommonCfg.DesiredHtPhy.MpduDensity,
498 pAd->CommonCfg.DesiredHtPhy.MaxRAmpduFactor));
499
500 if (pHTPhyMode->HtMode == HTMODE_GF) {
501 pAd->CommonCfg.HtCapability.HtCapInfo.GF = 1;
502 pAd->CommonCfg.DesiredHtPhy.GF = 1;
503 } else
504 pAd->CommonCfg.DesiredHtPhy.GF = 0;
505
506 /* Decide Rx MCSSet */
507 switch (RxStream) {
508 case 1:
509 pAd->CommonCfg.HtCapability.MCSSet[0] = 0xff;
510 pAd->CommonCfg.HtCapability.MCSSet[1] = 0x00;
511 break;
512
513 case 2:
514 pAd->CommonCfg.HtCapability.MCSSet[0] = 0xff;
515 pAd->CommonCfg.HtCapability.MCSSet[1] = 0xff;
516 break;
517
518 case 3: /* 3*3 */
519 pAd->CommonCfg.HtCapability.MCSSet[0] = 0xff;
520 pAd->CommonCfg.HtCapability.MCSSet[1] = 0xff;
521 pAd->CommonCfg.HtCapability.MCSSet[2] = 0xff;
522 break;
523 }
524
525 if (pAd->CommonCfg.bForty_Mhz_Intolerant
526 && (pAd->CommonCfg.Channel <= 14) && (pHTPhyMode->BW == BW_40)) {
527 pHTPhyMode->BW = BW_20;
528 pAd->CommonCfg.HtCapability.HtCapInfo.Forty_Mhz_Intolerant = 1;
529 }
530
531 if (pHTPhyMode->BW == BW_40) {
532 pAd->CommonCfg.HtCapability.MCSSet[4] = 0x1; /* MCS 32 */
533 pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth = 1;
534 if (pAd->CommonCfg.Channel <= 14)
535 pAd->CommonCfg.HtCapability.HtCapInfo.CCKmodein40 = 1;
536
537 pAd->CommonCfg.DesiredHtPhy.ChannelWidth = 1;
538 pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth = 1;
539 pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset =
540 (pHTPhyMode->ExtOffset ==
541 EXTCHA_BELOW) ? (EXTCHA_BELOW) : EXTCHA_ABOVE;
542 /* Set Regsiter for extension channel position. */
543 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
544 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBP3Value);
545 if ((pHTPhyMode->ExtOffset == EXTCHA_BELOW)) {
546 Value |= 0x1;
547 BBP3Value |= (0x20);
548 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
549 } else if ((pHTPhyMode->ExtOffset == EXTCHA_ABOVE)) {
550 Value &= 0xfe;
551 BBP3Value &= (~0x20);
552 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
553 }
554 /* Turn on BBP 40MHz mode now only as AP . */
555 /* Sta can turn on BBP 40MHz after connection with 40MHz AP. Sta only broadcast 40MHz capability before connection. */
556 if ((pAd->OpMode == OPMODE_AP) || INFRA_ON(pAd) || ADHOC_ON(pAd)
557 ) {
558 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
559 BBPValue &= (~0x18);
560 BBPValue |= 0x10;
561 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
562
563 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBP3Value);
564 pAd->CommonCfg.BBPCurrentBW = BW_40;
565 }
566 } else {
567 pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth = 0;
568 pAd->CommonCfg.DesiredHtPhy.ChannelWidth = 0;
569 pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth = 0;
570 pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset = EXTCHA_NONE;
571 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
572 /* Turn on BBP 20MHz mode by request here. */
573 {
574 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
575 BBPValue &= (~0x18);
576 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
577 pAd->CommonCfg.BBPCurrentBW = BW_20;
578 }
579 }
580
581 if (pHTPhyMode->STBC == STBC_USE) {
582 pAd->CommonCfg.HtCapability.HtCapInfo.TxSTBC = 1;
583 pAd->CommonCfg.DesiredHtPhy.TxSTBC = 1;
584 pAd->CommonCfg.HtCapability.HtCapInfo.RxSTBC = 1;
585 pAd->CommonCfg.DesiredHtPhy.RxSTBC = 1;
586 } else {
587 pAd->CommonCfg.DesiredHtPhy.TxSTBC = 0;
588 pAd->CommonCfg.DesiredHtPhy.RxSTBC = 0;
589 }
590
591 if (pHTPhyMode->SHORTGI == GI_400) {
592 pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor20 = 1;
593 pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor40 = 1;
594 pAd->CommonCfg.DesiredHtPhy.ShortGIfor20 = 1;
595 pAd->CommonCfg.DesiredHtPhy.ShortGIfor40 = 1;
596 } else {
597 pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor20 = 0;
598 pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor40 = 0;
599 pAd->CommonCfg.DesiredHtPhy.ShortGIfor20 = 0;
600 pAd->CommonCfg.DesiredHtPhy.ShortGIfor40 = 0;
601 }
602
603 /* We support link adaptation for unsolicit MCS feedback, set to 2. */
604 pAd->CommonCfg.HtCapability.ExtHtCapInfo.MCSFeedback = MCSFBK_NONE; /*MCSFBK_UNSOLICIT; */
605 pAd->CommonCfg.AddHTInfo.ControlChan = pAd->CommonCfg.Channel;
606 /* 1, the extension channel above the control channel. */
607
608 /* EDCA parameters used for AP's own transmission */
609 if (pAd->CommonCfg.APEdcaParm.bValid == FALSE) {
610 pAd->CommonCfg.APEdcaParm.bValid = TRUE;
611 pAd->CommonCfg.APEdcaParm.Aifsn[0] = 3;
612 pAd->CommonCfg.APEdcaParm.Aifsn[1] = 7;
613 pAd->CommonCfg.APEdcaParm.Aifsn[2] = 1;
614 pAd->CommonCfg.APEdcaParm.Aifsn[3] = 1;
615
616 pAd->CommonCfg.APEdcaParm.Cwmin[0] = 4;
617 pAd->CommonCfg.APEdcaParm.Cwmin[1] = 4;
618 pAd->CommonCfg.APEdcaParm.Cwmin[2] = 3;
619 pAd->CommonCfg.APEdcaParm.Cwmin[3] = 2;
620
621 pAd->CommonCfg.APEdcaParm.Cwmax[0] = 6;
622 pAd->CommonCfg.APEdcaParm.Cwmax[1] = 10;
623 pAd->CommonCfg.APEdcaParm.Cwmax[2] = 4;
624 pAd->CommonCfg.APEdcaParm.Cwmax[3] = 3;
625
626 pAd->CommonCfg.APEdcaParm.Txop[0] = 0;
627 pAd->CommonCfg.APEdcaParm.Txop[1] = 0;
628 pAd->CommonCfg.APEdcaParm.Txop[2] = 94;
629 pAd->CommonCfg.APEdcaParm.Txop[3] = 47;
630 }
631 AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
632
633 {
634 RTMPSetIndividualHT(pAd, 0);
635 }
636
637}
638
639/*
640 ========================================================================
641 Routine Description:
642 Caller ensures we has 802.11n support.
643 Calls at setting HT from AP/STASetinformation
644
645 Arguments:
646 pAd - Pointer to our adapter
647 phymode -
648
649 ========================================================================
650*/
651void RTMPSetIndividualHT(struct rt_rtmp_adapter *pAd, u8 apidx)
652{
653 struct rt_ht_phy_info *pDesired_ht_phy = NULL;
654 u8 TxStream = pAd->CommonCfg.TxStream;
655 u8 DesiredMcs = MCS_AUTO;
656
657 do {
658 {
659 pDesired_ht_phy = &pAd->StaCfg.DesiredHtPhyInfo;
660 DesiredMcs =
661 pAd->StaCfg.DesiredTransmitSetting.field.MCS;
662 /*pAd->StaCfg.bAutoTxRateSwitch = (DesiredMcs == MCS_AUTO) ? TRUE : FALSE; */
663 break;
664 }
665 } while (FALSE);
666
667 if (pDesired_ht_phy == NULL) {
668 DBGPRINT(RT_DEBUG_ERROR,
669 ("RTMPSetIndividualHT: invalid apidx(%d)\n", apidx));
670 return;
671 }
672 RTMPZeroMemory(pDesired_ht_phy, sizeof(struct rt_ht_phy_info));
673
674 DBGPRINT(RT_DEBUG_TRACE,
675 ("RTMPSetIndividualHT : Desired MCS = %d\n", DesiredMcs));
676 /* Check the validity of MCS */
677 if ((TxStream == 1)
678 && ((DesiredMcs >= MCS_8) && (DesiredMcs <= MCS_15))) {
679 DBGPRINT(RT_DEBUG_WARN,
680 ("RTMPSetIndividualHT: MCS(%d) is invalid in 1S, reset it as MCS_7\n",
681 DesiredMcs));
682 DesiredMcs = MCS_7;
683 }
684
685 if ((pAd->CommonCfg.DesiredHtPhy.ChannelWidth == BW_20)
686 && (DesiredMcs == MCS_32)) {
687 DBGPRINT(RT_DEBUG_WARN,
688 ("RTMPSetIndividualHT: MCS_32 is only supported in 40-MHz, reset it as MCS_0\n"));
689 DesiredMcs = MCS_0;
690 }
691
692 pDesired_ht_phy->bHtEnable = TRUE;
693
694 /* Decide desired Tx MCS */
695 switch (TxStream) {
696 case 1:
697 if (DesiredMcs == MCS_AUTO) {
698 pDesired_ht_phy->MCSSet[0] = 0xff;
699 pDesired_ht_phy->MCSSet[1] = 0x00;
700 } else if (DesiredMcs <= MCS_7) {
701 pDesired_ht_phy->MCSSet[0] = 1 << DesiredMcs;
702 pDesired_ht_phy->MCSSet[1] = 0x00;
703 }
704 break;
705
706 case 2:
707 if (DesiredMcs == MCS_AUTO) {
708 pDesired_ht_phy->MCSSet[0] = 0xff;
709 pDesired_ht_phy->MCSSet[1] = 0xff;
710 } else if (DesiredMcs <= MCS_15) {
711 unsigned long mode;
712
713 mode = DesiredMcs / 8;
714 if (mode < 2)
715 pDesired_ht_phy->MCSSet[mode] =
716 (1 << (DesiredMcs - mode * 8));
717 }
718 break;
719
720 case 3: /* 3*3 */
721 if (DesiredMcs == MCS_AUTO) {
722 /* MCS0 ~ MCS23, 3 bytes */
723 pDesired_ht_phy->MCSSet[0] = 0xff;
724 pDesired_ht_phy->MCSSet[1] = 0xff;
725 pDesired_ht_phy->MCSSet[2] = 0xff;
726 } else if (DesiredMcs <= MCS_23) {
727 unsigned long mode;
728
729 mode = DesiredMcs / 8;
730 if (mode < 3)
731 pDesired_ht_phy->MCSSet[mode] =
732 (1 << (DesiredMcs - mode * 8));
733 }
734 break;
735 }
736
737 if (pAd->CommonCfg.DesiredHtPhy.ChannelWidth == BW_40) {
738 if (DesiredMcs == MCS_AUTO || DesiredMcs == MCS_32)
739 pDesired_ht_phy->MCSSet[4] = 0x1;
740 }
741 /* update HT Rate setting */
742 if (pAd->OpMode == OPMODE_STA)
743 MlmeUpdateHtTxRates(pAd, BSS0);
744 else
745 MlmeUpdateHtTxRates(pAd, apidx);
746}
747
748/*
749 ========================================================================
750 Routine Description:
751 Update HT IE from our capability.
752
753 Arguments:
754 Send all HT IE in beacon/probe rsp/assoc rsp/action frame.
755
756 ========================================================================
757*/
758void RTMPUpdateHTIE(struct rt_ht_capability *pRtHt,
759 u8 * pMcsSet,
760 struct rt_ht_capability_ie * pHtCapability,
761 struct rt_add_ht_info_ie * pAddHtInfo)
762{
763 RTMPZeroMemory(pHtCapability, sizeof(struct rt_ht_capability_ie));
764 RTMPZeroMemory(pAddHtInfo, sizeof(struct rt_add_ht_info_ie));
765
766 pHtCapability->HtCapInfo.ChannelWidth = pRtHt->ChannelWidth;
767 pHtCapability->HtCapInfo.MimoPs = pRtHt->MimoPs;
768 pHtCapability->HtCapInfo.GF = pRtHt->GF;
769 pHtCapability->HtCapInfo.ShortGIfor20 = pRtHt->ShortGIfor20;
770 pHtCapability->HtCapInfo.ShortGIfor40 = pRtHt->ShortGIfor40;
771 pHtCapability->HtCapInfo.TxSTBC = pRtHt->TxSTBC;
772 pHtCapability->HtCapInfo.RxSTBC = pRtHt->RxSTBC;
773 pHtCapability->HtCapInfo.AMsduSize = pRtHt->AmsduSize;
774 pHtCapability->HtCapParm.MaxRAmpduFactor = pRtHt->MaxRAmpduFactor;
775 pHtCapability->HtCapParm.MpduDensity = pRtHt->MpduDensity;
776
777 pAddHtInfo->AddHtInfo.ExtChanOffset = pRtHt->ExtChanOffset;
778 pAddHtInfo->AddHtInfo.RecomWidth = pRtHt->RecomWidth;
779 pAddHtInfo->AddHtInfo2.OperaionMode = pRtHt->OperaionMode;
780 pAddHtInfo->AddHtInfo2.NonGfPresent = pRtHt->NonGfPresent;
781 RTMPMoveMemory(pAddHtInfo->MCSSet, /*pRtHt->MCSSet */ pMcsSet, 4); /* rt2860 only support MCS max=32, no need to copy all 16 uchar. */
782
783 DBGPRINT(RT_DEBUG_TRACE, ("RTMPUpdateHTIE <== \n"));
784}
785
786/*
787 ========================================================================
788 Description:
789 Add Client security information into ASIC WCID table and IVEIV table.
790 Return:
791 ========================================================================
792*/
793void RTMPAddWcidAttributeEntry(struct rt_rtmp_adapter *pAd,
794 u8 BssIdx,
795 u8 KeyIdx,
796 u8 CipherAlg, struct rt_mac_table_entry *pEntry)
797{
798 u32 WCIDAttri = 0;
799 u16 offset;
800 u8 IVEIV = 0;
801 u16 Wcid = 0;
802
803 {
804 {
805 if (BssIdx > BSS0) {
806 DBGPRINT(RT_DEBUG_ERROR,
807 ("RTMPAddWcidAttributeEntry: The BSS-index(%d) is out of range for Infra link. \n",
808 BssIdx));
809 return;
810 }
811 /* 1. In ADHOC mode, the AID is wcid number. And NO mesh link exists. */
812 /* 2. In Infra mode, the AID:1 MUST be wcid of infra STA. */
813 /* the AID:2~ assign to mesh link entry. */
814 if (pEntry)
815 Wcid = pEntry->Aid;
816 else
817 Wcid = MCAST_WCID;
818 }
819 }
820
821 /* Update WCID attribute table */
822 offset = MAC_WCID_ATTRIBUTE_BASE + (Wcid * HW_WCID_ATTRI_SIZE);
823
824 {
825 if (pEntry && pEntry->ValidAsMesh)
826 WCIDAttri = (CipherAlg << 1) | PAIRWISEKEYTABLE;
827 else
828 WCIDAttri = (CipherAlg << 1) | SHAREDKEYTABLE;
829 }
830
831 RTMP_IO_WRITE32(pAd, offset, WCIDAttri);
832
833 /* Update IV/EIV table */
834 offset = MAC_IVEIV_TABLE_BASE + (Wcid * HW_IVEIV_ENTRY_SIZE);
835
836 /* WPA mode */
837 if ((CipherAlg == CIPHER_TKIP) || (CipherAlg == CIPHER_TKIP_NO_MIC)
838 || (CipherAlg == CIPHER_AES)) {
839 /* Eiv bit on. keyid always is 0 for pairwise key */
840 IVEIV = (KeyIdx << 6) | 0x20;
841 } else {
842 /* WEP KeyIdx is default tx key. */
843 IVEIV = (KeyIdx << 6);
844 }
845
846 /* For key index and ext IV bit, so only need to update the position(offset+3). */
847#ifdef RTMP_MAC_PCI
848 RTMP_IO_WRITE8(pAd, offset + 3, IVEIV);
849#endif /* RTMP_MAC_PCI // */
850#ifdef RTMP_MAC_USB
851 RTUSBMultiWrite_OneByte(pAd, offset + 3, &IVEIV);
852#endif /* RTMP_MAC_USB // */
853
854 DBGPRINT(RT_DEBUG_TRACE,
855 ("RTMPAddWcidAttributeEntry: WCID #%d, KeyIndex #%d, Alg=%s\n",
856 Wcid, KeyIdx, CipherName[CipherAlg]));
857 DBGPRINT(RT_DEBUG_TRACE, (" WCIDAttri = 0x%x \n", WCIDAttri));
858
859}
860
861/*
862 ==========================================================================
863 Description:
864 Parse encryption type
865Arguments:
866 pAdapter Pointer to our adapter
867 wrq Pointer to the ioctl argument
868
869 Return Value:
870 None
871
872 Note:
873 ==========================================================================
874*/
875char *GetEncryptType(char enc)
876{
877 if (enc == Ndis802_11WEPDisabled)
878 return "NONE";
879 if (enc == Ndis802_11WEPEnabled)
880 return "WEP";
881 if (enc == Ndis802_11Encryption2Enabled)
882 return "TKIP";
883 if (enc == Ndis802_11Encryption3Enabled)
884 return "AES";
885 if (enc == Ndis802_11Encryption4Enabled)
886 return "TKIPAES";
887 else
888 return "UNKNOW";
889}
890
891char *GetAuthMode(char auth)
892{
893 if (auth == Ndis802_11AuthModeOpen)
894 return "OPEN";
895 if (auth == Ndis802_11AuthModeShared)
896 return "SHARED";
897 if (auth == Ndis802_11AuthModeAutoSwitch)
898 return "AUTOWEP";
899 if (auth == Ndis802_11AuthModeWPA)
900 return "WPA";
901 if (auth == Ndis802_11AuthModeWPAPSK)
902 return "WPAPSK";
903 if (auth == Ndis802_11AuthModeWPANone)
904 return "WPANONE";
905 if (auth == Ndis802_11AuthModeWPA2)
906 return "WPA2";
907 if (auth == Ndis802_11AuthModeWPA2PSK)
908 return "WPA2PSK";
909 if (auth == Ndis802_11AuthModeWPA1WPA2)
910 return "WPA1WPA2";
911 if (auth == Ndis802_11AuthModeWPA1PSKWPA2PSK)
912 return "WPA1PSKWPA2PSK";
913
914 return "UNKNOW";
915}
916
917int SetCommonHT(struct rt_rtmp_adapter *pAd)
918{
919 struct rt_oid_set_ht_phymode SetHT;
920
921 if (pAd->CommonCfg.PhyMode < PHY_11ABGN_MIXED)
922 return FALSE;
923
924 SetHT.PhyMode = pAd->CommonCfg.PhyMode;
925 SetHT.TransmitNo = ((u8)pAd->Antenna.field.TxPath);
926 SetHT.HtMode = (u8)pAd->CommonCfg.RegTransmitSetting.field.HTMODE;
927 SetHT.ExtOffset =
928 (u8)pAd->CommonCfg.RegTransmitSetting.field.EXTCHA;
929 SetHT.MCS = MCS_AUTO;
930 SetHT.BW = (u8)pAd->CommonCfg.RegTransmitSetting.field.BW;
931 SetHT.STBC = (u8)pAd->CommonCfg.RegTransmitSetting.field.STBC;
932 SetHT.SHORTGI = (u8)pAd->CommonCfg.RegTransmitSetting.field.ShortGI;
933
934 RTMPSetHT(pAd, &SetHT);
935
936 return TRUE;
937}
938
939char *RTMPGetRalinkEncryModeStr(u16 encryMode)
940{
941 switch (encryMode) {
942 case Ndis802_11WEPDisabled:
943 return "NONE";
944 case Ndis802_11WEPEnabled:
945 return "WEP";
946 case Ndis802_11Encryption2Enabled:
947 return "TKIP";
948 case Ndis802_11Encryption3Enabled:
949 return "AES";
950 case Ndis802_11Encryption4Enabled:
951 return "TKIPAES";
952 default:
953 return "UNKNOW";
954 }
955}
diff --git a/drivers/staging/rt2860/common/cmm_mac_pci.c b/drivers/staging/rt2860/common/cmm_mac_pci.c
deleted file mode 100644
index d06f0a6dc37..00000000000
--- a/drivers/staging/rt2860/common/cmm_mac_pci.c
+++ /dev/null
@@ -1,1661 +0,0 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26*/
27
28#ifdef RTMP_MAC_PCI
29#include "../rt_config.h"
30
31/*
32 ========================================================================
33
34 Routine Description:
35 Allocate DMA memory blocks for send, receive
36
37 Arguments:
38 Adapter Pointer to our adapter
39
40 Return Value:
41 NDIS_STATUS_SUCCESS
42 NDIS_STATUS_FAILURE
43 NDIS_STATUS_RESOURCES
44
45 IRQL = PASSIVE_LEVEL
46
47 Note:
48
49 ========================================================================
50*/
51int RTMPAllocTxRxRingMemory(struct rt_rtmp_adapter *pAd)
52{
53 int Status = NDIS_STATUS_SUCCESS;
54 unsigned long RingBasePaHigh;
55 unsigned long RingBasePaLow;
56 void *RingBaseVa;
57 int index, num;
58 struct rt_txd * pTxD;
59 struct rt_rxd * pRxD;
60 unsigned long ErrorValue = 0;
61 struct rt_rtmp_tx_ring *pTxRing;
62 struct rt_rtmp_dmabuf *pDmaBuf;
63 void *pPacket;
64/* PRTMP_REORDERBUF pReorderBuf; */
65
66 DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocTxRxRingMemory\n"));
67 do {
68 /* */
69 /* Allocate all ring descriptors, include TxD, RxD, MgmtD. */
70 /* Although each size is different, to prevent cacheline and alignment */
71 /* issue, I intentional set them all to 64 bytes. */
72 /* */
73 for (num = 0; num < NUM_OF_TX_RING; num++) {
74 unsigned long BufBasePaHigh;
75 unsigned long BufBasePaLow;
76 void *BufBaseVa;
77
78 /* */
79 /* Allocate Tx ring descriptor's memory (5 TX rings = 4 ACs + 1 HCCA) */
80 /* */
81 pAd->TxDescRing[num].AllocSize =
82 TX_RING_SIZE * TXD_SIZE;
83 RTMP_AllocateTxDescMemory(pAd, num,
84 pAd->TxDescRing[num].
85 AllocSize, FALSE,
86 &pAd->TxDescRing[num].AllocVa,
87 &pAd->TxDescRing[num].
88 AllocPa);
89
90 if (pAd->TxDescRing[num].AllocVa == NULL) {
91 ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
92 DBGPRINT_ERR("Failed to allocate a big buffer\n");
93 Status = NDIS_STATUS_RESOURCES;
94 break;
95 }
96 /* Zero init this memory block */
97 NdisZeroMemory(pAd->TxDescRing[num].AllocVa,
98 pAd->TxDescRing[num].AllocSize);
99
100 /* Save PA & VA for further operation */
101 RingBasePaHigh =
102 RTMP_GetPhysicalAddressHigh(pAd->TxDescRing[num].
103 AllocPa);
104 RingBasePaLow =
105 RTMP_GetPhysicalAddressLow(pAd->TxDescRing[num].
106 AllocPa);
107 RingBaseVa = pAd->TxDescRing[num].AllocVa;
108
109 /* */
110 /* Allocate all 1st TXBuf's memory for this TxRing */
111 /* */
112 pAd->TxBufSpace[num].AllocSize =
113 TX_RING_SIZE * TX_DMA_1ST_BUFFER_SIZE;
114 RTMP_AllocateFirstTxBuffer(pAd, num,
115 pAd->TxBufSpace[num].
116 AllocSize, FALSE,
117 &pAd->TxBufSpace[num].
118 AllocVa,
119 &pAd->TxBufSpace[num].
120 AllocPa);
121
122 if (pAd->TxBufSpace[num].AllocVa == NULL) {
123 ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
124 DBGPRINT_ERR("Failed to allocate a big buffer\n");
125 Status = NDIS_STATUS_RESOURCES;
126 break;
127 }
128 /* Zero init this memory block */
129 NdisZeroMemory(pAd->TxBufSpace[num].AllocVa,
130 pAd->TxBufSpace[num].AllocSize);
131
132 /* Save PA & VA for further operation */
133 BufBasePaHigh =
134 RTMP_GetPhysicalAddressHigh(pAd->TxBufSpace[num].
135 AllocPa);
136 BufBasePaLow =
137 RTMP_GetPhysicalAddressLow(pAd->TxBufSpace[num].
138 AllocPa);
139 BufBaseVa = pAd->TxBufSpace[num].AllocVa;
140
141 /* */
142 /* Initialize Tx Ring Descriptor and associated buffer memory */
143 /* */
144 pTxRing = &pAd->TxRing[num];
145 for (index = 0; index < TX_RING_SIZE; index++) {
146 pTxRing->Cell[index].pNdisPacket = NULL;
147 pTxRing->Cell[index].pNextNdisPacket = NULL;
148 /* Init Tx Ring Size, Va, Pa variables */
149 pTxRing->Cell[index].AllocSize = TXD_SIZE;
150 pTxRing->Cell[index].AllocVa = RingBaseVa;
151 RTMP_SetPhysicalAddressHigh(pTxRing->
152 Cell[index].AllocPa,
153 RingBasePaHigh);
154 RTMP_SetPhysicalAddressLow(pTxRing->Cell[index].
155 AllocPa,
156 RingBasePaLow);
157
158 /* Setup Tx Buffer size & address. only 802.11 header will store in this space */
159 pDmaBuf = &pTxRing->Cell[index].DmaBuf;
160 pDmaBuf->AllocSize = TX_DMA_1ST_BUFFER_SIZE;
161 pDmaBuf->AllocVa = BufBaseVa;
162 RTMP_SetPhysicalAddressHigh(pDmaBuf->AllocPa,
163 BufBasePaHigh);
164 RTMP_SetPhysicalAddressLow(pDmaBuf->AllocPa,
165 BufBasePaLow);
166
167 /* link the pre-allocated TxBuf to TXD */
168 pTxD =
169 (struct rt_txd *) pTxRing->Cell[index].AllocVa;
170 pTxD->SDPtr0 = BufBasePaLow;
171 /* advance to next ring descriptor address */
172 pTxD->DMADONE = 1;
173 RingBasePaLow += TXD_SIZE;
174 RingBaseVa = (u8 *)RingBaseVa + TXD_SIZE;
175
176 /* advance to next TxBuf address */
177 BufBasePaLow += TX_DMA_1ST_BUFFER_SIZE;
178 BufBaseVa =
179 (u8 *)BufBaseVa + TX_DMA_1ST_BUFFER_SIZE;
180 }
181 DBGPRINT(RT_DEBUG_TRACE,
182 ("TxRing[%d]: total %d entry allocated\n", num,
183 index));
184 }
185 if (Status == NDIS_STATUS_RESOURCES)
186 break;
187
188 /* */
189 /* Allocate MGMT ring descriptor's memory except Tx ring which allocated eariler */
190 /* */
191 pAd->MgmtDescRing.AllocSize = MGMT_RING_SIZE * TXD_SIZE;
192 RTMP_AllocateMgmtDescMemory(pAd,
193 pAd->MgmtDescRing.AllocSize,
194 FALSE,
195 &pAd->MgmtDescRing.AllocVa,
196 &pAd->MgmtDescRing.AllocPa);
197
198 if (pAd->MgmtDescRing.AllocVa == NULL) {
199 ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
200 DBGPRINT_ERR("Failed to allocate a big buffer\n");
201 Status = NDIS_STATUS_RESOURCES;
202 break;
203 }
204 /* Zero init this memory block */
205 NdisZeroMemory(pAd->MgmtDescRing.AllocVa,
206 pAd->MgmtDescRing.AllocSize);
207
208 /* Save PA & VA for further operation */
209 RingBasePaHigh =
210 RTMP_GetPhysicalAddressHigh(pAd->MgmtDescRing.AllocPa);
211 RingBasePaLow =
212 RTMP_GetPhysicalAddressLow(pAd->MgmtDescRing.AllocPa);
213 RingBaseVa = pAd->MgmtDescRing.AllocVa;
214
215 /* */
216 /* Initialize MGMT Ring and associated buffer memory */
217 /* */
218 for (index = 0; index < MGMT_RING_SIZE; index++) {
219 pAd->MgmtRing.Cell[index].pNdisPacket = NULL;
220 pAd->MgmtRing.Cell[index].pNextNdisPacket = NULL;
221 /* Init MGMT Ring Size, Va, Pa variables */
222 pAd->MgmtRing.Cell[index].AllocSize = TXD_SIZE;
223 pAd->MgmtRing.Cell[index].AllocVa = RingBaseVa;
224 RTMP_SetPhysicalAddressHigh(pAd->MgmtRing.Cell[index].
225 AllocPa, RingBasePaHigh);
226 RTMP_SetPhysicalAddressLow(pAd->MgmtRing.Cell[index].
227 AllocPa, RingBasePaLow);
228
229 /* Offset to next ring descriptor address */
230 RingBasePaLow += TXD_SIZE;
231 RingBaseVa = (u8 *)RingBaseVa + TXD_SIZE;
232
233 /* link the pre-allocated TxBuf to TXD */
234 pTxD = (struct rt_txd *) pAd->MgmtRing.Cell[index].AllocVa;
235 pTxD->DMADONE = 1;
236
237 /* no pre-allocated buffer required in MgmtRing for scatter-gather case */
238 }
239 DBGPRINT(RT_DEBUG_TRACE,
240 ("MGMT Ring: total %d entry allocated\n", index));
241
242 /* */
243 /* Allocate RX ring descriptor's memory except Tx ring which allocated eariler */
244 /* */
245 pAd->RxDescRing.AllocSize = RX_RING_SIZE * RXD_SIZE;
246 RTMP_AllocateRxDescMemory(pAd,
247 pAd->RxDescRing.AllocSize,
248 FALSE,
249 &pAd->RxDescRing.AllocVa,
250 &pAd->RxDescRing.AllocPa);
251
252 if (pAd->RxDescRing.AllocVa == NULL) {
253 ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
254 DBGPRINT_ERR("Failed to allocate a big buffer\n");
255 Status = NDIS_STATUS_RESOURCES;
256 break;
257 }
258 /* Zero init this memory block */
259 NdisZeroMemory(pAd->RxDescRing.AllocVa,
260 pAd->RxDescRing.AllocSize);
261
262 DBGPRINT(RT_DEBUG_OFF,
263 ("RX DESC %p size = %ld\n", pAd->RxDescRing.AllocVa,
264 pAd->RxDescRing.AllocSize));
265
266 /* Save PA & VA for further operation */
267 RingBasePaHigh =
268 RTMP_GetPhysicalAddressHigh(pAd->RxDescRing.AllocPa);
269 RingBasePaLow =
270 RTMP_GetPhysicalAddressLow(pAd->RxDescRing.AllocPa);
271 RingBaseVa = pAd->RxDescRing.AllocVa;
272
273 /* */
274 /* Initialize Rx Ring and associated buffer memory */
275 /* */
276 for (index = 0; index < RX_RING_SIZE; index++) {
277 /* Init RX Ring Size, Va, Pa variables */
278 pAd->RxRing.Cell[index].AllocSize = RXD_SIZE;
279 pAd->RxRing.Cell[index].AllocVa = RingBaseVa;
280 RTMP_SetPhysicalAddressHigh(pAd->RxRing.Cell[index].
281 AllocPa, RingBasePaHigh);
282 RTMP_SetPhysicalAddressLow(pAd->RxRing.Cell[index].
283 AllocPa, RingBasePaLow);
284
285 /*NdisZeroMemory(RingBaseVa, RXD_SIZE); */
286
287 /* Offset to next ring descriptor address */
288 RingBasePaLow += RXD_SIZE;
289 RingBaseVa = (u8 *)RingBaseVa + RXD_SIZE;
290
291 /* Setup Rx associated Buffer size & allocate share memory */
292 pDmaBuf = &pAd->RxRing.Cell[index].DmaBuf;
293 pDmaBuf->AllocSize = RX_BUFFER_AGGRESIZE;
294 pPacket = RTMP_AllocateRxPacketBuffer(pAd,
295 pDmaBuf->
296 AllocSize, FALSE,
297 &pDmaBuf->AllocVa,
298 &pDmaBuf->
299 AllocPa);
300
301 /* keep allocated rx packet */
302 pAd->RxRing.Cell[index].pNdisPacket = pPacket;
303
304 /* Error handling */
305 if (pDmaBuf->AllocVa == NULL) {
306 ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
307 DBGPRINT_ERR("Failed to allocate RxRing's 1st buffer\n");
308 Status = NDIS_STATUS_RESOURCES;
309 break;
310 }
311 /* Zero init this memory block */
312 NdisZeroMemory(pDmaBuf->AllocVa, pDmaBuf->AllocSize);
313
314 /* Write RxD buffer address & allocated buffer length */
315 pRxD = (struct rt_rxd *) pAd->RxRing.Cell[index].AllocVa;
316 pRxD->SDP0 =
317 RTMP_GetPhysicalAddressLow(pDmaBuf->AllocPa);
318 pRxD->DDONE = 0;
319
320 }
321
322 DBGPRINT(RT_DEBUG_TRACE,
323 ("Rx Ring: total %d entry allocated\n", index));
324
325 } while (FALSE);
326
327 NdisZeroMemory(&pAd->FragFrame, sizeof(struct rt_fragment_frame));
328 pAd->FragFrame.pFragPacket =
329 RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE);
330
331 if (pAd->FragFrame.pFragPacket == NULL) {
332 Status = NDIS_STATUS_RESOURCES;
333 }
334
335 if (Status != NDIS_STATUS_SUCCESS) {
336 /* Log error inforamtion */
337 NdisWriteErrorLogEntry(pAd->AdapterHandle,
338 NDIS_ERROR_CODE_OUT_OF_RESOURCES,
339 1, ErrorValue);
340 }
341 /* Following code segment get from original func:NICInitTxRxRingAndBacklogQueue(), now should integrate it to here. */
342 {
343 DBGPRINT(RT_DEBUG_TRACE,
344 ("--> NICInitTxRxRingAndBacklogQueue\n"));
345
346/*
347 // Disable DMA.
348 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
349 GloCfg.word &= 0xff0;
350 GloCfg.field.EnTXWriteBackDDONE =1;
351 RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
352*/
353
354 /* Initialize all transmit related software queues */
355 for (index = 0; index < NUM_OF_TX_RING; index++) {
356 InitializeQueueHeader(&pAd->TxSwQueue[index]);
357 /* Init TX rings index pointer */
358 pAd->TxRing[index].TxSwFreeIdx = 0;
359 pAd->TxRing[index].TxCpuIdx = 0;
360 /*RTMP_IO_WRITE32(pAd, (TX_CTX_IDX0 + i * 0x10) , pAd->TxRing[i].TX_CTX_IDX); */
361 }
362
363 /* Init RX Ring index pointer */
364 pAd->RxRing.RxSwReadIdx = 0;
365 pAd->RxRing.RxCpuIdx = RX_RING_SIZE - 1;
366 /*RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RX_CRX_IDX0); */
367
368 /* init MGMT ring index pointer */
369 pAd->MgmtRing.TxSwFreeIdx = 0;
370 pAd->MgmtRing.TxCpuIdx = 0;
371
372 pAd->PrivateInfo.TxRingFullCnt = 0;
373
374 DBGPRINT(RT_DEBUG_TRACE,
375 ("<-- NICInitTxRxRingAndBacklogQueue\n"));
376 }
377
378 DBGPRINT_S(Status,
379 ("<-- RTMPAllocTxRxRingMemory, Status=%x\n", Status));
380 return Status;
381}
382
383/*
384 ========================================================================
385
386 Routine Description:
387 Reset NIC Asics. Call after rest DMA. So reset TX_CTX_IDX to zero.
388
389 Arguments:
390 Adapter Pointer to our adapter
391
392 Return Value:
393 None
394
395 IRQL = PASSIVE_LEVEL
396 IRQL = DISPATCH_LEVEL
397
398 Note:
399 Reset NIC to initial state AS IS system boot up time.
400
401 ========================================================================
402*/
403void RTMPRingCleanUp(struct rt_rtmp_adapter *pAd, u8 RingType)
404{
405 struct rt_txd * pTxD;
406 struct rt_rxd * pRxD;
407 struct rt_queue_entry *pEntry;
408 void *pPacket;
409 int i;
410 struct rt_rtmp_tx_ring *pTxRing;
411 unsigned long IrqFlags;
412 /*u32 RxSwReadIdx; */
413
414 DBGPRINT(RT_DEBUG_TRACE,
415 ("RTMPRingCleanUp(RingIdx=%d, Pending-NDIS=%ld)\n", RingType,
416 pAd->RalinkCounters.PendingNdisPacketCount));
417 switch (RingType) {
418 case QID_AC_BK:
419 case QID_AC_BE:
420 case QID_AC_VI:
421 case QID_AC_VO:
422
423 pTxRing = &pAd->TxRing[RingType];
424
425 RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
426 /* We have to clean all descriptors in case some error happened with reset */
427 for (i = 0; i < TX_RING_SIZE; i++) /* We have to scan all TX ring */
428 {
429 pTxD = (struct rt_txd *) pTxRing->Cell[i].AllocVa;
430
431 pPacket = (void *)pTxRing->Cell[i].pNdisPacket;
432 /* release scatter-and-gather char */
433 if (pPacket) {
434 RELEASE_NDIS_PACKET(pAd, pPacket,
435 NDIS_STATUS_FAILURE);
436 pTxRing->Cell[i].pNdisPacket = NULL;
437 }
438
439 pPacket =
440 (void *)pTxRing->Cell[i].pNextNdisPacket;
441 /* release scatter-and-gather char */
442 if (pPacket) {
443 RELEASE_NDIS_PACKET(pAd, pPacket,
444 NDIS_STATUS_FAILURE);
445 pTxRing->Cell[i].pNextNdisPacket = NULL;
446 }
447 }
448
449 RTMP_IO_READ32(pAd, TX_DTX_IDX0 + RingType * 0x10,
450 &pTxRing->TxDmaIdx);
451 pTxRing->TxSwFreeIdx = pTxRing->TxDmaIdx;
452 pTxRing->TxCpuIdx = pTxRing->TxDmaIdx;
453 RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + RingType * 0x10,
454 pTxRing->TxCpuIdx);
455
456 RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
457
458 RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
459 while (pAd->TxSwQueue[RingType].Head != NULL) {
460 pEntry = RemoveHeadQueue(&pAd->TxSwQueue[RingType]);
461 pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
462 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
463 DBGPRINT(RT_DEBUG_TRACE,
464 ("Release 1 NDIS packet from s/w backlog queue\n"));
465 }
466 RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
467 break;
468
469 case QID_MGMT:
470 /* We have to clean all descriptors in case some error happened with reset */
471 NdisAcquireSpinLock(&pAd->MgmtRingLock);
472
473 for (i = 0; i < MGMT_RING_SIZE; i++) {
474 pTxD = (struct rt_txd *) pAd->MgmtRing.Cell[i].AllocVa;
475
476 pPacket =
477 (void *)pAd->MgmtRing.Cell[i].pNdisPacket;
478 /* rlease scatter-and-gather char */
479 if (pPacket) {
480 PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0,
481 pTxD->SDLen0,
482 PCI_DMA_TODEVICE);
483 RELEASE_NDIS_PACKET(pAd, pPacket,
484 NDIS_STATUS_FAILURE);
485 }
486 pAd->MgmtRing.Cell[i].pNdisPacket = NULL;
487
488 pPacket =
489 (void *)pAd->MgmtRing.Cell[i].
490 pNextNdisPacket;
491 /* release scatter-and-gather char */
492 if (pPacket) {
493 PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1,
494 pTxD->SDLen1,
495 PCI_DMA_TODEVICE);
496 RELEASE_NDIS_PACKET(pAd, pPacket,
497 NDIS_STATUS_FAILURE);
498 }
499 pAd->MgmtRing.Cell[i].pNextNdisPacket = NULL;
500
501 }
502
503 RTMP_IO_READ32(pAd, TX_MGMTDTX_IDX, &pAd->MgmtRing.TxDmaIdx);
504 pAd->MgmtRing.TxSwFreeIdx = pAd->MgmtRing.TxDmaIdx;
505 pAd->MgmtRing.TxCpuIdx = pAd->MgmtRing.TxDmaIdx;
506 RTMP_IO_WRITE32(pAd, TX_MGMTCTX_IDX, pAd->MgmtRing.TxCpuIdx);
507
508 NdisReleaseSpinLock(&pAd->MgmtRingLock);
509 pAd->RalinkCounters.MgmtRingFullCount = 0;
510 break;
511
512 case QID_RX:
513 /* We have to clean all descriptors in case some error happened with reset */
514 NdisAcquireSpinLock(&pAd->RxRingLock);
515
516 for (i = 0; i < RX_RING_SIZE; i++) {
517 pRxD = (struct rt_rxd *) pAd->RxRing.Cell[i].AllocVa;
518 pRxD->DDONE = 0;
519 }
520
521 RTMP_IO_READ32(pAd, RX_DRX_IDX, &pAd->RxRing.RxDmaIdx);
522 pAd->RxRing.RxSwReadIdx = pAd->RxRing.RxDmaIdx;
523 pAd->RxRing.RxCpuIdx =
524 ((pAd->RxRing.RxDmaIdx ==
525 0) ? (RX_RING_SIZE - 1) : (pAd->RxRing.RxDmaIdx - 1));
526 RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx);
527
528 NdisReleaseSpinLock(&pAd->RxRingLock);
529 break;
530
531 default:
532 break;
533 }
534}
535
536void RTMPFreeTxRxRingMemory(struct rt_rtmp_adapter *pAd)
537{
538 int index, num, j;
539 struct rt_rtmp_tx_ring *pTxRing;
540 struct rt_txd * pTxD;
541 void *pPacket;
542 unsigned int IrqFlags;
543
544 /*struct os_cookie *pObj =(struct os_cookie *)pAd->OS_Cookie; */
545
546 DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPFreeTxRxRingMemory\n"));
547
548 /* Free TxSwQueue Packet */
549 for (index = 0; index < NUM_OF_TX_RING; index++) {
550 struct rt_queue_entry *pEntry;
551 void *pPacket;
552 struct rt_queue_header *pQueue;
553
554 RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
555 pQueue = &pAd->TxSwQueue[index];
556 while (pQueue->Head) {
557 pEntry = RemoveHeadQueue(pQueue);
558 pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
559 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
560 }
561 RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
562 }
563
564 /* Free Tx Ring Packet */
565 for (index = 0; index < NUM_OF_TX_RING; index++) {
566 pTxRing = &pAd->TxRing[index];
567
568 for (j = 0; j < TX_RING_SIZE; j++) {
569 pTxD = (struct rt_txd *) (pTxRing->Cell[j].AllocVa);
570 pPacket = pTxRing->Cell[j].pNdisPacket;
571
572 if (pPacket) {
573 PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0,
574 pTxD->SDLen0,
575 PCI_DMA_TODEVICE);
576 RELEASE_NDIS_PACKET(pAd, pPacket,
577 NDIS_STATUS_SUCCESS);
578 }
579 /*Always assign pNdisPacket as NULL after clear */
580 pTxRing->Cell[j].pNdisPacket = NULL;
581
582 pPacket = pTxRing->Cell[j].pNextNdisPacket;
583
584 if (pPacket) {
585 PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1,
586 pTxD->SDLen1,
587 PCI_DMA_TODEVICE);
588 RELEASE_NDIS_PACKET(pAd, pPacket,
589 NDIS_STATUS_SUCCESS);
590 }
591 /*Always assign pNextNdisPacket as NULL after clear */
592 pTxRing->Cell[pTxRing->TxSwFreeIdx].pNextNdisPacket =
593 NULL;
594
595 }
596 }
597
598 for (index = RX_RING_SIZE - 1; index >= 0; index--) {
599 if ((pAd->RxRing.Cell[index].DmaBuf.AllocVa)
600 && (pAd->RxRing.Cell[index].pNdisPacket)) {
601 PCI_UNMAP_SINGLE(pAd,
602 pAd->RxRing.Cell[index].DmaBuf.AllocPa,
603 pAd->RxRing.Cell[index].DmaBuf.
604 AllocSize, PCI_DMA_FROMDEVICE);
605 RELEASE_NDIS_PACKET(pAd,
606 pAd->RxRing.Cell[index].pNdisPacket,
607 NDIS_STATUS_SUCCESS);
608 }
609 }
610 NdisZeroMemory(pAd->RxRing.Cell, RX_RING_SIZE * sizeof(struct rt_rtmp_dmacb));
611
612 if (pAd->RxDescRing.AllocVa) {
613 RTMP_FreeDescMemory(pAd, pAd->RxDescRing.AllocSize,
614 pAd->RxDescRing.AllocVa,
615 pAd->RxDescRing.AllocPa);
616 }
617 NdisZeroMemory(&pAd->RxDescRing, sizeof(struct rt_rtmp_dmabuf));
618
619 if (pAd->MgmtDescRing.AllocVa) {
620 RTMP_FreeDescMemory(pAd, pAd->MgmtDescRing.AllocSize,
621 pAd->MgmtDescRing.AllocVa,
622 pAd->MgmtDescRing.AllocPa);
623 }
624 NdisZeroMemory(&pAd->MgmtDescRing, sizeof(struct rt_rtmp_dmabuf));
625
626 for (num = 0; num < NUM_OF_TX_RING; num++) {
627 if (pAd->TxBufSpace[num].AllocVa) {
628 RTMP_FreeFirstTxBuffer(pAd,
629 pAd->TxBufSpace[num].AllocSize,
630 FALSE,
631 pAd->TxBufSpace[num].AllocVa,
632 pAd->TxBufSpace[num].AllocPa);
633 }
634 NdisZeroMemory(&pAd->TxBufSpace[num], sizeof(struct rt_rtmp_dmabuf));
635
636 if (pAd->TxDescRing[num].AllocVa) {
637 RTMP_FreeDescMemory(pAd, pAd->TxDescRing[num].AllocSize,
638 pAd->TxDescRing[num].AllocVa,
639 pAd->TxDescRing[num].AllocPa);
640 }
641 NdisZeroMemory(&pAd->TxDescRing[num], sizeof(struct rt_rtmp_dmabuf));
642 }
643
644 if (pAd->FragFrame.pFragPacket)
645 RELEASE_NDIS_PACKET(pAd, pAd->FragFrame.pFragPacket,
646 NDIS_STATUS_SUCCESS);
647
648 DBGPRINT(RT_DEBUG_TRACE, ("<-- RTMPFreeTxRxRingMemory\n"));
649}
650
651/***************************************************************************
652 *
653 * register related procedures.
654 *
655 **************************************************************************/
656/*
657========================================================================
658Routine Description:
659 Disable DMA.
660
661Arguments:
662 *pAd the raxx interface data pointer
663
664Return Value:
665 None
666
667Note:
668========================================================================
669*/
670void RT28XXDMADisable(struct rt_rtmp_adapter *pAd)
671{
672 WPDMA_GLO_CFG_STRUC GloCfg;
673
674 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
675 GloCfg.word &= 0xff0;
676 GloCfg.field.EnTXWriteBackDDONE = 1;
677 RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
678}
679
680/*
681========================================================================
682Routine Description:
683 Enable DMA.
684
685Arguments:
686 *pAd the raxx interface data pointer
687
688Return Value:
689 None
690
691Note:
692========================================================================
693*/
694void RT28XXDMAEnable(struct rt_rtmp_adapter *pAd)
695{
696 WPDMA_GLO_CFG_STRUC GloCfg;
697 int i = 0;
698
699 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x4);
700 do {
701 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
702 if ((GloCfg.field.TxDMABusy == 0)
703 && (GloCfg.field.RxDMABusy == 0))
704 break;
705
706 DBGPRINT(RT_DEBUG_TRACE, ("==> DMABusy\n"));
707 RTMPusecDelay(1000);
708 i++;
709 } while (i < 200);
710
711 RTMPusecDelay(50);
712
713 GloCfg.field.EnTXWriteBackDDONE = 1;
714 GloCfg.field.WPDMABurstSIZE = 2;
715 GloCfg.field.EnableRxDMA = 1;
716 GloCfg.field.EnableTxDMA = 1;
717
718 DBGPRINT(RT_DEBUG_TRACE,
719 ("<== WRITE DMA offset 0x208 = 0x%x\n", GloCfg.word));
720 RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
721
722}
723
724BOOLEAN AsicCheckCommanOk(struct rt_rtmp_adapter *pAd, u8 Command)
725{
726 u32 CmdStatus = 0, CID = 0, i;
727 u32 ThisCIDMask = 0;
728
729 i = 0;
730 do {
731 RTMP_IO_READ32(pAd, H2M_MAILBOX_CID, &CID);
732 /* Find where the command is. Because this is randomly specified by firmware. */
733 if ((CID & CID0MASK) == Command) {
734 ThisCIDMask = CID0MASK;
735 break;
736 } else if ((((CID & CID1MASK) >> 8) & 0xff) == Command) {
737 ThisCIDMask = CID1MASK;
738 break;
739 } else if ((((CID & CID2MASK) >> 16) & 0xff) == Command) {
740 ThisCIDMask = CID2MASK;
741 break;
742 } else if ((((CID & CID3MASK) >> 24) & 0xff) == Command) {
743 ThisCIDMask = CID3MASK;
744 break;
745 }
746
747 RTMPusecDelay(100);
748 i++;
749 } while (i < 200);
750
751 /* Get CommandStatus Value */
752 RTMP_IO_READ32(pAd, H2M_MAILBOX_STATUS, &CmdStatus);
753
754 /* This command's status is at the same position as command. So AND command position's bitmask to read status. */
755 if (i < 200) {
756 /* If Status is 1, the command is success. */
757 if (((CmdStatus & ThisCIDMask) == 0x1)
758 || ((CmdStatus & ThisCIDMask) == 0x100)
759 || ((CmdStatus & ThisCIDMask) == 0x10000)
760 || ((CmdStatus & ThisCIDMask) == 0x1000000)) {
761 DBGPRINT(RT_DEBUG_TRACE,
762 ("--> AsicCheckCommanOk CID = 0x%x, CmdStatus= 0x%x \n",
763 CID, CmdStatus));
764 RTMP_IO_WRITE32(pAd, H2M_MAILBOX_STATUS, 0xffffffff);
765 RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CID, 0xffffffff);
766 return TRUE;
767 }
768 DBGPRINT(RT_DEBUG_TRACE,
769 ("--> AsicCheckCommanFail1 CID = 0x%x, CmdStatus= 0x%x \n",
770 CID, CmdStatus));
771 } else {
772 DBGPRINT(RT_DEBUG_TRACE,
773 ("--> AsicCheckCommanFail2 Timeout Command = %d, CmdStatus= 0x%x \n",
774 Command, CmdStatus));
775 }
776 /* Clear Command and Status. */
777 RTMP_IO_WRITE32(pAd, H2M_MAILBOX_STATUS, 0xffffffff);
778 RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CID, 0xffffffff);
779
780 return FALSE;
781}
782
783/*
784========================================================================
785Routine Description:
786 Write Beacon buffer to Asic.
787
788Arguments:
789 *pAd the raxx interface data pointer
790
791Return Value:
792 None
793
794Note:
795========================================================================
796*/
797void RT28xx_UpdateBeaconToAsic(struct rt_rtmp_adapter *pAd,
798 int apidx,
799 unsigned long FrameLen, unsigned long UpdatePos)
800{
801 unsigned long CapInfoPos = 0;
802 u8 *ptr, *ptr_update, *ptr_capinfo;
803 u32 i;
804 BOOLEAN bBcnReq = FALSE;
805 u8 bcn_idx = 0;
806
807 {
808 DBGPRINT(RT_DEBUG_ERROR,
809 ("%s() : No valid Interface be found.\n", __func__));
810 return;
811 }
812
813 /*if ((pAd->WdsTab.Mode == WDS_BRIDGE_MODE) */
814 /* || ((pAd->ApCfg.MBSSID[apidx].MSSIDDev == NULL) */
815 /* || !(pAd->ApCfg.MBSSID[apidx].MSSIDDev->flags & IFF_UP)) */
816 /* ) */
817 if (bBcnReq == FALSE) {
818 /* when the ra interface is down, do not send its beacon frame */
819 /* clear all zero */
820 for (i = 0; i < TXWI_SIZE; i += 4)
821 RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i,
822 0x00);
823 } else {
824 ptr = (u8 *)& pAd->BeaconTxWI;
825 for (i = 0; i < TXWI_SIZE; i += 4) /* 16-byte TXWI field */
826 {
827 u32 longptr =
828 *ptr + (*(ptr + 1) << 8) + (*(ptr + 2) << 16) +
829 (*(ptr + 3) << 24);
830 RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i,
831 longptr);
832 ptr += 4;
833 }
834
835 /* Update CapabilityInfo in Beacon */
836 for (i = CapInfoPos; i < (CapInfoPos + 2); i++) {
837 RTMP_IO_WRITE8(pAd,
838 pAd->BeaconOffset[bcn_idx] + TXWI_SIZE +
839 i, *ptr_capinfo);
840 ptr_capinfo++;
841 }
842
843 if (FrameLen > UpdatePos) {
844 for (i = UpdatePos; i < (FrameLen); i++) {
845 RTMP_IO_WRITE8(pAd,
846 pAd->BeaconOffset[bcn_idx] +
847 TXWI_SIZE + i, *ptr_update);
848 ptr_update++;
849 }
850 }
851
852 }
853
854}
855
856void RT28xxPciStaAsicForceWakeup(struct rt_rtmp_adapter *pAd, IN BOOLEAN bFromTx)
857{
858 AUTO_WAKEUP_STRUC AutoWakeupCfg;
859
860 if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
861 return;
862
863 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WAKEUP_NOW)) {
864 DBGPRINT(RT_DEBUG_TRACE, ("waking up now!\n"));
865 return;
866 }
867
868 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_WAKEUP_NOW);
869
870 RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
871
872 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)
873 && pAd->StaCfg.PSControl.field.EnableNewPS == TRUE) {
874 /* Support PCIe Advance Power Save */
875 if (bFromTx == TRUE && (pAd->Mlme.bPsPollTimerRunning == TRUE)) {
876 pAd->Mlme.bPsPollTimerRunning = FALSE;
877 RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_WAKEUP);
878 RTMPusecDelay(3000);
879 DBGPRINT(RT_DEBUG_TRACE,
880 ("=======AsicForceWakeup===bFromTx\n"));
881 }
882
883 AutoWakeupCfg.word = 0;
884 RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
885
886 if (RT28xxPciAsicRadioOn(pAd, DOT11POWERSAVE)) {
887#ifdef PCIE_PS_SUPPORT
888 /* add by johnli, RF power sequence setup, load RF normal operation-mode setup */
889 if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
890 && IS_VERSION_AFTER_F(pAd)) {
891 struct rt_rtmp_chip_op *pChipOps = &pAd->chipOps;
892
893 if (pChipOps->AsicReverseRfFromSleepMode)
894 pChipOps->
895 AsicReverseRfFromSleepMode(pAd);
896 } else
897#endif /* PCIE_PS_SUPPORT // */
898 {
899 /* end johnli */
900 /* In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again. */
901 if (INFRA_ON(pAd)
902 && (pAd->CommonCfg.CentralChannel !=
903 pAd->CommonCfg.Channel)
904 && (pAd->MlmeAux.HtCapability.HtCapInfo.
905 ChannelWidth == BW_40)) {
906 /* Must using 40MHz. */
907 AsicSwitchChannel(pAd,
908 pAd->CommonCfg.
909 CentralChannel,
910 FALSE);
911 AsicLockChannel(pAd,
912 pAd->CommonCfg.
913 CentralChannel);
914 } else {
915 /* Must using 20MHz. */
916 AsicSwitchChannel(pAd,
917 pAd->CommonCfg.
918 Channel, FALSE);
919 AsicLockChannel(pAd,
920 pAd->CommonCfg.Channel);
921 }
922 }
923 }
924#ifdef PCIE_PS_SUPPORT
925 /* 3090 MCU Wakeup command needs more time to be stable. */
926 /* Before stable, don't issue other MCU command to prevent from firmware error. */
927 if (((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
928 && IS_VERSION_AFTER_F(pAd)) && IS_VERSION_AFTER_F(pAd)
929 && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
930 && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)) {
931 DBGPRINT(RT_DEBUG_TRACE,
932 ("<==RT28xxPciStaAsicForceWakeup::Release the MCU Lock(3090)\n"));
933 RTMP_SEM_LOCK(&pAd->McuCmdLock);
934 pAd->brt30xxBanMcuCmd = FALSE;
935 RTMP_SEM_UNLOCK(&pAd->McuCmdLock);
936 }
937#endif /* PCIE_PS_SUPPORT // */
938 } else {
939 /* PCI, 2860-PCIe */
940 DBGPRINT(RT_DEBUG_TRACE,
941 ("<==RT28xxPciStaAsicForceWakeup::Original PCI Power Saving\n"));
942 AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02);
943 AutoWakeupCfg.word = 0;
944 RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
945 }
946
947 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
948 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_WAKEUP_NOW);
949 DBGPRINT(RT_DEBUG_TRACE, ("<=======RT28xxPciStaAsicForceWakeup\n"));
950}
951
952void RT28xxPciStaAsicSleepThenAutoWakeup(struct rt_rtmp_adapter *pAd,
953 u16 TbttNumToNextWakeUp)
954{
955 BOOLEAN brc;
956
957 if (pAd->StaCfg.bRadio == FALSE) {
958 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
959 return;
960 }
961 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)
962 && pAd->StaCfg.PSControl.field.EnableNewPS == TRUE) {
963 unsigned long Now = 0;
964 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WAKEUP_NOW)) {
965 DBGPRINT(RT_DEBUG_TRACE, ("waking up now!\n"));
966 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
967 return;
968 }
969
970 NdisGetSystemUpTime(&Now);
971 /* If last send NULL fram time is too close to this receiving beacon (within 8ms), don't go to sleep for this DTM. */
972 /* Because Some AP can't queuing outgoing frames immediately. */
973 if (((pAd->Mlme.LastSendNULLpsmTime + 8) >= Now)
974 && (pAd->Mlme.LastSendNULLpsmTime <= Now)) {
975 DBGPRINT(RT_DEBUG_TRACE,
976 ("Now = %lu, LastSendNULLpsmTime=%lu : RxCountSinceLastNULL = %lu. \n",
977 Now, pAd->Mlme.LastSendNULLpsmTime,
978 pAd->RalinkCounters.RxCountSinceLastNULL));
979 return;
980 } else if ((pAd->RalinkCounters.RxCountSinceLastNULL > 0)
981 &&
982 ((pAd->Mlme.LastSendNULLpsmTime +
983 pAd->CommonCfg.BeaconPeriod) >= Now)) {
984 DBGPRINT(RT_DEBUG_TRACE,
985 ("Now = %lu, LastSendNULLpsmTime=%lu: RxCountSinceLastNULL = %lu > 0 \n",
986 Now, pAd->Mlme.LastSendNULLpsmTime,
987 pAd->RalinkCounters.RxCountSinceLastNULL));
988 return;
989 }
990
991 brc =
992 RT28xxPciAsicRadioOff(pAd, DOT11POWERSAVE,
993 TbttNumToNextWakeUp);
994 if (brc == TRUE)
995 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_DOZE);
996 } else {
997 AUTO_WAKEUP_STRUC AutoWakeupCfg;
998 /* we have decided to SLEEP, so at least do it for a BEACON period. */
999 if (TbttNumToNextWakeUp == 0)
1000 TbttNumToNextWakeUp = 1;
1001
1002 /*RTMP_IO_WRITE32(pAd, INT_MASK_CSR, AutoWakeupInt); */
1003
1004 AutoWakeupCfg.word = 0;
1005 RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
1006 AutoWakeupCfg.field.NumofSleepingTbtt = TbttNumToNextWakeUp - 1;
1007 AutoWakeupCfg.field.EnableAutoWakeup = 1;
1008 AutoWakeupCfg.field.AutoLeadTime = 5;
1009 RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
1010 AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x00); /* send POWER-SAVE command to MCU. Timeout 40us. */
1011 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_DOZE);
1012 DBGPRINT(RT_DEBUG_TRACE,
1013 ("<-- %s, TbttNumToNextWakeUp=%d \n", __func__,
1014 TbttNumToNextWakeUp));
1015 }
1016
1017}
1018
1019void PsPollWakeExec(void *SystemSpecific1,
1020 void *FunctionContext,
1021 void *SystemSpecific2, void *SystemSpecific3)
1022{
1023 struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext;
1024 unsigned long flags;
1025
1026 DBGPRINT(RT_DEBUG_TRACE, ("-->PsPollWakeExec \n"));
1027 RTMP_INT_LOCK(&pAd->irq_lock, flags);
1028 if (pAd->Mlme.bPsPollTimerRunning) {
1029 RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_WAKEUP);
1030 }
1031 pAd->Mlme.bPsPollTimerRunning = FALSE;
1032 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
1033#ifdef PCIE_PS_SUPPORT
1034 /* For rt30xx power solution 3, Use software timer to wake up in psm. So call */
1035 /* AsicForceWakeup here instead of handling twakeup interrupt. */
1036 if (((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
1037 && IS_VERSION_AFTER_F(pAd))
1038 && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
1039 && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)) {
1040 DBGPRINT(RT_DEBUG_TRACE,
1041 ("<--PsPollWakeExec::3090 calls AsicForceWakeup(pAd, DOT11POWERSAVE) in advance \n"));
1042 AsicForceWakeup(pAd, DOT11POWERSAVE);
1043 }
1044#endif /* PCIE_PS_SUPPORT // */
1045}
1046
1047void RadioOnExec(void *SystemSpecific1,
1048 void *FunctionContext,
1049 void *SystemSpecific2, void *SystemSpecific3)
1050{
1051 struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext;
1052 struct rt_rtmp_chip_op *pChipOps = &pAd->chipOps;
1053 WPDMA_GLO_CFG_STRUC DmaCfg;
1054 BOOLEAN Cancelled;
1055
1056 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) {
1057 DBGPRINT(RT_DEBUG_TRACE,
1058 ("-->RadioOnExec() return on fOP_STATUS_DOZE == TRUE; \n"));
1059/*KH Debug: Add the compile flag "RT2860 and condition */
1060#ifdef RTMP_PCI_SUPPORT
1061 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)
1062 && pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)
1063 RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 10);
1064#endif /* RTMP_PCI_SUPPORT // */
1065 return;
1066 }
1067
1068 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) {
1069 DBGPRINT(RT_DEBUG_TRACE,
1070 ("-->RadioOnExec() return on SCAN_IN_PROGRESS; \n"));
1071#ifdef RTMP_PCI_SUPPORT
1072 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)
1073 && pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)
1074 RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 10);
1075#endif /* RTMP_PCI_SUPPORT // */
1076 return;
1077 }
1078/*KH Debug: need to check. I add the compile flag "CONFIG_STA_SUPPORT" to enclose the following codes. */
1079#ifdef RTMP_PCI_SUPPORT
1080 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)
1081 && pAd->StaCfg.PSControl.field.EnableNewPS == TRUE) {
1082 pAd->Mlme.bPsPollTimerRunning = FALSE;
1083 RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
1084 }
1085#endif /* RTMP_PCI_SUPPORT // */
1086 if (pAd->StaCfg.bRadio == TRUE) {
1087 pAd->bPCIclkOff = FALSE;
1088 RTMPRingCleanUp(pAd, QID_AC_BK);
1089 RTMPRingCleanUp(pAd, QID_AC_BE);
1090 RTMPRingCleanUp(pAd, QID_AC_VI);
1091 RTMPRingCleanUp(pAd, QID_AC_VO);
1092 RTMPRingCleanUp(pAd, QID_MGMT);
1093 RTMPRingCleanUp(pAd, QID_RX);
1094
1095 /* 2. Send wake up command. */
1096 AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00, 0x02);
1097 /* 2-1. wait command ok. */
1098 AsicCheckCommanOk(pAd, PowerWakeCID);
1099
1100 /* When PCI clock is off, don't want to service interrupt. So when back to clock on, enable interrupt. */
1101 /*RTMP_IO_WRITE32(pAd, INT_MASK_CSR, (DELAYINTMASK|RxINT)); */
1102 RTMP_ASIC_INTERRUPT_ENABLE(pAd);
1103
1104 /* 3. Enable Tx DMA. */
1105 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &DmaCfg.word);
1106 DmaCfg.field.EnableTxDMA = 1;
1107 RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, DmaCfg.word);
1108
1109 /* In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again. */
1110 if (INFRA_ON(pAd)
1111 && (pAd->CommonCfg.CentralChannel != pAd->CommonCfg.Channel)
1112 && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth ==
1113 BW_40)) {
1114 /* Must using 40MHz. */
1115 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel,
1116 FALSE);
1117 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
1118 } else {
1119 /* Must using 20MHz. */
1120 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
1121 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
1122 }
1123
1124/*KH Debug:The following codes should be enclosed by RT3090 compile flag */
1125 if (pChipOps->AsicReverseRfFromSleepMode)
1126 pChipOps->AsicReverseRfFromSleepMode(pAd);
1127
1128#ifdef PCIE_PS_SUPPORT
1129/* 3090 MCU Wakeup command needs more time to be stable. */
1130/* Before stable, don't issue other MCU command to prevent from firmware error. */
1131 if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
1132 && IS_VERSION_AFTER_F(pAd)
1133 && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
1134 && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)) {
1135 RTMP_SEM_LOCK(&pAd->McuCmdLock);
1136 pAd->brt30xxBanMcuCmd = FALSE;
1137 RTMP_SEM_UNLOCK(&pAd->McuCmdLock);
1138 }
1139#endif /* PCIE_PS_SUPPORT // */
1140
1141 /* Clear Radio off flag */
1142 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
1143
1144 /* Set LED */
1145 RTMPSetLED(pAd, LED_RADIO_ON);
1146
1147 if (pAd->StaCfg.Psm == PWR_ACTIVE) {
1148 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3,
1149 pAd->StaCfg.BBPR3);
1150 }
1151 } else {
1152 RT28xxPciAsicRadioOff(pAd, GUIRADIO_OFF, 0);
1153 }
1154}
1155
1156/*
1157 ==========================================================================
1158 Description:
1159 This routine sends command to firmware and turn our chip to wake up mode from power save mode.
1160 Both RadioOn and .11 power save function needs to call this routine.
1161 Input:
1162 Level = GUIRADIO_OFF : call this function is from Radio Off to Radio On. Need to restore PCI host value.
1163 Level = other value : normal wake up function.
1164
1165 ==========================================================================
1166 */
1167BOOLEAN RT28xxPciAsicRadioOn(struct rt_rtmp_adapter *pAd, u8 Level)
1168{
1169 /*WPDMA_GLO_CFG_STRUC DmaCfg; */
1170 BOOLEAN Cancelled;
1171 /*u32 MACValue; */
1172
1173 if (pAd->OpMode == OPMODE_AP && Level == DOT11POWERSAVE)
1174 return FALSE;
1175
1176 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) {
1177 if (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE) {
1178 pAd->Mlme.bPsPollTimerRunning = FALSE;
1179 RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
1180 }
1181 if ((pAd->StaCfg.PSControl.field.EnableNewPS == TRUE &&
1182 (Level == GUIRADIO_OFF || Level == GUI_IDLE_POWER_SAVE)) ||
1183 RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND)) {
1184 /* Some chips don't need to delay 6ms, so copy RTMPPCIePowerLinkCtrlRestore */
1185 /* return condition here. */
1186 /*
1187 if (((pAd->MACVersion&0xffff0000) != 0x28600000)
1188 && ((pAd->DeviceID == NIC2860_PCIe_DEVICE_ID)
1189 ||(pAd->DeviceID == NIC2790_PCIe_DEVICE_ID)))
1190 */
1191 {
1192 DBGPRINT(RT_DEBUG_TRACE,
1193 ("RT28xxPciAsicRadioOn ()\n"));
1194 /* 1. Set PCI Link Control in Configuration Space. */
1195 RTMPPCIeLinkCtrlValueRestore(pAd,
1196 RESTORE_WAKEUP);
1197 RTMPusecDelay(6000);
1198 }
1199 }
1200 }
1201#ifdef PCIE_PS_SUPPORT
1202 if (!
1203 (((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
1204 && IS_VERSION_AFTER_F(pAd)
1205 && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
1206 && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE))))
1207#endif /* PCIE_PS_SUPPORT // */
1208 {
1209 pAd->bPCIclkOff = FALSE;
1210 DBGPRINT(RT_DEBUG_TRACE,
1211 ("PSM :309xbPCIclkOff == %d\n", pAd->bPCIclkOff));
1212 }
1213 /* 2. Send wake up command. */
1214 AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00, 0x02);
1215 pAd->bPCIclkOff = FALSE;
1216 /* 2-1. wait command ok. */
1217 AsicCheckCommanOk(pAd, PowerWakeCID);
1218 RTMP_ASIC_INTERRUPT_ENABLE(pAd);
1219
1220 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF);
1221 if (Level == GUI_IDLE_POWER_SAVE) {
1222#ifdef PCIE_PS_SUPPORT
1223
1224 /* add by johnli, RF power sequence setup, load RF normal operation-mode setup */
1225 if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))) {
1226 struct rt_rtmp_chip_op *pChipOps = &pAd->chipOps;
1227
1228 if (pChipOps->AsicReverseRfFromSleepMode)
1229 pChipOps->AsicReverseRfFromSleepMode(pAd);
1230 /* 3090 MCU Wakeup command needs more time to be stable. */
1231 /* Before stable, don't issue other MCU command to prevent from firmware error. */
1232 if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
1233 && IS_VERSION_AFTER_F(pAd)
1234 && (pAd->StaCfg.PSControl.field.rt30xxPowerMode ==
1235 3)
1236 && (pAd->StaCfg.PSControl.field.EnableNewPS ==
1237 TRUE)) {
1238 RTMP_SEM_LOCK(&pAd->McuCmdLock);
1239 pAd->brt30xxBanMcuCmd = FALSE;
1240 RTMP_SEM_UNLOCK(&pAd->McuCmdLock);
1241 }
1242 } else
1243 /* end johnli */
1244#endif /* PCIE_PS_SUPPORT // */
1245 {
1246 /* In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again. */
1247 {
1248 if (INFRA_ON(pAd)
1249 && (pAd->CommonCfg.CentralChannel !=
1250 pAd->CommonCfg.Channel)
1251 && (pAd->MlmeAux.HtCapability.HtCapInfo.
1252 ChannelWidth == BW_40)) {
1253 /* Must using 40MHz. */
1254 AsicSwitchChannel(pAd,
1255 pAd->CommonCfg.
1256 CentralChannel,
1257 FALSE);
1258 AsicLockChannel(pAd,
1259 pAd->CommonCfg.
1260 CentralChannel);
1261 } else {
1262 /* Must using 20MHz. */
1263 AsicSwitchChannel(pAd,
1264 pAd->CommonCfg.
1265 Channel, FALSE);
1266 AsicLockChannel(pAd,
1267 pAd->CommonCfg.Channel);
1268 }
1269 }
1270
1271 }
1272 }
1273 return TRUE;
1274
1275}
1276
1277/*
1278 ==========================================================================
1279 Description:
1280 This routine sends command to firmware and turn our chip to power save mode.
1281 Both RadioOff and .11 power save function needs to call this routine.
1282 Input:
1283 Level = GUIRADIO_OFF : GUI Radio Off mode
1284 Level = DOT11POWERSAVE : 802.11 power save mode
1285 Level = RTMP_HALT : When Disable device.
1286
1287 ==========================================================================
1288 */
1289BOOLEAN RT28xxPciAsicRadioOff(struct rt_rtmp_adapter *pAd,
1290 u8 Level, u16 TbttNumToNextWakeUp)
1291{
1292 WPDMA_GLO_CFG_STRUC DmaCfg;
1293 u8 i, tempBBP_R3 = 0;
1294 BOOLEAN brc = FALSE, Cancelled;
1295 u32 TbTTTime = 0;
1296 u32 PsPollTime = 0 /*, MACValue */ ;
1297 unsigned long BeaconPeriodTime;
1298 u32 RxDmaIdx, RxCpuIdx;
1299 DBGPRINT(RT_DEBUG_TRACE,
1300 ("AsicRadioOff ===> Lv= %d, TxCpuIdx = %d, TxDmaIdx = %d. RxCpuIdx = %d, RxDmaIdx = %d.\n",
1301 Level, pAd->TxRing[0].TxCpuIdx, pAd->TxRing[0].TxDmaIdx,
1302 pAd->RxRing.RxCpuIdx, pAd->RxRing.RxDmaIdx));
1303
1304 if (pAd->OpMode == OPMODE_AP && Level == DOT11POWERSAVE)
1305 return FALSE;
1306
1307 /* Check Rx DMA busy status, if more than half is occupied, give up this radio off. */
1308 RTMP_IO_READ32(pAd, RX_DRX_IDX, &RxDmaIdx);
1309 RTMP_IO_READ32(pAd, RX_CRX_IDX, &RxCpuIdx);
1310 if ((RxDmaIdx > RxCpuIdx) && ((RxDmaIdx - RxCpuIdx) > RX_RING_SIZE / 3)) {
1311 DBGPRINT(RT_DEBUG_TRACE,
1312 ("AsicRadioOff ===> return1. RxDmaIdx = %d , RxCpuIdx = %d. \n",
1313 RxDmaIdx, RxCpuIdx));
1314 return FALSE;
1315 } else if ((RxCpuIdx >= RxDmaIdx)
1316 && ((RxCpuIdx - RxDmaIdx) < RX_RING_SIZE / 3)) {
1317 DBGPRINT(RT_DEBUG_TRACE,
1318 ("AsicRadioOff ===> return2. RxCpuIdx = %d. RxDmaIdx = %d , \n",
1319 RxCpuIdx, RxDmaIdx));
1320 return FALSE;
1321 }
1322 /* Once go into this function, disable tx because don't want too many packets in queue to prevent HW stops. */
1323 /*pAd->bPCIclkOffDisableTx = TRUE; */
1324 RTMP_SET_PSFLAG(pAd, fRTMP_PS_DISABLE_TX);
1325 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)
1326 && pAd->OpMode == OPMODE_STA
1327 && pAd->StaCfg.PSControl.field.EnableNewPS == TRUE) {
1328 RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer, &Cancelled);
1329 RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
1330
1331 if (Level == DOT11POWERSAVE) {
1332 RTMP_IO_READ32(pAd, TBTT_TIMER, &TbTTTime);
1333 TbTTTime &= 0x1ffff;
1334 /* 00. check if need to do sleep in this DTIM period. If next beacon will arrive within 30ms , ...doesn't necessarily sleep. */
1335 /* TbTTTime uint = 64us, LEAD_TIME unit = 1024us, PsPollTime unit = 1ms */
1336 if (((64 * TbTTTime) < ((LEAD_TIME * 1024) + 40000))
1337 && (TbttNumToNextWakeUp == 0)) {
1338 DBGPRINT(RT_DEBUG_TRACE,
1339 ("TbTTTime = 0x%x , give up this sleep. \n",
1340 TbTTTime));
1341 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
1342 /*pAd->bPCIclkOffDisableTx = FALSE; */
1343 RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_DISABLE_TX);
1344 return FALSE;
1345 } else {
1346 PsPollTime =
1347 (64 * TbTTTime - LEAD_TIME * 1024) / 1000;
1348#ifdef PCIE_PS_SUPPORT
1349 if ((IS_RT3090(pAd) || IS_RT3572(pAd)
1350 || IS_RT3390(pAd))
1351 && IS_VERSION_AFTER_F(pAd)
1352 && (pAd->StaCfg.PSControl.field.
1353 rt30xxPowerMode == 3)
1354 && (pAd->StaCfg.PSControl.field.
1355 EnableNewPS == TRUE)) {
1356 PsPollTime -= 5;
1357 } else
1358#endif /* PCIE_PS_SUPPORT // */
1359 PsPollTime -= 3;
1360
1361 BeaconPeriodTime =
1362 pAd->CommonCfg.BeaconPeriod * 102 / 100;
1363 if (TbttNumToNextWakeUp > 0)
1364 PsPollTime +=
1365 ((TbttNumToNextWakeUp -
1366 1) * BeaconPeriodTime);
1367
1368 pAd->Mlme.bPsPollTimerRunning = TRUE;
1369 RTMPSetTimer(&pAd->Mlme.PsPollTimer,
1370 PsPollTime);
1371 }
1372 }
1373 } else {
1374 DBGPRINT(RT_DEBUG_TRACE,
1375 ("RT28xxPciAsicRadioOff::Level!=DOT11POWERSAVE \n"));
1376 }
1377
1378 pAd->bPCIclkOffDisableTx = FALSE;
1379
1380 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF);
1381
1382 /* Set to 1R. */
1383 if (pAd->Antenna.field.RxPath > 1 && pAd->OpMode == OPMODE_STA) {
1384 tempBBP_R3 = (pAd->StaCfg.BBPR3 & 0xE7);
1385 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, tempBBP_R3);
1386 }
1387 /* In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again. */
1388 if ((INFRA_ON(pAd) || pAd->OpMode == OPMODE_AP)
1389 && (pAd->CommonCfg.CentralChannel != pAd->CommonCfg.Channel)
1390 && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40)) {
1391 /* Must using 40MHz. */
1392 AsicTurnOffRFClk(pAd, pAd->CommonCfg.CentralChannel);
1393 } else {
1394 /* Must using 20MHz. */
1395 AsicTurnOffRFClk(pAd, pAd->CommonCfg.Channel);
1396 }
1397
1398 if (Level != RTMP_HALT) {
1399 /* Change Interrupt bitmask. */
1400 /* When PCI clock is off, don't want to service interrupt. */
1401 RTMP_IO_WRITE32(pAd, INT_MASK_CSR, AutoWakeupInt);
1402 } else {
1403 RTMP_ASIC_INTERRUPT_DISABLE(pAd);
1404 }
1405
1406 RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx);
1407 /* 2. Send Sleep command */
1408 RTMP_IO_WRITE32(pAd, H2M_MAILBOX_STATUS, 0xffffffff);
1409 RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CID, 0xffffffff);
1410 /* send POWER-SAVE command to MCU. high-byte = 1 save power as much as possible. high byte = 0 save less power */
1411 AsicSendCommandToMcu(pAd, 0x30, PowerSafeCID, 0xff, 0x1);
1412 /* 2-1. Wait command success */
1413 /* Status = 1 : success, Status = 2, already sleep, Status = 3, Maybe MAC is busy so can't finish this task. */
1414 brc = AsicCheckCommanOk(pAd, PowerSafeCID);
1415
1416 /* 3. After 0x30 command is ok, send radio off command. lowbyte = 0 for power safe. */
1417 /* If 0x30 command is not ok this time, we can ignore 0x35 command. It will make sure not cause firmware'r problem. */
1418 if ((Level == DOT11POWERSAVE) && (brc == TRUE)) {
1419 AsicSendCommandToMcu(pAd, 0x35, PowerRadioOffCID, 0, 0x00); /* lowbyte = 0 means to do power safe, NOT turn off radio. */
1420 /* 3-1. Wait command success */
1421 AsicCheckCommanOk(pAd, PowerRadioOffCID);
1422 } else if (brc == TRUE) {
1423 AsicSendCommandToMcu(pAd, 0x35, PowerRadioOffCID, 1, 0x00); /* lowbyte = 0 means to do power safe, NOT turn off radio. */
1424 /* 3-1. Wait command success */
1425 AsicCheckCommanOk(pAd, PowerRadioOffCID);
1426 }
1427 /* 1. Wait DMA not busy */
1428 i = 0;
1429 do {
1430 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &DmaCfg.word);
1431 if ((DmaCfg.field.RxDMABusy == 0)
1432 && (DmaCfg.field.TxDMABusy == 0))
1433 break;
1434 RTMPusecDelay(20);
1435 i++;
1436 } while (i < 50);
1437
1438 /*
1439 if (i >= 50)
1440 {
1441 pAd->CheckDmaBusyCount++;
1442 DBGPRINT(RT_DEBUG_TRACE, ("DMA Rx keeps busy. return on AsicRadioOff () CheckDmaBusyCount = %d \n", pAd->CheckDmaBusyCount));
1443 }
1444 else
1445 {
1446 pAd->CheckDmaBusyCount = 0;
1447 }
1448 */
1449/*KH Debug:My original codes have the following codes, but currecnt codes do not have it. */
1450/* Disable for stability. If PCIE Link Control is modified for advance power save, re-covery this code segment. */
1451 RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0x1280);
1452/*OPSTATUS_SET_FLAG(pAd, fOP_STATUS_CLKSELECT_40MHZ); */
1453
1454#ifdef PCIE_PS_SUPPORT
1455 if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
1456 && IS_VERSION_AFTER_F(pAd)
1457 && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
1458 && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)) {
1459 DBGPRINT(RT_DEBUG_TRACE,
1460 ("RT28xxPciAsicRadioOff::3090 return to skip the following TbttNumToNextWakeUp setting for 279x\n"));
1461 pAd->bPCIclkOff = TRUE;
1462 RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_DISABLE_TX);
1463 /* For this case, doesn't need to below actions, so return here. */
1464 return brc;
1465 }
1466#endif /* PCIE_PS_SUPPORT // */
1467
1468 if (Level == DOT11POWERSAVE) {
1469 AUTO_WAKEUP_STRUC AutoWakeupCfg;
1470 /*RTMPSetTimer(&pAd->Mlme.PsPollTimer, 90); */
1471
1472 /* we have decided to SLEEP, so at least do it for a BEACON period. */
1473 if (TbttNumToNextWakeUp == 0)
1474 TbttNumToNextWakeUp = 1;
1475
1476 AutoWakeupCfg.word = 0;
1477 RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
1478
1479 /* 1. Set auto wake up timer. */
1480 AutoWakeupCfg.field.NumofSleepingTbtt = TbttNumToNextWakeUp - 1;
1481 AutoWakeupCfg.field.EnableAutoWakeup = 1;
1482 AutoWakeupCfg.field.AutoLeadTime = LEAD_TIME;
1483 RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
1484 }
1485 /* 4-1. If it's to disable our device. Need to restore PCI Configuration Space to its original value. */
1486 if (Level == RTMP_HALT && pAd->OpMode == OPMODE_STA) {
1487 if ((brc == TRUE) && (i < 50))
1488 RTMPPCIeLinkCtrlSetting(pAd, 1);
1489 }
1490 /* 4. Set PCI configuration Space Link Comtrol fields. Only Radio Off needs to call this function */
1491 else if (pAd->OpMode == OPMODE_STA) {
1492 if ((brc == TRUE) && (i < 50))
1493 RTMPPCIeLinkCtrlSetting(pAd, 3);
1494 }
1495 /*pAd->bPCIclkOffDisableTx = FALSE; */
1496 RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_DISABLE_TX);
1497 return TRUE;
1498}
1499
1500void RT28xxPciMlmeRadioOn(struct rt_rtmp_adapter *pAd)
1501{
1502 if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
1503 return;
1504
1505 DBGPRINT(RT_DEBUG_TRACE, ("%s===>\n", __func__));
1506
1507 if ((pAd->OpMode == OPMODE_AP) || ((pAd->OpMode == OPMODE_STA)
1508 &&
1509 (!OPSTATUS_TEST_FLAG
1510 (pAd, fOP_STATUS_PCIE_DEVICE)
1511 || pAd->StaCfg.PSControl.field.
1512 EnableNewPS == FALSE))) {
1513 RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE);
1514 /*NICResetFromError(pAd); */
1515
1516 RTMPRingCleanUp(pAd, QID_AC_BK);
1517 RTMPRingCleanUp(pAd, QID_AC_BE);
1518 RTMPRingCleanUp(pAd, QID_AC_VI);
1519 RTMPRingCleanUp(pAd, QID_AC_VO);
1520 RTMPRingCleanUp(pAd, QID_MGMT);
1521 RTMPRingCleanUp(pAd, QID_RX);
1522
1523 /* Enable Tx/Rx */
1524 RTMPEnableRxTx(pAd);
1525
1526 /* Clear Radio off flag */
1527 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
1528
1529 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF);
1530
1531 /* Set LED */
1532 RTMPSetLED(pAd, LED_RADIO_ON);
1533 }
1534
1535 if ((pAd->OpMode == OPMODE_STA) &&
1536 (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE))
1537 && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)) {
1538 BOOLEAN Cancelled;
1539
1540 RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_WAKEUP);
1541
1542 pAd->Mlme.bPsPollTimerRunning = FALSE;
1543 RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
1544 RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer, &Cancelled);
1545 RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 40);
1546 }
1547}
1548
1549void RT28xxPciMlmeRadioOFF(struct rt_rtmp_adapter *pAd)
1550{
1551 BOOLEAN brc = TRUE;
1552
1553 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
1554 return;
1555
1556 /* Link down first if any association exists */
1557 if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) {
1558 if (INFRA_ON(pAd) || ADHOC_ON(pAd)) {
1559 struct rt_mlme_disassoc_req DisReq;
1560 struct rt_mlme_queue_elem *pMsgElem =
1561 kmalloc(sizeof(struct rt_mlme_queue_elem),
1562 MEM_ALLOC_FLAG);
1563
1564 if (pMsgElem) {
1565 COPY_MAC_ADDR(&DisReq.Addr,
1566 pAd->CommonCfg.Bssid);
1567 DisReq.Reason = REASON_DISASSOC_STA_LEAVING;
1568
1569 pMsgElem->Machine = ASSOC_STATE_MACHINE;
1570 pMsgElem->MsgType = MT2_MLME_DISASSOC_REQ;
1571 pMsgElem->MsgLen =
1572 sizeof(struct rt_mlme_disassoc_req);
1573 NdisMoveMemory(pMsgElem->Msg, &DisReq,
1574 sizeof
1575 (struct rt_mlme_disassoc_req));
1576
1577 MlmeDisassocReqAction(pAd, pMsgElem);
1578 kfree(pMsgElem);
1579
1580 RTMPusecDelay(1000);
1581 }
1582 }
1583 }
1584
1585 DBGPRINT(RT_DEBUG_TRACE, ("%s===>\n", __func__));
1586
1587 /* Set Radio off flag */
1588 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
1589
1590 {
1591 BOOLEAN Cancelled;
1592 if (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE) {
1593 if (RTMP_TEST_FLAG
1594 (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) {
1595 RTMPCancelTimer(&pAd->MlmeAux.ScanTimer,
1596 &Cancelled);
1597 RTMP_CLEAR_FLAG(pAd,
1598 fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
1599 }
1600 /* If during power safe mode. */
1601 if (pAd->StaCfg.bRadio == TRUE) {
1602 DBGPRINT(RT_DEBUG_TRACE,
1603 ("-->MlmeRadioOff() return on bRadio == TRUE; \n"));
1604 return;
1605 }
1606 /* Always radio on since the NIC needs to set the MCU command (LED_RADIO_OFF). */
1607 if (IDLE_ON(pAd) &&
1608 (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)))
1609 {
1610 RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE);
1611 }
1612 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) {
1613 BOOLEAN Cancelled;
1614 pAd->Mlme.bPsPollTimerRunning = FALSE;
1615 RTMPCancelTimer(&pAd->Mlme.PsPollTimer,
1616 &Cancelled);
1617 RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer,
1618 &Cancelled);
1619 }
1620 }
1621 /* Link down first if any association exists */
1622 if (INFRA_ON(pAd) || ADHOC_ON(pAd))
1623 LinkDown(pAd, FALSE);
1624 RTMPusecDelay(10000);
1625 /*========================================== */
1626 /* Clean up old bss table */
1627 BssTableInit(&pAd->ScanTab);
1628
1629 /*
1630 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE))
1631 {
1632 RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 10);
1633 return;
1634 }
1635 */
1636 }
1637
1638 /* Set LED.Move to here for fixing LED bug. This flag must be called after LinkDown */
1639 RTMPSetLED(pAd, LED_RADIO_OFF);
1640
1641/*KH Debug:All PCIe devices need to use timer to execute radio off function, or the PCIe&&EnableNewPS needs. */
1642/*KH Ans:It is right, because only when the PCIe and EnableNewPs is true, we need to delay the RadioOffTimer */
1643/*to avoid the deadlock with PCIe Power saving function. */
1644 if (pAd->OpMode == OPMODE_STA &&
1645 OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE) &&
1646 pAd->StaCfg.PSControl.field.EnableNewPS == TRUE) {
1647 RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 10);
1648 } else {
1649 brc = RT28xxPciAsicRadioOff(pAd, GUIRADIO_OFF, 0);
1650
1651 if (brc == FALSE) {
1652 DBGPRINT(RT_DEBUG_ERROR,
1653 ("%s call RT28xxPciAsicRadioOff fail!\n",
1654 __func__));
1655 }
1656 }
1657/*
1658*/
1659}
1660
1661#endif /* RTMP_MAC_PCI // */
diff --git a/drivers/staging/rt2860/common/cmm_mac_usb.c b/drivers/staging/rt2860/common/cmm_mac_usb.c
deleted file mode 100644
index 64a65a460c2..00000000000
--- a/drivers/staging/rt2860/common/cmm_mac_usb.c
+++ /dev/null
@@ -1,1162 +0,0 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26*/
27
28#ifdef RTMP_MAC_USB
29
30#include "../rt_config.h"
31
32/*
33========================================================================
34Routine Description:
35 Initialize receive data structures.
36
37Arguments:
38 pAd Pointer to our adapter
39
40Return Value:
41 NDIS_STATUS_SUCCESS
42 NDIS_STATUS_RESOURCES
43
44Note:
45 Initialize all receive releated private buffer, include those define
46 in struct rt_rtmp_adapter structure and all private data structures. The mahor
47 work is to allocate buffer for each packet and chain buffer to
48 NDIS packet descriptor.
49========================================================================
50*/
51int NICInitRecv(struct rt_rtmp_adapter *pAd)
52{
53 u8 i;
54 int Status = NDIS_STATUS_SUCCESS;
55 struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
56
57 DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitRecv\n"));
58 pObj = pObj;
59
60 /*InterlockedExchange(&pAd->PendingRx, 0); */
61 pAd->PendingRx = 0;
62 pAd->NextRxBulkInReadIndex = 0; /* Next Rx Read index */
63 pAd->NextRxBulkInIndex = 0; /*RX_RING_SIZE -1; // Rx Bulk pointer */
64 pAd->NextRxBulkInPosition = 0;
65
66 for (i = 0; i < (RX_RING_SIZE); i++) {
67 struct rt_rx_context *pRxContext = &(pAd->RxContext[i]);
68
69 /*Allocate URB */
70 pRxContext->pUrb = RTUSB_ALLOC_URB(0);
71 if (pRxContext->pUrb == NULL) {
72 Status = NDIS_STATUS_RESOURCES;
73 goto out1;
74 }
75 /* Allocate transfer buffer */
76 pRxContext->TransferBuffer =
77 RTUSB_URB_ALLOC_BUFFER(pObj->pUsb_Dev, MAX_RXBULK_SIZE,
78 &pRxContext->data_dma);
79 if (pRxContext->TransferBuffer == NULL) {
80 Status = NDIS_STATUS_RESOURCES;
81 goto out1;
82 }
83
84 NdisZeroMemory(pRxContext->TransferBuffer, MAX_RXBULK_SIZE);
85
86 pRxContext->pAd = pAd;
87 pRxContext->pIrp = NULL;
88 pRxContext->InUse = FALSE;
89 pRxContext->IRPPending = FALSE;
90 pRxContext->Readable = FALSE;
91 /*pRxContext->ReorderInUse = FALSE; */
92 pRxContext->bRxHandling = FALSE;
93 pRxContext->BulkInOffset = 0;
94 }
95
96 DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitRecv(Status=%d)\n", Status));
97 return Status;
98
99out1:
100 for (i = 0; i < (RX_RING_SIZE); i++) {
101 struct rt_rx_context *pRxContext = &(pAd->RxContext[i]);
102
103 if (NULL != pRxContext->TransferBuffer) {
104 RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, MAX_RXBULK_SIZE,
105 pRxContext->TransferBuffer,
106 pRxContext->data_dma);
107 pRxContext->TransferBuffer = NULL;
108 }
109
110 if (NULL != pRxContext->pUrb) {
111 RTUSB_UNLINK_URB(pRxContext->pUrb);
112 RTUSB_FREE_URB(pRxContext->pUrb);
113 pRxContext->pUrb = NULL;
114 }
115 }
116
117 return Status;
118}
119
120/*
121========================================================================
122Routine Description:
123 Initialize transmit data structures.
124
125Arguments:
126 pAd Pointer to our adapter
127
128Return Value:
129 NDIS_STATUS_SUCCESS
130 NDIS_STATUS_RESOURCES
131
132Note:
133========================================================================
134*/
135int NICInitTransmit(struct rt_rtmp_adapter *pAd)
136{
137#define LM_USB_ALLOC(pObj, Context, TB_Type, BufferSize, Status, msg1, err1, msg2, err2) \
138 Context->pUrb = RTUSB_ALLOC_URB(0); \
139 if (Context->pUrb == NULL) { \
140 DBGPRINT(RT_DEBUG_ERROR, msg1); \
141 Status = NDIS_STATUS_RESOURCES; \
142 goto err1; } \
143 \
144 Context->TransferBuffer = \
145 (TB_Type)RTUSB_URB_ALLOC_BUFFER(pObj->pUsb_Dev, BufferSize, &Context->data_dma); \
146 if (Context->TransferBuffer == NULL) { \
147 DBGPRINT(RT_DEBUG_ERROR, msg2); \
148 Status = NDIS_STATUS_RESOURCES; \
149 goto err2; }
150
151#define LM_URB_FREE(pObj, Context, BufferSize) \
152 if (NULL != Context->pUrb) { \
153 RTUSB_UNLINK_URB(Context->pUrb); \
154 RTUSB_FREE_URB(Context->pUrb); \
155 Context->pUrb = NULL; } \
156 if (NULL != Context->TransferBuffer) { \
157 RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, BufferSize, \
158 Context->TransferBuffer, \
159 Context->data_dma); \
160 Context->TransferBuffer = NULL; }
161
162 u8 i, acidx;
163 int Status = NDIS_STATUS_SUCCESS;
164 struct rt_tx_context *pNullContext = &(pAd->NullContext);
165 struct rt_tx_context *pPsPollContext = &(pAd->PsPollContext);
166 struct rt_tx_context *pRTSContext = &(pAd->RTSContext);
167 struct rt_tx_context *pMLMEContext = NULL;
168/* struct rt_ht_tx_context *pHTTXContext = NULL; */
169 struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
170 void *RingBaseVa;
171/* struct rt_rtmp_tx_ring *pTxRing; */
172 struct rt_rtmp_mgmt_ring *pMgmtRing;
173
174 DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitTransmit\n"));
175 pObj = pObj;
176
177 /* Init 4 set of Tx parameters */
178 for (acidx = 0; acidx < NUM_OF_TX_RING; acidx++) {
179 /* Initialize all Transmit releated queues */
180 InitializeQueueHeader(&pAd->TxSwQueue[acidx]);
181
182 /* Next Local tx ring pointer waiting for buck out */
183 pAd->NextBulkOutIndex[acidx] = acidx;
184 pAd->BulkOutPending[acidx] = FALSE; /* Buck Out control flag */
185 /*pAd->DataBulkDoneIdx[acidx] = 0; */
186 }
187
188 /*pAd->NextMLMEIndex = 0; */
189 /*pAd->PushMgmtIndex = 0; */
190 /*pAd->PopMgmtIndex = 0; */
191 /*InterlockedExchange(&pAd->MgmtQueueSize, 0); */
192 /*InterlockedExchange(&pAd->TxCount, 0); */
193
194 /*pAd->PrioRingFirstIndex = 0; */
195 /*pAd->PrioRingTxCnt = 0; */
196
197 do {
198 /* */
199 /* TX_RING_SIZE, 4 ACs */
200 /* */
201 for (acidx = 0; acidx < 4; acidx++) {
202 struct rt_ht_tx_context *pHTTXContext = &(pAd->TxContext[acidx]);
203
204 NdisZeroMemory(pHTTXContext, sizeof(struct rt_ht_tx_context));
205 /*Allocate URB */
206 LM_USB_ALLOC(pObj, pHTTXContext, struct rt_httx_buffer *,
207 sizeof(struct rt_httx_buffer), Status,
208 ("<-- ERROR in Alloc TX TxContext[%d] urb!\n",
209 acidx), done,
210 ("<-- ERROR in Alloc TX TxContext[%d] struct rt_httx_buffer!\n",
211 acidx), out1);
212
213 NdisZeroMemory(pHTTXContext->TransferBuffer->
214 Aggregation, 4);
215 pHTTXContext->pAd = pAd;
216 pHTTXContext->pIrp = NULL;
217 pHTTXContext->IRPPending = FALSE;
218 pHTTXContext->NextBulkOutPosition = 0;
219 pHTTXContext->ENextBulkOutPosition = 0;
220 pHTTXContext->CurWritePosition = 0;
221 pHTTXContext->CurWriteRealPos = 0;
222 pHTTXContext->BulkOutSize = 0;
223 pHTTXContext->BulkOutPipeId = acidx;
224 pHTTXContext->bRingEmpty = TRUE;
225 pHTTXContext->bCopySavePad = FALSE;
226 pAd->BulkOutPending[acidx] = FALSE;
227 }
228
229 /* */
230 /* MGMT_RING_SIZE */
231 /* */
232
233 /* Allocate MGMT ring descriptor's memory */
234 pAd->MgmtDescRing.AllocSize =
235 MGMT_RING_SIZE * sizeof(struct rt_tx_context);
236 os_alloc_mem(pAd, (u8 **) (&pAd->MgmtDescRing.AllocVa),
237 pAd->MgmtDescRing.AllocSize);
238 if (pAd->MgmtDescRing.AllocVa == NULL) {
239 DBGPRINT_ERR("Failed to allocate a big buffer for MgmtDescRing!\n");
240 Status = NDIS_STATUS_RESOURCES;
241 goto out1;
242 }
243 NdisZeroMemory(pAd->MgmtDescRing.AllocVa,
244 pAd->MgmtDescRing.AllocSize);
245 RingBaseVa = pAd->MgmtDescRing.AllocVa;
246
247 /* Initialize MGMT Ring and associated buffer memory */
248 pMgmtRing = &pAd->MgmtRing;
249 for (i = 0; i < MGMT_RING_SIZE; i++) {
250 /* link the pre-allocated Mgmt buffer to MgmtRing.Cell */
251 pMgmtRing->Cell[i].AllocSize = sizeof(struct rt_tx_context);
252 pMgmtRing->Cell[i].AllocVa = RingBaseVa;
253 pMgmtRing->Cell[i].pNdisPacket = NULL;
254 pMgmtRing->Cell[i].pNextNdisPacket = NULL;
255
256 /*Allocate URB for MLMEContext */
257 pMLMEContext =
258 (struct rt_tx_context *)pAd->MgmtRing.Cell[i].AllocVa;
259 pMLMEContext->pUrb = RTUSB_ALLOC_URB(0);
260 if (pMLMEContext->pUrb == NULL) {
261 DBGPRINT(RT_DEBUG_ERROR,
262 ("<-- ERROR in Alloc TX MLMEContext[%d] urb!\n",
263 i));
264 Status = NDIS_STATUS_RESOURCES;
265 goto out2;
266 }
267 pMLMEContext->pAd = pAd;
268 pMLMEContext->pIrp = NULL;
269 pMLMEContext->TransferBuffer = NULL;
270 pMLMEContext->InUse = FALSE;
271 pMLMEContext->IRPPending = FALSE;
272 pMLMEContext->bWaitingBulkOut = FALSE;
273 pMLMEContext->BulkOutSize = 0;
274 pMLMEContext->SelfIdx = i;
275
276 /* Offset to next ring descriptor address */
277 RingBaseVa = (u8 *)RingBaseVa + sizeof(struct rt_tx_context);
278 }
279 DBGPRINT(RT_DEBUG_TRACE,
280 ("MGMT Ring: total %d entry allocated\n", i));
281
282 /*pAd->MgmtRing.TxSwFreeIdx = (MGMT_RING_SIZE - 1); */
283 pAd->MgmtRing.TxSwFreeIdx = MGMT_RING_SIZE;
284 pAd->MgmtRing.TxCpuIdx = 0;
285 pAd->MgmtRing.TxDmaIdx = 0;
286
287 /* */
288 /* BEACON_RING_SIZE */
289 /* */
290 for (i = 0; i < BEACON_RING_SIZE; i++) /* 2 */
291 {
292 struct rt_tx_context *pBeaconContext = &(pAd->BeaconContext[i]);
293
294 NdisZeroMemory(pBeaconContext, sizeof(struct rt_tx_context));
295
296 /*Allocate URB */
297 LM_USB_ALLOC(pObj, pBeaconContext, struct rt_tx_buffer *,
298 sizeof(struct rt_tx_buffer), Status,
299 ("<-- ERROR in Alloc TX BeaconContext[%d] urb!\n",
300 i), out2,
301 ("<-- ERROR in Alloc TX BeaconContext[%d] struct rt_tx_buffer!\n",
302 i), out3);
303
304 pBeaconContext->pAd = pAd;
305 pBeaconContext->pIrp = NULL;
306 pBeaconContext->InUse = FALSE;
307 pBeaconContext->IRPPending = FALSE;
308 }
309
310 /* */
311 /* NullContext */
312 /* */
313 NdisZeroMemory(pNullContext, sizeof(struct rt_tx_context));
314
315 /*Allocate URB */
316 LM_USB_ALLOC(pObj, pNullContext, struct rt_tx_buffer *, sizeof(struct rt_tx_buffer),
317 Status,
318 ("<-- ERROR in Alloc TX NullContext urb!\n"),
319 out3,
320 ("<-- ERROR in Alloc TX NullContext struct rt_tx_buffer!\n"),
321 out4);
322
323 pNullContext->pAd = pAd;
324 pNullContext->pIrp = NULL;
325 pNullContext->InUse = FALSE;
326 pNullContext->IRPPending = FALSE;
327
328 /* */
329 /* RTSContext */
330 /* */
331 NdisZeroMemory(pRTSContext, sizeof(struct rt_tx_context));
332
333 /*Allocate URB */
334 LM_USB_ALLOC(pObj, pRTSContext, struct rt_tx_buffer *, sizeof(struct rt_tx_buffer),
335 Status,
336 ("<-- ERROR in Alloc TX RTSContext urb!\n"),
337 out4,
338 ("<-- ERROR in Alloc TX RTSContext struct rt_tx_buffer!\n"),
339 out5);
340
341 pRTSContext->pAd = pAd;
342 pRTSContext->pIrp = NULL;
343 pRTSContext->InUse = FALSE;
344 pRTSContext->IRPPending = FALSE;
345
346 /* */
347 /* PsPollContext */
348 /* */
349 /*NdisZeroMemory(pPsPollContext, sizeof(struct rt_tx_context)); */
350 /*Allocate URB */
351 LM_USB_ALLOC(pObj, pPsPollContext, struct rt_tx_buffer *,
352 sizeof(struct rt_tx_buffer), Status,
353 ("<-- ERROR in Alloc TX PsPollContext urb!\n"),
354 out5,
355 ("<-- ERROR in Alloc TX PsPollContext struct rt_tx_buffer!\n"),
356 out6);
357
358 pPsPollContext->pAd = pAd;
359 pPsPollContext->pIrp = NULL;
360 pPsPollContext->InUse = FALSE;
361 pPsPollContext->IRPPending = FALSE;
362 pPsPollContext->bAggregatible = FALSE;
363 pPsPollContext->LastOne = TRUE;
364
365 } while (FALSE);
366
367done:
368 DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitTransmit(Status=%d)\n", Status));
369
370 return Status;
371
372 /* --------------------------- ERROR HANDLE --------------------------- */
373out6:
374 LM_URB_FREE(pObj, pPsPollContext, sizeof(struct rt_tx_buffer));
375
376out5:
377 LM_URB_FREE(pObj, pRTSContext, sizeof(struct rt_tx_buffer));
378
379out4:
380 LM_URB_FREE(pObj, pNullContext, sizeof(struct rt_tx_buffer));
381
382out3:
383 for (i = 0; i < BEACON_RING_SIZE; i++) {
384 struct rt_tx_context *pBeaconContext = &(pAd->BeaconContext[i]);
385 if (pBeaconContext)
386 LM_URB_FREE(pObj, pBeaconContext, sizeof(struct rt_tx_buffer));
387 }
388
389out2:
390 if (pAd->MgmtDescRing.AllocVa) {
391 pMgmtRing = &pAd->MgmtRing;
392 for (i = 0; i < MGMT_RING_SIZE; i++) {
393 pMLMEContext =
394 (struct rt_tx_context *)pAd->MgmtRing.Cell[i].AllocVa;
395 if (pMLMEContext)
396 LM_URB_FREE(pObj, pMLMEContext,
397 sizeof(struct rt_tx_buffer));
398 }
399 os_free_mem(pAd, pAd->MgmtDescRing.AllocVa);
400 pAd->MgmtDescRing.AllocVa = NULL;
401 }
402
403out1:
404 for (acidx = 0; acidx < 4; acidx++) {
405 struct rt_ht_tx_context *pTxContext = &(pAd->TxContext[acidx]);
406 if (pTxContext)
407 LM_URB_FREE(pObj, pTxContext, sizeof(struct rt_httx_buffer));
408 }
409
410 /* Here we didn't have any pre-allocated memory need to free. */
411
412 return Status;
413}
414
415/*
416========================================================================
417Routine Description:
418 Allocate DMA memory blocks for send, receive.
419
420Arguments:
421 pAd Pointer to our adapter
422
423Return Value:
424 NDIS_STATUS_SUCCESS
425 NDIS_STATUS_FAILURE
426 NDIS_STATUS_RESOURCES
427
428Note:
429========================================================================
430*/
431int RTMPAllocTxRxRingMemory(struct rt_rtmp_adapter *pAd)
432{
433/* struct rt_counter_802_11 pCounter = &pAd->WlanCounters; */
434 int Status;
435 int num;
436
437 DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocTxRxRingMemory\n"));
438
439 do {
440 /* Init the struct rt_cmdq and CmdQLock */
441 NdisAllocateSpinLock(&pAd->CmdQLock);
442 NdisAcquireSpinLock(&pAd->CmdQLock);
443 RTUSBInitializeCmdQ(&pAd->CmdQ);
444 NdisReleaseSpinLock(&pAd->CmdQLock);
445
446 NdisAllocateSpinLock(&pAd->MLMEBulkOutLock);
447 /*NdisAllocateSpinLock(&pAd->MLMEWaitQueueLock); */
448 NdisAllocateSpinLock(&pAd->BulkOutLock[0]);
449 NdisAllocateSpinLock(&pAd->BulkOutLock[1]);
450 NdisAllocateSpinLock(&pAd->BulkOutLock[2]);
451 NdisAllocateSpinLock(&pAd->BulkOutLock[3]);
452 NdisAllocateSpinLock(&pAd->BulkOutLock[4]);
453 NdisAllocateSpinLock(&pAd->BulkOutLock[5]);
454 NdisAllocateSpinLock(&pAd->BulkInLock);
455
456 for (num = 0; num < NUM_OF_TX_RING; num++) {
457 NdisAllocateSpinLock(&pAd->TxContextQueueLock[num]);
458 }
459
460/* NdisAllocateSpinLock(&pAd->MemLock); // Not used in RT28XX */
461
462/* NdisAllocateSpinLock(&pAd->MacTabLock); // init it in UserCfgInit() */
463/* NdisAllocateSpinLock(&pAd->BATabLock); // init it in BATableInit() */
464
465/* for(num=0; num<MAX_LEN_OF_BA_REC_TABLE; num++) */
466/* { */
467/* NdisAllocateSpinLock(&pAd->BATable.BARecEntry[num].RxReRingLock); */
468/* } */
469
470 /* */
471 /* Init Mac Table */
472 /* */
473/* MacTableInitialize(pAd); */
474
475 /* */
476 /* Init send data structures and related parameters */
477 /* */
478 Status = NICInitTransmit(pAd);
479 if (Status != NDIS_STATUS_SUCCESS)
480 break;
481
482 /* */
483 /* Init receive data structures and related parameters */
484 /* */
485 Status = NICInitRecv(pAd);
486 if (Status != NDIS_STATUS_SUCCESS)
487 break;
488
489 pAd->PendingIoCount = 1;
490
491 } while (FALSE);
492
493 NdisZeroMemory(&pAd->FragFrame, sizeof(struct rt_fragment_frame));
494 pAd->FragFrame.pFragPacket =
495 RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE);
496
497 if (pAd->FragFrame.pFragPacket == NULL) {
498 Status = NDIS_STATUS_RESOURCES;
499 }
500
501 DBGPRINT_S(Status,
502 ("<-- RTMPAllocTxRxRingMemory, Status=%x\n", Status));
503 return Status;
504}
505
506/*
507========================================================================
508Routine Description:
509 Calls USB_InterfaceStop and frees memory allocated for the URBs
510 calls NdisMDeregisterDevice and frees the memory
511 allocated in VNetInitialize for the Adapter Object
512
513Arguments:
514 *pAd the raxx interface data pointer
515
516Return Value:
517 None
518
519Note:
520========================================================================
521*/
522void RTMPFreeTxRxRingMemory(struct rt_rtmp_adapter *pAd)
523{
524#define LM_URB_FREE(pObj, Context, BufferSize) \
525 if (NULL != Context->pUrb) { \
526 RTUSB_UNLINK_URB(Context->pUrb); \
527 RTUSB_FREE_URB(Context->pUrb); \
528 Context->pUrb = NULL; } \
529 if (NULL != Context->TransferBuffer) { \
530 RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, BufferSize, \
531 Context->TransferBuffer, \
532 Context->data_dma); \
533 Context->TransferBuffer = NULL; }
534
535 u32 i, acidx;
536 struct rt_tx_context *pNullContext = &pAd->NullContext;
537 struct rt_tx_context *pPsPollContext = &pAd->PsPollContext;
538 struct rt_tx_context *pRTSContext = &pAd->RTSContext;
539/* struct rt_ht_tx_context *pHTTXContext; */
540 /*PRTMP_REORDERBUF pReorderBuf; */
541 struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
542/* struct rt_rtmp_tx_ring *pTxRing; */
543
544 DBGPRINT(RT_DEBUG_ERROR, ("---> RTMPFreeTxRxRingMemory\n"));
545 pObj = pObj;
546
547 /* Free all resources for the RECEIVE buffer queue. */
548 for (i = 0; i < (RX_RING_SIZE); i++) {
549 struct rt_rx_context *pRxContext = &(pAd->RxContext[i]);
550 if (pRxContext)
551 LM_URB_FREE(pObj, pRxContext, MAX_RXBULK_SIZE);
552 }
553
554 /* Free PsPoll frame resource */
555 LM_URB_FREE(pObj, pPsPollContext, sizeof(struct rt_tx_buffer));
556
557 /* Free NULL frame resource */
558 LM_URB_FREE(pObj, pNullContext, sizeof(struct rt_tx_buffer));
559
560 /* Free RTS frame resource */
561 LM_URB_FREE(pObj, pRTSContext, sizeof(struct rt_tx_buffer));
562
563 /* Free beacon frame resource */
564 for (i = 0; i < BEACON_RING_SIZE; i++) {
565 struct rt_tx_context *pBeaconContext = &(pAd->BeaconContext[i]);
566 if (pBeaconContext)
567 LM_URB_FREE(pObj, pBeaconContext, sizeof(struct rt_tx_buffer));
568 }
569
570 /* Free mgmt frame resource */
571 for (i = 0; i < MGMT_RING_SIZE; i++) {
572 struct rt_tx_context *pMLMEContext =
573 (struct rt_tx_context *)pAd->MgmtRing.Cell[i].AllocVa;
574 /*LM_URB_FREE(pObj, pMLMEContext, sizeof(struct rt_tx_buffer)); */
575 if (NULL != pAd->MgmtRing.Cell[i].pNdisPacket) {
576 RTMPFreeNdisPacket(pAd,
577 pAd->MgmtRing.Cell[i].pNdisPacket);
578 pAd->MgmtRing.Cell[i].pNdisPacket = NULL;
579 pMLMEContext->TransferBuffer = NULL;
580 }
581
582 if (pMLMEContext) {
583 if (NULL != pMLMEContext->pUrb) {
584 RTUSB_UNLINK_URB(pMLMEContext->pUrb);
585 RTUSB_FREE_URB(pMLMEContext->pUrb);
586 pMLMEContext->pUrb = NULL;
587 }
588 }
589 }
590 if (pAd->MgmtDescRing.AllocVa)
591 os_free_mem(pAd, pAd->MgmtDescRing.AllocVa);
592
593 /* Free Tx frame resource */
594 for (acidx = 0; acidx < 4; acidx++) {
595 struct rt_ht_tx_context *pHTTXContext = &(pAd->TxContext[acidx]);
596 if (pHTTXContext)
597 LM_URB_FREE(pObj, pHTTXContext, sizeof(struct rt_httx_buffer));
598 }
599
600 if (pAd->FragFrame.pFragPacket)
601 RELEASE_NDIS_PACKET(pAd, pAd->FragFrame.pFragPacket,
602 NDIS_STATUS_SUCCESS);
603
604 for (i = 0; i < 6; i++) {
605 NdisFreeSpinLock(&pAd->BulkOutLock[i]);
606 }
607
608 NdisFreeSpinLock(&pAd->BulkInLock);
609 NdisFreeSpinLock(&pAd->MLMEBulkOutLock);
610
611 NdisFreeSpinLock(&pAd->CmdQLock);
612 /* Clear all pending bulk-out request flags. */
613 RTUSB_CLEAR_BULK_FLAG(pAd, 0xffffffff);
614
615/* NdisFreeSpinLock(&pAd->MacTabLock); */
616
617/* for(i=0; i<MAX_LEN_OF_BA_REC_TABLE; i++) */
618/* { */
619/* NdisFreeSpinLock(&pAd->BATable.BARecEntry[i].RxReRingLock); */
620/* } */
621
622 DBGPRINT(RT_DEBUG_ERROR, ("<--- RTMPFreeTxRxRingMemory\n"));
623}
624
625/*
626========================================================================
627Routine Description:
628 Write WLAN MAC address to USB 2870.
629
630Arguments:
631 pAd Pointer to our adapter
632
633Return Value:
634 NDIS_STATUS_SUCCESS
635
636Note:
637========================================================================
638*/
639int RTUSBWriteHWMACAddress(struct rt_rtmp_adapter *pAd)
640{
641 MAC_DW0_STRUC StaMacReg0;
642 MAC_DW1_STRUC StaMacReg1;
643 int Status = NDIS_STATUS_SUCCESS;
644 LARGE_INTEGER NOW;
645
646 /* initialize the random number generator */
647 RTMP_GetCurrentSystemTime(&NOW);
648
649 if (pAd->bLocalAdminMAC != TRUE) {
650 pAd->CurrentAddress[0] = pAd->PermanentAddress[0];
651 pAd->CurrentAddress[1] = pAd->PermanentAddress[1];
652 pAd->CurrentAddress[2] = pAd->PermanentAddress[2];
653 pAd->CurrentAddress[3] = pAd->PermanentAddress[3];
654 pAd->CurrentAddress[4] = pAd->PermanentAddress[4];
655 pAd->CurrentAddress[5] = pAd->PermanentAddress[5];
656 }
657 /* Write New MAC address to MAC_CSR2 & MAC_CSR3 & let ASIC know our new MAC */
658 StaMacReg0.field.Byte0 = pAd->CurrentAddress[0];
659 StaMacReg0.field.Byte1 = pAd->CurrentAddress[1];
660 StaMacReg0.field.Byte2 = pAd->CurrentAddress[2];
661 StaMacReg0.field.Byte3 = pAd->CurrentAddress[3];
662 StaMacReg1.field.Byte4 = pAd->CurrentAddress[4];
663 StaMacReg1.field.Byte5 = pAd->CurrentAddress[5];
664 StaMacReg1.field.U2MeMask = 0xff;
665 DBGPRINT_RAW(RT_DEBUG_TRACE,
666 ("Local MAC = %pM\n", pAd->CurrentAddress));
667
668 RTUSBWriteMACRegister(pAd, MAC_ADDR_DW0, StaMacReg0.word);
669 RTUSBWriteMACRegister(pAd, MAC_ADDR_DW1, StaMacReg1.word);
670 return Status;
671}
672
673/*
674========================================================================
675Routine Description:
676 Disable DMA.
677
678Arguments:
679 *pAd the raxx interface data pointer
680
681Return Value:
682 None
683
684Note:
685========================================================================
686*/
687void RT28XXDMADisable(struct rt_rtmp_adapter *pAd)
688{
689 /* no use */
690}
691
692/*
693========================================================================
694Routine Description:
695 Enable DMA.
696
697Arguments:
698 *pAd the raxx interface data pointer
699
700Return Value:
701 None
702
703Note:
704========================================================================
705*/
706void RT28XXDMAEnable(struct rt_rtmp_adapter *pAd)
707{
708 WPDMA_GLO_CFG_STRUC GloCfg;
709 USB_DMA_CFG_STRUC UsbCfg;
710 int i = 0;
711
712 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x4);
713 do {
714 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
715 if ((GloCfg.field.TxDMABusy == 0)
716 && (GloCfg.field.RxDMABusy == 0))
717 break;
718
719 DBGPRINT(RT_DEBUG_TRACE, ("==> DMABusy\n"));
720 RTMPusecDelay(1000);
721 i++;
722 } while (i < 200);
723
724 RTMPusecDelay(50);
725 GloCfg.field.EnTXWriteBackDDONE = 1;
726 GloCfg.field.EnableRxDMA = 1;
727 GloCfg.field.EnableTxDMA = 1;
728 DBGPRINT(RT_DEBUG_TRACE,
729 ("<== WRITE DMA offset 0x208 = 0x%x\n", GloCfg.word));
730 RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
731
732 UsbCfg.word = 0;
733 UsbCfg.field.phyclear = 0;
734 /* usb version is 1.1,do not use bulk in aggregation */
735 if (pAd->BulkInMaxPacketSize == 512)
736 UsbCfg.field.RxBulkAggEn = 1;
737 /* for last packet, PBF might use more than limited, so minus 2 to prevent from error */
738 UsbCfg.field.RxBulkAggLmt = (MAX_RXBULK_SIZE / 1024) - 3;
739 UsbCfg.field.RxBulkAggTOut = 0x80; /* 2006-10-18 */
740 UsbCfg.field.RxBulkEn = 1;
741 UsbCfg.field.TxBulkEn = 1;
742
743 RTUSBWriteMACRegister(pAd, USB_DMA_CFG, UsbCfg.word);
744
745}
746
747/********************************************************************
748 *
749 * 2870 Beacon Update Related functions.
750 *
751 ********************************************************************/
752
753/*
754========================================================================
755Routine Description:
756 Write Beacon buffer to Asic.
757
758Arguments:
759 *pAd the raxx interface data pointer
760
761Return Value:
762 None
763
764Note:
765========================================================================
766*/
767void RT28xx_UpdateBeaconToAsic(struct rt_rtmp_adapter *pAd,
768 int apidx,
769 unsigned long FrameLen, unsigned long UpdatePos)
770{
771 u8 *pBeaconFrame = NULL;
772 u8 *ptr;
773 u32 i, padding;
774 struct rt_beacon_sync *pBeaconSync = pAd->CommonCfg.pBeaconSync;
775 u32 longValue;
776/* u16 shortValue; */
777 BOOLEAN bBcnReq = FALSE;
778 u8 bcn_idx = 0;
779
780 if (pBeaconFrame == NULL) {
781 DBGPRINT(RT_DEBUG_ERROR, ("pBeaconFrame is NULL!\n"));
782 return;
783 }
784
785 if (pBeaconSync == NULL) {
786 DBGPRINT(RT_DEBUG_ERROR, ("pBeaconSync is NULL!\n"));
787 return;
788 }
789 /*if ((pAd->WdsTab.Mode == WDS_BRIDGE_MODE) || */
790 /* ((pAd->ApCfg.MBSSID[apidx].MSSIDDev == NULL) || !(pAd->ApCfg.MBSSID[apidx].MSSIDDev->flags & IFF_UP)) */
791 /* ) */
792 if (bBcnReq == FALSE) {
793 /* when the ra interface is down, do not send its beacon frame */
794 /* clear all zero */
795 for (i = 0; i < TXWI_SIZE; i += 4) {
796 RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i,
797 0x00);
798 }
799 pBeaconSync->BeaconBitMap &=
800 (~(BEACON_BITMAP_MASK & (1 << bcn_idx)));
801 NdisZeroMemory(pBeaconSync->BeaconTxWI[bcn_idx], TXWI_SIZE);
802 } else {
803 ptr = (u8 *)& pAd->BeaconTxWI;
804 if (NdisEqualMemory(pBeaconSync->BeaconTxWI[bcn_idx], &pAd->BeaconTxWI, TXWI_SIZE) == FALSE) { /* If BeaconTxWI changed, we need to rewrite the TxWI for the Beacon frames. */
805 pBeaconSync->BeaconBitMap &=
806 (~(BEACON_BITMAP_MASK & (1 << bcn_idx)));
807 NdisMoveMemory(pBeaconSync->BeaconTxWI[bcn_idx],
808 &pAd->BeaconTxWI, TXWI_SIZE);
809 }
810
811 if ((pBeaconSync->BeaconBitMap & (1 << bcn_idx)) !=
812 (1 << bcn_idx)) {
813 for (i = 0; i < TXWI_SIZE; i += 4) /* 16-byte TXWI field */
814 {
815 longValue =
816 *ptr + (*(ptr + 1) << 8) +
817 (*(ptr + 2) << 16) + (*(ptr + 3) << 24);
818 RTMP_IO_WRITE32(pAd,
819 pAd->BeaconOffset[bcn_idx] + i,
820 longValue);
821 ptr += 4;
822 }
823 }
824
825 ptr = pBeaconSync->BeaconBuf[bcn_idx];
826 padding = (FrameLen & 0x01);
827 NdisZeroMemory((u8 *)(pBeaconFrame + FrameLen), padding);
828 FrameLen += padding;
829 for (i = 0; i < FrameLen /*HW_BEACON_OFFSET */ ; i += 2) {
830 if (NdisEqualMemory(ptr, pBeaconFrame, 2) == FALSE) {
831 NdisMoveMemory(ptr, pBeaconFrame, 2);
832 /*shortValue = *ptr + (*(ptr+1)<<8); */
833 /*RTMP_IO_WRITE8(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, shortValue); */
834 RTUSBMultiWrite(pAd,
835 pAd->BeaconOffset[bcn_idx] +
836 TXWI_SIZE + i, ptr, 2);
837 }
838 ptr += 2;
839 pBeaconFrame += 2;
840 }
841
842 pBeaconSync->BeaconBitMap |= (1 << bcn_idx);
843
844 /* For AP interface, set the DtimBitOn so that we can send Bcast/Mcast frame out after this beacon frame. */
845 }
846
847}
848
849void RTUSBBssBeaconStop(struct rt_rtmp_adapter *pAd)
850{
851 struct rt_beacon_sync *pBeaconSync;
852 int i, offset;
853 BOOLEAN Cancelled = TRUE;
854
855 pBeaconSync = pAd->CommonCfg.pBeaconSync;
856 if (pBeaconSync && pBeaconSync->EnableBeacon) {
857 int NumOfBcn;
858
859 {
860 NumOfBcn = MAX_MESH_NUM;
861 }
862
863 RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled);
864
865 for (i = 0; i < NumOfBcn; i++) {
866 NdisZeroMemory(pBeaconSync->BeaconBuf[i],
867 HW_BEACON_OFFSET);
868 NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
869
870 for (offset = 0; offset < HW_BEACON_OFFSET; offset += 4)
871 RTMP_IO_WRITE32(pAd,
872 pAd->BeaconOffset[i] + offset,
873 0x00);
874
875 pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
876 pBeaconSync->TimIELocationInBeacon[i] = 0;
877 }
878 pBeaconSync->BeaconBitMap = 0;
879 pBeaconSync->DtimBitOn = 0;
880 }
881}
882
883void RTUSBBssBeaconStart(struct rt_rtmp_adapter *pAd)
884{
885 int apidx;
886 struct rt_beacon_sync *pBeaconSync;
887/* LARGE_INTEGER tsfTime, deltaTime; */
888
889 pBeaconSync = pAd->CommonCfg.pBeaconSync;
890 if (pBeaconSync && pBeaconSync->EnableBeacon) {
891 int NumOfBcn;
892
893 {
894 NumOfBcn = MAX_MESH_NUM;
895 }
896
897 for (apidx = 0; apidx < NumOfBcn; apidx++) {
898 u8 CapabilityInfoLocationInBeacon = 0;
899 u8 TimIELocationInBeacon = 0;
900
901 NdisZeroMemory(pBeaconSync->BeaconBuf[apidx],
902 HW_BEACON_OFFSET);
903 pBeaconSync->CapabilityInfoLocationInBeacon[apidx] =
904 CapabilityInfoLocationInBeacon;
905 pBeaconSync->TimIELocationInBeacon[apidx] =
906 TimIELocationInBeacon;
907 NdisZeroMemory(pBeaconSync->BeaconTxWI[apidx],
908 TXWI_SIZE);
909 }
910 pBeaconSync->BeaconBitMap = 0;
911 pBeaconSync->DtimBitOn = 0;
912 pAd->CommonCfg.BeaconUpdateTimer.Repeat = TRUE;
913
914 pAd->CommonCfg.BeaconAdjust = 0;
915 pAd->CommonCfg.BeaconFactor =
916 0xffffffff / (pAd->CommonCfg.BeaconPeriod << 10);
917 pAd->CommonCfg.BeaconRemain =
918 (0xffffffff % (pAd->CommonCfg.BeaconPeriod << 10)) + 1;
919 DBGPRINT(RT_DEBUG_TRACE,
920 ("RTUSBBssBeaconStart:BeaconFactor=%d, BeaconRemain=%d!\n",
921 pAd->CommonCfg.BeaconFactor,
922 pAd->CommonCfg.BeaconRemain));
923 RTMPSetTimer(&pAd->CommonCfg.BeaconUpdateTimer,
924 10 /*pAd->CommonCfg.BeaconPeriod */ );
925
926 }
927}
928
929void RTUSBBssBeaconInit(struct rt_rtmp_adapter *pAd)
930{
931 struct rt_beacon_sync *pBeaconSync;
932 int i;
933
934 os_alloc_mem(pAd, (u8 **) (&pAd->CommonCfg.pBeaconSync),
935 sizeof(struct rt_beacon_sync));
936 /*NdisAllocMemory(pAd->CommonCfg.pBeaconSync, sizeof(struct rt_beacon_sync), MEM_ALLOC_FLAG); */
937 if (pAd->CommonCfg.pBeaconSync) {
938 pBeaconSync = pAd->CommonCfg.pBeaconSync;
939 NdisZeroMemory(pBeaconSync, sizeof(struct rt_beacon_sync));
940 for (i = 0; i < HW_BEACON_MAX_COUNT; i++) {
941 NdisZeroMemory(pBeaconSync->BeaconBuf[i],
942 HW_BEACON_OFFSET);
943 pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
944 pBeaconSync->TimIELocationInBeacon[i] = 0;
945 NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
946 }
947 pBeaconSync->BeaconBitMap = 0;
948
949 /*RTMPInitTimer(pAd, &pAd->CommonCfg.BeaconUpdateTimer, GET_TIMER_FUNCTION(BeaconUpdateExec), pAd, TRUE); */
950 pBeaconSync->EnableBeacon = TRUE;
951 }
952}
953
954void RTUSBBssBeaconExit(struct rt_rtmp_adapter *pAd)
955{
956 struct rt_beacon_sync *pBeaconSync;
957 BOOLEAN Cancelled = TRUE;
958 int i;
959
960 if (pAd->CommonCfg.pBeaconSync) {
961 pBeaconSync = pAd->CommonCfg.pBeaconSync;
962 pBeaconSync->EnableBeacon = FALSE;
963 RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled);
964 pBeaconSync->BeaconBitMap = 0;
965
966 for (i = 0; i < HW_BEACON_MAX_COUNT; i++) {
967 NdisZeroMemory(pBeaconSync->BeaconBuf[i],
968 HW_BEACON_OFFSET);
969 pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
970 pBeaconSync->TimIELocationInBeacon[i] = 0;
971 NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
972 }
973
974 os_free_mem(pAd, pAd->CommonCfg.pBeaconSync);
975 pAd->CommonCfg.pBeaconSync = NULL;
976 }
977}
978
979/*
980 ========================================================================
981 Routine Description:
982 For device work as AP mode but didn't have TBTT interrupt event, we need a mechanism
983 to update the beacon context in each Beacon interval. Here we use a periodical timer
984 to simulate the TBTT interrupt to handle the beacon context update.
985
986 Arguments:
987 SystemSpecific1 - Not used.
988 FunctionContext - Pointer to our Adapter context.
989 SystemSpecific2 - Not used.
990 SystemSpecific3 - Not used.
991
992 Return Value:
993 None
994
995 ========================================================================
996*/
997void BeaconUpdateExec(void *SystemSpecific1,
998 void *FunctionContext,
999 void *SystemSpecific2, void *SystemSpecific3)
1000{
1001 struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext;
1002 LARGE_INTEGER tsfTime_a; /*, tsfTime_b, deltaTime_exp, deltaTime_ab; */
1003 u32 delta, delta2MS, period2US, remain, remain_low, remain_high;
1004/* BOOLEAN positive; */
1005
1006 if (pAd->CommonCfg.IsUpdateBeacon == TRUE) {
1007 ReSyncBeaconTime(pAd);
1008
1009 }
1010
1011 RTMP_IO_READ32(pAd, TSF_TIMER_DW0, &tsfTime_a.u.LowPart);
1012 RTMP_IO_READ32(pAd, TSF_TIMER_DW1, &tsfTime_a.u.HighPart);
1013
1014 /*positive=getDeltaTime(tsfTime_a, expectedTime, &deltaTime_exp); */
1015 period2US = (pAd->CommonCfg.BeaconPeriod << 10);
1016 remain_high = pAd->CommonCfg.BeaconRemain * tsfTime_a.u.HighPart;
1017 remain_low = tsfTime_a.u.LowPart % (pAd->CommonCfg.BeaconPeriod << 10);
1018 remain =
1019 (remain_high + remain_low) % (pAd->CommonCfg.BeaconPeriod << 10);
1020 delta = (pAd->CommonCfg.BeaconPeriod << 10) - remain;
1021
1022 delta2MS = (delta >> 10);
1023 if (delta2MS > 150) {
1024 pAd->CommonCfg.BeaconUpdateTimer.TimerValue = 100;
1025 pAd->CommonCfg.IsUpdateBeacon = FALSE;
1026 } else {
1027 pAd->CommonCfg.BeaconUpdateTimer.TimerValue = delta2MS + 10;
1028 pAd->CommonCfg.IsUpdateBeacon = TRUE;
1029 }
1030
1031}
1032
1033/********************************************************************
1034 *
1035 * 2870 Radio on/off Related functions.
1036 *
1037 ********************************************************************/
1038void RT28xxUsbMlmeRadioOn(struct rt_rtmp_adapter *pAd)
1039{
1040 struct rt_rtmp_chip_op *pChipOps = &pAd->chipOps;
1041
1042 DBGPRINT(RT_DEBUG_TRACE, ("RT28xxUsbMlmeRadioOn()\n"));
1043
1044 if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
1045 return;
1046
1047 {
1048 AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02);
1049 RTMPusecDelay(10000);
1050 }
1051 /*NICResetFromError(pAd); */
1052
1053 /* Enable Tx/Rx */
1054 RTMPEnableRxTx(pAd);
1055
1056 if (pChipOps->AsicReverseRfFromSleepMode)
1057 pChipOps->AsicReverseRfFromSleepMode(pAd);
1058
1059 /* Clear Radio off flag */
1060 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
1061
1062 RTUSBBulkReceive(pAd);
1063
1064 /* Set LED */
1065 RTMPSetLED(pAd, LED_RADIO_ON);
1066}
1067
1068void RT28xxUsbMlmeRadioOFF(struct rt_rtmp_adapter *pAd)
1069{
1070 WPDMA_GLO_CFG_STRUC GloCfg;
1071 u32 Value, i;
1072
1073 DBGPRINT(RT_DEBUG_TRACE, ("RT28xxUsbMlmeRadioOFF()\n"));
1074
1075 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
1076 return;
1077
1078 /* Clear PMKID cache. */
1079 pAd->StaCfg.SavedPMKNum = 0;
1080 RTMPZeroMemory(pAd->StaCfg.SavedPMK, (PMKID_NO * sizeof(struct rt_bssid_info)));
1081
1082 /* Link down first if any association exists */
1083 if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) {
1084 if (INFRA_ON(pAd) || ADHOC_ON(pAd)) {
1085 struct rt_mlme_disassoc_req DisReq;
1086 struct rt_mlme_queue_elem *pMsgElem =
1087 kmalloc(sizeof(struct rt_mlme_queue_elem),
1088 MEM_ALLOC_FLAG);
1089
1090 if (pMsgElem) {
1091 COPY_MAC_ADDR(&DisReq.Addr,
1092 pAd->CommonCfg.Bssid);
1093 DisReq.Reason = REASON_DISASSOC_STA_LEAVING;
1094
1095 pMsgElem->Machine = ASSOC_STATE_MACHINE;
1096 pMsgElem->MsgType = MT2_MLME_DISASSOC_REQ;
1097 pMsgElem->MsgLen =
1098 sizeof(struct rt_mlme_disassoc_req);
1099 NdisMoveMemory(pMsgElem->Msg, &DisReq,
1100 sizeof
1101 (struct rt_mlme_disassoc_req));
1102
1103 MlmeDisassocReqAction(pAd, pMsgElem);
1104 kfree(pMsgElem);
1105
1106 RTMPusecDelay(1000);
1107 }
1108 }
1109 }
1110 /* Set Radio off flag */
1111 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
1112
1113 {
1114 /* Link down first if any association exists */
1115 if (INFRA_ON(pAd) || ADHOC_ON(pAd))
1116 LinkDown(pAd, FALSE);
1117 RTMPusecDelay(10000);
1118
1119 /*========================================== */
1120 /* Clean up old bss table */
1121 BssTableInit(&pAd->ScanTab);
1122 }
1123
1124 /* Set LED */
1125 RTMPSetLED(pAd, LED_RADIO_OFF);
1126
1127 if (pAd->CommonCfg.BBPCurrentBW == BW_40) {
1128 /* Must using 40MHz. */
1129 AsicTurnOffRFClk(pAd, pAd->CommonCfg.CentralChannel);
1130 } else {
1131 /* Must using 20MHz. */
1132 AsicTurnOffRFClk(pAd, pAd->CommonCfg.Channel);
1133 }
1134
1135 /* Disable Tx/Rx DMA */
1136 RTUSBReadMACRegister(pAd, WPDMA_GLO_CFG, &GloCfg.word); /* disable DMA */
1137 GloCfg.field.EnableTxDMA = 0;
1138 GloCfg.field.EnableRxDMA = 0;
1139 RTUSBWriteMACRegister(pAd, WPDMA_GLO_CFG, GloCfg.word); /* abort all TX rings */
1140
1141 /* Waiting for DMA idle */
1142 i = 0;
1143 do {
1144 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
1145 if ((GloCfg.field.TxDMABusy == 0)
1146 && (GloCfg.field.RxDMABusy == 0))
1147 break;
1148
1149 RTMPusecDelay(1000);
1150 } while (i++ < 100);
1151
1152 /* Disable MAC Tx/Rx */
1153 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
1154 Value &= (0xfffffff3);
1155 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
1156
1157 {
1158 AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02);
1159 }
1160}
1161
1162#endif /* RTMP_MAC_USB // */
diff --git a/drivers/staging/rt2860/common/cmm_sanity.c b/drivers/staging/rt2860/common/cmm_sanity.c
deleted file mode 100644
index 3bfb4ad00c1..00000000000
--- a/drivers/staging/rt2860/common/cmm_sanity.c
+++ /dev/null
@@ -1,1205 +0,0 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 sanity.c
29
30 Abstract:
31
32 Revision History:
33 Who When What
34 -------- ---------- ----------------------------------------------
35 John Chang 2004-09-01 add WMM support
36*/
37#include "../rt_config.h"
38
39extern u8 CISCO_OUI[];
40
41extern u8 WPA_OUI[];
42extern u8 RSN_OUI[];
43extern u8 WME_INFO_ELEM[];
44extern u8 WME_PARM_ELEM[];
45extern u8 Ccx2QosInfo[];
46extern u8 RALINK_OUI[];
47extern u8 BROADCOM_OUI[];
48extern u8 WPS_OUI[];
49
50/*
51 ==========================================================================
52 Description:
53 MLME message sanity check
54 Return:
55 TRUE if all parameters are OK, FALSE otherwise
56
57 IRQL = DISPATCH_LEVEL
58
59 ==========================================================================
60 */
61BOOLEAN MlmeAddBAReqSanity(struct rt_rtmp_adapter *pAd,
62 void * Msg, unsigned long MsgLen, u8 *pAddr2)
63{
64 struct rt_mlme_addba_req *pInfo;
65
66 pInfo = (struct rt_mlme_addba_req *)Msg;
67
68 if ((MsgLen != sizeof(struct rt_mlme_addba_req))) {
69 DBGPRINT(RT_DEBUG_TRACE,
70 ("MlmeAddBAReqSanity fail - message length not correct.\n"));
71 return FALSE;
72 }
73
74 if ((pInfo->Wcid >= MAX_LEN_OF_MAC_TABLE)) {
75 DBGPRINT(RT_DEBUG_TRACE,
76 ("MlmeAddBAReqSanity fail - The peer Mac is not associated yet.\n"));
77 return FALSE;
78 }
79
80 if ((pInfo->pAddr[0] & 0x01) == 0x01) {
81 DBGPRINT(RT_DEBUG_TRACE,
82 ("MlmeAddBAReqSanity fail - broadcast address not support BA\n"));
83 return FALSE;
84 }
85
86 return TRUE;
87}
88
89/*
90 ==========================================================================
91 Description:
92 MLME message sanity check
93 Return:
94 TRUE if all parameters are OK, FALSE otherwise
95
96 IRQL = DISPATCH_LEVEL
97
98 ==========================================================================
99 */
100BOOLEAN MlmeDelBAReqSanity(struct rt_rtmp_adapter *pAd, void * Msg, unsigned long MsgLen)
101{
102 struct rt_mlme_delba_req *pInfo;
103 pInfo = (struct rt_mlme_delba_req *)Msg;
104
105 if ((MsgLen != sizeof(struct rt_mlme_delba_req))) {
106 DBGPRINT(RT_DEBUG_ERROR,
107 ("MlmeDelBAReqSanity fail - message length not correct.\n"));
108 return FALSE;
109 }
110
111 if ((pInfo->Wcid >= MAX_LEN_OF_MAC_TABLE)) {
112 DBGPRINT(RT_DEBUG_ERROR,
113 ("MlmeDelBAReqSanity fail - The peer Mac is not associated yet.\n"));
114 return FALSE;
115 }
116
117 if ((pInfo->TID & 0xf0)) {
118 DBGPRINT(RT_DEBUG_ERROR,
119 ("MlmeDelBAReqSanity fail - The peer TID is incorrect.\n"));
120 return FALSE;
121 }
122
123 if (NdisEqualMemory
124 (pAd->MacTab.Content[pInfo->Wcid].Addr, pInfo->Addr,
125 MAC_ADDR_LEN) == 0) {
126 DBGPRINT(RT_DEBUG_ERROR,
127 ("MlmeDelBAReqSanity fail - the peer addr dosen't exist.\n"));
128 return FALSE;
129 }
130
131 return TRUE;
132}
133
134BOOLEAN PeerAddBAReqActionSanity(struct rt_rtmp_adapter *pAd,
135 void * pMsg,
136 unsigned long MsgLen, u8 *pAddr2)
137{
138 struct rt_frame_802_11 * pFrame = (struct rt_frame_802_11 *) pMsg;
139 struct rt_frame_addba_req * pAddFrame;
140 pAddFrame = (struct rt_frame_addba_req *) (pMsg);
141 if (MsgLen < (sizeof(struct rt_frame_addba_req))) {
142 DBGPRINT(RT_DEBUG_ERROR,
143 ("PeerAddBAReqActionSanity: ADDBA Request frame length size = %ld incorrect\n",
144 MsgLen));
145 return FALSE;
146 }
147 /* we support immediate BA. */
148 *(u16 *) (&pAddFrame->BaParm) =
149 cpu2le16(*(u16 *) (&pAddFrame->BaParm));
150 pAddFrame->TimeOutValue = cpu2le16(pAddFrame->TimeOutValue);
151 pAddFrame->BaStartSeq.word = cpu2le16(pAddFrame->BaStartSeq.word);
152
153 if (pAddFrame->BaParm.BAPolicy != IMMED_BA) {
154 DBGPRINT(RT_DEBUG_ERROR,
155 ("PeerAddBAReqActionSanity: ADDBA Request Ba Policy[%d] not support\n",
156 pAddFrame->BaParm.BAPolicy));
157 DBGPRINT(RT_DEBUG_ERROR,
158 ("ADDBA Request. tid=%x, Bufsize=%x, AMSDUSupported=%x \n",
159 pAddFrame->BaParm.TID, pAddFrame->BaParm.BufSize,
160 pAddFrame->BaParm.AMSDUSupported));
161 return FALSE;
162 }
163 /* we support immediate BA. */
164 if (pAddFrame->BaParm.TID & 0xfff0) {
165 DBGPRINT(RT_DEBUG_ERROR,
166 ("PeerAddBAReqActionSanity: ADDBA Request incorrect TID = %d\n",
167 pAddFrame->BaParm.TID));
168 return FALSE;
169 }
170 COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
171 return TRUE;
172}
173
174BOOLEAN PeerAddBARspActionSanity(struct rt_rtmp_adapter *pAd,
175 void * pMsg, unsigned long MsgLen)
176{
177 struct rt_frame_addba_rsp * pAddFrame;
178
179 pAddFrame = (struct rt_frame_addba_rsp *) (pMsg);
180 if (MsgLen < (sizeof(struct rt_frame_addba_rsp))) {
181 DBGPRINT(RT_DEBUG_ERROR,
182 ("PeerAddBARspActionSanity: ADDBA Response frame length size = %ld incorrect\n",
183 MsgLen));
184 return FALSE;
185 }
186 /* we support immediate BA. */
187 *(u16 *) (&pAddFrame->BaParm) =
188 cpu2le16(*(u16 *) (&pAddFrame->BaParm));
189 pAddFrame->StatusCode = cpu2le16(pAddFrame->StatusCode);
190 pAddFrame->TimeOutValue = cpu2le16(pAddFrame->TimeOutValue);
191
192 if (pAddFrame->BaParm.BAPolicy != IMMED_BA) {
193 DBGPRINT(RT_DEBUG_ERROR,
194 ("PeerAddBAReqActionSanity: ADDBA Response Ba Policy[%d] not support\n",
195 pAddFrame->BaParm.BAPolicy));
196 return FALSE;
197 }
198 /* we support immediate BA. */
199 if (pAddFrame->BaParm.TID & 0xfff0) {
200 DBGPRINT(RT_DEBUG_ERROR,
201 ("PeerAddBARspActionSanity: ADDBA Response incorrect TID = %d\n",
202 pAddFrame->BaParm.TID));
203 return FALSE;
204 }
205 return TRUE;
206
207}
208
209BOOLEAN PeerDelBAActionSanity(struct rt_rtmp_adapter *pAd,
210 u8 Wcid, void * pMsg, unsigned long MsgLen)
211{
212 /*struct rt_frame_802_11 * pFrame = (struct rt_frame_802_11 *)pMsg; */
213 struct rt_frame_delba_req * pDelFrame;
214 if (MsgLen != (sizeof(struct rt_frame_delba_req)))
215 return FALSE;
216
217 if (Wcid >= MAX_LEN_OF_MAC_TABLE)
218 return FALSE;
219
220 pDelFrame = (struct rt_frame_delba_req *) (pMsg);
221
222 *(u16 *) (&pDelFrame->DelbaParm) =
223 cpu2le16(*(u16 *) (&pDelFrame->DelbaParm));
224 pDelFrame->ReasonCode = cpu2le16(pDelFrame->ReasonCode);
225
226 if (pDelFrame->DelbaParm.TID & 0xfff0)
227 return FALSE;
228
229 return TRUE;
230}
231
232/*
233 ==========================================================================
234 Description:
235 MLME message sanity check
236 Return:
237 TRUE if all parameters are OK, FALSE otherwise
238
239 IRQL = DISPATCH_LEVEL
240
241 ==========================================================================
242 */
243BOOLEAN PeerBeaconAndProbeRspSanity(struct rt_rtmp_adapter *pAd, void * Msg, unsigned long MsgLen, u8 MsgChannel, u8 *pAddr2, u8 *pBssid, char Ssid[], u8 * pSsidLen, u8 * pBssType, u16 * pBeaconPeriod, u8 * pChannel, u8 * pNewChannel, OUT LARGE_INTEGER * pTimestamp, struct rt_cf_parm * pCfParm, u16 * pAtimWin, u16 * pCapabilityInfo, u8 * pErp, u8 * pDtimCount, u8 * pDtimPeriod, u8 * pBcastFlag, u8 * pMessageToMe, u8 SupRate[], u8 * pSupRateLen, u8 ExtRate[], u8 * pExtRateLen, u8 * pCkipFlag, u8 * pAironetCellPowerLimit, struct rt_edca_parm *pEdcaParm, struct rt_qbss_load_parm *pQbssLoad, struct rt_qos_capability_parm *pQosCapability, unsigned long * pRalinkIe, u8 * pHtCapabilityLen, u8 * pPreNHtCapabilityLen, struct rt_ht_capability_ie * pHtCapability, u8 * AddHtInfoLen, struct rt_add_ht_info_ie * AddHtInfo, u8 * NewExtChannelOffset, /* Ht extension channel offset(above or below) */
244 u16 * LengthVIE,
245 struct rt_ndis_802_11_variable_ies *pVIE)
246{
247 u8 *Ptr;
248 u8 TimLen;
249 struct rt_frame_802_11 * pFrame;
250 struct rt_eid * pEid;
251 u8 SubType;
252 u8 Sanity;
253 /*u8 ECWMin, ECWMax; */
254 /*MAC_CSR9_STRUC Csr9; */
255 unsigned long Length = 0;
256
257 /* For some 11a AP which didn't have DS_IE, we use two conditions to decide the channel */
258 /* 1. If the AP is 11n enabled, then check the control channel. */
259 /* 2. If the AP didn't have any info about channel, use the channel we received this frame as the channel. (May inaccuracy!) */
260 u8 CtrlChannel = 0;
261
262 /* Add for 3 necessary EID field check */
263 Sanity = 0;
264
265 *pAtimWin = 0;
266 *pErp = 0;
267 *pDtimCount = 0;
268 *pDtimPeriod = 0;
269 *pBcastFlag = 0;
270 *pMessageToMe = 0;
271 *pExtRateLen = 0;
272 *pCkipFlag = 0; /* Default of CkipFlag is 0 */
273 *pAironetCellPowerLimit = 0xFF; /* Default of AironetCellPowerLimit is 0xFF */
274 *LengthVIE = 0; /* Set the length of VIE to init value 0 */
275 *pHtCapabilityLen = 0; /* Set the length of VIE to init value 0 */
276 if (pAd->OpMode == OPMODE_STA)
277 *pPreNHtCapabilityLen = 0; /* Set the length of VIE to init value 0 */
278 *AddHtInfoLen = 0; /* Set the length of VIE to init value 0 */
279 *pRalinkIe = 0;
280 *pNewChannel = 0;
281 *NewExtChannelOffset = 0xff; /*Default 0xff means no such IE */
282 pCfParm->bValid = FALSE; /* default: no IE_CF found */
283 pQbssLoad->bValid = FALSE; /* default: no IE_QBSS_LOAD found */
284 pEdcaParm->bValid = FALSE; /* default: no IE_EDCA_PARAMETER found */
285 pQosCapability->bValid = FALSE; /* default: no IE_QOS_CAPABILITY found */
286
287 pFrame = (struct rt_frame_802_11 *) Msg;
288
289 /* get subtype from header */
290 SubType = (u8)pFrame->Hdr.FC.SubType;
291
292 /* get Addr2 and BSSID from header */
293 COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
294 COPY_MAC_ADDR(pBssid, pFrame->Hdr.Addr3);
295
296 Ptr = pFrame->Octet;
297 Length += LENGTH_802_11;
298
299 /* get timestamp from payload and advance the pointer */
300 NdisMoveMemory(pTimestamp, Ptr, TIMESTAMP_LEN);
301
302 pTimestamp->u.LowPart = cpu2le32(pTimestamp->u.LowPart);
303 pTimestamp->u.HighPart = cpu2le32(pTimestamp->u.HighPart);
304
305 Ptr += TIMESTAMP_LEN;
306 Length += TIMESTAMP_LEN;
307
308 /* get beacon interval from payload and advance the pointer */
309 NdisMoveMemory(pBeaconPeriod, Ptr, 2);
310 Ptr += 2;
311 Length += 2;
312
313 /* get capability info from payload and advance the pointer */
314 NdisMoveMemory(pCapabilityInfo, Ptr, 2);
315 Ptr += 2;
316 Length += 2;
317
318 if (CAP_IS_ESS_ON(*pCapabilityInfo))
319 *pBssType = BSS_INFRA;
320 else
321 *pBssType = BSS_ADHOC;
322
323 pEid = (struct rt_eid *) Ptr;
324
325 /* get variable fields from payload and advance the pointer */
326 while ((Length + 2 + pEid->Len) <= MsgLen) {
327 /* */
328 /* Secure copy VIE to VarIE[MAX_VIE_LEN] didn't overflow. */
329 /* */
330 if ((*LengthVIE + pEid->Len + 2) >= MAX_VIE_LEN) {
331 DBGPRINT(RT_DEBUG_WARN,
332 ("PeerBeaconAndProbeRspSanity - Variable IEs out of resource [len(=%d) > MAX_VIE_LEN(=%d)]\n",
333 (*LengthVIE + pEid->Len + 2), MAX_VIE_LEN));
334 break;
335 }
336
337 switch (pEid->Eid) {
338 case IE_SSID:
339 /* Already has one SSID EID in this beacon, ignore the second one */
340 if (Sanity & 0x1)
341 break;
342 if (pEid->Len <= MAX_LEN_OF_SSID) {
343 NdisMoveMemory(Ssid, pEid->Octet, pEid->Len);
344 *pSsidLen = pEid->Len;
345 Sanity |= 0x1;
346 } else {
347 DBGPRINT(RT_DEBUG_TRACE,
348 ("PeerBeaconAndProbeRspSanity - wrong IE_SSID (len=%d)\n",
349 pEid->Len));
350 return FALSE;
351 }
352 break;
353
354 case IE_SUPP_RATES:
355 if (pEid->Len <= MAX_LEN_OF_SUPPORTED_RATES) {
356 Sanity |= 0x2;
357 NdisMoveMemory(SupRate, pEid->Octet, pEid->Len);
358 *pSupRateLen = pEid->Len;
359
360 /* TODO: 2004-09-14 not a good design here, cause it exclude extra rates */
361 /* from ScanTab. We should report as is. And filter out unsupported */
362 /* rates in MlmeAux. */
363 /* Check against the supported rates */
364 /* RTMPCheckRates(pAd, SupRate, pSupRateLen); */
365 } else {
366 DBGPRINT(RT_DEBUG_TRACE,
367 ("PeerBeaconAndProbeRspSanity - wrong IE_SUPP_RATES (len=%d)\n",
368 pEid->Len));
369 return FALSE;
370 }
371 break;
372
373 case IE_HT_CAP:
374 if (pEid->Len >= SIZE_HT_CAP_IE) /*Note: allow extension! */
375 {
376 NdisMoveMemory(pHtCapability, pEid->Octet,
377 sizeof(struct rt_ht_capability_ie));
378 *pHtCapabilityLen = SIZE_HT_CAP_IE; /* Nnow we only support 26 bytes. */
379
380 *(u16 *) (&pHtCapability->HtCapInfo) =
381 cpu2le16(*(u16 *)
382 (&pHtCapability->HtCapInfo));
383 *(u16 *) (&pHtCapability->ExtHtCapInfo) =
384 cpu2le16(*(u16 *)
385 (&pHtCapability->ExtHtCapInfo));
386
387 {
388 *pPreNHtCapabilityLen = 0; /* Nnow we only support 26 bytes. */
389
390 Ptr = (u8 *)pVIE;
391 NdisMoveMemory(Ptr + *LengthVIE,
392 &pEid->Eid,
393 pEid->Len + 2);
394 *LengthVIE += (pEid->Len + 2);
395 }
396 } else {
397 DBGPRINT(RT_DEBUG_WARN,
398 ("PeerBeaconAndProbeRspSanity - wrong IE_HT_CAP. pEid->Len = %d\n",
399 pEid->Len));
400 }
401
402 break;
403 case IE_ADD_HT:
404 if (pEid->Len >= sizeof(struct rt_add_ht_info_ie)) {
405 /* This IE allows extension, but we can ignore extra bytes beyond our knowledge , so only */
406 /* copy first sizeof(struct rt_add_ht_info_ie) */
407 NdisMoveMemory(AddHtInfo, pEid->Octet,
408 sizeof(struct rt_add_ht_info_ie));
409 *AddHtInfoLen = SIZE_ADD_HT_INFO_IE;
410
411 CtrlChannel = AddHtInfo->ControlChan;
412
413 *(u16 *) (&AddHtInfo->AddHtInfo2) =
414 cpu2le16(*(u16 *)
415 (&AddHtInfo->AddHtInfo2));
416 *(u16 *) (&AddHtInfo->AddHtInfo3) =
417 cpu2le16(*(u16 *)
418 (&AddHtInfo->AddHtInfo3));
419
420 {
421 Ptr = (u8 *)pVIE;
422 NdisMoveMemory(Ptr + *LengthVIE,
423 &pEid->Eid,
424 pEid->Len + 2);
425 *LengthVIE += (pEid->Len + 2);
426 }
427 } else {
428 DBGPRINT(RT_DEBUG_WARN,
429 ("PeerBeaconAndProbeRspSanity - wrong IE_ADD_HT. \n"));
430 }
431
432 break;
433 case IE_SECONDARY_CH_OFFSET:
434 if (pEid->Len == 1) {
435 *NewExtChannelOffset = pEid->Octet[0];
436 } else {
437 DBGPRINT(RT_DEBUG_WARN,
438 ("PeerBeaconAndProbeRspSanity - wrong IE_SECONDARY_CH_OFFSET. \n"));
439 }
440
441 break;
442 case IE_FH_PARM:
443 DBGPRINT(RT_DEBUG_TRACE,
444 ("PeerBeaconAndProbeRspSanity(IE_FH_PARM) \n"));
445 break;
446
447 case IE_DS_PARM:
448 if (pEid->Len == 1) {
449 *pChannel = *pEid->Octet;
450
451 {
452 if (ChannelSanity(pAd, *pChannel) == 0) {
453
454 return FALSE;
455 }
456 }
457
458 Sanity |= 0x4;
459 } else {
460 DBGPRINT(RT_DEBUG_TRACE,
461 ("PeerBeaconAndProbeRspSanity - wrong IE_DS_PARM (len=%d)\n",
462 pEid->Len));
463 return FALSE;
464 }
465 break;
466
467 case IE_CF_PARM:
468 if (pEid->Len == 6) {
469 pCfParm->bValid = TRUE;
470 pCfParm->CfpCount = pEid->Octet[0];
471 pCfParm->CfpPeriod = pEid->Octet[1];
472 pCfParm->CfpMaxDuration =
473 pEid->Octet[2] + 256 * pEid->Octet[3];
474 pCfParm->CfpDurRemaining =
475 pEid->Octet[4] + 256 * pEid->Octet[5];
476 } else {
477 DBGPRINT(RT_DEBUG_TRACE,
478 ("PeerBeaconAndProbeRspSanity - wrong IE_CF_PARM\n"));
479 return FALSE;
480 }
481 break;
482
483 case IE_IBSS_PARM:
484 if (pEid->Len == 2) {
485 NdisMoveMemory(pAtimWin, pEid->Octet,
486 pEid->Len);
487 } else {
488 DBGPRINT(RT_DEBUG_TRACE,
489 ("PeerBeaconAndProbeRspSanity - wrong IE_IBSS_PARM\n"));
490 return FALSE;
491 }
492 break;
493
494 case IE_TIM:
495 if (INFRA_ON(pAd) && SubType == SUBTYPE_BEACON) {
496 GetTimBit((char *)pEid, pAd->StaActive.Aid,
497 &TimLen, pBcastFlag, pDtimCount,
498 pDtimPeriod, pMessageToMe);
499 }
500 break;
501 case IE_CHANNEL_SWITCH_ANNOUNCEMENT:
502 if (pEid->Len == 3) {
503 *pNewChannel = pEid->Octet[1]; /*extract new channel number */
504 }
505 break;
506
507 /* New for WPA */
508 /* CCX v2 has the same IE, we need to parse that too */
509 /* Wifi WMM use the same IE vale, need to parse that too */
510 /* case IE_WPA: */
511 case IE_VENDOR_SPECIFIC:
512 /* Check Broadcom/Atheros 802.11n OUI version, for HT Capability IE. */
513 /* This HT IE is before IEEE draft set HT IE value.2006-09-28 by Jan. */
514 /*if (NdisEqualMemory(pEid->Octet, BROADCOM_OUI, 3) && (pEid->Len >= 4))
515 {
516 if ((pEid->Octet[3] == OUI_BROADCOM_HT) && (pEid->Len >= 30))
517 {
518 {
519 NdisMoveMemory(pHtCapability, &pEid->Octet[4], sizeof(struct rt_ht_capability_ie));
520 *pHtCapabilityLen = SIZE_HT_CAP_IE; // Nnow we only support 26 bytes.
521 }
522 }
523 if ((pEid->Octet[3] == OUI_BROADCOM_HT) && (pEid->Len >= 26))
524 {
525 {
526 NdisMoveMemory(AddHtInfo, &pEid->Octet[4], sizeof(struct rt_add_ht_info_ie));
527 *AddHtInfoLen = SIZE_ADD_HT_INFO_IE; // Nnow we only support 26 bytes.
528 }
529 }
530 }
531 */
532 /* Check the OUI version, filter out non-standard usage */
533 if (NdisEqualMemory(pEid->Octet, RALINK_OUI, 3)
534 && (pEid->Len == 7)) {
535 /**pRalinkIe = pEid->Octet[3]; */
536 if (pEid->Octet[3] != 0)
537 *pRalinkIe = pEid->Octet[3];
538 else
539 *pRalinkIe = 0xf0000000; /* Set to non-zero value (can't set bit0-2) to represent this is Ralink Chip. So at linkup, we will set ralinkchip flag. */
540 }
541 /* This HT IE is before IEEE draft set HT IE value.2006-09-28 by Jan. */
542
543 /* Other vendors had production before IE_HT_CAP value is assigned. To backward support those old-firmware AP, */
544 /* Check broadcom-defiend pre-802.11nD1.0 OUI for HT related IE, including HT Capatilities IE and HT Information IE */
545 else if ((*pHtCapabilityLen == 0)
546 && NdisEqualMemory(pEid->Octet, PRE_N_HT_OUI,
547 3) && (pEid->Len >= 4)
548 && (pAd->OpMode == OPMODE_STA)) {
549 if ((pEid->Octet[3] == OUI_PREN_HT_CAP)
550 && (pEid->Len >= 30)
551 && (*pHtCapabilityLen == 0)) {
552 NdisMoveMemory(pHtCapability,
553 &pEid->Octet[4],
554 sizeof
555 (struct rt_ht_capability_ie));
556 *pPreNHtCapabilityLen = SIZE_HT_CAP_IE;
557 }
558
559 if ((pEid->Octet[3] == OUI_PREN_ADD_HT)
560 && (pEid->Len >= 26)) {
561 NdisMoveMemory(AddHtInfo,
562 &pEid->Octet[4],
563 sizeof(struct rt_add_ht_info_ie));
564 *AddHtInfoLen = SIZE_ADD_HT_INFO_IE;
565 }
566 } else if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4)) {
567 /* Copy to pVIE which will report to microsoft bssid list. */
568 Ptr = (u8 *)pVIE;
569 NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid,
570 pEid->Len + 2);
571 *LengthVIE += (pEid->Len + 2);
572 } else
573 if (NdisEqualMemory(pEid->Octet, WME_PARM_ELEM, 6)
574 && (pEid->Len == 24)) {
575 u8 *ptr;
576 int i;
577
578 /* parsing EDCA parameters */
579 pEdcaParm->bValid = TRUE;
580 pEdcaParm->bQAck = FALSE; /* pEid->Octet[0] & 0x10; */
581 pEdcaParm->bQueueRequest = FALSE; /* pEid->Octet[0] & 0x20; */
582 pEdcaParm->bTxopRequest = FALSE; /* pEid->Octet[0] & 0x40; */
583 pEdcaParm->EdcaUpdateCount =
584 pEid->Octet[6] & 0x0f;
585 pEdcaParm->bAPSDCapable =
586 (pEid->Octet[6] & 0x80) ? 1 : 0;
587 ptr = &pEid->Octet[8];
588 for (i = 0; i < 4; i++) {
589 u8 aci = (*ptr & 0x60) >> 5; /* b5~6 is AC INDEX */
590 pEdcaParm->bACM[aci] = (((*ptr) & 0x10) == 0x10); /* b5 is ACM */
591 pEdcaParm->Aifsn[aci] = (*ptr) & 0x0f; /* b0~3 is AIFSN */
592 pEdcaParm->Cwmin[aci] = *(ptr + 1) & 0x0f; /* b0~4 is Cwmin */
593 pEdcaParm->Cwmax[aci] = *(ptr + 1) >> 4; /* b5~8 is Cwmax */
594 pEdcaParm->Txop[aci] = *(ptr + 2) + 256 * (*(ptr + 3)); /* in unit of 32-us */
595 ptr += 4; /* point to next AC */
596 }
597 } else
598 if (NdisEqualMemory(pEid->Octet, WME_INFO_ELEM, 6)
599 && (pEid->Len == 7)) {
600 /* parsing EDCA parameters */
601 pEdcaParm->bValid = TRUE;
602 pEdcaParm->bQAck = FALSE; /* pEid->Octet[0] & 0x10; */
603 pEdcaParm->bQueueRequest = FALSE; /* pEid->Octet[0] & 0x20; */
604 pEdcaParm->bTxopRequest = FALSE; /* pEid->Octet[0] & 0x40; */
605 pEdcaParm->EdcaUpdateCount =
606 pEid->Octet[6] & 0x0f;
607 pEdcaParm->bAPSDCapable =
608 (pEid->Octet[6] & 0x80) ? 1 : 0;
609
610 /* use default EDCA parameter */
611 pEdcaParm->bACM[QID_AC_BE] = 0;
612 pEdcaParm->Aifsn[QID_AC_BE] = 3;
613 pEdcaParm->Cwmin[QID_AC_BE] = CW_MIN_IN_BITS;
614 pEdcaParm->Cwmax[QID_AC_BE] = CW_MAX_IN_BITS;
615 pEdcaParm->Txop[QID_AC_BE] = 0;
616
617 pEdcaParm->bACM[QID_AC_BK] = 0;
618 pEdcaParm->Aifsn[QID_AC_BK] = 7;
619 pEdcaParm->Cwmin[QID_AC_BK] = CW_MIN_IN_BITS;
620 pEdcaParm->Cwmax[QID_AC_BK] = CW_MAX_IN_BITS;
621 pEdcaParm->Txop[QID_AC_BK] = 0;
622
623 pEdcaParm->bACM[QID_AC_VI] = 0;
624 pEdcaParm->Aifsn[QID_AC_VI] = 2;
625 pEdcaParm->Cwmin[QID_AC_VI] =
626 CW_MIN_IN_BITS - 1;
627 pEdcaParm->Cwmax[QID_AC_VI] = CW_MAX_IN_BITS;
628 pEdcaParm->Txop[QID_AC_VI] = 96; /* AC_VI: 96*32us ~= 3ms */
629
630 pEdcaParm->bACM[QID_AC_VO] = 0;
631 pEdcaParm->Aifsn[QID_AC_VO] = 2;
632 pEdcaParm->Cwmin[QID_AC_VO] =
633 CW_MIN_IN_BITS - 2;
634 pEdcaParm->Cwmax[QID_AC_VO] =
635 CW_MAX_IN_BITS - 1;
636 pEdcaParm->Txop[QID_AC_VO] = 48; /* AC_VO: 48*32us ~= 1.5ms */
637 }
638
639 break;
640
641 case IE_EXT_SUPP_RATES:
642 if (pEid->Len <= MAX_LEN_OF_SUPPORTED_RATES) {
643 NdisMoveMemory(ExtRate, pEid->Octet, pEid->Len);
644 *pExtRateLen = pEid->Len;
645
646 /* TODO: 2004-09-14 not a good design here, cause it exclude extra rates */
647 /* from ScanTab. We should report as is. And filter out unsupported */
648 /* rates in MlmeAux. */
649 /* Check against the supported rates */
650 /* RTMPCheckRates(pAd, ExtRate, pExtRateLen); */
651 }
652 break;
653
654 case IE_ERP:
655 if (pEid->Len == 1) {
656 *pErp = (u8)pEid->Octet[0];
657 }
658 break;
659
660 case IE_AIRONET_CKIP:
661 /* 0. Check Aironet IE length, it must be larger or equal to 28 */
662 /* Cisco AP350 used length as 28 */
663 /* Cisco AP12XX used length as 30 */
664 if (pEid->Len < (CKIP_NEGOTIATION_LENGTH - 2))
665 break;
666
667 /* 1. Copy CKIP flag byte to buffer for process */
668 *pCkipFlag = *(pEid->Octet + 8);
669 break;
670
671 case IE_AP_TX_POWER:
672 /* AP Control of Client Transmit Power */
673 /*0. Check Aironet IE length, it must be 6 */
674 if (pEid->Len != 0x06)
675 break;
676
677 /* Get cell power limit in dBm */
678 if (NdisEqualMemory(pEid->Octet, CISCO_OUI, 3) == 1)
679 *pAironetCellPowerLimit = *(pEid->Octet + 4);
680 break;
681
682 /* WPA2 & 802.11i RSN */
683 case IE_RSN:
684 /* There is no OUI for version anymore, check the group cipher OUI before copying */
685 if (RTMPEqualMemory(pEid->Octet + 2, RSN_OUI, 3)) {
686 /* Copy to pVIE which will report to microsoft bssid list. */
687 Ptr = (u8 *)pVIE;
688 NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid,
689 pEid->Len + 2);
690 *LengthVIE += (pEid->Len + 2);
691 }
692 break;
693
694 default:
695 break;
696 }
697
698 Length = Length + 2 + pEid->Len; /* Eid[1] + Len[1]+ content[Len] */
699 pEid = (struct rt_eid *) ((u8 *) pEid + 2 + pEid->Len);
700 }
701
702 /* For some 11a AP. it did not have the channel EID, patch here */
703 {
704 u8 LatchRfChannel = MsgChannel;
705 if ((pAd->LatchRfRegs.Channel > 14) && ((Sanity & 0x4) == 0)) {
706 if (CtrlChannel != 0)
707 *pChannel = CtrlChannel;
708 else
709 *pChannel = LatchRfChannel;
710 Sanity |= 0x4;
711 }
712 }
713
714 if (Sanity != 0x7) {
715 DBGPRINT(RT_DEBUG_LOUD,
716 ("PeerBeaconAndProbeRspSanity - missing field, Sanity=0x%02x\n",
717 Sanity));
718 return FALSE;
719 } else {
720 return TRUE;
721 }
722
723}
724
725/*
726 ==========================================================================
727 Description:
728 MLME message sanity check
729 Return:
730 TRUE if all parameters are OK, FALSE otherwise
731 ==========================================================================
732 */
733BOOLEAN MlmeScanReqSanity(struct rt_rtmp_adapter *pAd,
734 void * Msg,
735 unsigned long MsgLen,
736 u8 * pBssType,
737 char Ssid[],
738 u8 * pSsidLen, u8 * pScanType)
739{
740 struct rt_mlme_scan_req *Info;
741
742 Info = (struct rt_mlme_scan_req *)(Msg);
743 *pBssType = Info->BssType;
744 *pSsidLen = Info->SsidLen;
745 NdisMoveMemory(Ssid, Info->Ssid, *pSsidLen);
746 *pScanType = Info->ScanType;
747
748 if ((*pBssType == BSS_INFRA || *pBssType == BSS_ADHOC
749 || *pBssType == BSS_ANY)
750 && (*pScanType == SCAN_ACTIVE || *pScanType == SCAN_PASSIVE)) {
751 return TRUE;
752 } else {
753 DBGPRINT(RT_DEBUG_TRACE,
754 ("MlmeScanReqSanity fail - wrong BssType or ScanType\n"));
755 return FALSE;
756 }
757}
758
759/* IRQL = DISPATCH_LEVEL */
760u8 ChannelSanity(struct rt_rtmp_adapter *pAd, u8 channel)
761{
762 int i;
763
764 for (i = 0; i < pAd->ChannelListNum; i++) {
765 if (channel == pAd->ChannelList[i].Channel)
766 return 1;
767 }
768 return 0;
769}
770
771/*
772 ==========================================================================
773 Description:
774 MLME message sanity check
775 Return:
776 TRUE if all parameters are OK, FALSE otherwise
777
778 IRQL = DISPATCH_LEVEL
779
780 ==========================================================================
781 */
782BOOLEAN PeerDeauthSanity(struct rt_rtmp_adapter *pAd,
783 void * Msg,
784 unsigned long MsgLen,
785 u8 *pAddr2, u16 * pReason)
786{
787 struct rt_frame_802_11 * pFrame = (struct rt_frame_802_11 *) Msg;
788
789 COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
790 NdisMoveMemory(pReason, &pFrame->Octet[0], 2);
791
792 return TRUE;
793}
794
795/*
796 ==========================================================================
797 Description:
798 MLME message sanity check
799 Return:
800 TRUE if all parameters are OK, FALSE otherwise
801
802 IRQL = DISPATCH_LEVEL
803
804 ==========================================================================
805 */
806BOOLEAN PeerAuthSanity(struct rt_rtmp_adapter *pAd,
807 void * Msg,
808 unsigned long MsgLen,
809 u8 *pAddr,
810 u16 * pAlg,
811 u16 * pSeq,
812 u16 * pStatus, char * pChlgText)
813{
814 struct rt_frame_802_11 * pFrame = (struct rt_frame_802_11 *) Msg;
815
816 COPY_MAC_ADDR(pAddr, pFrame->Hdr.Addr2);
817 NdisMoveMemory(pAlg, &pFrame->Octet[0], 2);
818 NdisMoveMemory(pSeq, &pFrame->Octet[2], 2);
819 NdisMoveMemory(pStatus, &pFrame->Octet[4], 2);
820
821 if (*pAlg == AUTH_MODE_OPEN) {
822 if (*pSeq == 1 || *pSeq == 2) {
823 return TRUE;
824 } else {
825 DBGPRINT(RT_DEBUG_TRACE,
826 ("PeerAuthSanity fail - wrong Seg#\n"));
827 return FALSE;
828 }
829 } else if (*pAlg == AUTH_MODE_KEY) {
830 if (*pSeq == 1 || *pSeq == 4) {
831 return TRUE;
832 } else if (*pSeq == 2 || *pSeq == 3) {
833 NdisMoveMemory(pChlgText, &pFrame->Octet[8],
834 CIPHER_TEXT_LEN);
835 return TRUE;
836 } else {
837 DBGPRINT(RT_DEBUG_TRACE,
838 ("PeerAuthSanity fail - wrong Seg#\n"));
839 return FALSE;
840 }
841 } else {
842 DBGPRINT(RT_DEBUG_TRACE,
843 ("PeerAuthSanity fail - wrong algorithm\n"));
844 return FALSE;
845 }
846}
847
848/*
849 ==========================================================================
850 Description:
851 MLME message sanity check
852 Return:
853 TRUE if all parameters are OK, FALSE otherwise
854 ==========================================================================
855 */
856BOOLEAN MlmeAuthReqSanity(struct rt_rtmp_adapter *pAd,
857 void * Msg,
858 unsigned long MsgLen,
859 u8 *pAddr,
860 unsigned long * pTimeout, u16 * pAlg)
861{
862 struct rt_mlme_auth_req *pInfo;
863
864 pInfo = (struct rt_mlme_auth_req *)Msg;
865 COPY_MAC_ADDR(pAddr, pInfo->Addr);
866 *pTimeout = pInfo->Timeout;
867 *pAlg = pInfo->Alg;
868
869 if (((*pAlg == AUTH_MODE_KEY) || (*pAlg == AUTH_MODE_OPEN)
870 ) && ((*pAddr & 0x01) == 0)) {
871 return TRUE;
872 } else {
873 DBGPRINT(RT_DEBUG_TRACE,
874 ("MlmeAuthReqSanity fail - wrong algorithm\n"));
875 return FALSE;
876 }
877}
878
879/*
880 ==========================================================================
881 Description:
882 MLME message sanity check
883 Return:
884 TRUE if all parameters are OK, FALSE otherwise
885
886 IRQL = DISPATCH_LEVEL
887
888 ==========================================================================
889 */
890BOOLEAN MlmeAssocReqSanity(struct rt_rtmp_adapter *pAd,
891 void * Msg,
892 unsigned long MsgLen,
893 u8 *pApAddr,
894 u16 * pCapabilityInfo,
895 unsigned long * pTimeout, u16 * pListenIntv)
896{
897 struct rt_mlme_assoc_req *pInfo;
898
899 pInfo = (struct rt_mlme_assoc_req *)Msg;
900 *pTimeout = pInfo->Timeout; /* timeout */
901 COPY_MAC_ADDR(pApAddr, pInfo->Addr); /* AP address */
902 *pCapabilityInfo = pInfo->CapabilityInfo; /* capability info */
903 *pListenIntv = pInfo->ListenIntv;
904
905 return TRUE;
906}
907
908/*
909 ==========================================================================
910 Description:
911 MLME message sanity check
912 Return:
913 TRUE if all parameters are OK, FALSE otherwise
914
915 IRQL = DISPATCH_LEVEL
916
917 ==========================================================================
918 */
919BOOLEAN PeerDisassocSanity(struct rt_rtmp_adapter *pAd,
920 void * Msg,
921 unsigned long MsgLen,
922 u8 *pAddr2, u16 * pReason)
923{
924 struct rt_frame_802_11 * pFrame = (struct rt_frame_802_11 *) Msg;
925
926 COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
927 NdisMoveMemory(pReason, &pFrame->Octet[0], 2);
928
929 return TRUE;
930}
931
932/*
933 ========================================================================
934 Routine Description:
935 Sanity check NetworkType (11b, 11g or 11a)
936
937 Arguments:
938 pBss - Pointer to BSS table.
939
940 Return Value:
941 Ndis802_11DS .......(11b)
942 Ndis802_11OFDM24....(11g)
943 Ndis802_11OFDM5.....(11a)
944
945 IRQL = DISPATCH_LEVEL
946
947 ========================================================================
948*/
949NDIS_802_11_NETWORK_TYPE NetworkTypeInUseSanity(struct rt_bss_entry *pBss)
950{
951 NDIS_802_11_NETWORK_TYPE NetWorkType;
952 u8 rate, i;
953
954 NetWorkType = Ndis802_11DS;
955
956 if (pBss->Channel <= 14) {
957 /* */
958 /* First check support Rate. */
959 /* */
960 for (i = 0; i < pBss->SupRateLen; i++) {
961 rate = pBss->SupRate[i] & 0x7f; /* Mask out basic rate set bit */
962 if ((rate == 2) || (rate == 4) || (rate == 11)
963 || (rate == 22)) {
964 continue;
965 } else {
966 /* */
967 /* Otherwise (even rate > 108) means Ndis802_11OFDM24 */
968 /* */
969 NetWorkType = Ndis802_11OFDM24;
970 break;
971 }
972 }
973
974 /* */
975 /* Second check Extend Rate. */
976 /* */
977 if (NetWorkType != Ndis802_11OFDM24) {
978 for (i = 0; i < pBss->ExtRateLen; i++) {
979 rate = pBss->SupRate[i] & 0x7f; /* Mask out basic rate set bit */
980 if ((rate == 2) || (rate == 4) || (rate == 11)
981 || (rate == 22)) {
982 continue;
983 } else {
984 /* */
985 /* Otherwise (even rate > 108) means Ndis802_11OFDM24 */
986 /* */
987 NetWorkType = Ndis802_11OFDM24;
988 break;
989 }
990 }
991 }
992 } else {
993 NetWorkType = Ndis802_11OFDM5;
994 }
995
996 if (pBss->HtCapabilityLen != 0) {
997 if (NetWorkType == Ndis802_11OFDM5)
998 NetWorkType = Ndis802_11OFDM5_N;
999 else
1000 NetWorkType = Ndis802_11OFDM24_N;
1001 }
1002
1003 return NetWorkType;
1004}
1005
1006/*
1007 ==========================================================================
1008 Description:
1009 Check the validity of the received EAPoL frame
1010 Return:
1011 TRUE if all parameters are OK,
1012 FALSE otherwise
1013 ==========================================================================
1014 */
1015BOOLEAN PeerWpaMessageSanity(struct rt_rtmp_adapter *pAd,
1016 struct rt_eapol_packet * pMsg,
1017 unsigned long MsgLen,
1018 u8 MsgType, struct rt_mac_table_entry *pEntry)
1019{
1020 u8 mic[LEN_KEY_DESC_MIC], digest[80], KEYDATA[MAX_LEN_OF_RSNIE];
1021 BOOLEAN bReplayDiff = FALSE;
1022 BOOLEAN bWPA2 = FALSE;
1023 struct rt_key_info EapolKeyInfo;
1024 u8 GroupKeyIndex = 0;
1025
1026 NdisZeroMemory(mic, sizeof(mic));
1027 NdisZeroMemory(digest, sizeof(digest));
1028 NdisZeroMemory(KEYDATA, sizeof(KEYDATA));
1029 NdisZeroMemory((u8 *)& EapolKeyInfo, sizeof(EapolKeyInfo));
1030
1031 NdisMoveMemory((u8 *)& EapolKeyInfo,
1032 (u8 *)& pMsg->KeyDesc.KeyInfo, sizeof(struct rt_key_info));
1033
1034 *((u16 *) & EapolKeyInfo) = cpu2le16(*((u16 *) & EapolKeyInfo));
1035
1036 /* Choose WPA2 or not */
1037 if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2)
1038 || (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK))
1039 bWPA2 = TRUE;
1040
1041 /* 0. Check MsgType */
1042 if ((MsgType > EAPOL_GROUP_MSG_2) || (MsgType < EAPOL_PAIR_MSG_1)) {
1043 DBGPRINT(RT_DEBUG_ERROR,
1044 ("The message type is invalid(%d)! \n", MsgType));
1045 return FALSE;
1046 }
1047 /* 1. Replay counter check */
1048 if (MsgType == EAPOL_PAIR_MSG_1 || MsgType == EAPOL_PAIR_MSG_3 || MsgType == EAPOL_GROUP_MSG_1) /* For supplicant */
1049 {
1050 /* First validate replay counter, only accept message with larger replay counter. */
1051 /* Let equal pass, some AP start with all zero replay counter */
1052 u8 ZeroReplay[LEN_KEY_DESC_REPLAY];
1053
1054 NdisZeroMemory(ZeroReplay, LEN_KEY_DESC_REPLAY);
1055 if ((RTMPCompareMemory
1056 (pMsg->KeyDesc.ReplayCounter, pEntry->R_Counter,
1057 LEN_KEY_DESC_REPLAY) != 1)
1058 &&
1059 (RTMPCompareMemory
1060 (pMsg->KeyDesc.ReplayCounter, ZeroReplay,
1061 LEN_KEY_DESC_REPLAY) != 0)) {
1062 bReplayDiff = TRUE;
1063 }
1064 } else if (MsgType == EAPOL_PAIR_MSG_2 || MsgType == EAPOL_PAIR_MSG_4 || MsgType == EAPOL_GROUP_MSG_2) /* For authenticator */
1065 {
1066 /* check Replay Counter coresponds to MSG from authenticator, otherwise discard */
1067 if (!NdisEqualMemory
1068 (pMsg->KeyDesc.ReplayCounter, pEntry->R_Counter,
1069 LEN_KEY_DESC_REPLAY)) {
1070 bReplayDiff = TRUE;
1071 }
1072 }
1073 /* Replay Counter different condition */
1074 if (bReplayDiff) {
1075 /* send wireless event - for replay counter different */
1076 if (pAd->CommonCfg.bWirelessEvent)
1077 RTMPSendWirelessEvent(pAd,
1078 IW_REPLAY_COUNTER_DIFF_EVENT_FLAG,
1079 pEntry->Addr, pEntry->apidx, 0);
1080
1081 if (MsgType < EAPOL_GROUP_MSG_1) {
1082 DBGPRINT(RT_DEBUG_ERROR,
1083 ("Replay Counter Different in pairwise msg %d of 4-way handshake!\n",
1084 MsgType));
1085 } else {
1086 DBGPRINT(RT_DEBUG_ERROR,
1087 ("Replay Counter Different in group msg %d of 2-way handshake!\n",
1088 (MsgType - EAPOL_PAIR_MSG_4)));
1089 }
1090
1091 hex_dump("Receive replay counter ", pMsg->KeyDesc.ReplayCounter,
1092 LEN_KEY_DESC_REPLAY);
1093 hex_dump("Current replay counter ", pEntry->R_Counter,
1094 LEN_KEY_DESC_REPLAY);
1095 return FALSE;
1096 }
1097 /* 2. Verify MIC except Pairwise Msg1 */
1098 if (MsgType != EAPOL_PAIR_MSG_1) {
1099 u8 rcvd_mic[LEN_KEY_DESC_MIC];
1100
1101 /* Record the received MIC for check later */
1102 NdisMoveMemory(rcvd_mic, pMsg->KeyDesc.KeyMic,
1103 LEN_KEY_DESC_MIC);
1104 NdisZeroMemory(pMsg->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
1105
1106 if (EapolKeyInfo.KeyDescVer == DESC_TYPE_TKIP) /* TKIP */
1107 {
1108 HMAC_MD5(pEntry->PTK, LEN_EAP_MICK, (u8 *)pMsg,
1109 MsgLen, mic, MD5_DIGEST_SIZE);
1110 } else if (EapolKeyInfo.KeyDescVer == DESC_TYPE_AES) /* AES */
1111 {
1112 HMAC_SHA1(pEntry->PTK, LEN_EAP_MICK, (u8 *)pMsg,
1113 MsgLen, digest, SHA1_DIGEST_SIZE);
1114 NdisMoveMemory(mic, digest, LEN_KEY_DESC_MIC);
1115 }
1116
1117 if (!NdisEqualMemory(rcvd_mic, mic, LEN_KEY_DESC_MIC)) {
1118 /* send wireless event - for MIC different */
1119 if (pAd->CommonCfg.bWirelessEvent)
1120 RTMPSendWirelessEvent(pAd,
1121 IW_MIC_DIFF_EVENT_FLAG,
1122 pEntry->Addr,
1123 pEntry->apidx, 0);
1124
1125 if (MsgType < EAPOL_GROUP_MSG_1) {
1126 DBGPRINT(RT_DEBUG_ERROR,
1127 ("MIC Different in pairwise msg %d of 4-way handshake!\n",
1128 MsgType));
1129 } else {
1130 DBGPRINT(RT_DEBUG_ERROR,
1131 ("MIC Different in group msg %d of 2-way handshake!\n",
1132 (MsgType - EAPOL_PAIR_MSG_4)));
1133 }
1134
1135 hex_dump("Received MIC", rcvd_mic, LEN_KEY_DESC_MIC);
1136 hex_dump("Desired MIC", mic, LEN_KEY_DESC_MIC);
1137
1138 return FALSE;
1139 }
1140 }
1141 /* 1. Decrypt the Key Data field if GTK is included. */
1142 /* 2. Extract the context of the Key Data field if it exist. */
1143 /* The field in pairwise_msg_2_WPA1(WPA2) & pairwise_msg_3_WPA1 is clear. */
1144 /* The field in group_msg_1_WPA1(WPA2) & pairwise_msg_3_WPA2 is encrypted. */
1145 if (CONV_ARRARY_TO_u16(pMsg->KeyDesc.KeyDataLen) > 0) {
1146 /* Decrypt this field */
1147 if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2)
1148 || (MsgType == EAPOL_GROUP_MSG_1)) {
1149 if ((EapolKeyInfo.KeyDescVer == DESC_TYPE_AES)) {
1150 /* AES */
1151 AES_GTK_KEY_UNWRAP(&pEntry->PTK[16], KEYDATA,
1152 CONV_ARRARY_TO_u16(pMsg->
1153 KeyDesc.
1154 KeyDataLen),
1155 pMsg->KeyDesc.KeyData);
1156 } else {
1157 int i;
1158 u8 Key[32];
1159 /* Decrypt TKIP GTK */
1160 /* Construct 32 bytes RC4 Key */
1161 NdisMoveMemory(Key, pMsg->KeyDesc.KeyIv, 16);
1162 NdisMoveMemory(&Key[16], &pEntry->PTK[16], 16);
1163 ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, Key,
1164 32);
1165 /*discard first 256 bytes */
1166 for (i = 0; i < 256; i++)
1167 ARCFOUR_BYTE(&pAd->PrivateInfo.
1168 WEPCONTEXT);
1169 /* Decrypt GTK. Becareful, there is no ICV to check the result is correct or not */
1170 ARCFOUR_DECRYPT(&pAd->PrivateInfo.WEPCONTEXT,
1171 KEYDATA, pMsg->KeyDesc.KeyData,
1172 CONV_ARRARY_TO_u16(pMsg->
1173 KeyDesc.
1174 KeyDataLen));
1175 }
1176
1177 if (!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1))
1178 GroupKeyIndex = EapolKeyInfo.KeyIndex;
1179
1180 } else if ((MsgType == EAPOL_PAIR_MSG_2)
1181 || (MsgType == EAPOL_PAIR_MSG_3 && !bWPA2)) {
1182 NdisMoveMemory(KEYDATA, pMsg->KeyDesc.KeyData,
1183 CONV_ARRARY_TO_u16(pMsg->KeyDesc.
1184 KeyDataLen));
1185 } else {
1186
1187 return TRUE;
1188 }
1189
1190 /* Parse Key Data field to */
1191 /* 1. verify RSN IE for pairwise_msg_2_WPA1(WPA2) ,pairwise_msg_3_WPA1(WPA2) */
1192 /* 2. verify KDE format for pairwise_msg_3_WPA2, group_msg_1_WPA2 */
1193 /* 3. update shared key for pairwise_msg_3_WPA2, group_msg_1_WPA1(WPA2) */
1194 if (!RTMPParseEapolKeyData(pAd, KEYDATA,
1195 CONV_ARRARY_TO_u16(pMsg->KeyDesc.
1196 KeyDataLen),
1197 GroupKeyIndex, MsgType, bWPA2,
1198 pEntry)) {
1199 return FALSE;
1200 }
1201 }
1202
1203 return TRUE;
1204
1205}
diff --git a/drivers/staging/rt2860/common/cmm_sync.c b/drivers/staging/rt2860/common/cmm_sync.c
deleted file mode 100644
index aefe1b77465..00000000000
--- a/drivers/staging/rt2860/common/cmm_sync.c
+++ /dev/null
@@ -1,718 +0,0 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 cmm_sync.c
29
30 Abstract:
31
32 Revision History:
33 Who When What
34 -------- ---------- ----------------------------------------------
35 John Chang 2004-09-01 modified for rt2561/2661
36*/
37#include "../rt_config.h"
38
39/* 2.4 Ghz channel plan index in the TxPower arrays. */
40#define BG_BAND_REGION_0_START 0 /* 1,2,3,4,5,6,7,8,9,10,11 */
41#define BG_BAND_REGION_0_SIZE 11
42#define BG_BAND_REGION_1_START 0 /* 1,2,3,4,5,6,7,8,9,10,11,12,13 */
43#define BG_BAND_REGION_1_SIZE 13
44#define BG_BAND_REGION_2_START 9 /* 10,11 */
45#define BG_BAND_REGION_2_SIZE 2
46#define BG_BAND_REGION_3_START 9 /* 10,11,12,13 */
47#define BG_BAND_REGION_3_SIZE 4
48#define BG_BAND_REGION_4_START 13 /* 14 */
49#define BG_BAND_REGION_4_SIZE 1
50#define BG_BAND_REGION_5_START 0 /* 1,2,3,4,5,6,7,8,9,10,11,12,13,14 */
51#define BG_BAND_REGION_5_SIZE 14
52#define BG_BAND_REGION_6_START 2 /* 3,4,5,6,7,8,9 */
53#define BG_BAND_REGION_6_SIZE 7
54#define BG_BAND_REGION_7_START 4 /* 5,6,7,8,9,10,11,12,13 */
55#define BG_BAND_REGION_7_SIZE 9
56#define BG_BAND_REGION_31_START 0 /* 1,2,3,4,5,6,7,8,9,10,11,12,13,14 */
57#define BG_BAND_REGION_31_SIZE 14
58
59/* 5 Ghz channel plan index in the TxPower arrays. */
60u8 A_BAND_REGION_0_CHANNEL_LIST[] =
61 { 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165 };
62u8 A_BAND_REGION_1_CHANNEL_LIST[] =
63 { 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128,
64132, 136, 140 };
65u8 A_BAND_REGION_2_CHANNEL_LIST[] = { 36, 40, 44, 48, 52, 56, 60, 64 };
66u8 A_BAND_REGION_3_CHANNEL_LIST[] = { 52, 56, 60, 64, 149, 153, 157, 161 };
67u8 A_BAND_REGION_4_CHANNEL_LIST[] = { 149, 153, 157, 161, 165 };
68u8 A_BAND_REGION_5_CHANNEL_LIST[] = { 149, 153, 157, 161 };
69u8 A_BAND_REGION_6_CHANNEL_LIST[] = { 36, 40, 44, 48 };
70u8 A_BAND_REGION_7_CHANNEL_LIST[] =
71 { 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128,
72132, 136, 140, 149, 153, 157, 161, 165, 169, 173 };
73u8 A_BAND_REGION_8_CHANNEL_LIST[] = { 52, 56, 60, 64 };
74u8 A_BAND_REGION_9_CHANNEL_LIST[] =
75 { 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140,
76149, 153, 157, 161, 165 };
77u8 A_BAND_REGION_10_CHANNEL_LIST[] =
78 { 36, 40, 44, 48, 149, 153, 157, 161, 165 };
79u8 A_BAND_REGION_11_CHANNEL_LIST[] =
80 { 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 149, 153,
81157, 161 };
82u8 A_BAND_REGION_12_CHANNEL_LIST[] =
83 { 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128,
84132, 136, 140 };
85u8 A_BAND_REGION_13_CHANNEL_LIST[] =
86 { 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140,
87149, 153, 157, 161 };
88u8 A_BAND_REGION_14_CHANNEL_LIST[] =
89 { 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149,
90153, 157, 161, 165 };
91u8 A_BAND_REGION_15_CHANNEL_LIST[] = { 149, 153, 157, 161, 165, 169, 173 };
92
93/*BaSizeArray follows the 802.11n definition as MaxRxFactor. 2^(13+factor) bytes. When factor =0, it's about Ba buffer size =8. */
94u8 BaSizeArray[4] = { 8, 16, 32, 64 };
95
96/*
97 ==========================================================================
98 Description:
99 Update StaCfg->ChannelList[] according to 1) Country Region 2) RF IC type,
100 and 3) PHY-mode user selected.
101 The outcome is used by driver when doing site survey.
102
103 IRQL = PASSIVE_LEVEL
104 IRQL = DISPATCH_LEVEL
105
106 ==========================================================================
107 */
108void BuildChannelList(struct rt_rtmp_adapter *pAd)
109{
110 u8 i, j, index = 0, num = 0;
111 u8 *pChannelList = NULL;
112
113 NdisZeroMemory(pAd->ChannelList,
114 MAX_NUM_OF_CHANNELS * sizeof(struct rt_channel_tx_power));
115
116 /* if not 11a-only mode, channel list starts from 2.4Ghz band */
117 if ((pAd->CommonCfg.PhyMode != PHY_11A)
118 && (pAd->CommonCfg.PhyMode != PHY_11AN_MIXED)
119 && (pAd->CommonCfg.PhyMode != PHY_11N_5G)
120 ) {
121 switch (pAd->CommonCfg.CountryRegion & 0x7f) {
122 case REGION_0_BG_BAND: /* 1 -11 */
123 NdisMoveMemory(&pAd->ChannelList[index],
124 &pAd->TxPower[BG_BAND_REGION_0_START],
125 sizeof(struct rt_channel_tx_power) *
126 BG_BAND_REGION_0_SIZE);
127 index += BG_BAND_REGION_0_SIZE;
128 break;
129 case REGION_1_BG_BAND: /* 1 - 13 */
130 NdisMoveMemory(&pAd->ChannelList[index],
131 &pAd->TxPower[BG_BAND_REGION_1_START],
132 sizeof(struct rt_channel_tx_power) *
133 BG_BAND_REGION_1_SIZE);
134 index += BG_BAND_REGION_1_SIZE;
135 break;
136 case REGION_2_BG_BAND: /* 10 - 11 */
137 NdisMoveMemory(&pAd->ChannelList[index],
138 &pAd->TxPower[BG_BAND_REGION_2_START],
139 sizeof(struct rt_channel_tx_power) *
140 BG_BAND_REGION_2_SIZE);
141 index += BG_BAND_REGION_2_SIZE;
142 break;
143 case REGION_3_BG_BAND: /* 10 - 13 */
144 NdisMoveMemory(&pAd->ChannelList[index],
145 &pAd->TxPower[BG_BAND_REGION_3_START],
146 sizeof(struct rt_channel_tx_power) *
147 BG_BAND_REGION_3_SIZE);
148 index += BG_BAND_REGION_3_SIZE;
149 break;
150 case REGION_4_BG_BAND: /* 14 */
151 NdisMoveMemory(&pAd->ChannelList[index],
152 &pAd->TxPower[BG_BAND_REGION_4_START],
153 sizeof(struct rt_channel_tx_power) *
154 BG_BAND_REGION_4_SIZE);
155 index += BG_BAND_REGION_4_SIZE;
156 break;
157 case REGION_5_BG_BAND: /* 1 - 14 */
158 NdisMoveMemory(&pAd->ChannelList[index],
159 &pAd->TxPower[BG_BAND_REGION_5_START],
160 sizeof(struct rt_channel_tx_power) *
161 BG_BAND_REGION_5_SIZE);
162 index += BG_BAND_REGION_5_SIZE;
163 break;
164 case REGION_6_BG_BAND: /* 3 - 9 */
165 NdisMoveMemory(&pAd->ChannelList[index],
166 &pAd->TxPower[BG_BAND_REGION_6_START],
167 sizeof(struct rt_channel_tx_power) *
168 BG_BAND_REGION_6_SIZE);
169 index += BG_BAND_REGION_6_SIZE;
170 break;
171 case REGION_7_BG_BAND: /* 5 - 13 */
172 NdisMoveMemory(&pAd->ChannelList[index],
173 &pAd->TxPower[BG_BAND_REGION_7_START],
174 sizeof(struct rt_channel_tx_power) *
175 BG_BAND_REGION_7_SIZE);
176 index += BG_BAND_REGION_7_SIZE;
177 break;
178 case REGION_31_BG_BAND: /* 1 - 14 */
179 NdisMoveMemory(&pAd->ChannelList[index],
180 &pAd->TxPower[BG_BAND_REGION_31_START],
181 sizeof(struct rt_channel_tx_power) *
182 BG_BAND_REGION_31_SIZE);
183 index += BG_BAND_REGION_31_SIZE;
184 break;
185 default: /* Error. should never happen */
186 break;
187 }
188 for (i = 0; i < index; i++)
189 pAd->ChannelList[i].MaxTxPwr = 20;
190 }
191
192 if ((pAd->CommonCfg.PhyMode == PHY_11A)
193 || (pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED)
194 || (pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED)
195 || (pAd->CommonCfg.PhyMode == PHY_11AN_MIXED)
196 || (pAd->CommonCfg.PhyMode == PHY_11AGN_MIXED)
197 || (pAd->CommonCfg.PhyMode == PHY_11N_5G)
198 ) {
199 switch (pAd->CommonCfg.CountryRegionForABand & 0x7f) {
200 case REGION_0_A_BAND:
201 num =
202 sizeof(A_BAND_REGION_0_CHANNEL_LIST) /
203 sizeof(u8);
204 pChannelList = A_BAND_REGION_0_CHANNEL_LIST;
205 break;
206 case REGION_1_A_BAND:
207 num =
208 sizeof(A_BAND_REGION_1_CHANNEL_LIST) /
209 sizeof(u8);
210 pChannelList = A_BAND_REGION_1_CHANNEL_LIST;
211 break;
212 case REGION_2_A_BAND:
213 num =
214 sizeof(A_BAND_REGION_2_CHANNEL_LIST) /
215 sizeof(u8);
216 pChannelList = A_BAND_REGION_2_CHANNEL_LIST;
217 break;
218 case REGION_3_A_BAND:
219 num =
220 sizeof(A_BAND_REGION_3_CHANNEL_LIST) /
221 sizeof(u8);
222 pChannelList = A_BAND_REGION_3_CHANNEL_LIST;
223 break;
224 case REGION_4_A_BAND:
225 num =
226 sizeof(A_BAND_REGION_4_CHANNEL_LIST) /
227 sizeof(u8);
228 pChannelList = A_BAND_REGION_4_CHANNEL_LIST;
229 break;
230 case REGION_5_A_BAND:
231 num =
232 sizeof(A_BAND_REGION_5_CHANNEL_LIST) /
233 sizeof(u8);
234 pChannelList = A_BAND_REGION_5_CHANNEL_LIST;
235 break;
236 case REGION_6_A_BAND:
237 num =
238 sizeof(A_BAND_REGION_6_CHANNEL_LIST) /
239 sizeof(u8);
240 pChannelList = A_BAND_REGION_6_CHANNEL_LIST;
241 break;
242 case REGION_7_A_BAND:
243 num =
244 sizeof(A_BAND_REGION_7_CHANNEL_LIST) /
245 sizeof(u8);
246 pChannelList = A_BAND_REGION_7_CHANNEL_LIST;
247 break;
248 case REGION_8_A_BAND:
249 num =
250 sizeof(A_BAND_REGION_8_CHANNEL_LIST) /
251 sizeof(u8);
252 pChannelList = A_BAND_REGION_8_CHANNEL_LIST;
253 break;
254 case REGION_9_A_BAND:
255 num =
256 sizeof(A_BAND_REGION_9_CHANNEL_LIST) /
257 sizeof(u8);
258 pChannelList = A_BAND_REGION_9_CHANNEL_LIST;
259 break;
260
261 case REGION_10_A_BAND:
262 num =
263 sizeof(A_BAND_REGION_10_CHANNEL_LIST) /
264 sizeof(u8);
265 pChannelList = A_BAND_REGION_10_CHANNEL_LIST;
266 break;
267
268 case REGION_11_A_BAND:
269 num =
270 sizeof(A_BAND_REGION_11_CHANNEL_LIST) /
271 sizeof(u8);
272 pChannelList = A_BAND_REGION_11_CHANNEL_LIST;
273 break;
274 case REGION_12_A_BAND:
275 num =
276 sizeof(A_BAND_REGION_12_CHANNEL_LIST) /
277 sizeof(u8);
278 pChannelList = A_BAND_REGION_12_CHANNEL_LIST;
279 break;
280 case REGION_13_A_BAND:
281 num =
282 sizeof(A_BAND_REGION_13_CHANNEL_LIST) /
283 sizeof(u8);
284 pChannelList = A_BAND_REGION_13_CHANNEL_LIST;
285 break;
286 case REGION_14_A_BAND:
287 num =
288 sizeof(A_BAND_REGION_14_CHANNEL_LIST) /
289 sizeof(u8);
290 pChannelList = A_BAND_REGION_14_CHANNEL_LIST;
291 break;
292 case REGION_15_A_BAND:
293 num =
294 sizeof(A_BAND_REGION_15_CHANNEL_LIST) /
295 sizeof(u8);
296 pChannelList = A_BAND_REGION_15_CHANNEL_LIST;
297 break;
298 default: /* Error. should never happen */
299 DBGPRINT(RT_DEBUG_WARN,
300 ("countryregion=%d not support",
301 pAd->CommonCfg.CountryRegionForABand));
302 break;
303 }
304
305 if (num != 0) {
306 u8 RadarCh[15] =
307 { 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124,
308 128, 132, 136, 140 };
309 for (i = 0; i < num; i++) {
310 for (j = 0; j < MAX_NUM_OF_CHANNELS; j++) {
311 if (pChannelList[i] ==
312 pAd->TxPower[j].Channel)
313 NdisMoveMemory(&pAd->
314 ChannelList[index
315 + i],
316 &pAd->TxPower[j],
317 sizeof
318 (struct rt_channel_tx_power));
319 }
320 for (j = 0; j < 15; j++) {
321 if (pChannelList[i] == RadarCh[j])
322 pAd->ChannelList[index +
323 i].DfsReq =
324 TRUE;
325 }
326 pAd->ChannelList[index + i].MaxTxPwr = 20;
327 }
328 index += num;
329 }
330 }
331
332 pAd->ChannelListNum = index;
333 DBGPRINT(RT_DEBUG_TRACE,
334 ("country code=%d/%d, RFIC=%d, PHY mode=%d, support %d channels\n",
335 pAd->CommonCfg.CountryRegion,
336 pAd->CommonCfg.CountryRegionForABand, pAd->RfIcType,
337 pAd->CommonCfg.PhyMode, pAd->ChannelListNum));
338#ifdef DBG
339 for (i = 0; i < pAd->ChannelListNum; i++) {
340 DBGPRINT_RAW(RT_DEBUG_TRACE,
341 ("BuildChannel # %d :: Pwr0 = %d, Pwr1 =%d, \n ",
342 pAd->ChannelList[i].Channel,
343 pAd->ChannelList[i].Power,
344 pAd->ChannelList[i].Power2));
345 }
346#endif
347}
348
349/*
350 ==========================================================================
351 Description:
352 This routine return the first channel number according to the country
353 code selection and RF IC selection (signal band or dual band). It is called
354 whenever driver need to start a site survey of all supported channels.
355 Return:
356 ch - the first channel number of current country code setting
357
358 IRQL = PASSIVE_LEVEL
359
360 ==========================================================================
361 */
362u8 FirstChannel(struct rt_rtmp_adapter *pAd)
363{
364 return pAd->ChannelList[0].Channel;
365}
366
367/*
368 ==========================================================================
369 Description:
370 This routine returns the next channel number. This routine is called
371 during driver need to start a site survey of all supported channels.
372 Return:
373 next_channel - the next channel number valid in current country code setting.
374 Note:
375 return 0 if no more next channel
376 ==========================================================================
377 */
378u8 NextChannel(struct rt_rtmp_adapter *pAd, u8 channel)
379{
380 int i;
381 u8 next_channel = 0;
382
383 for (i = 0; i < (pAd->ChannelListNum - 1); i++)
384 if (channel == pAd->ChannelList[i].Channel) {
385 next_channel = pAd->ChannelList[i + 1].Channel;
386 break;
387 }
388 return next_channel;
389}
390
391/*
392 ==========================================================================
393 Description:
394 This routine is for Cisco Compatible Extensions 2.X
395 Spec31. AP Control of Client Transmit Power
396 Return:
397 None
398 Note:
399 Required by Aironet dBm(mW)
400 0dBm(1mW), 1dBm(5mW), 13dBm(20mW), 15dBm(30mW),
401 17dBm(50mw), 20dBm(100mW)
402
403 We supported
404 3dBm(Lowest), 6dBm(10%), 9dBm(25%), 12dBm(50%),
405 14dBm(75%), 15dBm(100%)
406
407 The client station's actual transmit power shall be within +/- 5dB of
408 the minimum value or next lower value.
409 ==========================================================================
410 */
411void ChangeToCellPowerLimit(struct rt_rtmp_adapter *pAd,
412 u8 AironetCellPowerLimit)
413{
414 /*valud 0xFF means that hasn't found power limit information */
415 /*from the AP's Beacon/Probe response. */
416 if (AironetCellPowerLimit == 0xFF)
417 return;
418
419 if (AironetCellPowerLimit < 6) /*Used Lowest Power Percentage. */
420 pAd->CommonCfg.TxPowerPercentage = 6;
421 else if (AironetCellPowerLimit < 9)
422 pAd->CommonCfg.TxPowerPercentage = 10;
423 else if (AironetCellPowerLimit < 12)
424 pAd->CommonCfg.TxPowerPercentage = 25;
425 else if (AironetCellPowerLimit < 14)
426 pAd->CommonCfg.TxPowerPercentage = 50;
427 else if (AironetCellPowerLimit < 15)
428 pAd->CommonCfg.TxPowerPercentage = 75;
429 else
430 pAd->CommonCfg.TxPowerPercentage = 100; /*else used maximum */
431
432 if (pAd->CommonCfg.TxPowerPercentage > pAd->CommonCfg.TxPowerDefault)
433 pAd->CommonCfg.TxPowerPercentage =
434 pAd->CommonCfg.TxPowerDefault;
435
436}
437
438char ConvertToRssi(struct rt_rtmp_adapter *pAd, char Rssi, u8 RssiNumber)
439{
440 u8 RssiOffset, LNAGain;
441
442 /* Rssi equals to zero should be an invalid value */
443 if (Rssi == 0)
444 return -99;
445
446 LNAGain = GET_LNA_GAIN(pAd);
447 if (pAd->LatchRfRegs.Channel > 14) {
448 if (RssiNumber == 0)
449 RssiOffset = pAd->ARssiOffset0;
450 else if (RssiNumber == 1)
451 RssiOffset = pAd->ARssiOffset1;
452 else
453 RssiOffset = pAd->ARssiOffset2;
454 } else {
455 if (RssiNumber == 0)
456 RssiOffset = pAd->BGRssiOffset0;
457 else if (RssiNumber == 1)
458 RssiOffset = pAd->BGRssiOffset1;
459 else
460 RssiOffset = pAd->BGRssiOffset2;
461 }
462
463 return (-12 - RssiOffset - LNAGain - Rssi);
464}
465
466/*
467 ==========================================================================
468 Description:
469 Scan next channel
470 ==========================================================================
471 */
472void ScanNextChannel(struct rt_rtmp_adapter *pAd)
473{
474 struct rt_header_802_11 Hdr80211;
475 u8 *pOutBuffer = NULL;
476 int NStatus;
477 unsigned long FrameLen = 0;
478 u8 SsidLen = 0, ScanType = pAd->MlmeAux.ScanType, BBPValue = 0;
479 u16 Status;
480 struct rt_header_802_11 * pHdr80211;
481 u32 ScanTimeIn5gChannel = SHORT_CHANNEL_TIME;
482
483 {
484 if (MONITOR_ON(pAd))
485 return;
486 }
487
488 if (pAd->MlmeAux.Channel == 0) {
489 if ((pAd->CommonCfg.BBPCurrentBW == BW_40)
490 && (INFRA_ON(pAd)
491 || (pAd->OpMode == OPMODE_AP))
492 ) {
493 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel,
494 FALSE);
495 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
496 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
497 BBPValue &= (~0x18);
498 BBPValue |= 0x10;
499 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
500 DBGPRINT(RT_DEBUG_TRACE,
501 ("SYNC - End of SCAN, restore to 40MHz channel %d, Total BSS[%02d]\n",
502 pAd->CommonCfg.CentralChannel,
503 pAd->ScanTab.BssNr));
504 } else {
505 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
506 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
507 DBGPRINT(RT_DEBUG_TRACE,
508 ("SYNC - End of SCAN, restore to channel %d, Total BSS[%02d]\n",
509 pAd->CommonCfg.Channel, pAd->ScanTab.BssNr));
510 }
511
512 {
513 /* */
514 /* To prevent data lost. */
515 /* Send an NULL data with turned PSM bit on to current associated AP before SCAN progress. */
516 /* Now, we need to send an NULL data with turned PSM bit off to AP, when scan progress done */
517 /* */
518 if (OPSTATUS_TEST_FLAG
519 (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
520 && (INFRA_ON(pAd))) {
521 NStatus =
522 MlmeAllocateMemory(pAd,
523 (void *)& pOutBuffer);
524 if (NStatus == NDIS_STATUS_SUCCESS) {
525 pHdr80211 = (struct rt_header_802_11 *) pOutBuffer;
526 MgtMacHeaderInit(pAd, pHdr80211,
527 SUBTYPE_NULL_FUNC, 1,
528 pAd->CommonCfg.Bssid,
529 pAd->CommonCfg.Bssid);
530 pHdr80211->Duration = 0;
531 pHdr80211->FC.Type = BTYPE_DATA;
532 pHdr80211->FC.PwrMgmt =
533 (pAd->StaCfg.Psm == PWR_SAVE);
534
535 /* Send using priority queue */
536 MiniportMMRequest(pAd, 0, pOutBuffer,
537 sizeof
538 (struct rt_header_802_11));
539 DBGPRINT(RT_DEBUG_TRACE,
540 ("MlmeScanReqAction -- Send PSM Data frame\n"));
541 MlmeFreeMemory(pAd, pOutBuffer);
542 RTMPusecDelay(5000);
543 }
544 }
545
546 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
547 Status = MLME_SUCCESS;
548 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF,
549 2, &Status);
550 }
551
552 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
553 }
554#ifdef RTMP_MAC_USB
555 else if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)
556 && (pAd->OpMode == OPMODE_STA)) {
557 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
558 MlmeCntlConfirm(pAd, MT2_SCAN_CONF, MLME_FAIL_NO_RESOURCE);
559 }
560#endif /* RTMP_MAC_USB // */
561 else {
562 {
563 /* BBP and RF are not accessible in PS mode, we has to wake them up first */
564 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
565 AsicForceWakeup(pAd, TRUE);
566
567 /* leave PSM during scanning. otherwise we may lost ProbeRsp & BEACON */
568 if (pAd->StaCfg.Psm == PWR_SAVE)
569 RTMP_SET_PSM_BIT(pAd, PWR_ACTIVE);
570 }
571
572 AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, TRUE);
573 AsicLockChannel(pAd, pAd->MlmeAux.Channel);
574
575 {
576 if (pAd->MlmeAux.Channel > 14) {
577 if ((pAd->CommonCfg.bIEEE80211H == 1)
578 && RadarChannelCheck(pAd,
579 pAd->MlmeAux.
580 Channel)) {
581 ScanType = SCAN_PASSIVE;
582 ScanTimeIn5gChannel = MIN_CHANNEL_TIME;
583 }
584 }
585 }
586
587 /*Global country domain(ch1-11:active scan, ch12-14 passive scan) */
588 if ((pAd->MlmeAux.Channel <= 14) && (pAd->MlmeAux.Channel >= 12)
589 && ((pAd->CommonCfg.CountryRegion & 0x7f) ==
590 REGION_31_BG_BAND)) {
591 ScanType = SCAN_PASSIVE;
592 }
593 /* We need to shorten active scan time in order for WZC connect issue */
594 /* Chnage the channel scan time for CISCO stuff based on its IAPP announcement */
595 if (ScanType == FAST_SCAN_ACTIVE)
596 RTMPSetTimer(&pAd->MlmeAux.ScanTimer,
597 FAST_ACTIVE_SCAN_TIME);
598 else /* must be SCAN_PASSIVE or SCAN_ACTIVE */
599 {
600 if ((pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED)
601 || (pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED)
602 || (pAd->CommonCfg.PhyMode == PHY_11AGN_MIXED)
603 ) {
604 if (pAd->MlmeAux.Channel > 14)
605 RTMPSetTimer(&pAd->MlmeAux.ScanTimer,
606 ScanTimeIn5gChannel);
607 else
608 RTMPSetTimer(&pAd->MlmeAux.ScanTimer,
609 MIN_CHANNEL_TIME);
610 } else
611 RTMPSetTimer(&pAd->MlmeAux.ScanTimer,
612 MAX_CHANNEL_TIME);
613 }
614
615 if ((ScanType == SCAN_ACTIVE)
616 || (ScanType == FAST_SCAN_ACTIVE)
617 ) {
618 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */
619 if (NStatus != NDIS_STATUS_SUCCESS) {
620 DBGPRINT(RT_DEBUG_TRACE,
621 ("SYNC - ScanNextChannel() allocate memory fail\n"));
622
623 {
624 pAd->Mlme.SyncMachine.CurrState =
625 SYNC_IDLE;
626 Status = MLME_FAIL_NO_RESOURCE;
627 MlmeEnqueue(pAd,
628 MLME_CNTL_STATE_MACHINE,
629 MT2_SCAN_CONF, 2, &Status);
630 }
631
632 return;
633 }
634 /* There is no need to send broadcast probe request if active scan is in effect. */
635 if ((ScanType == SCAN_ACTIVE)
636 || (ScanType == FAST_SCAN_ACTIVE)
637 )
638 SsidLen = pAd->MlmeAux.SsidLen;
639 else
640 SsidLen = 0;
641
642 MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0,
643 BROADCAST_ADDR, BROADCAST_ADDR);
644 MakeOutgoingFrame(pOutBuffer, &FrameLen,
645 sizeof(struct rt_header_802_11), &Hdr80211, 1,
646 &SsidIe, 1, &SsidLen, SsidLen,
647 pAd->MlmeAux.Ssid, 1, &SupRateIe, 1,
648 &pAd->CommonCfg.SupRateLen,
649 pAd->CommonCfg.SupRateLen,
650 pAd->CommonCfg.SupRate, END_OF_ARGS);
651
652 if (pAd->CommonCfg.ExtRateLen) {
653 unsigned long Tmp;
654 MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
655 1, &ExtRateIe,
656 1, &pAd->CommonCfg.ExtRateLen,
657 pAd->CommonCfg.ExtRateLen,
658 pAd->CommonCfg.ExtRate,
659 END_OF_ARGS);
660 FrameLen += Tmp;
661 }
662
663 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) {
664 unsigned long Tmp;
665 u8 HtLen;
666 u8 BROADCOM[4] = { 0x0, 0x90, 0x4c, 0x33 };
667
668 if (pAd->bBroadComHT == TRUE) {
669 HtLen =
670 pAd->MlmeAux.HtCapabilityLen + 4;
671
672 MakeOutgoingFrame(pOutBuffer + FrameLen,
673 &Tmp, 1, &WpaIe, 1,
674 &HtLen, 4,
675 &BROADCOM[0],
676 pAd->MlmeAux.
677 HtCapabilityLen,
678 &pAd->MlmeAux.
679 HtCapability,
680 END_OF_ARGS);
681 } else {
682 HtLen = pAd->MlmeAux.HtCapabilityLen;
683
684 MakeOutgoingFrame(pOutBuffer + FrameLen,
685 &Tmp, 1, &HtCapIe, 1,
686 &HtLen, HtLen,
687 &pAd->CommonCfg.
688 HtCapability,
689 END_OF_ARGS);
690 }
691 FrameLen += Tmp;
692 }
693
694 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
695 MlmeFreeMemory(pAd, pOutBuffer);
696 }
697 /* For SCAN_CISCO_PASSIVE, do nothing and silently wait for beacon or other probe response */
698
699 pAd->Mlme.SyncMachine.CurrState = SCAN_LISTEN;
700 }
701}
702
703void MgtProbReqMacHeaderInit(struct rt_rtmp_adapter *pAd,
704 struct rt_header_802_11 * pHdr80211,
705 u8 SubType,
706 u8 ToDs, u8 *pDA, u8 *pBssid)
707{
708 NdisZeroMemory(pHdr80211, sizeof(struct rt_header_802_11));
709
710 pHdr80211->FC.Type = BTYPE_MGMT;
711 pHdr80211->FC.SubType = SubType;
712 if (SubType == SUBTYPE_ACK)
713 pHdr80211->FC.Type = BTYPE_CNTL;
714 pHdr80211->FC.ToDs = ToDs;
715 COPY_MAC_ADDR(pHdr80211->Addr1, pDA);
716 COPY_MAC_ADDR(pHdr80211->Addr2, pAd->CurrentAddress);
717 COPY_MAC_ADDR(pHdr80211->Addr3, pBssid);
718}
diff --git a/drivers/staging/rt2860/common/cmm_tkip.c b/drivers/staging/rt2860/common/cmm_tkip.c
deleted file mode 100644
index 4881ef9ba02..00000000000
--- a/drivers/staging/rt2860/common/cmm_tkip.c
+++ /dev/null
@@ -1,833 +0,0 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 cmm_tkip.c
29
30 Abstract:
31
32 Revision History:
33 Who When What
34 -------- ---------- ----------------------------------------------
35 Paul Wu 02-25-02 Initial
36*/
37
38#include "../rt_config.h"
39
40/* Rotation functions on 32 bit values */
41#define ROL32( A, n ) \
42 ( ((A) << (n)) | ( ((A)>>(32-(n))) & ( (1UL << (n)) - 1 ) ) )
43#define ROR32( A, n ) ROL32( (A), 32-(n) )
44
45u32 Tkip_Sbox_Lower[256] = {
46 0xA5, 0x84, 0x99, 0x8D, 0x0D, 0xBD, 0xB1, 0x54,
47 0x50, 0x03, 0xA9, 0x7D, 0x19, 0x62, 0xE6, 0x9A,
48 0x45, 0x9D, 0x40, 0x87, 0x15, 0xEB, 0xC9, 0x0B,
49 0xEC, 0x67, 0xFD, 0xEA, 0xBF, 0xF7, 0x96, 0x5B,
50 0xC2, 0x1C, 0xAE, 0x6A, 0x5A, 0x41, 0x02, 0x4F,
51 0x5C, 0xF4, 0x34, 0x08, 0x93, 0x73, 0x53, 0x3F,
52 0x0C, 0x52, 0x65, 0x5E, 0x28, 0xA1, 0x0F, 0xB5,
53 0x09, 0x36, 0x9B, 0x3D, 0x26, 0x69, 0xCD, 0x9F,
54 0x1B, 0x9E, 0x74, 0x2E, 0x2D, 0xB2, 0xEE, 0xFB,
55 0xF6, 0x4D, 0x61, 0xCE, 0x7B, 0x3E, 0x71, 0x97,
56 0xF5, 0x68, 0x00, 0x2C, 0x60, 0x1F, 0xC8, 0xED,
57 0xBE, 0x46, 0xD9, 0x4B, 0xDE, 0xD4, 0xE8, 0x4A,
58 0x6B, 0x2A, 0xE5, 0x16, 0xC5, 0xD7, 0x55, 0x94,
59 0xCF, 0x10, 0x06, 0x81, 0xF0, 0x44, 0xBA, 0xE3,
60 0xF3, 0xFE, 0xC0, 0x8A, 0xAD, 0xBC, 0x48, 0x04,
61 0xDF, 0xC1, 0x75, 0x63, 0x30, 0x1A, 0x0E, 0x6D,
62 0x4C, 0x14, 0x35, 0x2F, 0xE1, 0xA2, 0xCC, 0x39,
63 0x57, 0xF2, 0x82, 0x47, 0xAC, 0xE7, 0x2B, 0x95,
64 0xA0, 0x98, 0xD1, 0x7F, 0x66, 0x7E, 0xAB, 0x83,
65 0xCA, 0x29, 0xD3, 0x3C, 0x79, 0xE2, 0x1D, 0x76,
66 0x3B, 0x56, 0x4E, 0x1E, 0xDB, 0x0A, 0x6C, 0xE4,
67 0x5D, 0x6E, 0xEF, 0xA6, 0xA8, 0xA4, 0x37, 0x8B,
68 0x32, 0x43, 0x59, 0xB7, 0x8C, 0x64, 0xD2, 0xE0,
69 0xB4, 0xFA, 0x07, 0x25, 0xAF, 0x8E, 0xE9, 0x18,
70 0xD5, 0x88, 0x6F, 0x72, 0x24, 0xF1, 0xC7, 0x51,
71 0x23, 0x7C, 0x9C, 0x21, 0xDD, 0xDC, 0x86, 0x85,
72 0x90, 0x42, 0xC4, 0xAA, 0xD8, 0x05, 0x01, 0x12,
73 0xA3, 0x5F, 0xF9, 0xD0, 0x91, 0x58, 0x27, 0xB9,
74 0x38, 0x13, 0xB3, 0x33, 0xBB, 0x70, 0x89, 0xA7,
75 0xB6, 0x22, 0x92, 0x20, 0x49, 0xFF, 0x78, 0x7A,
76 0x8F, 0xF8, 0x80, 0x17, 0xDA, 0x31, 0xC6, 0xB8,
77 0xC3, 0xB0, 0x77, 0x11, 0xCB, 0xFC, 0xD6, 0x3A
78};
79
80u32 Tkip_Sbox_Upper[256] = {
81 0xC6, 0xF8, 0xEE, 0xF6, 0xFF, 0xD6, 0xDE, 0x91,
82 0x60, 0x02, 0xCE, 0x56, 0xE7, 0xB5, 0x4D, 0xEC,
83 0x8F, 0x1F, 0x89, 0xFA, 0xEF, 0xB2, 0x8E, 0xFB,
84 0x41, 0xB3, 0x5F, 0x45, 0x23, 0x53, 0xE4, 0x9B,
85 0x75, 0xE1, 0x3D, 0x4C, 0x6C, 0x7E, 0xF5, 0x83,
86 0x68, 0x51, 0xD1, 0xF9, 0xE2, 0xAB, 0x62, 0x2A,
87 0x08, 0x95, 0x46, 0x9D, 0x30, 0x37, 0x0A, 0x2F,
88 0x0E, 0x24, 0x1B, 0xDF, 0xCD, 0x4E, 0x7F, 0xEA,
89 0x12, 0x1D, 0x58, 0x34, 0x36, 0xDC, 0xB4, 0x5B,
90 0xA4, 0x76, 0xB7, 0x7D, 0x52, 0xDD, 0x5E, 0x13,
91 0xA6, 0xB9, 0x00, 0xC1, 0x40, 0xE3, 0x79, 0xB6,
92 0xD4, 0x8D, 0x67, 0x72, 0x94, 0x98, 0xB0, 0x85,
93 0xBB, 0xC5, 0x4F, 0xED, 0x86, 0x9A, 0x66, 0x11,
94 0x8A, 0xE9, 0x04, 0xFE, 0xA0, 0x78, 0x25, 0x4B,
95 0xA2, 0x5D, 0x80, 0x05, 0x3F, 0x21, 0x70, 0xF1,
96 0x63, 0x77, 0xAF, 0x42, 0x20, 0xE5, 0xFD, 0xBF,
97 0x81, 0x18, 0x26, 0xC3, 0xBE, 0x35, 0x88, 0x2E,
98 0x93, 0x55, 0xFC, 0x7A, 0xC8, 0xBA, 0x32, 0xE6,
99 0xC0, 0x19, 0x9E, 0xA3, 0x44, 0x54, 0x3B, 0x0B,
100 0x8C, 0xC7, 0x6B, 0x28, 0xA7, 0xBC, 0x16, 0xAD,
101 0xDB, 0x64, 0x74, 0x14, 0x92, 0x0C, 0x48, 0xB8,
102 0x9F, 0xBD, 0x43, 0xC4, 0x39, 0x31, 0xD3, 0xF2,
103 0xD5, 0x8B, 0x6E, 0xDA, 0x01, 0xB1, 0x9C, 0x49,
104 0xD8, 0xAC, 0xF3, 0xCF, 0xCA, 0xF4, 0x47, 0x10,
105 0x6F, 0xF0, 0x4A, 0x5C, 0x38, 0x57, 0x73, 0x97,
106 0xCB, 0xA1, 0xE8, 0x3E, 0x96, 0x61, 0x0D, 0x0F,
107 0xE0, 0x7C, 0x71, 0xCC, 0x90, 0x06, 0xF7, 0x1C,
108 0xC2, 0x6A, 0xAE, 0x69, 0x17, 0x99, 0x3A, 0x27,
109 0xD9, 0xEB, 0x2B, 0x22, 0xD2, 0xA9, 0x07, 0x33,
110 0x2D, 0x3C, 0x15, 0xC9, 0x87, 0xAA, 0x50, 0xA5,
111 0x03, 0x59, 0x09, 0x1A, 0x65, 0xD7, 0x84, 0xD0,
112 0x82, 0x29, 0x5A, 0x1E, 0x7B, 0xA8, 0x6D, 0x2C
113};
114
115/* */
116/* Expanded IV for TKIP function. */
117/* */
118struct PACKED rt_tkip_iv {
119 union PACKED {
120 struct PACKED {
121 u8 rc0;
122 u8 rc1;
123 u8 rc2;
124
125 union PACKED {
126 struct PACKED {
127 u8 Rsvd:5;
128 u8 ExtIV:1;
129 u8 KeyID:2;
130 } field;
131 u8 Byte;
132 } CONTROL;
133 } field;
134
135 unsigned long word;
136 } IV16;
137
138 unsigned long IV32;
139};
140
141/*
142 ========================================================================
143
144 Routine Description:
145 Convert from u8[] to unsigned long in a portable way
146
147 Arguments:
148 pMICKey pointer to MIC Key
149
150 Return Value:
151 None
152
153 Note:
154
155 ========================================================================
156*/
157unsigned long RTMPTkipGetUInt32(u8 *pMICKey)
158{
159 unsigned long res = 0;
160 int i;
161
162 for (i = 0; i < 4; i++) {
163 res |= (*pMICKey++) << (8 * i);
164 }
165
166 return res;
167}
168
169/*
170 ========================================================================
171
172 Routine Description:
173 Convert from unsigned long to u8[] in a portable way
174
175 Arguments:
176 pDst pointer to destination for convert unsigned long to u8[]
177 val the value for convert
178
179 Return Value:
180 None
181
182 IRQL = DISPATCH_LEVEL
183
184 Note:
185
186 ========================================================================
187*/
188void RTMPTkipPutUInt32(IN u8 *pDst, unsigned long val)
189{
190 int i;
191
192 for (i = 0; i < 4; i++) {
193 *pDst++ = (u8)(val & 0xff);
194 val >>= 8;
195 }
196}
197
198/*
199 ========================================================================
200
201 Routine Description:
202 Set the MIC Key.
203
204 Arguments:
205 pAd Pointer to our adapter
206 pMICKey pointer to MIC Key
207
208 Return Value:
209 None
210
211 IRQL = DISPATCH_LEVEL
212
213 Note:
214
215 ========================================================================
216*/
217void RTMPTkipSetMICKey(struct rt_tkip_key_info *pTkip, u8 *pMICKey)
218{
219 /* Set the key */
220 pTkip->K0 = RTMPTkipGetUInt32(pMICKey);
221 pTkip->K1 = RTMPTkipGetUInt32(pMICKey + 4);
222 /* and reset the message */
223 pTkip->L = pTkip->K0;
224 pTkip->R = pTkip->K1;
225 pTkip->nBytesInM = 0;
226 pTkip->M = 0;
227}
228
229/*
230 ========================================================================
231
232 Routine Description:
233 Calculate the MIC Value.
234
235 Arguments:
236 pAd Pointer to our adapter
237 uChar Append this uChar
238
239 Return Value:
240 None
241
242 IRQL = DISPATCH_LEVEL
243
244 Note:
245
246 ========================================================================
247*/
248void RTMPTkipAppendByte(struct rt_tkip_key_info *pTkip, u8 uChar)
249{
250 /* Append the byte to our word-sized buffer */
251 pTkip->M |= (uChar << (8 * pTkip->nBytesInM));
252 pTkip->nBytesInM++;
253 /* Process the word if it is full. */
254 if (pTkip->nBytesInM >= 4) {
255 pTkip->L ^= pTkip->M;
256 pTkip->R ^= ROL32(pTkip->L, 17);
257 pTkip->L += pTkip->R;
258 pTkip->R ^=
259 ((pTkip->L & 0xff00ff00) >> 8) | ((pTkip->
260 L & 0x00ff00ff) << 8);
261 pTkip->L += pTkip->R;
262 pTkip->R ^= ROL32(pTkip->L, 3);
263 pTkip->L += pTkip->R;
264 pTkip->R ^= ROR32(pTkip->L, 2);
265 pTkip->L += pTkip->R;
266 /* Clear the buffer */
267 pTkip->M = 0;
268 pTkip->nBytesInM = 0;
269 }
270}
271
272/*
273 ========================================================================
274
275 Routine Description:
276 Calculate the MIC Value.
277
278 Arguments:
279 pAd Pointer to our adapter
280 pSrc Pointer to source data for Calculate MIC Value
281 Len Indicate the length of the source data
282
283 Return Value:
284 None
285
286 IRQL = DISPATCH_LEVEL
287
288 Note:
289
290 ========================================================================
291*/
292void RTMPTkipAppend(struct rt_tkip_key_info *pTkip, u8 *pSrc, u32 nBytes)
293{
294 /* This is simple */
295 while (nBytes > 0) {
296 RTMPTkipAppendByte(pTkip, *pSrc++);
297 nBytes--;
298 }
299}
300
301/*
302 ========================================================================
303
304 Routine Description:
305 Get the MIC Value.
306
307 Arguments:
308 pAd Pointer to our adapter
309
310 Return Value:
311 None
312
313 IRQL = DISPATCH_LEVEL
314
315 Note:
316 the MIC Value is store in pAd->PrivateInfo.MIC
317 ========================================================================
318*/
319void RTMPTkipGetMIC(struct rt_tkip_key_info *pTkip)
320{
321 /* Append the minimum padding */
322 RTMPTkipAppendByte(pTkip, 0x5a);
323 RTMPTkipAppendByte(pTkip, 0);
324 RTMPTkipAppendByte(pTkip, 0);
325 RTMPTkipAppendByte(pTkip, 0);
326 RTMPTkipAppendByte(pTkip, 0);
327 /* and then zeroes until the length is a multiple of 4 */
328 while (pTkip->nBytesInM != 0) {
329 RTMPTkipAppendByte(pTkip, 0);
330 }
331 /* The appendByte function has already computed the result. */
332 RTMPTkipPutUInt32(pTkip->MIC, pTkip->L);
333 RTMPTkipPutUInt32(pTkip->MIC + 4, pTkip->R);
334}
335
336/*
337 ========================================================================
338
339 Routine Description:
340 Init Tkip function.
341
342 Arguments:
343 pAd Pointer to our adapter
344 pTKey Pointer to the Temporal Key (TK), TK shall be 128bits.
345 KeyId TK Key ID
346 pTA Pointer to transmitter address
347 pMICKey pointer to MIC Key
348
349 Return Value:
350 None
351
352 IRQL = DISPATCH_LEVEL
353
354 Note:
355
356 ========================================================================
357*/
358void RTMPInitTkipEngine(struct rt_rtmp_adapter *pAd,
359 u8 *pKey,
360 u8 KeyId,
361 u8 *pTA,
362 u8 *pMICKey,
363 u8 *pTSC, unsigned long *pIV16, unsigned long *pIV32)
364{
365 struct rt_tkip_iv tkipIv;
366
367 /* Prepare 8 bytes TKIP encapsulation for MPDU */
368 NdisZeroMemory(&tkipIv, sizeof(struct rt_tkip_iv));
369 tkipIv.IV16.field.rc0 = *(pTSC + 1);
370 tkipIv.IV16.field.rc1 = (tkipIv.IV16.field.rc0 | 0x20) & 0x7f;
371 tkipIv.IV16.field.rc2 = *pTSC;
372 tkipIv.IV16.field.CONTROL.field.ExtIV = 1; /* 0: non-extended IV, 1: an extended IV */
373 tkipIv.IV16.field.CONTROL.field.KeyID = KeyId;
374/* tkipIv.IV32 = *(unsigned long *)(pTSC + 2); */
375 NdisMoveMemory(&tkipIv.IV32, (pTSC + 2), 4); /* Copy IV */
376
377 *pIV16 = tkipIv.IV16.word;
378 *pIV32 = tkipIv.IV32;
379}
380
381/*
382 ========================================================================
383
384 Routine Description:
385 Init MIC Value calculation function which include set MIC key &
386 calculate first 16 bytes (DA + SA + priority + 0)
387
388 Arguments:
389 pAd Pointer to our adapter
390 pTKey Pointer to the Temporal Key (TK), TK shall be 128bits.
391 pDA Pointer to DA address
392 pSA Pointer to SA address
393 pMICKey pointer to MIC Key
394
395 Return Value:
396 None
397
398 Note:
399
400 ========================================================================
401*/
402void RTMPInitMICEngine(struct rt_rtmp_adapter *pAd,
403 u8 *pKey,
404 u8 *pDA,
405 u8 *pSA, u8 UserPriority, u8 *pMICKey)
406{
407 unsigned long Priority = UserPriority;
408
409 /* Init MIC value calculation */
410 RTMPTkipSetMICKey(&pAd->PrivateInfo.Tx, pMICKey);
411 /* DA */
412 RTMPTkipAppend(&pAd->PrivateInfo.Tx, pDA, MAC_ADDR_LEN);
413 /* SA */
414 RTMPTkipAppend(&pAd->PrivateInfo.Tx, pSA, MAC_ADDR_LEN);
415 /* Priority + 3 bytes of 0 */
416 RTMPTkipAppend(&pAd->PrivateInfo.Tx, (u8 *)& Priority, 4);
417}
418
419/*
420 ========================================================================
421
422 Routine Description:
423 Compare MIC value of received MSDU
424
425 Arguments:
426 pAd Pointer to our adapter
427 pSrc Pointer to the received Plain text data
428 pDA Pointer to DA address
429 pSA Pointer to SA address
430 pMICKey pointer to MIC Key
431 Len the length of the received plain text data exclude MIC value
432
433 Return Value:
434 TRUE MIC value matched
435 FALSE MIC value mismatched
436
437 IRQL = DISPATCH_LEVEL
438
439 Note:
440
441 ========================================================================
442*/
443BOOLEAN RTMPTkipCompareMICValue(struct rt_rtmp_adapter *pAd,
444 u8 *pSrc,
445 u8 *pDA,
446 u8 *pSA,
447 u8 *pMICKey,
448 u8 UserPriority, u32 Len)
449{
450 u8 OldMic[8];
451 unsigned long Priority = UserPriority;
452
453 /* Init MIC value calculation */
454 RTMPTkipSetMICKey(&pAd->PrivateInfo.Rx, pMICKey);
455 /* DA */
456 RTMPTkipAppend(&pAd->PrivateInfo.Rx, pDA, MAC_ADDR_LEN);
457 /* SA */
458 RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSA, MAC_ADDR_LEN);
459 /* Priority + 3 bytes of 0 */
460 RTMPTkipAppend(&pAd->PrivateInfo.Rx, (u8 *)& Priority, 4);
461
462 /* Calculate MIC value from plain text data */
463 RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSrc, Len);
464
465 /* Get MIC valude from received frame */
466 NdisMoveMemory(OldMic, pSrc + Len, 8);
467
468 /* Get MIC value from decrypted plain data */
469 RTMPTkipGetMIC(&pAd->PrivateInfo.Rx);
470
471 /* Move MIC value from MSDU, this steps should move to data path. */
472 /* Since the MIC value might cross MPDUs. */
473 if (!NdisEqualMemory(pAd->PrivateInfo.Rx.MIC, OldMic, 8)) {
474 DBGPRINT_RAW(RT_DEBUG_ERROR, ("RTMPTkipCompareMICValue(): TKIP MIC Error !\n")); /*MIC error. */
475
476 return (FALSE);
477 }
478 return (TRUE);
479}
480
481/*
482 ========================================================================
483
484 Routine Description:
485 Copy frame from waiting queue into relative ring buffer and set
486 appropriate ASIC register to kick hardware transmit function
487
488 Arguments:
489 pAd Pointer to our adapter
490 void * Pointer to Ndis Packet for MIC calculation
491 pEncap Pointer to LLC encap data
492 LenEncap Total encap length, might be 0 which indicates no encap
493
494 Return Value:
495 None
496
497 IRQL = DISPATCH_LEVEL
498
499 Note:
500
501 ========================================================================
502*/
503void RTMPCalculateMICValue(struct rt_rtmp_adapter *pAd,
504 void *pPacket,
505 u8 *pEncap,
506 struct rt_cipher_key *pKey, u8 apidx)
507{
508 struct rt_packet_info PacketInfo;
509 u8 *pSrcBufVA;
510 u32 SrcBufLen;
511 u8 *pSrc;
512 u8 UserPriority;
513 u8 vlan_offset = 0;
514
515 RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
516
517 UserPriority = RTMP_GET_PACKET_UP(pPacket);
518 pSrc = pSrcBufVA;
519
520 /* determine if this is a vlan packet */
521 if (((*(pSrc + 12) << 8) + *(pSrc + 13)) == 0x8100)
522 vlan_offset = 4;
523
524 {
525 RTMPInitMICEngine(pAd,
526 pKey->Key,
527 pSrc, pSrc + 6, UserPriority, pKey->TxMic);
528 }
529
530 if (pEncap != NULL) {
531 /* LLC encapsulation */
532 RTMPTkipAppend(&pAd->PrivateInfo.Tx, pEncap, 6);
533 /* Protocol Type */
534 RTMPTkipAppend(&pAd->PrivateInfo.Tx, pSrc + 12 + vlan_offset,
535 2);
536 }
537 SrcBufLen -= (14 + vlan_offset);
538 pSrc += (14 + vlan_offset);
539 do {
540 if (SrcBufLen > 0) {
541 RTMPTkipAppend(&pAd->PrivateInfo.Tx, pSrc, SrcBufLen);
542 }
543
544 break; /* No need handle next packet */
545
546 } while (TRUE); /* End of copying payload */
547
548 /* Compute the final MIC Value */
549 RTMPTkipGetMIC(&pAd->PrivateInfo.Tx);
550}
551
552/************************************************************/
553/* tkip_sbox() */
554/* Returns a 16 bit value from a 64K entry table. The Table */
555/* is synthesized from two 256 entry byte wide tables. */
556/************************************************************/
557
558u32 tkip_sbox(u32 index)
559{
560 u32 index_low;
561 u32 index_high;
562 u32 left, right;
563
564 index_low = (index % 256);
565 index_high = ((index >> 8) % 256);
566
567 left = Tkip_Sbox_Lower[index_low] + (Tkip_Sbox_Upper[index_low] * 256);
568 right =
569 Tkip_Sbox_Upper[index_high] + (Tkip_Sbox_Lower[index_high] * 256);
570
571 return (left ^ right);
572}
573
574u32 rotr1(u32 a)
575{
576 unsigned int b;
577
578 if ((a & 0x01) == 0x01) {
579 b = (a >> 1) | 0x8000;
580 } else {
581 b = (a >> 1) & 0x7fff;
582 }
583 b = b % 65536;
584 return b;
585}
586
587void RTMPTkipMixKey(u8 * key, u8 * ta, unsigned long pnl, /* Least significant 16 bits of PN */
588 unsigned long pnh, /* Most significant 32 bits of PN */
589 u8 * rc4key, u32 * p1k)
590{
591
592 u32 tsc0;
593 u32 tsc1;
594 u32 tsc2;
595
596 u32 ppk0;
597 u32 ppk1;
598 u32 ppk2;
599 u32 ppk3;
600 u32 ppk4;
601 u32 ppk5;
602
603 int i;
604 int j;
605
606 tsc0 = (unsigned int)((pnh >> 16) % 65536); /* msb */
607 tsc1 = (unsigned int)(pnh % 65536);
608 tsc2 = (unsigned int)(pnl % 65536); /* lsb */
609
610 /* Phase 1, step 1 */
611 p1k[0] = tsc1;
612 p1k[1] = tsc0;
613 p1k[2] = (u32)(ta[0] + (ta[1] * 256));
614 p1k[3] = (u32)(ta[2] + (ta[3] * 256));
615 p1k[4] = (u32)(ta[4] + (ta[5] * 256));
616
617 /* Phase 1, step 2 */
618 for (i = 0; i < 8; i++) {
619 j = 2 * (i & 1);
620 p1k[0] =
621 (p1k[0] +
622 tkip_sbox((p1k[4] ^ ((256 * key[1 + j]) + key[j])) %
623 65536)) % 65536;
624 p1k[1] =
625 (p1k[1] +
626 tkip_sbox((p1k[0] ^ ((256 * key[5 + j]) + key[4 + j])) %
627 65536)) % 65536;
628 p1k[2] =
629 (p1k[2] +
630 tkip_sbox((p1k[1] ^ ((256 * key[9 + j]) + key[8 + j])) %
631 65536)) % 65536;
632 p1k[3] =
633 (p1k[3] +
634 tkip_sbox((p1k[2] ^ ((256 * key[13 + j]) + key[12 + j])) %
635 65536)) % 65536;
636 p1k[4] =
637 (p1k[4] +
638 tkip_sbox((p1k[3] ^ (((256 * key[1 + j]) + key[j]))) %
639 65536)) % 65536;
640 p1k[4] = (p1k[4] + i) % 65536;
641 }
642
643 /* Phase 2, Step 1 */
644 ppk0 = p1k[0];
645 ppk1 = p1k[1];
646 ppk2 = p1k[2];
647 ppk3 = p1k[3];
648 ppk4 = p1k[4];
649 ppk5 = (p1k[4] + tsc2) % 65536;
650
651 /* Phase2, Step 2 */
652 ppk0 = ppk0 + tkip_sbox((ppk5 ^ ((256 * key[1]) + key[0])) % 65536);
653 ppk1 = ppk1 + tkip_sbox((ppk0 ^ ((256 * key[3]) + key[2])) % 65536);
654 ppk2 = ppk2 + tkip_sbox((ppk1 ^ ((256 * key[5]) + key[4])) % 65536);
655 ppk3 = ppk3 + tkip_sbox((ppk2 ^ ((256 * key[7]) + key[6])) % 65536);
656 ppk4 = ppk4 + tkip_sbox((ppk3 ^ ((256 * key[9]) + key[8])) % 65536);
657 ppk5 = ppk5 + tkip_sbox((ppk4 ^ ((256 * key[11]) + key[10])) % 65536);
658
659 ppk0 = ppk0 + rotr1(ppk5 ^ ((256 * key[13]) + key[12]));
660 ppk1 = ppk1 + rotr1(ppk0 ^ ((256 * key[15]) + key[14]));
661 ppk2 = ppk2 + rotr1(ppk1);
662 ppk3 = ppk3 + rotr1(ppk2);
663 ppk4 = ppk4 + rotr1(ppk3);
664 ppk5 = ppk5 + rotr1(ppk4);
665
666 /* Phase 2, Step 3 */
667 /* Phase 2, Step 3 */
668
669 tsc0 = (unsigned int)((pnh >> 16) % 65536); /* msb */
670 tsc1 = (unsigned int)(pnh % 65536);
671 tsc2 = (unsigned int)(pnl % 65536); /* lsb */
672
673 rc4key[0] = (tsc2 >> 8) % 256;
674 rc4key[1] = (((tsc2 >> 8) % 256) | 0x20) & 0x7f;
675 rc4key[2] = tsc2 % 256;
676 rc4key[3] = ((ppk5 ^ ((256 * key[1]) + key[0])) >> 1) % 256;
677
678 rc4key[4] = ppk0 % 256;
679 rc4key[5] = (ppk0 >> 8) % 256;
680
681 rc4key[6] = ppk1 % 256;
682 rc4key[7] = (ppk1 >> 8) % 256;
683
684 rc4key[8] = ppk2 % 256;
685 rc4key[9] = (ppk2 >> 8) % 256;
686
687 rc4key[10] = ppk3 % 256;
688 rc4key[11] = (ppk3 >> 8) % 256;
689
690 rc4key[12] = ppk4 % 256;
691 rc4key[13] = (ppk4 >> 8) % 256;
692
693 rc4key[14] = ppk5 % 256;
694 rc4key[15] = (ppk5 >> 8) % 256;
695}
696
697/* */
698/* TRUE: Success! */
699/* FALSE: Decrypt Error! */
700/* */
701BOOLEAN RTMPSoftDecryptTKIP(struct rt_rtmp_adapter *pAd,
702 u8 *pData,
703 unsigned long DataByteCnt,
704 u8 UserPriority, struct rt_cipher_key *pWpaKey)
705{
706 u8 KeyID;
707 u32 HeaderLen;
708 u8 fc0;
709 u8 fc1;
710 u16 fc;
711 u32 frame_type;
712 u32 frame_subtype;
713 u32 from_ds;
714 u32 to_ds;
715 int a4_exists;
716 int qc_exists;
717 u16 duration;
718 u16 seq_control;
719 u16 qos_control;
720 u8 TA[MAC_ADDR_LEN];
721 u8 DA[MAC_ADDR_LEN];
722 u8 SA[MAC_ADDR_LEN];
723 u8 RC4Key[16];
724 u32 p1k[5]; /*for mix_key; */
725 unsigned long pnl; /* Least significant 16 bits of PN */
726 unsigned long pnh; /* Most significant 32 bits of PN */
727 u32 num_blocks;
728 u32 payload_remainder;
729 struct rt_arcfourcontext ArcFourContext;
730 u32 crc32 = 0;
731 u32 trailfcs = 0;
732 u8 MIC[8];
733 u8 TrailMIC[8];
734
735 fc0 = *pData;
736 fc1 = *(pData + 1);
737
738 fc = *((u16 *)pData);
739
740 frame_type = ((fc0 >> 2) & 0x03);
741 frame_subtype = ((fc0 >> 4) & 0x0f);
742
743 from_ds = (fc1 & 0x2) >> 1;
744 to_ds = (fc1 & 0x1);
745
746 a4_exists = (from_ds & to_ds);
747 qc_exists = ((frame_subtype == 0x08) || /* Assumed QoS subtypes */
748 (frame_subtype == 0x09) || /* Likely to change. */
749 (frame_subtype == 0x0a) || (frame_subtype == 0x0b)
750 );
751
752 HeaderLen = 24;
753 if (a4_exists)
754 HeaderLen += 6;
755
756 KeyID = *((u8 *)(pData + HeaderLen + 3));
757 KeyID = KeyID >> 6;
758
759 if (pWpaKey[KeyID].KeyLen == 0) {
760 DBGPRINT(RT_DEBUG_TRACE,
761 ("RTMPSoftDecryptTKIP failed!(KeyID[%d] Length can not be 0)\n",
762 KeyID));
763 return FALSE;
764 }
765
766 duration = *((u16 *)(pData + 2));
767
768 seq_control = *((u16 *)(pData + 22));
769
770 if (qc_exists) {
771 if (a4_exists) {
772 qos_control = *((u16 *)(pData + 30));
773 } else {
774 qos_control = *((u16 *)(pData + 24));
775 }
776 }
777
778 if (to_ds == 0 && from_ds == 1) {
779 NdisMoveMemory(DA, pData + 4, MAC_ADDR_LEN);
780 NdisMoveMemory(SA, pData + 16, MAC_ADDR_LEN);
781 NdisMoveMemory(TA, pData + 10, MAC_ADDR_LEN); /*BSSID */
782 } else if (to_ds == 0 && from_ds == 0) {
783 NdisMoveMemory(TA, pData + 10, MAC_ADDR_LEN);
784 NdisMoveMemory(DA, pData + 4, MAC_ADDR_LEN);
785 NdisMoveMemory(SA, pData + 10, MAC_ADDR_LEN);
786 } else if (to_ds == 1 && from_ds == 0) {
787 NdisMoveMemory(SA, pData + 10, MAC_ADDR_LEN);
788 NdisMoveMemory(TA, pData + 10, MAC_ADDR_LEN);
789 NdisMoveMemory(DA, pData + 16, MAC_ADDR_LEN);
790 } else if (to_ds == 1 && from_ds == 1) {
791 NdisMoveMemory(TA, pData + 10, MAC_ADDR_LEN);
792 NdisMoveMemory(DA, pData + 16, MAC_ADDR_LEN);
793 NdisMoveMemory(SA, pData + 22, MAC_ADDR_LEN);
794 }
795
796 num_blocks = (DataByteCnt - 16) / 16;
797 payload_remainder = (DataByteCnt - 16) % 16;
798
799 pnl = (*(pData + HeaderLen)) * 256 + *(pData + HeaderLen + 2);
800 pnh = *((unsigned long *)(pData + HeaderLen + 4));
801 pnh = cpu2le32(pnh);
802 RTMPTkipMixKey(pWpaKey[KeyID].Key, TA, pnl, pnh, RC4Key, p1k);
803
804 ARCFOUR_INIT(&ArcFourContext, RC4Key, 16);
805
806 ARCFOUR_DECRYPT(&ArcFourContext, pData + HeaderLen,
807 pData + HeaderLen + 8, DataByteCnt - HeaderLen - 8);
808 NdisMoveMemory(&trailfcs, pData + DataByteCnt - 8 - 4, 4);
809 crc32 = RTMP_CALC_FCS32(PPPINITFCS32, pData + HeaderLen, DataByteCnt - HeaderLen - 8 - 4); /*Skip IV+EIV 8 bytes & Skip last 4 bytes(FCS). */
810 crc32 ^= 0xffffffff; /* complement */
811
812 if (crc32 != cpu2le32(trailfcs)) {
813 DBGPRINT(RT_DEBUG_TRACE, ("RTMPSoftDecryptTKIP, WEP Data ICV Error !\n")); /*ICV error. */
814
815 return (FALSE);
816 }
817
818 NdisMoveMemory(TrailMIC, pData + DataByteCnt - 8 - 8 - 4, 8);
819 RTMPInitMICEngine(pAd, pWpaKey[KeyID].Key, DA, SA, UserPriority,
820 pWpaKey[KeyID].RxMic);
821 RTMPTkipAppend(&pAd->PrivateInfo.Tx, pData + HeaderLen,
822 DataByteCnt - HeaderLen - 8 - 12);
823 RTMPTkipGetMIC(&pAd->PrivateInfo.Tx);
824 NdisMoveMemory(MIC, pAd->PrivateInfo.Tx.MIC, 8);
825
826 if (!NdisEqualMemory(MIC, TrailMIC, 8)) {
827 DBGPRINT(RT_DEBUG_ERROR, ("RTMPSoftDecryptTKIP, WEP Data MIC Error !\n")); /*MIC error. */
828 /*RTMPReportMicError(pAd, &pWpaKey[KeyID]); // marked by AlbertY @ 20060630 */
829 return (FALSE);
830 }
831 /*DBGPRINT(RT_DEBUG_TRACE, "RTMPSoftDecryptTKIP Decript done!\n"); */
832 return TRUE;
833}
diff --git a/drivers/staging/rt2860/common/cmm_wep.c b/drivers/staging/rt2860/common/cmm_wep.c
deleted file mode 100644
index 76f880cb39b..00000000000
--- a/drivers/staging/rt2860/common/cmm_wep.c
+++ /dev/null
@@ -1,473 +0,0 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 rtmp_wep.c
29
30 Abstract:
31
32 Revision History:
33 Who When What
34 -------- ---------- ----------------------------------------------
35 Paul Wu 10-28-02 Initial
36*/
37
38#include "../rt_config.h"
39
40u32 FCSTAB_32[256] = {
41 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
42 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
43 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
44 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
45 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
46 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
47 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
48 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
49 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
50 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
51 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
52 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
53 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
54 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
55 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
56 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
57 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
58 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
59 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
60 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
61 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
62 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
63 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
64 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
65 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
66 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
67 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
68 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
69 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
70 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
71 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
72 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
73 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
74 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
75 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
76 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
77 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
78 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
79 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
80 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
81 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
82 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
83 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
84 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
85 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
86 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
87 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
88 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
89 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
90 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
91 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
92 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
93 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
94 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
95 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
96 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
97 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
98 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
99 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
100 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
101 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
102 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
103 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
104 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
105};
106
107/*
108u8 WEPKEY[] = {
109 //IV
110 0x00, 0x11, 0x22,
111 //WEP KEY
112 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC
113 };
114 */
115
116/*
117 ========================================================================
118
119 Routine Description:
120 Init WEP function.
121
122 Arguments:
123 pAd Pointer to our adapter
124 pKey Pointer to the WEP KEY
125 KeyId WEP Key ID
126 KeyLen the length of WEP KEY
127 pDest Pointer to the destination which Encryption data will store in.
128
129 Return Value:
130 None
131
132 IRQL = DISPATCH_LEVEL
133
134 Note:
135
136 ========================================================================
137*/
138void RTMPInitWepEngine(struct rt_rtmp_adapter *pAd,
139 u8 *pKey,
140 u8 KeyId, u8 KeyLen, IN u8 *pDest)
141{
142 u32 i;
143 u8 WEPKEY[] = {
144 /*IV */
145 0x00, 0x11, 0x22,
146 /*WEP KEY */
147 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
148 0xAA, 0xBB, 0xCC
149 };
150
151 pAd->PrivateInfo.FCSCRC32 = PPPINITFCS32; /*Init crc32. */
152
153 {
154 NdisMoveMemory(WEPKEY + 3, pKey, KeyLen);
155
156 for (i = 0; i < 3; i++)
157 WEPKEY[i] = RandomByte(pAd); /*Call mlme RandomByte() function. */
158 ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, WEPKEY, KeyLen + 3); /*INIT SBOX, KEYLEN+3(IV) */
159
160 NdisMoveMemory(pDest, WEPKEY, 3); /*Append Init Vector */
161 }
162 *(pDest + 3) = (KeyId << 6); /*Append KEYID */
163
164}
165
166/*
167 ========================================================================
168
169 Routine Description:
170 Encrypt transimitted data
171
172 Arguments:
173 pAd Pointer to our adapter
174 pSrc Pointer to the transimitted source data that will be encrypt
175 pDest Pointer to the destination where entryption data will be store in.
176 Len Indicate the length of the source data
177
178 Return Value:
179 None
180
181 IRQL = DISPATCH_LEVEL
182
183 Note:
184
185 ========================================================================
186*/
187void RTMPEncryptData(struct rt_rtmp_adapter *pAd,
188 u8 *pSrc, u8 *pDest, u32 Len)
189{
190 pAd->PrivateInfo.FCSCRC32 =
191 RTMP_CALC_FCS32(pAd->PrivateInfo.FCSCRC32, pSrc, Len);
192 ARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, pDest, pSrc, Len);
193}
194
195/*
196 ========================================================================
197
198 Routine Description:
199 Decrypt received WEP data
200
201 Arguments:
202 pAdapter Pointer to our adapter
203 pSrc Pointer to the received data
204 Len the length of the received data
205
206 Return Value:
207 TRUE Decrypt WEP data success
208 FALSE Decrypt WEP data failed
209
210 Note:
211
212 ========================================================================
213*/
214BOOLEAN RTMPSoftDecryptWEP(struct rt_rtmp_adapter *pAd,
215 u8 *pData,
216 unsigned long DataByteCnt, struct rt_cipher_key *pGroupKey)
217{
218 u32 trailfcs;
219 u32 crc32;
220 u8 KeyIdx;
221 u8 WEPKEY[] = {
222 /*IV */
223 0x00, 0x11, 0x22,
224 /*WEP KEY */
225 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
226 0xAA, 0xBB, 0xCC
227 };
228 u8 *pPayload = (u8 *) pData + LENGTH_802_11;
229 unsigned long payload_len = DataByteCnt - LENGTH_802_11;
230
231 NdisMoveMemory(WEPKEY, pPayload, 3); /*Get WEP IV */
232
233 KeyIdx = (*(pPayload + 3) & 0xc0) >> 6;
234 if (pGroupKey[KeyIdx].KeyLen == 0)
235 return (FALSE);
236
237 NdisMoveMemory(WEPKEY + 3, pGroupKey[KeyIdx].Key,
238 pGroupKey[KeyIdx].KeyLen);
239 ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, WEPKEY,
240 pGroupKey[KeyIdx].KeyLen + 3);
241 ARCFOUR_DECRYPT(&pAd->PrivateInfo.WEPCONTEXT, pPayload, pPayload + 4,
242 payload_len - 4);
243 NdisMoveMemory(&trailfcs, pPayload + payload_len - 8, 4);
244 crc32 = RTMP_CALC_FCS32(PPPINITFCS32, pPayload, payload_len - 8); /*Skip last 4 bytes(FCS). */
245 crc32 ^= 0xffffffff; /* complement */
246
247 if (crc32 != cpu2le32(trailfcs)) {
248 DBGPRINT(RT_DEBUG_TRACE, ("WEP Data CRC Error!\n")); /*CRC error. */
249 return (FALSE);
250 }
251 return (TRUE);
252}
253
254/*
255 ========================================================================
256
257 Routine Description:
258 The Stream Cipher Encryption Algorithm "struct rt_arcfour" initialize
259
260 Arguments:
261 Ctx Pointer to struct rt_arcfour CONTEXT (SBOX)
262 pKey Pointer to the WEP KEY
263 KeyLen Indicate the length fo the WEP KEY
264
265 Return Value:
266 None
267
268 IRQL = DISPATCH_LEVEL
269
270 Note:
271
272 ========================================================================
273*/
274void ARCFOUR_INIT(struct rt_arcfourcontext *Ctx, u8 *pKey, u32 KeyLen)
275{
276 u8 t, u;
277 u32 keyindex;
278 u32 stateindex;
279 u8 *state;
280 u32 counter;
281
282 state = Ctx->STATE;
283 Ctx->X = 0;
284 Ctx->Y = 0;
285 for (counter = 0; counter < 256; counter++)
286 state[counter] = (u8)counter;
287 keyindex = 0;
288 stateindex = 0;
289 for (counter = 0; counter < 256; counter++) {
290 t = state[counter];
291 stateindex = (stateindex + pKey[keyindex] + t) & 0xff;
292 u = state[stateindex];
293 state[stateindex] = t;
294 state[counter] = u;
295 if (++keyindex >= KeyLen)
296 keyindex = 0;
297 }
298}
299
300/*
301 ========================================================================
302
303 Routine Description:
304 Get bytes from struct rt_arcfour CONTEXT (S-BOX)
305
306 Arguments:
307 Ctx Pointer to struct rt_arcfour CONTEXT (SBOX)
308
309 Return Value:
310 u8 - the value of the struct rt_arcfour CONTEXT (S-BOX)
311
312 Note:
313
314 ========================================================================
315*/
316u8 ARCFOUR_BYTE(struct rt_arcfourcontext *Ctx)
317{
318 u32 x;
319 u32 y;
320 u8 sx, sy;
321 u8 *state;
322
323 state = Ctx->STATE;
324 x = (Ctx->X + 1) & 0xff;
325 sx = state[x];
326 y = (sx + Ctx->Y) & 0xff;
327 sy = state[y];
328 Ctx->X = x;
329 Ctx->Y = y;
330 state[y] = sx;
331 state[x] = sy;
332
333 return (state[(sx + sy) & 0xff]);
334
335}
336
337/*
338 ========================================================================
339
340 Routine Description:
341 The Stream Cipher Decryption Algorithm
342
343 Arguments:
344 Ctx Pointer to struct rt_arcfour CONTEXT (SBOX)
345 pDest Pointer to the Destination
346 pSrc Pointer to the Source data
347 Len Indicate the length of the Source data
348
349 Return Value:
350 None
351
352 Note:
353
354 ========================================================================
355*/
356void ARCFOUR_DECRYPT(struct rt_arcfourcontext *Ctx,
357 u8 *pDest, u8 *pSrc, u32 Len)
358{
359 u32 i;
360
361 for (i = 0; i < Len; i++)
362 pDest[i] = pSrc[i] ^ ARCFOUR_BYTE(Ctx);
363}
364
365/*
366 ========================================================================
367
368 Routine Description:
369 The Stream Cipher Encryption Algorithm
370
371 Arguments:
372 Ctx Pointer to struct rt_arcfour CONTEXT (SBOX)
373 pDest Pointer to the Destination
374 pSrc Pointer to the Source data
375 Len Indicate the length of the Source dta
376
377 Return Value:
378 None
379
380 IRQL = DISPATCH_LEVEL
381
382 Note:
383
384 ========================================================================
385*/
386void ARCFOUR_ENCRYPT(struct rt_arcfourcontext *Ctx,
387 u8 *pDest, u8 *pSrc, u32 Len)
388{
389 u32 i;
390
391 for (i = 0; i < Len; i++)
392 pDest[i] = pSrc[i] ^ ARCFOUR_BYTE(Ctx);
393}
394
395/*
396 ========================================================================
397
398 Routine Description:
399 The Stream Cipher Encryption Algorithm which conform to the special requirement to encrypt GTK.
400
401 Arguments:
402 Ctx Pointer to struct rt_arcfour CONTEXT (SBOX)
403 pDest Pointer to the Destination
404 pSrc Pointer to the Source data
405 Len Indicate the length of the Source dta
406
407 ========================================================================
408*/
409
410void WPAARCFOUR_ENCRYPT(struct rt_arcfourcontext *Ctx,
411 u8 *pDest, u8 *pSrc, u32 Len)
412{
413 u32 i;
414 /*discard first 256 bytes */
415 for (i = 0; i < 256; i++)
416 ARCFOUR_BYTE(Ctx);
417
418 for (i = 0; i < Len; i++)
419 pDest[i] = pSrc[i] ^ ARCFOUR_BYTE(Ctx);
420}
421
422/*
423 ========================================================================
424
425 Routine Description:
426 Calculate a new FCS given the current FCS and the new data.
427
428 Arguments:
429 Fcs the original FCS value
430 Cp pointer to the data which will be calculate the FCS
431 Len the length of the data
432
433 Return Value:
434 u32 - FCS 32 bits
435
436 IRQL = DISPATCH_LEVEL
437
438 Note:
439
440 ========================================================================
441*/
442u32 RTMP_CALC_FCS32(u32 Fcs, u8 *Cp, int Len)
443{
444 while (Len--)
445 Fcs = (((Fcs) >> 8) ^ FCSTAB_32[((Fcs) ^ (*Cp++)) & 0xff]);
446
447 return (Fcs);
448}
449
450/*
451 ========================================================================
452
453 Routine Description:
454 Get last FCS and encrypt it to the destination
455
456 Arguments:
457 pDest Pointer to the Destination
458
459 Return Value:
460 None
461
462 Note:
463
464 ========================================================================
465*/
466void RTMPSetICV(struct rt_rtmp_adapter *pAd, u8 *pDest)
467{
468 pAd->PrivateInfo.FCSCRC32 ^= 0xffffffff; /* complement */
469 pAd->PrivateInfo.FCSCRC32 = cpu2le32(pAd->PrivateInfo.FCSCRC32);
470
471 ARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, pDest,
472 (u8 *)& pAd->PrivateInfo.FCSCRC32, 4);
473}
diff --git a/drivers/staging/rt2860/common/cmm_wpa.c b/drivers/staging/rt2860/common/cmm_wpa.c
deleted file mode 100644
index 616ebec50c6..00000000000
--- a/drivers/staging/rt2860/common/cmm_wpa.c
+++ /dev/null
@@ -1,3010 +0,0 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 wpa.c
29
30 Abstract:
31
32 Revision History:
33 Who When What
34 -------- ---------- ----------------------------------------------
35 Jan Lee 03-07-22 Initial
36 Paul Lin 03-11-28 Modify for supplicant
37*/
38#include "../rt_config.h"
39/* WPA OUI */
40u8 OUI_WPA_NONE_AKM[4] = { 0x00, 0x50, 0xF2, 0x00 };
41u8 OUI_WPA_VERSION[4] = { 0x00, 0x50, 0xF2, 0x01 };
42u8 OUI_WPA_WEP40[4] = { 0x00, 0x50, 0xF2, 0x01 };
43u8 OUI_WPA_TKIP[4] = { 0x00, 0x50, 0xF2, 0x02 };
44u8 OUI_WPA_CCMP[4] = { 0x00, 0x50, 0xF2, 0x04 };
45u8 OUI_WPA_WEP104[4] = { 0x00, 0x50, 0xF2, 0x05 };
46u8 OUI_WPA_8021X_AKM[4] = { 0x00, 0x50, 0xF2, 0x01 };
47u8 OUI_WPA_PSK_AKM[4] = { 0x00, 0x50, 0xF2, 0x02 };
48
49/* WPA2 OUI */
50u8 OUI_WPA2_WEP40[4] = { 0x00, 0x0F, 0xAC, 0x01 };
51u8 OUI_WPA2_TKIP[4] = { 0x00, 0x0F, 0xAC, 0x02 };
52u8 OUI_WPA2_CCMP[4] = { 0x00, 0x0F, 0xAC, 0x04 };
53u8 OUI_WPA2_8021X_AKM[4] = { 0x00, 0x0F, 0xAC, 0x01 };
54u8 OUI_WPA2_PSK_AKM[4] = { 0x00, 0x0F, 0xAC, 0x02 };
55u8 OUI_WPA2_WEP104[4] = { 0x00, 0x0F, 0xAC, 0x05 };
56
57static void ConstructEapolKeyData(struct rt_mac_table_entry *pEntry,
58 u8 GroupKeyWepStatus,
59 u8 keyDescVer,
60 u8 MsgType,
61 u8 DefaultKeyIdx,
62 u8 * GTK,
63 u8 * RSNIE,
64 u8 RSNIE_LEN, struct rt_eapol_packet * pMsg);
65
66static void CalculateMIC(u8 KeyDescVer,
67 u8 * PTK, struct rt_eapol_packet * pMsg);
68
69static void WpaEAPPacketAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
70
71static void WpaEAPOLASFAlertAction(struct rt_rtmp_adapter *pAd,
72 struct rt_mlme_queue_elem *Elem);
73
74static void WpaEAPOLLogoffAction(struct rt_rtmp_adapter *pAd,
75 struct rt_mlme_queue_elem *Elem);
76
77static void WpaEAPOLStartAction(struct rt_rtmp_adapter *pAd,
78 struct rt_mlme_queue_elem *Elem);
79
80static void WpaEAPOLKeyAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
81
82/*
83 ==========================================================================
84 Description:
85 association state machine init, including state transition and timer init
86 Parameters:
87 S - pointer to the association state machine
88 ==========================================================================
89 */
90void WpaStateMachineInit(struct rt_rtmp_adapter *pAd,
91 struct rt_state_machine *S, OUT STATE_MACHINE_FUNC Trans[])
92{
93 StateMachineInit(S, (STATE_MACHINE_FUNC *) Trans, MAX_WPA_PTK_STATE,
94 MAX_WPA_MSG, (STATE_MACHINE_FUNC) Drop, WPA_PTK,
95 WPA_MACHINE_BASE);
96
97 StateMachineSetAction(S, WPA_PTK, MT2_EAPPacket,
98 (STATE_MACHINE_FUNC) WpaEAPPacketAction);
99 StateMachineSetAction(S, WPA_PTK, MT2_EAPOLStart,
100 (STATE_MACHINE_FUNC) WpaEAPOLStartAction);
101 StateMachineSetAction(S, WPA_PTK, MT2_EAPOLLogoff,
102 (STATE_MACHINE_FUNC) WpaEAPOLLogoffAction);
103 StateMachineSetAction(S, WPA_PTK, MT2_EAPOLKey,
104 (STATE_MACHINE_FUNC) WpaEAPOLKeyAction);
105 StateMachineSetAction(S, WPA_PTK, MT2_EAPOLASFAlert,
106 (STATE_MACHINE_FUNC) WpaEAPOLASFAlertAction);
107}
108
109/*
110 ==========================================================================
111 Description:
112 this is state machine function.
113 When receiving EAP packets which is for 802.1x authentication use.
114 Not use in PSK case
115 Return:
116 ==========================================================================
117*/
118void WpaEAPPacketAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
119{
120}
121
122void WpaEAPOLASFAlertAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
123{
124}
125
126void WpaEAPOLLogoffAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
127{
128}
129
130/*
131 ==========================================================================
132 Description:
133 Start 4-way HS when rcv EAPOL_START which may create by our driver in assoc.c
134 Return:
135 ==========================================================================
136*/
137void WpaEAPOLStartAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
138{
139 struct rt_mac_table_entry *pEntry;
140 struct rt_header_802_11 * pHeader;
141
142 DBGPRINT(RT_DEBUG_TRACE, ("WpaEAPOLStartAction ===> \n"));
143
144 pHeader = (struct rt_header_802_11 *) Elem->Msg;
145
146 /*For normaol PSK, we enqueue an EAPOL-Start command to trigger the process. */
147 if (Elem->MsgLen == 6)
148 pEntry = MacTableLookup(pAd, Elem->Msg);
149 else {
150 pEntry = MacTableLookup(pAd, pHeader->Addr2);
151 }
152
153 if (pEntry) {
154 DBGPRINT(RT_DEBUG_TRACE,
155 (" PortSecured(%d), WpaState(%d), AuthMode(%d), PMKID_CacheIdx(%d) \n",
156 pEntry->PortSecured, pEntry->WpaState,
157 pEntry->AuthMode, pEntry->PMKID_CacheIdx));
158
159 if ((pEntry->PortSecured == WPA_802_1X_PORT_NOT_SECURED)
160 && (pEntry->WpaState < AS_PTKSTART)
161 && ((pEntry->AuthMode == Ndis802_11AuthModeWPAPSK)
162 || (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK)
163 || ((pEntry->AuthMode == Ndis802_11AuthModeWPA2)
164 && (pEntry->PMKID_CacheIdx != ENTRY_NOT_FOUND)))) {
165 pEntry->PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
166 pEntry->WpaState = AS_INITPSK;
167 pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED;
168 NdisZeroMemory(pEntry->R_Counter,
169 sizeof(pEntry->R_Counter));
170 pEntry->ReTryCounter = PEER_MSG1_RETRY_TIMER_CTR;
171
172 WPAStart4WayHS(pAd, pEntry, PEER_MSG1_RETRY_EXEC_INTV);
173 }
174 }
175}
176
177/*
178 ==========================================================================
179 Description:
180 This is state machine function.
181 When receiving EAPOL packets which is for 802.1x key management.
182 Use both in WPA, and WPAPSK case.
183 In this function, further dispatch to different functions according to the received packet. 3 categories are :
184 1. normal 4-way pairwisekey and 2-way groupkey handshake
185 2. MIC error (Countermeasures attack) report packet from STA.
186 3. Request for pairwise/group key update from STA
187 Return:
188 ==========================================================================
189*/
190void WpaEAPOLKeyAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
191{
192 struct rt_mac_table_entry *pEntry;
193 struct rt_header_802_11 * pHeader;
194 struct rt_eapol_packet * pEapol_packet;
195 struct rt_key_info peerKeyInfo;
196
197 DBGPRINT(RT_DEBUG_TRACE, ("WpaEAPOLKeyAction ===>\n"));
198
199 pHeader = (struct rt_header_802_11 *) Elem->Msg;
200 pEapol_packet =
201 (struct rt_eapol_packet *) & Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
202
203 NdisZeroMemory((u8 *)& peerKeyInfo, sizeof(peerKeyInfo));
204 NdisMoveMemory((u8 *)& peerKeyInfo,
205 (u8 *)& pEapol_packet->KeyDesc.KeyInfo,
206 sizeof(struct rt_key_info));
207
208 hex_dump("Received Eapol frame", (unsigned char *)pEapol_packet,
209 (Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H));
210
211 *((u16 *) & peerKeyInfo) = cpu2le16(*((u16 *) & peerKeyInfo));
212
213 do {
214 pEntry = MacTableLookup(pAd, pHeader->Addr2);
215
216 if (!pEntry
217 || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli)))
218 break;
219
220 if (pEntry->AuthMode < Ndis802_11AuthModeWPA)
221 break;
222
223 DBGPRINT(RT_DEBUG_TRACE,
224 ("Receive EAPoL-Key frame from STA %pMF\n",
225 pEntry->Addr));
226
227 if (((pEapol_packet->ProVer != EAPOL_VER)
228 && (pEapol_packet->ProVer != EAPOL_VER2))
229 || ((pEapol_packet->KeyDesc.Type != WPA1_KEY_DESC)
230 && (pEapol_packet->KeyDesc.Type != WPA2_KEY_DESC))) {
231 DBGPRINT(RT_DEBUG_ERROR,
232 ("Key descripter does not match with WPA rule\n"));
233 break;
234 }
235 /* The value 1 shall be used for all EAPOL-Key frames to and from a STA when */
236 /* neither the group nor pairwise ciphers are CCMP for Key Descriptor 1. */
237 if ((pEntry->WepStatus == Ndis802_11Encryption2Enabled)
238 && (peerKeyInfo.KeyDescVer != DESC_TYPE_TKIP)) {
239 DBGPRINT(RT_DEBUG_ERROR,
240 ("Key descripter version not match(TKIP) \n"));
241 break;
242 }
243 /* The value 2 shall be used for all EAPOL-Key frames to and from a STA when */
244 /* either the pairwise or the group cipher is AES-CCMP for Key Descriptor 2. */
245 else if ((pEntry->WepStatus == Ndis802_11Encryption3Enabled)
246 && (peerKeyInfo.KeyDescVer != DESC_TYPE_AES)) {
247 DBGPRINT(RT_DEBUG_ERROR,
248 ("Key descripter version not match(AES) \n"));
249 break;
250 }
251 /* Check if this STA is in class 3 state and the WPA state is started */
252 if ((pEntry->Sst == SST_ASSOC)
253 && (pEntry->WpaState >= AS_INITPSK)) {
254 /* Check the Key Ack (bit 7) of the Key Information to determine the Authenticator */
255 /* or not. */
256 /* An EAPOL-Key frame that is sent by the Supplicant in response to an EAPOL- */
257 /* Key frame from the Authenticator must not have the Ack bit set. */
258 if (peerKeyInfo.KeyAck == 1) {
259 /* The frame is snet by Authenticator. */
260 /* So the Supplicant side shall handle this. */
261
262 if ((peerKeyInfo.Secure == 0)
263 && (peerKeyInfo.Request == 0)
264 && (peerKeyInfo.Error == 0)
265 && (peerKeyInfo.KeyType == PAIRWISEKEY)) {
266 /* Process 1. the message 1 of 4-way HS in WPA or WPA2 */
267 /* EAPOL-Key(0,0,1,0,P,0,0,ANonce,0,DataKD_M1) */
268 /* 2. the message 3 of 4-way HS in WPA */
269 /* EAPOL-Key(0,1,1,1,P,0,KeyRSC,ANonce,MIC,DataKD_M3) */
270 if (peerKeyInfo.KeyMic == 0)
271 PeerPairMsg1Action(pAd, pEntry,
272 Elem);
273 else
274 PeerPairMsg3Action(pAd, pEntry,
275 Elem);
276 } else if ((peerKeyInfo.Secure == 1)
277 && (peerKeyInfo.KeyMic == 1)
278 && (peerKeyInfo.Request == 0)
279 && (peerKeyInfo.Error == 0)) {
280 /* Process 1. the message 3 of 4-way HS in WPA2 */
281 /* EAPOL-Key(1,1,1,1,P,0,KeyRSC,ANonce,MIC,DataKD_M3) */
282 /* 2. the message 1 of group KS in WPA or WPA2 */
283 /* EAPOL-Key(1,1,1,0,G,0,Key RSC,0, MIC,GTK[N]) */
284 if (peerKeyInfo.KeyType == PAIRWISEKEY)
285 PeerPairMsg3Action(pAd, pEntry,
286 Elem);
287 else
288 PeerGroupMsg1Action(pAd, pEntry,
289 Elem);
290 }
291 } else {
292 /* The frame is snet by Supplicant. */
293 /* So the Authenticator side shall handle this. */
294 if ((peerKeyInfo.Request == 0) &&
295 (peerKeyInfo.Error == 0) &&
296 (peerKeyInfo.KeyMic == 1)) {
297 if (peerKeyInfo.Secure == 0
298 && peerKeyInfo.KeyType ==
299 PAIRWISEKEY) {
300 /* EAPOL-Key(0,1,0,0,P,0,0,SNonce,MIC,Data) */
301 /* Process 1. message 2 of 4-way HS in WPA or WPA2 */
302 /* 2. message 4 of 4-way HS in WPA */
303 if (CONV_ARRARY_TO_u16
304 (pEapol_packet->KeyDesc.
305 KeyDataLen) == 0) {
306 PeerPairMsg4Action(pAd,
307 pEntry,
308 Elem);
309 } else {
310 PeerPairMsg2Action(pAd,
311 pEntry,
312 Elem);
313 }
314 } else if (peerKeyInfo.Secure == 1
315 && peerKeyInfo.KeyType ==
316 PAIRWISEKEY) {
317 /* EAPOL-Key(1,1,0,0,P,0,0,0,MIC,0) */
318 /* Process message 4 of 4-way HS in WPA2 */
319 PeerPairMsg4Action(pAd, pEntry,
320 Elem);
321 } else if (peerKeyInfo.Secure == 1
322 && peerKeyInfo.KeyType ==
323 GROUPKEY) {
324 /* EAPOL-Key(1,1,0,0,G,0,0,0,MIC,0) */
325 /* Process message 2 of Group key HS in WPA or WPA2 */
326 PeerGroupMsg2Action(pAd, pEntry,
327 &Elem->
328 Msg
329 [LENGTH_802_11],
330 (Elem->
331 MsgLen -
332 LENGTH_802_11));
333 }
334 }
335 }
336 }
337 } while (FALSE);
338}
339
340/*
341 ========================================================================
342
343 Routine Description:
344 Copy frame from waiting queue into relative ring buffer and set
345 appropriate ASIC register to kick hardware encryption before really
346 sent out to air.
347
348 Arguments:
349 pAd Pointer to our adapter
350 void * Pointer to outgoing Ndis frame
351 NumberOfFrag Number of fragment required
352
353 Return Value:
354 None
355
356 Note:
357
358 ========================================================================
359*/
360void RTMPToWirelessSta(struct rt_rtmp_adapter *pAd,
361 struct rt_mac_table_entry *pEntry,
362 u8 *pHeader802_3,
363 u32 HdrLen,
364 u8 *pData, u32 DataLen, IN BOOLEAN bClearFrame)
365{
366 void *pPacket;
367 int Status;
368
369 if ((!pEntry) || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli)))
370 return;
371
372 do {
373 /* build a NDIS packet */
374 Status =
375 RTMPAllocateNdisPacket(pAd, &pPacket, pHeader802_3, HdrLen,
376 pData, DataLen);
377 if (Status != NDIS_STATUS_SUCCESS)
378 break;
379
380 if (bClearFrame)
381 RTMP_SET_PACKET_CLEAR_EAP_FRAME(pPacket, 1);
382 else
383 RTMP_SET_PACKET_CLEAR_EAP_FRAME(pPacket, 0);
384 {
385 RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
386
387 RTMP_SET_PACKET_NET_DEVICE_MBSSID(pPacket, MAIN_MBSSID); /* set a default value */
388 if (pEntry->apidx != 0)
389 RTMP_SET_PACKET_NET_DEVICE_MBSSID(pPacket,
390 pEntry->
391 apidx);
392
393 RTMP_SET_PACKET_WCID(pPacket, (u8)pEntry->Aid);
394 RTMP_SET_PACKET_MOREDATA(pPacket, FALSE);
395 }
396
397 {
398 /* send out the packet */
399 Status = STASendPacket(pAd, pPacket);
400 if (Status == NDIS_STATUS_SUCCESS) {
401 u8 Index;
402
403 /* Dequeue one frame from TxSwQueue0..3 queue and process it */
404 /* There are three place calling dequeue for TX ring. */
405 /* 1. Here, right after queueing the frame. */
406 /* 2. At the end of TxRingTxDone service routine. */
407 /* 3. Upon NDIS call RTMPSendPackets */
408 if ((!RTMP_TEST_FLAG
409 (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
410 &&
411 (!RTMP_TEST_FLAG
412 (pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS))) {
413 for (Index = 0; Index < 5; Index++)
414 if (pAd->TxSwQueue[Index].
415 Number > 0)
416 RTMPDeQueuePacket(pAd,
417 FALSE,
418 Index,
419 MAX_TX_PROCESS);
420 }
421 }
422 }
423
424 } while (FALSE);
425}
426
427/*
428 ==========================================================================
429 Description:
430 This is a function to initialize 4-way handshake
431
432 Return:
433
434 ==========================================================================
435*/
436void WPAStart4WayHS(struct rt_rtmp_adapter *pAd,
437 struct rt_mac_table_entry *pEntry, unsigned long TimeInterval)
438{
439 u8 Header802_3[14];
440 struct rt_eapol_packet EAPOLPKT;
441 u8 *pBssid = NULL;
442 u8 group_cipher = Ndis802_11WEPDisabled;
443
444 DBGPRINT(RT_DEBUG_TRACE, ("===> WPAStart4WayHS\n"));
445
446 if (RTMP_TEST_FLAG
447 (pAd,
448 fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_HALT_IN_PROGRESS))
449 {
450 DBGPRINT(RT_DEBUG_ERROR,
451 ("[ERROR]WPAStart4WayHS : The interface is closed...\n"));
452 return;
453 }
454
455 if (pBssid == NULL) {
456 DBGPRINT(RT_DEBUG_ERROR,
457 ("[ERROR]WPAStart4WayHS : No corresponding Authenticator.\n"));
458 return;
459 }
460 /* Check the status */
461 if ((pEntry->WpaState > AS_PTKSTART) || (pEntry->WpaState < AS_INITPMK)) {
462 DBGPRINT(RT_DEBUG_ERROR,
463 ("[ERROR]WPAStart4WayHS : Not expect calling\n"));
464 return;
465 }
466
467 /* Increment replay counter by 1 */
468 ADD_ONE_To_64BIT_VAR(pEntry->R_Counter);
469
470 /* Randomly generate ANonce */
471 GenRandom(pAd, (u8 *) pBssid, pEntry->ANonce);
472
473 /* Construct EAPoL message - Pairwise Msg 1 */
474 /* EAPOL-Key(0,0,1,0,P,0,0,ANonce,0,DataKD_M1) */
475 NdisZeroMemory(&EAPOLPKT, sizeof(struct rt_eapol_packet));
476 ConstructEapolMsg(pEntry, group_cipher, EAPOL_PAIR_MSG_1, 0, /* Default key index */
477 pEntry->ANonce, NULL, /* TxRSC */
478 NULL, /* GTK */
479 NULL, /* RSNIE */
480 0, /* RSNIE length */
481 &EAPOLPKT);
482
483 /* Make outgoing frame */
484 MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pBssid, EAPOL);
485 RTMPToWirelessSta(pAd, pEntry, Header802_3,
486 LENGTH_802_3, (u8 *)& EAPOLPKT,
487 CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4,
488 (pEntry->PortSecured ==
489 WPA_802_1X_PORT_SECURED) ? FALSE : TRUE);
490
491 /* Trigger Retry Timer */
492 RTMPModTimer(&pEntry->RetryTimer, TimeInterval);
493
494 /* Update State */
495 pEntry->WpaState = AS_PTKSTART;
496
497 DBGPRINT(RT_DEBUG_TRACE,
498 ("<=== WPAStart4WayHS: send Msg1 of 4-way \n"));
499
500}
501
502/*
503 ========================================================================
504
505 Routine Description:
506 Process Pairwise key Msg-1 of 4-way handshaking and send Msg-2
507
508 Arguments:
509 pAd Pointer to our adapter
510 Elem Message body
511
512 Return Value:
513 None
514
515 Note:
516
517 ========================================================================
518*/
519void PeerPairMsg1Action(struct rt_rtmp_adapter *pAd,
520 struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem)
521{
522 u8 PTK[80];
523 u8 Header802_3[14];
524 struct rt_eapol_packet * pMsg1;
525 u32 MsgLen;
526 struct rt_eapol_packet EAPOLPKT;
527 u8 *pCurrentAddr = NULL;
528 u8 *pmk_ptr = NULL;
529 u8 group_cipher = Ndis802_11WEPDisabled;
530 u8 *rsnie_ptr = NULL;
531 u8 rsnie_len = 0;
532
533 DBGPRINT(RT_DEBUG_TRACE, ("===> PeerPairMsg1Action \n"));
534
535 if ((!pEntry) || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli)))
536 return;
537
538 if (Elem->MsgLen <
539 (LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H +
540 sizeof(struct rt_key_descripter) - MAX_LEN_OF_RSNIE - 2))
541 return;
542
543 {
544 pCurrentAddr = pAd->CurrentAddress;
545 pmk_ptr = pAd->StaCfg.PMK;
546 group_cipher = pAd->StaCfg.GroupCipher;
547 rsnie_ptr = pAd->StaCfg.RSN_IE;
548 rsnie_len = pAd->StaCfg.RSNIE_Len;
549 }
550
551 /* Store the received frame */
552 pMsg1 = (struct rt_eapol_packet *) & Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
553 MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H;
554
555 /* Sanity Check peer Pairwise message 1 - Replay Counter */
556 if (PeerWpaMessageSanity(pAd, pMsg1, MsgLen, EAPOL_PAIR_MSG_1, pEntry)
557 == FALSE)
558 return;
559
560 /* Store Replay counter, it will use to verify message 3 and construct message 2 */
561 NdisMoveMemory(pEntry->R_Counter, pMsg1->KeyDesc.ReplayCounter,
562 LEN_KEY_DESC_REPLAY);
563
564 /* Store ANonce */
565 NdisMoveMemory(pEntry->ANonce, pMsg1->KeyDesc.KeyNonce,
566 LEN_KEY_DESC_NONCE);
567
568 /* Generate random SNonce */
569 GenRandom(pAd, (u8 *) pCurrentAddr, pEntry->SNonce);
570
571 {
572 /* Calculate PTK(ANonce, SNonce) */
573 WpaDerivePTK(pAd,
574 pmk_ptr,
575 pEntry->ANonce,
576 pEntry->Addr,
577 pEntry->SNonce, pCurrentAddr, PTK, LEN_PTK);
578
579 /* Save key to PTK entry */
580 NdisMoveMemory(pEntry->PTK, PTK, LEN_PTK);
581 }
582
583 /* Update WpaState */
584 pEntry->WpaState = AS_PTKINIT_NEGOTIATING;
585
586 /* Construct EAPoL message - Pairwise Msg 2 */
587 /* EAPOL-Key(0,1,0,0,P,0,0,SNonce,MIC,DataKD_M2) */
588 NdisZeroMemory(&EAPOLPKT, sizeof(struct rt_eapol_packet));
589 ConstructEapolMsg(pEntry, group_cipher, EAPOL_PAIR_MSG_2, 0, /* DefaultKeyIdx */
590 pEntry->SNonce, NULL, /* TxRsc */
591 NULL, /* GTK */
592 (u8 *) rsnie_ptr, rsnie_len, &EAPOLPKT);
593
594 /* Make outgoing frame */
595 MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pCurrentAddr, EAPOL);
596
597 RTMPToWirelessSta(pAd, pEntry,
598 Header802_3, sizeof(Header802_3), (u8 *)& EAPOLPKT,
599 CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4, TRUE);
600
601 DBGPRINT(RT_DEBUG_TRACE,
602 ("<=== PeerPairMsg1Action: send Msg2 of 4-way \n"));
603}
604
605/*
606 ==========================================================================
607 Description:
608 When receiving the second packet of 4-way pairwisekey handshake.
609 Return:
610 ==========================================================================
611*/
612void PeerPairMsg2Action(struct rt_rtmp_adapter *pAd,
613 struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem)
614{
615 u8 PTK[80];
616 BOOLEAN Cancelled;
617 struct rt_header_802_11 * pHeader;
618 struct rt_eapol_packet EAPOLPKT;
619 struct rt_eapol_packet * pMsg2;
620 u32 MsgLen;
621 u8 Header802_3[LENGTH_802_3];
622 u8 TxTsc[6];
623 u8 *pBssid = NULL;
624 u8 *pmk_ptr = NULL;
625 u8 *gtk_ptr = NULL;
626 u8 default_key = 0;
627 u8 group_cipher = Ndis802_11WEPDisabled;
628 u8 *rsnie_ptr = NULL;
629 u8 rsnie_len = 0;
630
631 DBGPRINT(RT_DEBUG_TRACE, ("===> PeerPairMsg2Action \n"));
632
633 if ((!pEntry) || (!pEntry->ValidAsCLI))
634 return;
635
636 if (Elem->MsgLen <
637 (LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H +
638 sizeof(struct rt_key_descripter) - MAX_LEN_OF_RSNIE - 2))
639 return;
640
641 /* check Entry in valid State */
642 if (pEntry->WpaState < AS_PTKSTART)
643 return;
644
645 /* pointer to 802.11 header */
646 pHeader = (struct rt_header_802_11 *) Elem->Msg;
647
648 /* skip 802.11_header(24-byte) and LLC_header(8) */
649 pMsg2 = (struct rt_eapol_packet *) & Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
650 MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H;
651
652 /* Store SNonce */
653 NdisMoveMemory(pEntry->SNonce, pMsg2->KeyDesc.KeyNonce,
654 LEN_KEY_DESC_NONCE);
655
656 {
657 /* Derive PTK */
658 WpaDerivePTK(pAd, (u8 *) pmk_ptr, pEntry->ANonce, /* ANONCE */
659 (u8 *) pBssid, pEntry->SNonce, /* SNONCE */
660 pEntry->Addr, PTK, LEN_PTK);
661
662 NdisMoveMemory(pEntry->PTK, PTK, LEN_PTK);
663 }
664
665 /* Sanity Check peer Pairwise message 2 - Replay Counter, MIC, RSNIE */
666 if (PeerWpaMessageSanity(pAd, pMsg2, MsgLen, EAPOL_PAIR_MSG_2, pEntry)
667 == FALSE)
668 return;
669
670 do {
671 /* delete retry timer */
672 RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled);
673
674 /* Change state */
675 pEntry->WpaState = AS_PTKINIT_NEGOTIATING;
676
677 /* Increment replay counter by 1 */
678 ADD_ONE_To_64BIT_VAR(pEntry->R_Counter);
679
680 /* Construct EAPoL message - Pairwise Msg 3 */
681 NdisZeroMemory(&EAPOLPKT, sizeof(struct rt_eapol_packet));
682 ConstructEapolMsg(pEntry,
683 group_cipher,
684 EAPOL_PAIR_MSG_3,
685 default_key,
686 pEntry->ANonce,
687 TxTsc,
688 (u8 *) gtk_ptr,
689 (u8 *) rsnie_ptr, rsnie_len, &EAPOLPKT);
690
691 /* Make outgoing frame */
692 MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pBssid, EAPOL);
693 RTMPToWirelessSta(pAd, pEntry, Header802_3, LENGTH_802_3,
694 (u8 *)& EAPOLPKT,
695 CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4,
696 (pEntry->PortSecured ==
697 WPA_802_1X_PORT_SECURED) ? FALSE : TRUE);
698
699 pEntry->ReTryCounter = PEER_MSG3_RETRY_TIMER_CTR;
700 RTMPSetTimer(&pEntry->RetryTimer, PEER_MSG3_RETRY_EXEC_INTV);
701
702 /* Update State */
703 pEntry->WpaState = AS_PTKINIT_NEGOTIATING;
704 } while (FALSE);
705
706 DBGPRINT(RT_DEBUG_TRACE,
707 ("<=== PeerPairMsg2Action: send Msg3 of 4-way \n"));
708}
709
710/*
711 ========================================================================
712
713 Routine Description:
714 Process Pairwise key Msg 3 of 4-way handshaking and send Msg 4
715
716 Arguments:
717 pAd Pointer to our adapter
718 Elem Message body
719
720 Return Value:
721 None
722
723 Note:
724
725 ========================================================================
726*/
727void PeerPairMsg3Action(struct rt_rtmp_adapter *pAd,
728 struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem)
729{
730 struct rt_header_802_11 * pHeader;
731 u8 Header802_3[14];
732 struct rt_eapol_packet EAPOLPKT;
733 struct rt_eapol_packet * pMsg3;
734 u32 MsgLen;
735 u8 *pCurrentAddr = NULL;
736 u8 group_cipher = Ndis802_11WEPDisabled;
737
738 DBGPRINT(RT_DEBUG_TRACE, ("===> PeerPairMsg3Action \n"));
739
740 if ((!pEntry) || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli)))
741 return;
742
743 if (Elem->MsgLen <
744 (LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H +
745 sizeof(struct rt_key_descripter) - MAX_LEN_OF_RSNIE - 2))
746 return;
747
748 {
749 pCurrentAddr = pAd->CurrentAddress;
750 group_cipher = pAd->StaCfg.GroupCipher;
751
752 }
753
754 /* Record 802.11 header & the received EAPOL packet Msg3 */
755 pHeader = (struct rt_header_802_11 *) Elem->Msg;
756 pMsg3 = (struct rt_eapol_packet *) & Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
757 MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H;
758
759 /* Sanity Check peer Pairwise message 3 - Replay Counter, MIC, RSNIE */
760 if (PeerWpaMessageSanity(pAd, pMsg3, MsgLen, EAPOL_PAIR_MSG_3, pEntry)
761 == FALSE)
762 return;
763
764 /* Save Replay counter, it will use construct message 4 */
765 NdisMoveMemory(pEntry->R_Counter, pMsg3->KeyDesc.ReplayCounter,
766 LEN_KEY_DESC_REPLAY);
767
768 /* Double check ANonce */
769 if (!NdisEqualMemory
770 (pEntry->ANonce, pMsg3->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE)) {
771 return;
772 }
773 /* Construct EAPoL message - Pairwise Msg 4 */
774 NdisZeroMemory(&EAPOLPKT, sizeof(struct rt_eapol_packet));
775 ConstructEapolMsg(pEntry, group_cipher, EAPOL_PAIR_MSG_4, 0, /* group key index not used in message 4 */
776 NULL, /* Nonce not used in message 4 */
777 NULL, /* TxRSC not used in message 4 */
778 NULL, /* GTK not used in message 4 */
779 NULL, /* RSN IE not used in message 4 */
780 0, &EAPOLPKT);
781
782 /* Update WpaState */
783 pEntry->WpaState = AS_PTKINITDONE;
784
785 /* Update pairwise key */
786 {
787 struct rt_cipher_key *pSharedKey;
788
789 pSharedKey = &pAd->SharedKey[BSS0][0];
790
791 NdisMoveMemory(pAd->StaCfg.PTK, pEntry->PTK, LEN_PTK);
792
793 /* Prepare pair-wise key information into shared key table */
794 NdisZeroMemory(pSharedKey, sizeof(struct rt_cipher_key));
795 pSharedKey->KeyLen = LEN_TKIP_EK;
796 NdisMoveMemory(pSharedKey->Key, &pAd->StaCfg.PTK[32],
797 LEN_TKIP_EK);
798 NdisMoveMemory(pSharedKey->RxMic, &pAd->StaCfg.PTK[48],
799 LEN_TKIP_RXMICK);
800 NdisMoveMemory(pSharedKey->TxMic,
801 &pAd->StaCfg.PTK[48 + LEN_TKIP_RXMICK],
802 LEN_TKIP_TXMICK);
803
804 /* Decide its ChiperAlg */
805 if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
806 pSharedKey->CipherAlg = CIPHER_TKIP;
807 else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
808 pSharedKey->CipherAlg = CIPHER_AES;
809 else
810 pSharedKey->CipherAlg = CIPHER_NONE;
811
812 /* Update these related information to struct rt_mac_table_entry */
813 pEntry = &pAd->MacTab.Content[BSSID_WCID];
814 NdisMoveMemory(pEntry->PairwiseKey.Key, &pAd->StaCfg.PTK[32],
815 LEN_TKIP_EK);
816 NdisMoveMemory(pEntry->PairwiseKey.RxMic, &pAd->StaCfg.PTK[48],
817 LEN_TKIP_RXMICK);
818 NdisMoveMemory(pEntry->PairwiseKey.TxMic,
819 &pAd->StaCfg.PTK[48 + LEN_TKIP_RXMICK],
820 LEN_TKIP_TXMICK);
821 pEntry->PairwiseKey.CipherAlg = pSharedKey->CipherAlg;
822
823 /* Update pairwise key information to ASIC Shared Key Table */
824 AsicAddSharedKeyEntry(pAd,
825 BSS0,
826 0,
827 pSharedKey->CipherAlg,
828 pSharedKey->Key,
829 pSharedKey->TxMic, pSharedKey->RxMic);
830
831 /* Update ASIC WCID attribute table and IVEIV table */
832 RTMPAddWcidAttributeEntry(pAd,
833 BSS0,
834 0, pSharedKey->CipherAlg, pEntry);
835
836 }
837
838 /* open 802.1x port control and privacy filter */
839 if (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK ||
840 pEntry->AuthMode == Ndis802_11AuthModeWPA2) {
841 pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
842 pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
843
844 STA_PORT_SECURED(pAd);
845 /* Indicate Connected for GUI */
846 pAd->IndicateMediaState = NdisMediaStateConnected;
847 DBGPRINT(RT_DEBUG_TRACE,
848 ("PeerPairMsg3Action: AuthMode(%s) PairwiseCipher(%s) GroupCipher(%s) \n",
849 GetAuthMode(pEntry->AuthMode),
850 GetEncryptType(pEntry->WepStatus),
851 GetEncryptType(group_cipher)));
852 } else {
853 }
854
855 /* Init 802.3 header and send out */
856 MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pCurrentAddr, EAPOL);
857 RTMPToWirelessSta(pAd, pEntry,
858 Header802_3, sizeof(Header802_3),
859 (u8 *)& EAPOLPKT,
860 CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4, TRUE);
861
862 DBGPRINT(RT_DEBUG_TRACE,
863 ("<=== PeerPairMsg3Action: send Msg4 of 4-way \n"));
864}
865
866/*
867 ==========================================================================
868 Description:
869 When receiving the last packet of 4-way pairwisekey handshake.
870 Initialize 2-way groupkey handshake following.
871 Return:
872 ==========================================================================
873*/
874void PeerPairMsg4Action(struct rt_rtmp_adapter *pAd,
875 struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem)
876{
877 struct rt_eapol_packet * pMsg4;
878 struct rt_header_802_11 * pHeader;
879 u32 MsgLen;
880 BOOLEAN Cancelled;
881 u8 group_cipher = Ndis802_11WEPDisabled;
882
883 DBGPRINT(RT_DEBUG_TRACE, ("===> PeerPairMsg4Action\n"));
884
885 do {
886 if ((!pEntry) || (!pEntry->ValidAsCLI))
887 break;
888
889 if (Elem->MsgLen <
890 (LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H +
891 sizeof(struct rt_key_descripter) - MAX_LEN_OF_RSNIE - 2))
892 break;
893
894 if (pEntry->WpaState < AS_PTKINIT_NEGOTIATING)
895 break;
896
897 /* pointer to 802.11 header */
898 pHeader = (struct rt_header_802_11 *) Elem->Msg;
899
900 /* skip 802.11_header(24-byte) and LLC_header(8) */
901 pMsg4 =
902 (struct rt_eapol_packet *) & Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
903 MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H;
904
905 /* Sanity Check peer Pairwise message 4 - Replay Counter, MIC */
906 if (PeerWpaMessageSanity
907 (pAd, pMsg4, MsgLen, EAPOL_PAIR_MSG_4, pEntry) == FALSE)
908 break;
909
910 /* 3. uses the MLME.SETKEYS.request to configure PTK into MAC */
911 NdisZeroMemory(&pEntry->PairwiseKey, sizeof(struct rt_cipher_key));
912
913 /* reset IVEIV in Asic */
914 AsicUpdateWCIDIVEIV(pAd, pEntry->Aid, 1, 0);
915
916 pEntry->PairwiseKey.KeyLen = LEN_TKIP_EK;
917 NdisMoveMemory(pEntry->PairwiseKey.Key, &pEntry->PTK[32],
918 LEN_TKIP_EK);
919 NdisMoveMemory(pEntry->PairwiseKey.RxMic,
920 &pEntry->PTK[TKIP_AP_RXMICK_OFFSET],
921 LEN_TKIP_RXMICK);
922 NdisMoveMemory(pEntry->PairwiseKey.TxMic,
923 &pEntry->PTK[TKIP_AP_TXMICK_OFFSET],
924 LEN_TKIP_TXMICK);
925
926 /* Set pairwise key to Asic */
927 {
928 pEntry->PairwiseKey.CipherAlg = CIPHER_NONE;
929 if (pEntry->WepStatus == Ndis802_11Encryption2Enabled)
930 pEntry->PairwiseKey.CipherAlg = CIPHER_TKIP;
931 else if (pEntry->WepStatus ==
932 Ndis802_11Encryption3Enabled)
933 pEntry->PairwiseKey.CipherAlg = CIPHER_AES;
934
935 /* Add Pair-wise key to Asic */
936 AsicAddPairwiseKeyEntry(pAd,
937 pEntry->Addr,
938 (u8)pEntry->Aid,
939 &pEntry->PairwiseKey);
940
941 /* update WCID attribute table and IVEIV table for this entry */
942 RTMPAddWcidAttributeEntry(pAd,
943 pEntry->apidx,
944 0,
945 pEntry->PairwiseKey.CipherAlg,
946 pEntry);
947 }
948
949 /* 4. upgrade state */
950 pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
951 pEntry->WpaState = AS_PTKINITDONE;
952 pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
953
954 if (pEntry->AuthMode == Ndis802_11AuthModeWPA2 ||
955 pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK) {
956 pEntry->GTKState = REKEY_ESTABLISHED;
957 RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled);
958
959 /* send wireless event - for set key done WPA2 */
960 if (pAd->CommonCfg.bWirelessEvent)
961 RTMPSendWirelessEvent(pAd,
962 IW_SET_KEY_DONE_WPA2_EVENT_FLAG,
963 pEntry->Addr,
964 pEntry->apidx, 0);
965
966 DBGPRINT(RT_DEBUG_OFF,
967 ("AP SETKEYS DONE - WPA2, AuthMode(%d)=%s, WepStatus(%d)=%s, GroupWepStatus(%d)=%s\n\n",
968 pEntry->AuthMode,
969 GetAuthMode(pEntry->AuthMode),
970 pEntry->WepStatus,
971 GetEncryptType(pEntry->WepStatus),
972 group_cipher, GetEncryptType(group_cipher)));
973 } else {
974 /* 5. init Group 2-way handshake if necessary. */
975 WPAStart2WayGroupHS(pAd, pEntry);
976
977 pEntry->ReTryCounter = GROUP_MSG1_RETRY_TIMER_CTR;
978 RTMPModTimer(&pEntry->RetryTimer,
979 PEER_MSG3_RETRY_EXEC_INTV);
980 }
981 } while (FALSE);
982
983}
984
985/*
986 ==========================================================================
987 Description:
988 This is a function to send the first packet of 2-way groupkey handshake
989 Return:
990
991 ==========================================================================
992*/
993void WPAStart2WayGroupHS(struct rt_rtmp_adapter *pAd, struct rt_mac_table_entry *pEntry)
994{
995 u8 Header802_3[14];
996 u8 TxTsc[6];
997 struct rt_eapol_packet EAPOLPKT;
998 u8 group_cipher = Ndis802_11WEPDisabled;
999 u8 default_key = 0;
1000 u8 *gnonce_ptr = NULL;
1001 u8 *gtk_ptr = NULL;
1002 u8 *pBssid = NULL;
1003
1004 DBGPRINT(RT_DEBUG_TRACE, ("===> WPAStart2WayGroupHS\n"));
1005
1006 if ((!pEntry) || (!pEntry->ValidAsCLI))
1007 return;
1008
1009 do {
1010 /* Increment replay counter by 1 */
1011 ADD_ONE_To_64BIT_VAR(pEntry->R_Counter);
1012
1013 /* Construct EAPoL message - Group Msg 1 */
1014 NdisZeroMemory(&EAPOLPKT, sizeof(struct rt_eapol_packet));
1015 ConstructEapolMsg(pEntry,
1016 group_cipher,
1017 EAPOL_GROUP_MSG_1,
1018 default_key,
1019 (u8 *) gnonce_ptr,
1020 TxTsc, (u8 *) gtk_ptr, NULL, 0, &EAPOLPKT);
1021
1022 /* Make outgoing frame */
1023 MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pBssid, EAPOL);
1024 RTMPToWirelessSta(pAd, pEntry,
1025 Header802_3, LENGTH_802_3,
1026 (u8 *)& EAPOLPKT,
1027 CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4,
1028 FALSE);
1029
1030 } while (FALSE);
1031
1032 DBGPRINT(RT_DEBUG_TRACE,
1033 ("<=== WPAStart2WayGroupHS : send out Group Message 1 \n"));
1034
1035 return;
1036}
1037
1038/*
1039 ========================================================================
1040
1041 Routine Description:
1042 Process Group key 2-way handshaking
1043
1044 Arguments:
1045 pAd Pointer to our adapter
1046 Elem Message body
1047
1048 Return Value:
1049 None
1050
1051 Note:
1052
1053 ========================================================================
1054*/
1055void PeerGroupMsg1Action(struct rt_rtmp_adapter *pAd,
1056 struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem)
1057{
1058 u8 Header802_3[14];
1059 struct rt_eapol_packet EAPOLPKT;
1060 struct rt_eapol_packet * pGroup;
1061 u32 MsgLen;
1062 BOOLEAN Cancelled;
1063 u8 default_key = 0;
1064 u8 group_cipher = Ndis802_11WEPDisabled;
1065 u8 *pCurrentAddr = NULL;
1066
1067 DBGPRINT(RT_DEBUG_TRACE, ("===> PeerGroupMsg1Action \n"));
1068
1069 if ((!pEntry) || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli)))
1070 return;
1071
1072 {
1073 pCurrentAddr = pAd->CurrentAddress;
1074 group_cipher = pAd->StaCfg.GroupCipher;
1075 default_key = pAd->StaCfg.DefaultKeyId;
1076 }
1077
1078 /* Process Group Message 1 frame. skip 802.11 header(24) & LLC_SNAP header(8) */
1079 pGroup = (struct rt_eapol_packet *) & Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
1080 MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H;
1081
1082 /* Sanity Check peer group message 1 - Replay Counter, MIC, RSNIE */
1083 if (PeerWpaMessageSanity(pAd, pGroup, MsgLen, EAPOL_GROUP_MSG_1, pEntry)
1084 == FALSE)
1085 return;
1086
1087 /* delete retry timer */
1088 RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled);
1089
1090 /* Save Replay counter, it will use to construct message 2 */
1091 NdisMoveMemory(pEntry->R_Counter, pGroup->KeyDesc.ReplayCounter,
1092 LEN_KEY_DESC_REPLAY);
1093
1094 /* Construct EAPoL message - Group Msg 2 */
1095 NdisZeroMemory(&EAPOLPKT, sizeof(struct rt_eapol_packet));
1096 ConstructEapolMsg(pEntry, group_cipher, EAPOL_GROUP_MSG_2, default_key, NULL, /* Nonce not used */
1097 NULL, /* TxRSC not used */
1098 NULL, /* GTK not used */
1099 NULL, /* RSN IE not used */
1100 0, &EAPOLPKT);
1101
1102 /* open 802.1x port control and privacy filter */
1103 pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
1104 pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
1105
1106 STA_PORT_SECURED(pAd);
1107 /* Indicate Connected for GUI */
1108 pAd->IndicateMediaState = NdisMediaStateConnected;
1109
1110 DBGPRINT(RT_DEBUG_TRACE,
1111 ("PeerGroupMsg1Action: AuthMode(%s) PairwiseCipher(%s) GroupCipher(%s) \n",
1112 GetAuthMode(pEntry->AuthMode),
1113 GetEncryptType(pEntry->WepStatus),
1114 GetEncryptType(group_cipher)));
1115
1116 /* init header and Fill Packet and send Msg 2 to authenticator */
1117 MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pCurrentAddr, EAPOL);
1118 RTMPToWirelessSta(pAd, pEntry,
1119 Header802_3, sizeof(Header802_3),
1120 (u8 *)& EAPOLPKT,
1121 CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4, FALSE);
1122
1123 DBGPRINT(RT_DEBUG_TRACE,
1124 ("<=== PeerGroupMsg1Action: sned group message 2\n"));
1125}
1126
1127/*
1128 ==========================================================================
1129 Description:
1130 When receiving the last packet of 2-way groupkey handshake.
1131 Return:
1132 ==========================================================================
1133*/
1134void PeerGroupMsg2Action(struct rt_rtmp_adapter *pAd,
1135 struct rt_mac_table_entry *pEntry,
1136 void * Msg, u32 MsgLen)
1137{
1138 u32 Len;
1139 u8 *pData;
1140 BOOLEAN Cancelled;
1141 struct rt_eapol_packet * pMsg2;
1142 u8 group_cipher = Ndis802_11WEPDisabled;
1143
1144 DBGPRINT(RT_DEBUG_TRACE, ("===> PeerGroupMsg2Action \n"));
1145
1146 do {
1147 if ((!pEntry) || (!pEntry->ValidAsCLI))
1148 break;
1149
1150 if (MsgLen <
1151 (LENGTH_802_1_H + LENGTH_EAPOL_H + sizeof(struct rt_key_descripter) -
1152 MAX_LEN_OF_RSNIE - 2))
1153 break;
1154
1155 if (pEntry->WpaState != AS_PTKINITDONE)
1156 break;
1157
1158 pData = (u8 *)Msg;
1159 pMsg2 = (struct rt_eapol_packet *) (pData + LENGTH_802_1_H);
1160 Len = MsgLen - LENGTH_802_1_H;
1161
1162 /* Sanity Check peer group message 2 - Replay Counter, MIC */
1163 if (PeerWpaMessageSanity
1164 (pAd, pMsg2, Len, EAPOL_GROUP_MSG_2, pEntry) == FALSE)
1165 break;
1166
1167 /* 3. upgrade state */
1168
1169 RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled);
1170 pEntry->GTKState = REKEY_ESTABLISHED;
1171
1172 if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2)
1173 || (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK)) {
1174 /* send wireless event - for set key done WPA2 */
1175 if (pAd->CommonCfg.bWirelessEvent)
1176 RTMPSendWirelessEvent(pAd,
1177 IW_SET_KEY_DONE_WPA2_EVENT_FLAG,
1178 pEntry->Addr,
1179 pEntry->apidx, 0);
1180
1181 DBGPRINT(RT_DEBUG_OFF,
1182 ("AP SETKEYS DONE - WPA2, AuthMode(%d)=%s, WepStatus(%d)=%s, GroupWepStatus(%d)=%s\n\n",
1183 pEntry->AuthMode,
1184 GetAuthMode(pEntry->AuthMode),
1185 pEntry->WepStatus,
1186 GetEncryptType(pEntry->WepStatus),
1187 group_cipher, GetEncryptType(group_cipher)));
1188 } else {
1189 /* send wireless event - for set key done WPA */
1190 if (pAd->CommonCfg.bWirelessEvent)
1191 RTMPSendWirelessEvent(pAd,
1192 IW_SET_KEY_DONE_WPA1_EVENT_FLAG,
1193 pEntry->Addr,
1194 pEntry->apidx, 0);
1195
1196 DBGPRINT(RT_DEBUG_OFF,
1197 ("AP SETKEYS DONE - WPA1, AuthMode(%d)=%s, WepStatus(%d)=%s, GroupWepStatus(%d)=%s\n\n",
1198 pEntry->AuthMode,
1199 GetAuthMode(pEntry->AuthMode),
1200 pEntry->WepStatus,
1201 GetEncryptType(pEntry->WepStatus),
1202 group_cipher, GetEncryptType(group_cipher)));
1203 }
1204 } while (FALSE);
1205}
1206
1207/*
1208 ========================================================================
1209
1210 Routine Description:
1211 Classify WPA EAP message type
1212
1213 Arguments:
1214 EAPType Value of EAP message type
1215 MsgType Internal Message definition for MLME state machine
1216
1217 Return Value:
1218 TRUE Found appropriate message type
1219 FALSE No appropriate message type
1220
1221 IRQL = DISPATCH_LEVEL
1222
1223 Note:
1224 All these constants are defined in wpa.h
1225 For supplicant, there is only EAPOL Key message available
1226
1227 ========================================================================
1228*/
1229BOOLEAN WpaMsgTypeSubst(u8 EAPType, int * MsgType)
1230{
1231 switch (EAPType) {
1232 case EAPPacket:
1233 *MsgType = MT2_EAPPacket;
1234 break;
1235 case EAPOLStart:
1236 *MsgType = MT2_EAPOLStart;
1237 break;
1238 case EAPOLLogoff:
1239 *MsgType = MT2_EAPOLLogoff;
1240 break;
1241 case EAPOLKey:
1242 *MsgType = MT2_EAPOLKey;
1243 break;
1244 case EAPOLASFAlert:
1245 *MsgType = MT2_EAPOLASFAlert;
1246 break;
1247 default:
1248 return FALSE;
1249 }
1250 return TRUE;
1251}
1252
1253/*
1254 ========================================================================
1255
1256 Routine Description:
1257 The pseudo-random function(PRF) that hashes various inputs to
1258 derive a pseudo-random value. To add liveness to the pseudo-random
1259 value, a nonce should be one of the inputs.
1260
1261 It is used to generate PTK, GTK or some specific random value.
1262
1263 Arguments:
1264 u8 *key, - the key material for HMAC_SHA1 use
1265 int key_len - the length of key
1266 u8 *prefix - a prefix label
1267 int prefix_len - the length of the label
1268 u8 *data - a specific data with variable length
1269 int data_len - the length of a specific data
1270 int len - the output length
1271
1272 Return Value:
1273 u8 *output - the calculated result
1274
1275 Note:
1276 802.11i-2004 Annex H.3
1277
1278 ========================================================================
1279*/
1280void PRF(u8 * key,
1281 int key_len,
1282 u8 * prefix,
1283 int prefix_len,
1284 u8 * data, int data_len, u8 * output, int len)
1285{
1286 int i;
1287 u8 *input;
1288 int currentindex = 0;
1289 int total_len;
1290
1291 /* Allocate memory for input */
1292 os_alloc_mem(NULL, (u8 **) & input, 1024);
1293
1294 if (input == NULL) {
1295 DBGPRINT(RT_DEBUG_ERROR, ("PRF: no memory!\n"));
1296 return;
1297 }
1298 /* Generate concatenation input */
1299 NdisMoveMemory(input, prefix, prefix_len);
1300
1301 /* Concatenate a single octet containing 0 */
1302 input[prefix_len] = 0;
1303
1304 /* Concatenate specific data */
1305 NdisMoveMemory(&input[prefix_len + 1], data, data_len);
1306 total_len = prefix_len + 1 + data_len;
1307
1308 /* Concatenate a single octet containing 0 */
1309 /* This octet shall be update later */
1310 input[total_len] = 0;
1311 total_len++;
1312
1313 /* Iterate to calculate the result by hmac-sha-1 */
1314 /* Then concatenate to last result */
1315 for (i = 0; i < (len + 19) / 20; i++) {
1316 HMAC_SHA1(key, key_len, input, total_len, &output[currentindex],
1317 SHA1_DIGEST_SIZE);
1318 currentindex += 20;
1319
1320 /* update the last octet */
1321 input[total_len - 1]++;
1322 }
1323 os_free_mem(NULL, input);
1324}
1325
1326/*
1327* F(P, S, c, i) = U1 xor U2 xor ... Uc
1328* U1 = PRF(P, S || Int(i))
1329* U2 = PRF(P, U1)
1330* Uc = PRF(P, Uc-1)
1331*/
1332
1333static void F(char *password, unsigned char *ssid, int ssidlength,
1334 int iterations, int count, unsigned char *output)
1335{
1336 unsigned char digest[36], digest1[SHA1_DIGEST_SIZE];
1337 int i, j;
1338
1339 /* U1 = PRF(P, S || int(i)) */
1340 memcpy(digest, ssid, ssidlength);
1341 digest[ssidlength] = (unsigned char)((count >> 24) & 0xff);
1342 digest[ssidlength + 1] = (unsigned char)((count >> 16) & 0xff);
1343 digest[ssidlength + 2] = (unsigned char)((count >> 8) & 0xff);
1344 digest[ssidlength + 3] = (unsigned char)(count & 0xff);
1345 HMAC_SHA1((unsigned char *)password, (int)strlen(password), digest, ssidlength + 4, digest1, SHA1_DIGEST_SIZE); /* for WPA update */
1346
1347 /* output = U1 */
1348 memcpy(output, digest1, SHA1_DIGEST_SIZE);
1349
1350 for (i = 1; i < iterations; i++) {
1351 /* Un = PRF(P, Un-1) */
1352 HMAC_SHA1((unsigned char *)password, (int)strlen(password), digest1, SHA1_DIGEST_SIZE, digest, SHA1_DIGEST_SIZE); /* for WPA update */
1353 memcpy(digest1, digest, SHA1_DIGEST_SIZE);
1354
1355 /* output = output xor Un */
1356 for (j = 0; j < SHA1_DIGEST_SIZE; j++) {
1357 output[j] ^= digest[j];
1358 }
1359 }
1360}
1361
1362/*
1363* password - ascii string up to 63 characters in length
1364* ssid - octet string up to 32 octets
1365* ssidlength - length of ssid in octets
1366* output must be 40 octets in length and outputs 256 bits of key
1367*/
1368int PasswordHash(char *password, u8 *ssid, int ssidlength, u8 *output)
1369{
1370 if ((strlen(password) > 63) || (ssidlength > 32))
1371 return 0;
1372
1373 F(password, ssid, ssidlength, 4096, 1, output);
1374 F(password, ssid, ssidlength, 4096, 2, &output[SHA1_DIGEST_SIZE]);
1375 return 1;
1376}
1377
1378/*
1379 ========================================================================
1380
1381 Routine Description:
1382 It utilizes PRF-384 or PRF-512 to derive session-specific keys from a PMK.
1383 It shall be called by 4-way handshake processing.
1384
1385 Arguments:
1386 pAd - pointer to our pAdapter context
1387 PMK - pointer to PMK
1388 ANonce - pointer to ANonce
1389 AA - pointer to Authenticator Address
1390 SNonce - pointer to SNonce
1391 SA - pointer to Supplicant Address
1392 len - indicate the length of PTK (octet)
1393
1394 Return Value:
1395 Output pointer to the PTK
1396
1397 Note:
1398 Refer to IEEE 802.11i-2004 8.5.1.2
1399
1400 ========================================================================
1401*/
1402void WpaDerivePTK(struct rt_rtmp_adapter *pAd,
1403 u8 * PMK,
1404 u8 * ANonce,
1405 u8 * AA,
1406 u8 * SNonce,
1407 u8 * SA, u8 * output, u32 len)
1408{
1409 u8 concatenation[76];
1410 u32 CurrPos = 0;
1411 u8 temp[32];
1412 u8 Prefix[] =
1413 { 'P', 'a', 'i', 'r', 'w', 'i', 's', 'e', ' ', 'k', 'e', 'y', ' ',
1414 'e', 'x', 'p', 'a', 'n', 's', 'i', 'o', 'n'
1415 };
1416
1417 /* initiate the concatenation input */
1418 NdisZeroMemory(temp, sizeof(temp));
1419 NdisZeroMemory(concatenation, 76);
1420
1421 /* Get smaller address */
1422 if (RTMPCompareMemory(SA, AA, 6) == 1)
1423 NdisMoveMemory(concatenation, AA, 6);
1424 else
1425 NdisMoveMemory(concatenation, SA, 6);
1426 CurrPos += 6;
1427
1428 /* Get larger address */
1429 if (RTMPCompareMemory(SA, AA, 6) == 1)
1430 NdisMoveMemory(&concatenation[CurrPos], SA, 6);
1431 else
1432 NdisMoveMemory(&concatenation[CurrPos], AA, 6);
1433
1434 /* store the larger mac address for backward compatible of */
1435 /* ralink proprietary STA-key issue */
1436 NdisMoveMemory(temp, &concatenation[CurrPos], MAC_ADDR_LEN);
1437 CurrPos += 6;
1438
1439 /* Get smaller Nonce */
1440 if (RTMPCompareMemory(ANonce, SNonce, 32) == 0)
1441 NdisMoveMemory(&concatenation[CurrPos], temp, 32); /* patch for ralink proprietary STA-key issue */
1442 else if (RTMPCompareMemory(ANonce, SNonce, 32) == 1)
1443 NdisMoveMemory(&concatenation[CurrPos], SNonce, 32);
1444 else
1445 NdisMoveMemory(&concatenation[CurrPos], ANonce, 32);
1446 CurrPos += 32;
1447
1448 /* Get larger Nonce */
1449 if (RTMPCompareMemory(ANonce, SNonce, 32) == 0)
1450 NdisMoveMemory(&concatenation[CurrPos], temp, 32); /* patch for ralink proprietary STA-key issue */
1451 else if (RTMPCompareMemory(ANonce, SNonce, 32) == 1)
1452 NdisMoveMemory(&concatenation[CurrPos], ANonce, 32);
1453 else
1454 NdisMoveMemory(&concatenation[CurrPos], SNonce, 32);
1455 CurrPos += 32;
1456
1457 hex_dump("concatenation=", concatenation, 76);
1458
1459 /* Use PRF to generate PTK */
1460 PRF(PMK, LEN_MASTER_KEY, Prefix, 22, concatenation, 76, output, len);
1461
1462}
1463
1464/*
1465 ========================================================================
1466
1467 Routine Description:
1468 Generate random number by software.
1469
1470 Arguments:
1471 pAd - pointer to our pAdapter context
1472 macAddr - pointer to local MAC address
1473
1474 Return Value:
1475
1476 Note:
1477 802.1ii-2004 Annex H.5
1478
1479 ========================================================================
1480*/
1481void GenRandom(struct rt_rtmp_adapter *pAd, u8 * macAddr, u8 * random)
1482{
1483 int i, curr;
1484 u8 local[80], KeyCounter[32];
1485 u8 result[80];
1486 unsigned long CurrentTime;
1487 u8 prefix[] =
1488 { 'I', 'n', 'i', 't', ' ', 'C', 'o', 'u', 'n', 't', 'e', 'r' };
1489
1490 /* Zero the related information */
1491 NdisZeroMemory(result, 80);
1492 NdisZeroMemory(local, 80);
1493 NdisZeroMemory(KeyCounter, 32);
1494
1495 for (i = 0; i < 32; i++) {
1496 /* copy the local MAC address */
1497 COPY_MAC_ADDR(local, macAddr);
1498 curr = MAC_ADDR_LEN;
1499
1500 /* concatenate the current time */
1501 NdisGetSystemUpTime(&CurrentTime);
1502 NdisMoveMemory(&local[curr], &CurrentTime, sizeof(CurrentTime));
1503 curr += sizeof(CurrentTime);
1504
1505 /* concatenate the last result */
1506 NdisMoveMemory(&local[curr], result, 32);
1507 curr += 32;
1508
1509 /* concatenate a variable */
1510 NdisMoveMemory(&local[curr], &i, 2);
1511 curr += 2;
1512
1513 /* calculate the result */
1514 PRF(KeyCounter, 32, prefix, 12, local, curr, result, 32);
1515 }
1516
1517 NdisMoveMemory(random, result, 32);
1518}
1519
1520/*
1521 ========================================================================
1522
1523 Routine Description:
1524 Build cipher suite in RSN-IE.
1525 It only shall be called by RTMPMakeRSNIE.
1526
1527 Arguments:
1528 pAd - pointer to our pAdapter context
1529 ElementID - indicate the WPA1 or WPA2
1530 WepStatus - indicate the encryption type
1531 bMixCipher - a boolean to indicate the pairwise cipher and group
1532 cipher are the same or not
1533
1534 Return Value:
1535
1536 Note:
1537
1538 ========================================================================
1539*/
1540static void RTMPMakeRsnIeCipher(struct rt_rtmp_adapter *pAd,
1541 u8 ElementID,
1542 u32 WepStatus,
1543 IN BOOLEAN bMixCipher,
1544 u8 FlexibleCipher,
1545 u8 *pRsnIe, u8 * rsn_len)
1546{
1547 u8 PairwiseCnt;
1548
1549 *rsn_len = 0;
1550
1551 /* decide WPA2 or WPA1 */
1552 if (ElementID == Wpa2Ie) {
1553 struct rt_rsnie2 *pRsnie_cipher = (struct rt_rsnie2 *)pRsnIe;
1554
1555 /* Assign the verson as 1 */
1556 pRsnie_cipher->version = 1;
1557
1558 switch (WepStatus) {
1559 /* TKIP mode */
1560 case Ndis802_11Encryption2Enabled:
1561 NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4);
1562 pRsnie_cipher->ucount = 1;
1563 NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
1564 OUI_WPA2_TKIP, 4);
1565 *rsn_len = sizeof(struct rt_rsnie2);
1566 break;
1567
1568 /* AES mode */
1569 case Ndis802_11Encryption3Enabled:
1570 if (bMixCipher)
1571 NdisMoveMemory(pRsnie_cipher->mcast,
1572 OUI_WPA2_TKIP, 4);
1573 else
1574 NdisMoveMemory(pRsnie_cipher->mcast,
1575 OUI_WPA2_CCMP, 4);
1576 pRsnie_cipher->ucount = 1;
1577 NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
1578 OUI_WPA2_CCMP, 4);
1579 *rsn_len = sizeof(struct rt_rsnie2);
1580 break;
1581
1582 /* TKIP-AES mix mode */
1583 case Ndis802_11Encryption4Enabled:
1584 NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4);
1585
1586 PairwiseCnt = 1;
1587 /* Insert WPA2 TKIP as the first pairwise cipher */
1588 if (MIX_CIPHER_WPA2_TKIP_ON(FlexibleCipher)) {
1589 NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
1590 OUI_WPA2_TKIP, 4);
1591 /* Insert WPA2 AES as the secondary pairwise cipher */
1592 if (MIX_CIPHER_WPA2_AES_ON(FlexibleCipher)) {
1593 NdisMoveMemory(pRsnie_cipher->ucast[0].
1594 oui + 4, OUI_WPA2_CCMP,
1595 4);
1596 PairwiseCnt = 2;
1597 }
1598 } else {
1599 /* Insert WPA2 AES as the first pairwise cipher */
1600 NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
1601 OUI_WPA2_CCMP, 4);
1602 }
1603
1604 pRsnie_cipher->ucount = PairwiseCnt;
1605 *rsn_len = sizeof(struct rt_rsnie2) + (4 * (PairwiseCnt - 1));
1606 break;
1607 }
1608
1609 if ((pAd->OpMode == OPMODE_STA) &&
1610 (pAd->StaCfg.GroupCipher != Ndis802_11Encryption2Enabled) &&
1611 (pAd->StaCfg.GroupCipher != Ndis802_11Encryption3Enabled)) {
1612 u32 GroupCipher = pAd->StaCfg.GroupCipher;
1613 switch (GroupCipher) {
1614 case Ndis802_11GroupWEP40Enabled:
1615 NdisMoveMemory(pRsnie_cipher->mcast,
1616 OUI_WPA2_WEP40, 4);
1617 break;
1618 case Ndis802_11GroupWEP104Enabled:
1619 NdisMoveMemory(pRsnie_cipher->mcast,
1620 OUI_WPA2_WEP104, 4);
1621 break;
1622 }
1623 }
1624 /* swap for big-endian platform */
1625 pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version);
1626 pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount);
1627 } else {
1628 struct rt_rsnie *pRsnie_cipher = (struct rt_rsnie *)pRsnIe;
1629
1630 /* Assign OUI and version */
1631 NdisMoveMemory(pRsnie_cipher->oui, OUI_WPA_VERSION, 4);
1632 pRsnie_cipher->version = 1;
1633
1634 switch (WepStatus) {
1635 /* TKIP mode */
1636 case Ndis802_11Encryption2Enabled:
1637 NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4);
1638 pRsnie_cipher->ucount = 1;
1639 NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
1640 OUI_WPA_TKIP, 4);
1641 *rsn_len = sizeof(struct rt_rsnie);
1642 break;
1643
1644 /* AES mode */
1645 case Ndis802_11Encryption3Enabled:
1646 if (bMixCipher)
1647 NdisMoveMemory(pRsnie_cipher->mcast,
1648 OUI_WPA_TKIP, 4);
1649 else
1650 NdisMoveMemory(pRsnie_cipher->mcast,
1651 OUI_WPA_CCMP, 4);
1652 pRsnie_cipher->ucount = 1;
1653 NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
1654 OUI_WPA_CCMP, 4);
1655 *rsn_len = sizeof(struct rt_rsnie);
1656 break;
1657
1658 /* TKIP-AES mix mode */
1659 case Ndis802_11Encryption4Enabled:
1660 NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4);
1661
1662 PairwiseCnt = 1;
1663 /* Insert WPA TKIP as the first pairwise cipher */
1664 if (MIX_CIPHER_WPA_TKIP_ON(FlexibleCipher)) {
1665 NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
1666 OUI_WPA_TKIP, 4);
1667 /* Insert WPA AES as the secondary pairwise cipher */
1668 if (MIX_CIPHER_WPA_AES_ON(FlexibleCipher)) {
1669 NdisMoveMemory(pRsnie_cipher->ucast[0].
1670 oui + 4, OUI_WPA_CCMP,
1671 4);
1672 PairwiseCnt = 2;
1673 }
1674 } else {
1675 /* Insert WPA AES as the first pairwise cipher */
1676 NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
1677 OUI_WPA_CCMP, 4);
1678 }
1679
1680 pRsnie_cipher->ucount = PairwiseCnt;
1681 *rsn_len = sizeof(struct rt_rsnie) + (4 * (PairwiseCnt - 1));
1682 break;
1683 }
1684
1685 if ((pAd->OpMode == OPMODE_STA) &&
1686 (pAd->StaCfg.GroupCipher != Ndis802_11Encryption2Enabled) &&
1687 (pAd->StaCfg.GroupCipher != Ndis802_11Encryption3Enabled)) {
1688 u32 GroupCipher = pAd->StaCfg.GroupCipher;
1689 switch (GroupCipher) {
1690 case Ndis802_11GroupWEP40Enabled:
1691 NdisMoveMemory(pRsnie_cipher->mcast,
1692 OUI_WPA_WEP40, 4);
1693 break;
1694 case Ndis802_11GroupWEP104Enabled:
1695 NdisMoveMemory(pRsnie_cipher->mcast,
1696 OUI_WPA_WEP104, 4);
1697 break;
1698 }
1699 }
1700 /* swap for big-endian platform */
1701 pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version);
1702 pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount);
1703 }
1704}
1705
1706/*
1707 ========================================================================
1708
1709 Routine Description:
1710 Build AKM suite in RSN-IE.
1711 It only shall be called by RTMPMakeRSNIE.
1712
1713 Arguments:
1714 pAd - pointer to our pAdapter context
1715 ElementID - indicate the WPA1 or WPA2
1716 AuthMode - indicate the authentication mode
1717 apidx - indicate the interface index
1718
1719 Return Value:
1720
1721 Note:
1722
1723 ========================================================================
1724*/
1725static void RTMPMakeRsnIeAKM(struct rt_rtmp_adapter *pAd,
1726 u8 ElementID,
1727 u32 AuthMode,
1728 u8 apidx,
1729 u8 *pRsnIe, u8 * rsn_len)
1730{
1731 struct rt_rsnie_auth *pRsnie_auth;
1732 u8 AkmCnt = 1; /* default as 1 */
1733
1734 pRsnie_auth = (struct rt_rsnie_auth *) (pRsnIe + (*rsn_len));
1735
1736 /* decide WPA2 or WPA1 */
1737 if (ElementID == Wpa2Ie) {
1738
1739 switch (AuthMode) {
1740 case Ndis802_11AuthModeWPA2:
1741 case Ndis802_11AuthModeWPA1WPA2:
1742 NdisMoveMemory(pRsnie_auth->auth[0].oui,
1743 OUI_WPA2_8021X_AKM, 4);
1744 break;
1745
1746 case Ndis802_11AuthModeWPA2PSK:
1747 case Ndis802_11AuthModeWPA1PSKWPA2PSK:
1748 NdisMoveMemory(pRsnie_auth->auth[0].oui,
1749 OUI_WPA2_PSK_AKM, 4);
1750 break;
1751 default:
1752 AkmCnt = 0;
1753 break;
1754
1755 }
1756 } else {
1757 switch (AuthMode) {
1758 case Ndis802_11AuthModeWPA:
1759 case Ndis802_11AuthModeWPA1WPA2:
1760 NdisMoveMemory(pRsnie_auth->auth[0].oui,
1761 OUI_WPA_8021X_AKM, 4);
1762 break;
1763
1764 case Ndis802_11AuthModeWPAPSK:
1765 case Ndis802_11AuthModeWPA1PSKWPA2PSK:
1766 NdisMoveMemory(pRsnie_auth->auth[0].oui,
1767 OUI_WPA_PSK_AKM, 4);
1768 break;
1769
1770 case Ndis802_11AuthModeWPANone:
1771 NdisMoveMemory(pRsnie_auth->auth[0].oui,
1772 OUI_WPA_NONE_AKM, 4);
1773 break;
1774 default:
1775 AkmCnt = 0;
1776 break;
1777 }
1778 }
1779
1780 pRsnie_auth->acount = AkmCnt;
1781 pRsnie_auth->acount = cpu2le16(pRsnie_auth->acount);
1782
1783 /* update current RSNIE length */
1784 (*rsn_len) += (sizeof(struct rt_rsnie_auth) + (4 * (AkmCnt - 1)));
1785
1786}
1787
1788/*
1789 ========================================================================
1790
1791 Routine Description:
1792 Build capability in RSN-IE.
1793 It only shall be called by RTMPMakeRSNIE.
1794
1795 Arguments:
1796 pAd - pointer to our pAdapter context
1797 ElementID - indicate the WPA1 or WPA2
1798 apidx - indicate the interface index
1799
1800 Return Value:
1801
1802 Note:
1803
1804 ========================================================================
1805*/
1806static void RTMPMakeRsnIeCap(struct rt_rtmp_adapter *pAd,
1807 u8 ElementID,
1808 u8 apidx,
1809 u8 *pRsnIe, u8 * rsn_len)
1810{
1811 RSN_CAPABILITIES *pRSN_Cap;
1812
1813 /* it could be ignored in WPA1 mode */
1814 if (ElementID == WpaIe)
1815 return;
1816
1817 pRSN_Cap = (RSN_CAPABILITIES *) (pRsnIe + (*rsn_len));
1818
1819 pRSN_Cap->word = cpu2le16(pRSN_Cap->word);
1820
1821 (*rsn_len) += sizeof(RSN_CAPABILITIES); /* update current RSNIE length */
1822
1823}
1824
1825/*
1826 ========================================================================
1827
1828 Routine Description:
1829 Build RSN IE context. It is not included element-ID and length.
1830
1831 Arguments:
1832 pAd - pointer to our pAdapter context
1833 AuthMode - indicate the authentication mode
1834 WepStatus - indicate the encryption type
1835 apidx - indicate the interface index
1836
1837 Return Value:
1838
1839 Note:
1840
1841 ========================================================================
1842*/
1843void RTMPMakeRSNIE(struct rt_rtmp_adapter *pAd,
1844 u32 AuthMode, u32 WepStatus, u8 apidx)
1845{
1846 u8 *pRsnIe = NULL; /* primary RSNIE */
1847 u8 *rsnielen_cur_p = 0; /* the length of the primary RSNIE */
1848 u8 *rsnielen_ex_cur_p = 0; /* the length of the secondary RSNIE */
1849 u8 PrimaryRsnie;
1850 BOOLEAN bMixCipher = FALSE; /* indicate the pairwise and group cipher are different */
1851 u8 p_offset;
1852 WPA_MIX_PAIR_CIPHER FlexibleCipher = WPA_TKIPAES_WPA2_TKIPAES; /* it provide the more flexible cipher combination in WPA-WPA2 and TKIPAES mode */
1853
1854 rsnielen_cur_p = NULL;
1855 rsnielen_ex_cur_p = NULL;
1856
1857 {
1858 {
1859 if (pAd->StaCfg.WpaSupplicantUP !=
1860 WPA_SUPPLICANT_DISABLE) {
1861 if (AuthMode < Ndis802_11AuthModeWPA)
1862 return;
1863 } else {
1864 /* Support WPAPSK or WPA2PSK in STA-Infra mode */
1865 /* Support WPANone in STA-Adhoc mode */
1866 if ((AuthMode != Ndis802_11AuthModeWPAPSK) &&
1867 (AuthMode != Ndis802_11AuthModeWPA2PSK) &&
1868 (AuthMode != Ndis802_11AuthModeWPANone)
1869 )
1870 return;
1871 }
1872
1873 DBGPRINT(RT_DEBUG_TRACE, ("==> RTMPMakeRSNIE(STA)\n"));
1874
1875 /* Zero RSNIE context */
1876 pAd->StaCfg.RSNIE_Len = 0;
1877 NdisZeroMemory(pAd->StaCfg.RSN_IE, MAX_LEN_OF_RSNIE);
1878
1879 /* Pointer to RSNIE */
1880 rsnielen_cur_p = &pAd->StaCfg.RSNIE_Len;
1881 pRsnIe = pAd->StaCfg.RSN_IE;
1882
1883 bMixCipher = pAd->StaCfg.bMixCipher;
1884 }
1885 }
1886
1887 /* indicate primary RSNIE as WPA or WPA2 */
1888 if ((AuthMode == Ndis802_11AuthModeWPA) ||
1889 (AuthMode == Ndis802_11AuthModeWPAPSK) ||
1890 (AuthMode == Ndis802_11AuthModeWPANone) ||
1891 (AuthMode == Ndis802_11AuthModeWPA1WPA2) ||
1892 (AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK))
1893 PrimaryRsnie = WpaIe;
1894 else
1895 PrimaryRsnie = Wpa2Ie;
1896
1897 {
1898 /* Build the primary RSNIE */
1899 /* 1. insert cipher suite */
1900 RTMPMakeRsnIeCipher(pAd, PrimaryRsnie, WepStatus, bMixCipher,
1901 FlexibleCipher, pRsnIe, &p_offset);
1902
1903 /* 2. insert AKM */
1904 RTMPMakeRsnIeAKM(pAd, PrimaryRsnie, AuthMode, apidx, pRsnIe,
1905 &p_offset);
1906
1907 /* 3. insert capability */
1908 RTMPMakeRsnIeCap(pAd, PrimaryRsnie, apidx, pRsnIe, &p_offset);
1909 }
1910
1911 /* 4. update the RSNIE length */
1912 *rsnielen_cur_p = p_offset;
1913
1914 hex_dump("The primary RSNIE", pRsnIe, (*rsnielen_cur_p));
1915
1916}
1917
1918/*
1919 ==========================================================================
1920 Description:
1921 Check whether the received frame is EAP frame.
1922
1923 Arguments:
1924 pAd - pointer to our pAdapter context
1925 pEntry - pointer to active entry
1926 pData - the received frame
1927 DataByteCount - the received frame's length
1928 FromWhichBSSID - indicate the interface index
1929
1930 Return:
1931 TRUE - This frame is EAP frame
1932 FALSE - otherwise
1933 ==========================================================================
1934*/
1935BOOLEAN RTMPCheckWPAframe(struct rt_rtmp_adapter *pAd,
1936 struct rt_mac_table_entry *pEntry,
1937 u8 *pData,
1938 unsigned long DataByteCount, u8 FromWhichBSSID)
1939{
1940 unsigned long Body_len;
1941 BOOLEAN Cancelled;
1942
1943 if (DataByteCount < (LENGTH_802_1_H + LENGTH_EAPOL_H))
1944 return FALSE;
1945
1946 /* Skip LLC header */
1947 if (NdisEqualMemory(SNAP_802_1H, pData, 6) ||
1948 /* Cisco 1200 AP may send packet with SNAP_BRIDGE_TUNNEL */
1949 NdisEqualMemory(SNAP_BRIDGE_TUNNEL, pData, 6)) {
1950 pData += 6;
1951 }
1952 /* Skip 2-bytes EAPoL type */
1953 if (NdisEqualMemory(EAPOL, pData, 2)) {
1954 pData += 2;
1955 } else
1956 return FALSE;
1957
1958 switch (*(pData + 1)) {
1959 case EAPPacket:
1960 Body_len = (*(pData + 2) << 8) | (*(pData + 3));
1961 DBGPRINT(RT_DEBUG_TRACE,
1962 ("Receive EAP-Packet frame, TYPE = 0, Length = %ld\n",
1963 Body_len));
1964 break;
1965 case EAPOLStart:
1966 DBGPRINT(RT_DEBUG_TRACE,
1967 ("Receive EAPOL-Start frame, TYPE = 1 \n"));
1968 if (pEntry->EnqueueEapolStartTimerRunning !=
1969 EAPOL_START_DISABLE) {
1970 DBGPRINT(RT_DEBUG_TRACE,
1971 ("Cancel the EnqueueEapolStartTimerRunning \n"));
1972 RTMPCancelTimer(&pEntry->EnqueueStartForPSKTimer,
1973 &Cancelled);
1974 pEntry->EnqueueEapolStartTimerRunning =
1975 EAPOL_START_DISABLE;
1976 }
1977 break;
1978 case EAPOLLogoff:
1979 DBGPRINT(RT_DEBUG_TRACE,
1980 ("Receive EAPOLLogoff frame, TYPE = 2 \n"));
1981 break;
1982 case EAPOLKey:
1983 Body_len = (*(pData + 2) << 8) | (*(pData + 3));
1984 DBGPRINT(RT_DEBUG_TRACE,
1985 ("Receive EAPOL-Key frame, TYPE = 3, Length = %ld\n",
1986 Body_len));
1987 break;
1988 case EAPOLASFAlert:
1989 DBGPRINT(RT_DEBUG_TRACE,
1990 ("Receive EAPOLASFAlert frame, TYPE = 4 \n"));
1991 break;
1992 default:
1993 return FALSE;
1994
1995 }
1996 return TRUE;
1997}
1998
1999/*
2000 ==========================================================================
2001 Description:
2002 Report the EAP message type
2003
2004 Arguments:
2005 msg - EAPOL_PAIR_MSG_1
2006 EAPOL_PAIR_MSG_2
2007 EAPOL_PAIR_MSG_3
2008 EAPOL_PAIR_MSG_4
2009 EAPOL_GROUP_MSG_1
2010 EAPOL_GROUP_MSG_2
2011
2012 Return:
2013 message type string
2014
2015 ==========================================================================
2016*/
2017char *GetEapolMsgType(char msg)
2018{
2019 if (msg == EAPOL_PAIR_MSG_1)
2020 return "Pairwise Message 1";
2021 else if (msg == EAPOL_PAIR_MSG_2)
2022 return "Pairwise Message 2";
2023 else if (msg == EAPOL_PAIR_MSG_3)
2024 return "Pairwise Message 3";
2025 else if (msg == EAPOL_PAIR_MSG_4)
2026 return "Pairwise Message 4";
2027 else if (msg == EAPOL_GROUP_MSG_1)
2028 return "Group Message 1";
2029 else if (msg == EAPOL_GROUP_MSG_2)
2030 return "Group Message 2";
2031 else
2032 return "Invalid Message";
2033}
2034
2035/*
2036 ========================================================================
2037
2038 Routine Description:
2039 Check Sanity RSN IE of EAPoL message
2040
2041 Arguments:
2042
2043 Return Value:
2044
2045 ========================================================================
2046*/
2047BOOLEAN RTMPCheckRSNIE(struct rt_rtmp_adapter *pAd,
2048 u8 *pData,
2049 u8 DataLen,
2050 struct rt_mac_table_entry *pEntry, u8 * Offset)
2051{
2052 u8 *pVIE;
2053 u8 len;
2054 struct rt_eid * pEid;
2055 BOOLEAN result = FALSE;
2056
2057 pVIE = pData;
2058 len = DataLen;
2059 *Offset = 0;
2060
2061 while (len > sizeof(struct rt_rsnie2)) {
2062 pEid = (struct rt_eid *) pVIE;
2063 /* WPA RSN IE */
2064 if ((pEid->Eid == IE_WPA)
2065 && (NdisEqualMemory(pEid->Octet, WPA_OUI, 4))) {
2066 if ((pEntry->AuthMode == Ndis802_11AuthModeWPA
2067 || pEntry->AuthMode == Ndis802_11AuthModeWPAPSK)
2068 &&
2069 (NdisEqualMemory
2070 (pVIE, pEntry->RSN_IE, pEntry->RSNIE_Len))
2071 && (pEntry->RSNIE_Len == (pEid->Len + 2))) {
2072 result = TRUE;
2073 }
2074
2075 *Offset += (pEid->Len + 2);
2076 }
2077 /* WPA2 RSN IE */
2078 else if ((pEid->Eid == IE_RSN)
2079 && (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3))) {
2080 if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2
2081 || pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK)
2082 && (pEid->Eid == pEntry->RSN_IE[0])
2083 && ((pEid->Len + 2) >= pEntry->RSNIE_Len)
2084 &&
2085 (NdisEqualMemory
2086 (pEid->Octet, &pEntry->RSN_IE[2],
2087 pEntry->RSNIE_Len - 2))) {
2088
2089 result = TRUE;
2090 }
2091
2092 *Offset += (pEid->Len + 2);
2093 } else {
2094 break;
2095 }
2096
2097 pVIE += (pEid->Len + 2);
2098 len -= (pEid->Len + 2);
2099 }
2100
2101 return result;
2102
2103}
2104
2105/*
2106 ========================================================================
2107
2108 Routine Description:
2109 Parse KEYDATA field. KEYDATA[] May contain 2 RSN IE and optionally GTK.
2110 GTK is encaptulated in KDE format at p.83 802.11i D10
2111
2112 Arguments:
2113
2114 Return Value:
2115
2116 Note:
2117 802.11i D10
2118
2119 ========================================================================
2120*/
2121BOOLEAN RTMPParseEapolKeyData(struct rt_rtmp_adapter *pAd,
2122 u8 *pKeyData,
2123 u8 KeyDataLen,
2124 u8 GroupKeyIndex,
2125 u8 MsgType,
2126 IN BOOLEAN bWPA2, struct rt_mac_table_entry *pEntry)
2127{
2128 struct rt_kde_encap * pKDE = NULL;
2129 u8 *pMyKeyData = pKeyData;
2130 u8 KeyDataLength = KeyDataLen;
2131 u8 GTKLEN = 0;
2132 u8 DefaultIdx = 0;
2133 u8 skip_offset;
2134
2135 /* Verify The RSN IE contained in pairewise_msg_2 && pairewise_msg_3 and skip it */
2136 if (MsgType == EAPOL_PAIR_MSG_2 || MsgType == EAPOL_PAIR_MSG_3) {
2137 /* Check RSN IE whether it is WPA2/WPA2PSK */
2138 if (!RTMPCheckRSNIE
2139 (pAd, pKeyData, KeyDataLen, pEntry, &skip_offset)) {
2140 /* send wireless event - for RSN IE different */
2141 if (pAd->CommonCfg.bWirelessEvent)
2142 RTMPSendWirelessEvent(pAd,
2143 IW_RSNIE_DIFF_EVENT_FLAG,
2144 pEntry->Addr,
2145 pEntry->apidx, 0);
2146
2147 DBGPRINT(RT_DEBUG_ERROR,
2148 ("RSN_IE Different in msg %d of 4-way handshake!\n",
2149 MsgType));
2150 hex_dump("Receive RSN_IE ", pKeyData, KeyDataLen);
2151 hex_dump("Desired RSN_IE ", pEntry->RSN_IE,
2152 pEntry->RSNIE_Len);
2153
2154 return FALSE;
2155 } else {
2156 if (bWPA2 && MsgType == EAPOL_PAIR_MSG_3) {
2157 WpaShowAllsuite(pMyKeyData, skip_offset);
2158
2159 /* skip RSN IE */
2160 pMyKeyData += skip_offset;
2161 KeyDataLength -= skip_offset;
2162 DBGPRINT(RT_DEBUG_TRACE,
2163 ("RTMPParseEapolKeyData ==> WPA2/WPA2PSK RSN IE matched in Msg 3, Length(%d) \n",
2164 skip_offset));
2165 } else
2166 return TRUE;
2167 }
2168 }
2169
2170 DBGPRINT(RT_DEBUG_TRACE,
2171 ("RTMPParseEapolKeyData ==> KeyDataLength %d without RSN_IE \n",
2172 KeyDataLength));
2173 /*hex_dump("remain data", pMyKeyData, KeyDataLength); */
2174
2175 /* Parse EKD format in pairwise_msg_3_WPA2 && group_msg_1_WPA2 */
2176 if (bWPA2
2177 && (MsgType == EAPOL_PAIR_MSG_3 || MsgType == EAPOL_GROUP_MSG_1)) {
2178 if (KeyDataLength >= 8) /* KDE format exclude GTK length */
2179 {
2180 pKDE = (struct rt_kde_encap *) pMyKeyData;
2181
2182 DefaultIdx = pKDE->GTKEncap.Kid;
2183
2184 /* Sanity check - KED length */
2185 if (KeyDataLength < (pKDE->Len + 2)) {
2186 DBGPRINT(RT_DEBUG_ERROR,
2187 ("ERROR: The len from KDE is too short \n"));
2188 return FALSE;
2189 }
2190 /* Get GTK length - refer to IEEE 802.11i-2004 p.82 */
2191 GTKLEN = pKDE->Len - 6;
2192 if (GTKLEN < LEN_AES_KEY) {
2193 DBGPRINT(RT_DEBUG_ERROR,
2194 ("ERROR: GTK Key length is too short (%d) \n",
2195 GTKLEN));
2196 return FALSE;
2197 }
2198
2199 } else {
2200 DBGPRINT(RT_DEBUG_ERROR,
2201 ("ERROR: KDE format length is too short \n"));
2202 return FALSE;
2203 }
2204
2205 DBGPRINT(RT_DEBUG_TRACE,
2206 ("GTK in KDE format ,DefaultKeyID=%d, KeyLen=%d \n",
2207 DefaultIdx, GTKLEN));
2208 /* skip it */
2209 pMyKeyData += 8;
2210 KeyDataLength -= 8;
2211
2212 } else if (!bWPA2 && MsgType == EAPOL_GROUP_MSG_1) {
2213 DefaultIdx = GroupKeyIndex;
2214 DBGPRINT(RT_DEBUG_TRACE,
2215 ("GTK DefaultKeyID=%d \n", DefaultIdx));
2216 }
2217 /* Sanity check - shared key index must be 1 ~ 3 */
2218 if (DefaultIdx < 1 || DefaultIdx > 3) {
2219 DBGPRINT(RT_DEBUG_ERROR,
2220 ("ERROR: GTK Key index(%d) is invalid in %s %s \n",
2221 DefaultIdx, ((bWPA2) ? "WPA2" : "WPA"),
2222 GetEapolMsgType(MsgType)));
2223 return FALSE;
2224 }
2225
2226 {
2227 struct rt_cipher_key *pSharedKey;
2228
2229 /* set key material, TxMic and RxMic */
2230 NdisMoveMemory(pAd->StaCfg.GTK, pMyKeyData, 32);
2231 pAd->StaCfg.DefaultKeyId = DefaultIdx;
2232
2233 pSharedKey = &pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId];
2234
2235 /* Prepare pair-wise key information into shared key table */
2236 NdisZeroMemory(pSharedKey, sizeof(struct rt_cipher_key));
2237 pSharedKey->KeyLen = LEN_TKIP_EK;
2238 NdisMoveMemory(pSharedKey->Key, pAd->StaCfg.GTK, LEN_TKIP_EK);
2239 NdisMoveMemory(pSharedKey->RxMic, &pAd->StaCfg.GTK[16],
2240 LEN_TKIP_RXMICK);
2241 NdisMoveMemory(pSharedKey->TxMic, &pAd->StaCfg.GTK[24],
2242 LEN_TKIP_TXMICK);
2243
2244 /* Update Shared Key CipherAlg */
2245 pSharedKey->CipherAlg = CIPHER_NONE;
2246 if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
2247 pSharedKey->CipherAlg = CIPHER_TKIP;
2248 else if (pAd->StaCfg.GroupCipher ==
2249 Ndis802_11Encryption3Enabled)
2250 pSharedKey->CipherAlg = CIPHER_AES;
2251 else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP40Enabled)
2252 pSharedKey->CipherAlg = CIPHER_WEP64;
2253 else if (pAd->StaCfg.GroupCipher ==
2254 Ndis802_11GroupWEP104Enabled)
2255 pSharedKey->CipherAlg = CIPHER_WEP128;
2256
2257 /* Update group key information to ASIC Shared Key Table */
2258 AsicAddSharedKeyEntry(pAd,
2259 BSS0,
2260 pAd->StaCfg.DefaultKeyId,
2261 pSharedKey->CipherAlg,
2262 pSharedKey->Key,
2263 pSharedKey->TxMic, pSharedKey->RxMic);
2264
2265 /* Update ASIC WCID attribute table and IVEIV table */
2266 RTMPAddWcidAttributeEntry(pAd,
2267 BSS0,
2268 pAd->StaCfg.DefaultKeyId,
2269 pSharedKey->CipherAlg, NULL);
2270 }
2271
2272 return TRUE;
2273
2274}
2275
2276/*
2277 ========================================================================
2278
2279 Routine Description:
2280 Construct EAPoL message for WPA handshaking
2281 Its format is below,
2282
2283 +--------------------+
2284 | Protocol Version | 1 octet
2285 +--------------------+
2286 | Protocol Type | 1 octet
2287 +--------------------+
2288 | Body Length | 2 octets
2289 +--------------------+
2290 | Descriptor Type | 1 octet
2291 +--------------------+
2292 | Key Information | 2 octets
2293 +--------------------+
2294 | Key Length | 1 octet
2295 +--------------------+
2296 | Key Repaly Counter | 8 octets
2297 +--------------------+
2298 | Key Nonce | 32 octets
2299 +--------------------+
2300 | Key IV | 16 octets
2301 +--------------------+
2302 | Key RSC | 8 octets
2303 +--------------------+
2304 | Key ID or Reserved | 8 octets
2305 +--------------------+
2306 | Key MIC | 16 octets
2307 +--------------------+
2308 | Key Data Length | 2 octets
2309 +--------------------+
2310 | Key Data | n octets
2311 +--------------------+
2312
2313 Arguments:
2314 pAd Pointer to our adapter
2315
2316 Return Value:
2317 None
2318
2319 Note:
2320
2321 ========================================================================
2322*/
2323void ConstructEapolMsg(struct rt_mac_table_entry *pEntry,
2324 u8 GroupKeyWepStatus,
2325 u8 MsgType,
2326 u8 DefaultKeyIdx,
2327 u8 * KeyNonce,
2328 u8 * TxRSC,
2329 u8 * GTK,
2330 u8 * RSNIE,
2331 u8 RSNIE_Len, struct rt_eapol_packet * pMsg)
2332{
2333 BOOLEAN bWPA2 = FALSE;
2334 u8 KeyDescVer;
2335
2336 /* Choose WPA2 or not */
2337 if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) ||
2338 (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK))
2339 bWPA2 = TRUE;
2340
2341 /* Init Packet and Fill header */
2342 pMsg->ProVer = EAPOL_VER;
2343 pMsg->ProType = EAPOLKey;
2344
2345 /* Default 95 bytes, the EAPoL-Key descriptor exclude Key-data field */
2346 SET_u16_TO_ARRARY(pMsg->Body_Len, LEN_EAPOL_KEY_MSG);
2347
2348 /* Fill in EAPoL descriptor */
2349 if (bWPA2)
2350 pMsg->KeyDesc.Type = WPA2_KEY_DESC;
2351 else
2352 pMsg->KeyDesc.Type = WPA1_KEY_DESC;
2353
2354 /* Key Descriptor Version (bits 0-2) specifies the key descriptor version type */
2355 {
2356 /* Fill in Key information, refer to IEEE Std 802.11i-2004 page 78 */
2357 /* When either the pairwise or the group cipher is AES, the DESC_TYPE_AES(2) shall be used. */
2358 KeyDescVer =
2359 (((pEntry->WepStatus == Ndis802_11Encryption3Enabled)
2360 || (GroupKeyWepStatus ==
2361 Ndis802_11Encryption3Enabled)) ? (DESC_TYPE_AES)
2362 : (DESC_TYPE_TKIP));
2363 }
2364
2365 pMsg->KeyDesc.KeyInfo.KeyDescVer = KeyDescVer;
2366
2367 /* Specify Key Type as Group(0) or Pairwise(1) */
2368 if (MsgType >= EAPOL_GROUP_MSG_1)
2369 pMsg->KeyDesc.KeyInfo.KeyType = GROUPKEY;
2370 else
2371 pMsg->KeyDesc.KeyInfo.KeyType = PAIRWISEKEY;
2372
2373 /* Specify Key Index, only group_msg1_WPA1 */
2374 if (!bWPA2 && (MsgType >= EAPOL_GROUP_MSG_1))
2375 pMsg->KeyDesc.KeyInfo.KeyIndex = DefaultKeyIdx;
2376
2377 if (MsgType == EAPOL_PAIR_MSG_3)
2378 pMsg->KeyDesc.KeyInfo.Install = 1;
2379
2380 if ((MsgType == EAPOL_PAIR_MSG_1) || (MsgType == EAPOL_PAIR_MSG_3)
2381 || (MsgType == EAPOL_GROUP_MSG_1))
2382 pMsg->KeyDesc.KeyInfo.KeyAck = 1;
2383
2384 if (MsgType != EAPOL_PAIR_MSG_1)
2385 pMsg->KeyDesc.KeyInfo.KeyMic = 1;
2386
2387 if ((bWPA2 && (MsgType >= EAPOL_PAIR_MSG_3)) ||
2388 (!bWPA2 && (MsgType >= EAPOL_GROUP_MSG_1))) {
2389 pMsg->KeyDesc.KeyInfo.Secure = 1;
2390 }
2391
2392 if (bWPA2 && ((MsgType == EAPOL_PAIR_MSG_3) ||
2393 (MsgType == EAPOL_GROUP_MSG_1))) {
2394 pMsg->KeyDesc.KeyInfo.EKD_DL = 1;
2395 }
2396 /* key Information element has done. */
2397 *(u16 *) (&pMsg->KeyDesc.KeyInfo) =
2398 cpu2le16(*(u16 *) (&pMsg->KeyDesc.KeyInfo));
2399
2400 /* Fill in Key Length */
2401 {
2402 if (MsgType >= EAPOL_GROUP_MSG_1) {
2403 /* the length of group key cipher */
2404 pMsg->KeyDesc.KeyLength[1] =
2405 ((GroupKeyWepStatus ==
2406 Ndis802_11Encryption2Enabled) ? TKIP_GTK_LENGTH :
2407 LEN_AES_KEY);
2408 } else {
2409 /* the length of pairwise key cipher */
2410 pMsg->KeyDesc.KeyLength[1] =
2411 ((pEntry->WepStatus ==
2412 Ndis802_11Encryption2Enabled) ? LEN_TKIP_KEY :
2413 LEN_AES_KEY);
2414 }
2415 }
2416
2417 /* Fill in replay counter */
2418 NdisMoveMemory(pMsg->KeyDesc.ReplayCounter, pEntry->R_Counter,
2419 LEN_KEY_DESC_REPLAY);
2420
2421 /* Fill Key Nonce field */
2422 /* ANonce : pairwise_msg1 & pairwise_msg3 */
2423 /* SNonce : pairwise_msg2 */
2424 /* GNonce : group_msg1_wpa1 */
2425 if ((MsgType <= EAPOL_PAIR_MSG_3)
2426 || ((!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1))))
2427 NdisMoveMemory(pMsg->KeyDesc.KeyNonce, KeyNonce,
2428 LEN_KEY_DESC_NONCE);
2429
2430 /* Fill key IV - WPA2 as 0, WPA1 as random */
2431 if (!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1)) {
2432 /* Suggest IV be random number plus some number, */
2433 NdisMoveMemory(pMsg->KeyDesc.KeyIv, &KeyNonce[16],
2434 LEN_KEY_DESC_IV);
2435 pMsg->KeyDesc.KeyIv[15] += 2;
2436 }
2437 /* Fill Key RSC field */
2438 /* It contains the RSC for the GTK being installed. */
2439 if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2)
2440 || (MsgType == EAPOL_GROUP_MSG_1)) {
2441 NdisMoveMemory(pMsg->KeyDesc.KeyRsc, TxRSC, 6);
2442 }
2443 /* Clear Key MIC field for MIC calculation later */
2444 NdisZeroMemory(pMsg->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
2445
2446 ConstructEapolKeyData(pEntry,
2447 GroupKeyWepStatus,
2448 KeyDescVer,
2449 MsgType,
2450 DefaultKeyIdx, GTK, RSNIE, RSNIE_Len, pMsg);
2451
2452 /* Calculate MIC and fill in KeyMic Field except Pairwise Msg 1. */
2453 if (MsgType != EAPOL_PAIR_MSG_1) {
2454 CalculateMIC(KeyDescVer, pEntry->PTK, pMsg);
2455 }
2456
2457 DBGPRINT(RT_DEBUG_TRACE,
2458 ("===> ConstructEapolMsg for %s %s\n",
2459 ((bWPA2) ? "WPA2" : "WPA"), GetEapolMsgType(MsgType)));
2460 DBGPRINT(RT_DEBUG_TRACE,
2461 (" Body length = %d \n",
2462 CONV_ARRARY_TO_u16(pMsg->Body_Len)));
2463 DBGPRINT(RT_DEBUG_TRACE,
2464 (" Key length = %d \n",
2465 CONV_ARRARY_TO_u16(pMsg->KeyDesc.KeyLength)));
2466
2467}
2468
2469/*
2470 ========================================================================
2471
2472 Routine Description:
2473 Construct the Key Data field of EAPoL message
2474
2475 Arguments:
2476 pAd Pointer to our adapter
2477 Elem Message body
2478
2479 Return Value:
2480 None
2481
2482 Note:
2483
2484 ========================================================================
2485*/
2486void ConstructEapolKeyData(struct rt_mac_table_entry *pEntry,
2487 u8 GroupKeyWepStatus,
2488 u8 keyDescVer,
2489 u8 MsgType,
2490 u8 DefaultKeyIdx,
2491 u8 * GTK,
2492 u8 * RSNIE,
2493 u8 RSNIE_LEN, struct rt_eapol_packet * pMsg)
2494{
2495 u8 *mpool, *Key_Data, *Rc4GTK;
2496 u8 ekey[(LEN_KEY_DESC_IV + LEN_EAP_EK)];
2497 unsigned long data_offset;
2498 BOOLEAN bWPA2Capable = FALSE;
2499 struct rt_rtmp_adapter *pAd = pEntry->pAd;
2500 BOOLEAN GTK_Included = FALSE;
2501
2502 /* Choose WPA2 or not */
2503 if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) ||
2504 (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK))
2505 bWPA2Capable = TRUE;
2506
2507 if (MsgType == EAPOL_PAIR_MSG_1 ||
2508 MsgType == EAPOL_PAIR_MSG_4 || MsgType == EAPOL_GROUP_MSG_2)
2509 return;
2510
2511 /* allocate memory pool */
2512 os_alloc_mem(NULL, (u8 **) & mpool, 1500);
2513
2514 if (mpool == NULL)
2515 return;
2516
2517 /* Rc4GTK Len = 512 */
2518 Rc4GTK = (u8 *) ROUND_UP(mpool, 4);
2519 /* Key_Data Len = 512 */
2520 Key_Data = (u8 *) ROUND_UP(Rc4GTK + 512, 4);
2521
2522 NdisZeroMemory(Key_Data, 512);
2523 SET_u16_TO_ARRARY(pMsg->KeyDesc.KeyDataLen, 0);
2524 data_offset = 0;
2525
2526 /* Encapsulate RSNIE in pairwise_msg2 & pairwise_msg3 */
2527 if (RSNIE_LEN
2528 && ((MsgType == EAPOL_PAIR_MSG_2)
2529 || (MsgType == EAPOL_PAIR_MSG_3))) {
2530 u8 *pmkid_ptr = NULL;
2531 u8 pmkid_len = 0;
2532
2533 RTMPInsertRSNIE(&Key_Data[data_offset],
2534 &data_offset,
2535 RSNIE, RSNIE_LEN, pmkid_ptr, pmkid_len);
2536 }
2537
2538 /* Encapsulate KDE format in pairwise_msg3_WPA2 & group_msg1_WPA2 */
2539 if (bWPA2Capable
2540 && ((MsgType == EAPOL_PAIR_MSG_3)
2541 || (MsgType == EAPOL_GROUP_MSG_1))) {
2542 /* Key Data Encapsulation (KDE) format - 802.11i-2004 Figure-43w and Table-20h */
2543 Key_Data[data_offset + 0] = 0xDD;
2544
2545 if (GroupKeyWepStatus == Ndis802_11Encryption3Enabled) {
2546 Key_Data[data_offset + 1] = 0x16; /* 4+2+16(OUI+DataType+DataField) */
2547 } else {
2548 Key_Data[data_offset + 1] = 0x26; /* 4+2+32(OUI+DataType+DataField) */
2549 }
2550
2551 Key_Data[data_offset + 2] = 0x00;
2552 Key_Data[data_offset + 3] = 0x0F;
2553 Key_Data[data_offset + 4] = 0xAC;
2554 Key_Data[data_offset + 5] = 0x01;
2555
2556 /* GTK KDE format - 802.11i-2004 Figure-43x */
2557 Key_Data[data_offset + 6] = (DefaultKeyIdx & 0x03);
2558 Key_Data[data_offset + 7] = 0x00; /* Reserved Byte */
2559
2560 data_offset += 8;
2561 }
2562
2563 /* Encapsulate GTK */
2564 /* Only for pairwise_msg3_WPA2 and group_msg1 */
2565 if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2Capable)
2566 || (MsgType == EAPOL_GROUP_MSG_1)) {
2567 /* Fill in GTK */
2568 if (GroupKeyWepStatus == Ndis802_11Encryption3Enabled) {
2569 NdisMoveMemory(&Key_Data[data_offset], GTK,
2570 LEN_AES_KEY);
2571 data_offset += LEN_AES_KEY;
2572 } else {
2573 NdisMoveMemory(&Key_Data[data_offset], GTK,
2574 TKIP_GTK_LENGTH);
2575 data_offset += TKIP_GTK_LENGTH;
2576 }
2577
2578 GTK_Included = TRUE;
2579 }
2580
2581 /* This whole key-data field shall be encrypted if a GTK is included. */
2582 /* Encrypt the data material in key data field with KEK */
2583 if (GTK_Included) {
2584 /*hex_dump("GTK_Included", Key_Data, data_offset); */
2585
2586 if ((keyDescVer == DESC_TYPE_AES)) {
2587 u8 remainder = 0;
2588 u8 pad_len = 0;
2589
2590 /* Key Descriptor Version 2 or 3: AES key wrap, defined in IETF RFC 3394, */
2591 /* shall be used to encrypt the Key Data field using the KEK field from */
2592 /* the derived PTK. */
2593
2594 /* If the Key Data field uses the NIST AES key wrap, then the Key Data field */
2595 /* shall be padded before encrypting if the key data length is less than 16 */
2596 /* octets or if it is not a multiple of 8. The padding consists of appending */
2597 /* a single octet 0xdd followed by zero or more 0x00 octets. */
2598 if ((remainder = data_offset & 0x07) != 0) {
2599 int i;
2600
2601 pad_len = (8 - remainder);
2602 Key_Data[data_offset] = 0xDD;
2603 for (i = 1; i < pad_len; i++)
2604 Key_Data[data_offset + i] = 0;
2605
2606 data_offset += pad_len;
2607 }
2608
2609 AES_GTK_KEY_WRAP(&pEntry->PTK[16], Key_Data,
2610 data_offset, Rc4GTK);
2611 /* AES wrap function will grow 8 bytes in length */
2612 data_offset += 8;
2613 } else {
2614 /* Key Descriptor Version 1: ARC4 is used to encrypt the Key Data field
2615 using the KEK field from the derived PTK. */
2616
2617 /* PREPARE Encrypted "Key DATA" field. (Encrypt GTK with RC4, usinf PTK[16]->[31] as Key, IV-field as IV) */
2618 /* put TxTsc in Key RSC field */
2619 pAd->PrivateInfo.FCSCRC32 = PPPINITFCS32; /*Init crc32. */
2620
2621 /* ekey is the contanetion of IV-field, and PTK[16]->PTK[31] */
2622 NdisMoveMemory(ekey, pMsg->KeyDesc.KeyIv,
2623 LEN_KEY_DESC_IV);
2624 NdisMoveMemory(&ekey[LEN_KEY_DESC_IV], &pEntry->PTK[16],
2625 LEN_EAP_EK);
2626 ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, ekey, sizeof(ekey)); /*INIT SBOX, KEYLEN+3(IV) */
2627 pAd->PrivateInfo.FCSCRC32 =
2628 RTMP_CALC_FCS32(pAd->PrivateInfo.FCSCRC32, Key_Data,
2629 data_offset);
2630 WPAARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, Rc4GTK,
2631 Key_Data, data_offset);
2632 }
2633
2634 NdisMoveMemory(pMsg->KeyDesc.KeyData, Rc4GTK, data_offset);
2635 } else {
2636 NdisMoveMemory(pMsg->KeyDesc.KeyData, Key_Data, data_offset);
2637 }
2638
2639 /* Update key data length field and total body length */
2640 SET_u16_TO_ARRARY(pMsg->KeyDesc.KeyDataLen, data_offset);
2641 INC_u16_TO_ARRARY(pMsg->Body_Len, data_offset);
2642
2643 os_free_mem(NULL, mpool);
2644
2645}
2646
2647/*
2648 ========================================================================
2649
2650 Routine Description:
2651 Calcaulate MIC. It is used during 4-ways handsharking.
2652
2653 Arguments:
2654 pAd - pointer to our pAdapter context
2655 PeerWepStatus - indicate the encryption type
2656
2657 Return Value:
2658
2659 Note:
2660
2661 ========================================================================
2662*/
2663static void CalculateMIC(u8 KeyDescVer,
2664 u8 * PTK, struct rt_eapol_packet * pMsg)
2665{
2666 u8 *OutBuffer;
2667 unsigned long FrameLen = 0;
2668 u8 mic[LEN_KEY_DESC_MIC];
2669 u8 digest[80];
2670
2671 /* allocate memory for MIC calculation */
2672 os_alloc_mem(NULL, (u8 **) & OutBuffer, 512);
2673
2674 if (OutBuffer == NULL) {
2675 DBGPRINT(RT_DEBUG_ERROR, ("CalculateMIC: no memory!\n"));
2676 return;
2677 }
2678 /* make a frame for calculating MIC. */
2679 MakeOutgoingFrame(OutBuffer, &FrameLen,
2680 CONV_ARRARY_TO_u16(pMsg->Body_Len) + 4, pMsg,
2681 END_OF_ARGS);
2682
2683 NdisZeroMemory(mic, sizeof(mic));
2684
2685 /* Calculate MIC */
2686 if (KeyDescVer == DESC_TYPE_AES) {
2687 HMAC_SHA1(PTK, LEN_EAP_MICK, OutBuffer, FrameLen, digest,
2688 SHA1_DIGEST_SIZE);
2689 NdisMoveMemory(mic, digest, LEN_KEY_DESC_MIC);
2690 } else {
2691 HMAC_MD5(PTK, LEN_EAP_MICK, OutBuffer, FrameLen, mic,
2692 MD5_DIGEST_SIZE);
2693 }
2694
2695 /* store the calculated MIC */
2696 NdisMoveMemory(pMsg->KeyDesc.KeyMic, mic, LEN_KEY_DESC_MIC);
2697
2698 os_free_mem(NULL, OutBuffer);
2699}
2700
2701/*
2702 ========================================================================
2703
2704 Routine Description:
2705 Some received frames can't decrypt by Asic, so decrypt them by software.
2706
2707 Arguments:
2708 pAd - pointer to our pAdapter context
2709 PeerWepStatus - indicate the encryption type
2710
2711 Return Value:
2712 NDIS_STATUS_SUCCESS - decryption successful
2713 NDIS_STATUS_FAILURE - decryption failure
2714
2715 ========================================================================
2716*/
2717int RTMPSoftDecryptBroadCastData(struct rt_rtmp_adapter *pAd,
2718 struct rt_rx_blk *pRxBlk,
2719 IN NDIS_802_11_ENCRYPTION_STATUS
2720 GroupCipher, struct rt_cipher_key *pShard_key)
2721{
2722 struct rt_rxwi * pRxWI = pRxBlk->pRxWI;
2723
2724 /* handle WEP decryption */
2725 if (GroupCipher == Ndis802_11Encryption1Enabled) {
2726 if (RTMPSoftDecryptWEP
2727 (pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount,
2728 pShard_key)) {
2729
2730 /*Minus IV[4] & ICV[4] */
2731 pRxWI->MPDUtotalByteCount -= 8;
2732 } else {
2733 DBGPRINT(RT_DEBUG_ERROR,
2734 ("ERROR : Software decrypt WEP data fails.\n"));
2735 /* give up this frame */
2736 return NDIS_STATUS_FAILURE;
2737 }
2738 }
2739 /* handle TKIP decryption */
2740 else if (GroupCipher == Ndis802_11Encryption2Enabled) {
2741 if (RTMPSoftDecryptTKIP
2742 (pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount, 0,
2743 pShard_key)) {
2744
2745 /*Minus 8 bytes MIC, 8 bytes IV/EIV, 4 bytes ICV */
2746 pRxWI->MPDUtotalByteCount -= 20;
2747 } else {
2748 DBGPRINT(RT_DEBUG_ERROR,
2749 ("ERROR : RTMPSoftDecryptTKIP Failed\n"));
2750 /* give up this frame */
2751 return NDIS_STATUS_FAILURE;
2752 }
2753 }
2754 /* handle AES decryption */
2755 else if (GroupCipher == Ndis802_11Encryption3Enabled) {
2756 if (RTMPSoftDecryptAES
2757 (pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount,
2758 pShard_key)) {
2759
2760 /*8 bytes MIC, 8 bytes IV/EIV (CCMP Header) */
2761 pRxWI->MPDUtotalByteCount -= 16;
2762 } else {
2763 DBGPRINT(RT_DEBUG_ERROR,
2764 ("ERROR : RTMPSoftDecryptAES Failed\n"));
2765 /* give up this frame */
2766 return NDIS_STATUS_FAILURE;
2767 }
2768 } else {
2769 /* give up this frame */
2770 return NDIS_STATUS_FAILURE;
2771 }
2772
2773 return NDIS_STATUS_SUCCESS;
2774
2775}
2776
2777u8 *GetSuiteFromRSNIE(u8 *rsnie,
2778 u32 rsnie_len, u8 type, u8 * count)
2779{
2780 struct rt_eid * pEid;
2781 int len;
2782 u8 *pBuf;
2783 int offset = 0;
2784 struct rt_rsnie_auth *pAkm;
2785 u16 acount;
2786 BOOLEAN isWPA2 = FALSE;
2787
2788 pEid = (struct rt_eid *) rsnie;
2789 len = rsnie_len - 2; /* exclude IE and length */
2790 pBuf = (u8 *)& pEid->Octet[0];
2791
2792 /* set default value */
2793 *count = 0;
2794
2795 /* Check length */
2796 if ((len <= 0) || (pEid->Len != len)) {
2797 DBGPRINT_ERR("%s : The length is invalid\n", __func__);
2798 return NULL;
2799 }
2800 /* Check WPA or WPA2 */
2801 if (pEid->Eid == IE_WPA) {
2802 struct rt_rsnie *pRsnie = (struct rt_rsnie *)pBuf;
2803 u16 ucount;
2804
2805 if (len < sizeof(struct rt_rsnie)) {
2806 DBGPRINT_ERR("%s : The length is too short for WPA\n", __func__);
2807 return NULL;
2808 }
2809 /* Get the count of pairwise cipher */
2810 ucount = cpu2le16(pRsnie->ucount);
2811 if (ucount > 2) {
2812 DBGPRINT_ERR("%s : The count(%d) of pairwise cipher is invlaid\n", __func__, ucount);
2813 return NULL;
2814 }
2815 /* Get the group cipher */
2816 if (type == GROUP_SUITE) {
2817 *count = 1;
2818 return pRsnie->mcast;
2819 }
2820 /* Get the pairwise cipher suite */
2821 else if (type == PAIRWISE_SUITE) {
2822 DBGPRINT(RT_DEBUG_TRACE,
2823 ("%s : The count of pairwise cipher is %d\n",
2824 __func__, ucount));
2825 *count = ucount;
2826 return pRsnie->ucast[0].oui;
2827 }
2828
2829 offset = sizeof(struct rt_rsnie) + (4 * (ucount - 1));
2830
2831 } else if (pEid->Eid == IE_RSN) {
2832 struct rt_rsnie2 *pRsnie = (struct rt_rsnie2 *)pBuf;
2833 u16 ucount;
2834
2835 isWPA2 = TRUE;
2836
2837 if (len < sizeof(struct rt_rsnie2)) {
2838 DBGPRINT_ERR("%s : The length is too short for WPA2\n", __func__);
2839 return NULL;
2840 }
2841 /* Get the count of pairwise cipher */
2842 ucount = cpu2le16(pRsnie->ucount);
2843 if (ucount > 2) {
2844 DBGPRINT_ERR("%s : The count(%d) of pairwise cipher is invlaid\n", __func__, ucount);
2845 return NULL;
2846 }
2847 /* Get the group cipher */
2848 if (type == GROUP_SUITE) {
2849 *count = 1;
2850 return pRsnie->mcast;
2851 }
2852 /* Get the pairwise cipher suite */
2853 else if (type == PAIRWISE_SUITE) {
2854 DBGPRINT(RT_DEBUG_TRACE,
2855 ("%s : The count of pairwise cipher is %d\n",
2856 __func__, ucount));
2857 *count = ucount;
2858 return pRsnie->ucast[0].oui;
2859 }
2860
2861 offset = sizeof(struct rt_rsnie2) + (4 * (ucount - 1));
2862
2863 } else {
2864 DBGPRINT_ERR("%s : Unknown IE (%d)\n", __func__, pEid->Eid);
2865 return NULL;
2866 }
2867
2868 /* skip group cipher and pairwise cipher suite */
2869 pBuf += offset;
2870 len -= offset;
2871
2872 if (len < sizeof(struct rt_rsnie_auth)) {
2873 DBGPRINT_ERR("%s : The length of RSNIE is too short\n", __func__);
2874 return NULL;
2875 }
2876 /* pointer to AKM count */
2877 pAkm = (struct rt_rsnie_auth *)pBuf;
2878
2879 /* Get the count of pairwise cipher */
2880 acount = cpu2le16(pAkm->acount);
2881 if (acount > 2) {
2882 DBGPRINT_ERR("%s : The count(%d) of AKM is invlaid\n", __func__, acount);
2883 return NULL;
2884 }
2885 /* Get the AKM suite */
2886 if (type == AKM_SUITE) {
2887 DBGPRINT(RT_DEBUG_TRACE, ("%s : The count of AKM is %d\n",
2888 __func__, acount));
2889 *count = acount;
2890 return pAkm->auth[0].oui;
2891 }
2892 offset = sizeof(struct rt_rsnie_auth) + (4 * (acount - 1));
2893
2894 pBuf += offset;
2895 len -= offset;
2896
2897 /* The remaining length must larger than (RSN-Capability(2) + PMKID-Count(2) + PMKID(16~)) */
2898 if (len >= (sizeof(RSN_CAPABILITIES) + 2 + LEN_PMKID)) {
2899 /* Skip RSN capability and PMKID-Count */
2900 pBuf += (sizeof(RSN_CAPABILITIES) + 2);
2901 len -= (sizeof(RSN_CAPABILITIES) + 2);
2902
2903 /* Get PMKID */
2904 if (type == PMKID_LIST) {
2905 *count = 1;
2906 return pBuf;
2907 }
2908 } else {
2909 DBGPRINT_ERR("%s : it can't get any more information beyond AKM \n", __func__);
2910 return NULL;
2911 }
2912
2913 *count = 0;
2914 /*DBGPRINT_ERR(("%s : The type(%d) doesn't support \n", __func__, type)); */
2915 return NULL;
2916
2917}
2918
2919void WpaShowAllsuite(u8 *rsnie, u32 rsnie_len)
2920{
2921 u8 *pSuite = NULL;
2922 u8 count;
2923
2924 hex_dump("RSNIE", rsnie, rsnie_len);
2925
2926 /* group cipher */
2927 pSuite = GetSuiteFromRSNIE(rsnie, rsnie_len, GROUP_SUITE, &count);
2928 if (pSuite != NULL) {
2929 hex_dump("group cipher", pSuite, 4 * count);
2930 }
2931 /* pairwise cipher */
2932 pSuite = GetSuiteFromRSNIE(rsnie, rsnie_len, PAIRWISE_SUITE, &count);
2933 if (pSuite != NULL) {
2934 hex_dump("pairwise cipher", pSuite, 4 * count);
2935 }
2936 /* AKM */
2937 pSuite = GetSuiteFromRSNIE(rsnie, rsnie_len, AKM_SUITE, &count);
2938 if (pSuite != NULL) {
2939 hex_dump("AKM suite", pSuite, 4 * count);
2940 }
2941 /* PMKID */
2942 pSuite = GetSuiteFromRSNIE(rsnie, rsnie_len, PMKID_LIST, &count);
2943 if (pSuite != NULL) {
2944 hex_dump("PMKID", pSuite, LEN_PMKID);
2945 }
2946
2947}
2948
2949void RTMPInsertRSNIE(u8 *pFrameBuf,
2950 unsigned long *pFrameLen,
2951 u8 *rsnie_ptr,
2952 u8 rsnie_len,
2953 u8 *pmkid_ptr, u8 pmkid_len)
2954{
2955 u8 *pTmpBuf;
2956 unsigned long TempLen = 0;
2957 u8 extra_len = 0;
2958 u16 pmk_count = 0;
2959 u8 ie_num;
2960 u8 total_len = 0;
2961 u8 WPA2_OUI[3] = { 0x00, 0x0F, 0xAC };
2962
2963 pTmpBuf = pFrameBuf;
2964
2965 /* PMKID-List Must larger than 0 and the multiple of 16. */
2966 if (pmkid_len > 0 && ((pmkid_len & 0x0f) == 0)) {
2967 extra_len = sizeof(u16)+ pmkid_len;
2968
2969 pmk_count = (pmkid_len >> 4);
2970 pmk_count = cpu2le16(pmk_count);
2971 } else {
2972 DBGPRINT(RT_DEBUG_WARN,
2973 ("%s : The length is PMKID-List is invalid (%d), so don't insert it.\n",
2974 __func__, pmkid_len));
2975 }
2976
2977 if (rsnie_len != 0) {
2978 ie_num = IE_WPA;
2979 total_len = rsnie_len;
2980
2981 if (NdisEqualMemory(rsnie_ptr + 2, WPA2_OUI, sizeof(WPA2_OUI))) {
2982 ie_num = IE_RSN;
2983 total_len += extra_len;
2984 }
2985
2986 /* construct RSNIE body */
2987 MakeOutgoingFrame(pTmpBuf, &TempLen,
2988 1, &ie_num,
2989 1, &total_len,
2990 rsnie_len, rsnie_ptr, END_OF_ARGS);
2991
2992 pTmpBuf += TempLen;
2993 *pFrameLen = *pFrameLen + TempLen;
2994
2995 if (ie_num == IE_RSN) {
2996 /* Insert PMKID-List field */
2997 if (extra_len > 0) {
2998 MakeOutgoingFrame(pTmpBuf, &TempLen,
2999 2, &pmk_count,
3000 pmkid_len, pmkid_ptr,
3001 END_OF_ARGS);
3002
3003 pTmpBuf += TempLen;
3004 *pFrameLen = *pFrameLen + TempLen;
3005 }
3006 }
3007 }
3008
3009 return;
3010}
diff --git a/drivers/staging/rt2860/common/crypt_hmac.c b/drivers/staging/rt2860/common/crypt_hmac.c
deleted file mode 100644
index d7ab08ec1a4..00000000000
--- a/drivers/staging/rt2860/common/crypt_hmac.c
+++ /dev/null
@@ -1,187 +0,0 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************/
26
27#include "../crypt_hmac.h"
28
29#ifdef HMAC_SHA1_SUPPORT
30/*
31========================================================================
32Routine Description:
33 HMAC using SHA1 hash function
34
35Arguments:
36 key Secret key
37 key_len The length of the key in bytes
38 message Message context
39 message_len The length of message in bytes
40 macLen Request the length of message authentication code
41
42Return Value:
43 mac Message authentication code
44
45Note:
46 None
47========================================================================
48*/
49void HMAC_SHA1(IN const u8 Key[],
50 u32 KeyLen,
51 IN const u8 Message[],
52 u32 MessageLen, u8 MAC[], u32 MACLen)
53{
54 struct rt_sha1_ctx sha_ctx1;
55 struct rt_sha1_ctx sha_ctx2;
56 u8 K0[SHA1_BLOCK_SIZE];
57 u8 Digest[SHA1_DIGEST_SIZE];
58 u32 index;
59
60 NdisZeroMemory(&sha_ctx1, sizeof(struct rt_sha1_ctx));
61 NdisZeroMemory(&sha_ctx2, sizeof(struct rt_sha1_ctx));
62 /*
63 * If the length of K = B(Block size): K0 = K.
64 * If the length of K > B: hash K to obtain an L byte string,
65 * then append (B-L) zeros to create a B-byte string K0 (i.e., K0 = H(K) || 00...00).
66 * If the length of K < B: append zeros to the end of K to create a B-byte string K0
67 */
68 NdisZeroMemory(K0, SHA1_BLOCK_SIZE);
69 if (KeyLen <= SHA1_BLOCK_SIZE)
70 NdisMoveMemory(K0, Key, KeyLen);
71 else
72 RT_SHA1(Key, KeyLen, K0);
73 /* End of if */
74
75 /* Exclusive-Or K0 with ipad */
76 /* ipad: Inner pad; the byte x¡¦36¡¦ repeated B times. */
77 for (index = 0; index < SHA1_BLOCK_SIZE; index++)
78 K0[index] ^= 0x36;
79 /* End of for */
80
81 RT_SHA1_Init(&sha_ctx1);
82 /* H(K0^ipad) */
83 SHA1_Append(&sha_ctx1, K0, sizeof(K0));
84 /* H((K0^ipad)||text) */
85 SHA1_Append(&sha_ctx1, Message, MessageLen);
86 SHA1_End(&sha_ctx1, Digest);
87
88 /* Exclusive-Or K0 with opad and remove ipad */
89 /* opad: Outer pad; the byte x¡¦5c¡¦ repeated B times. */
90 for (index = 0; index < SHA1_BLOCK_SIZE; index++)
91 K0[index] ^= 0x36 ^ 0x5c;
92 /* End of for */
93
94 RT_SHA1_Init(&sha_ctx2);
95 /* H(K0^opad) */
96 SHA1_Append(&sha_ctx2, K0, sizeof(K0));
97 /* H( (K0^opad) || H((K0^ipad)||text) ) */
98 SHA1_Append(&sha_ctx2, Digest, SHA1_DIGEST_SIZE);
99 SHA1_End(&sha_ctx2, Digest);
100
101 if (MACLen > SHA1_DIGEST_SIZE)
102 NdisMoveMemory(MAC, Digest, SHA1_DIGEST_SIZE);
103 else
104 NdisMoveMemory(MAC, Digest, MACLen);
105} /* End of HMAC_SHA1 */
106#endif /* HMAC_SHA1_SUPPORT */
107
108#ifdef HMAC_MD5_SUPPORT
109/*
110========================================================================
111Routine Description:
112 HMAC using MD5 hash function
113
114Arguments:
115 key Secret key
116 key_len The length of the key in bytes
117 message Message context
118 message_len The length of message in bytes
119 macLen Request the length of message authentication code
120
121Return Value:
122 mac Message authentication code
123
124Note:
125 None
126========================================================================
127*/
128void HMAC_MD5(IN const u8 Key[],
129 u32 KeyLen,
130 IN const u8 Message[],
131 u32 MessageLen, u8 MAC[], u32 MACLen)
132{
133 struct rt_md5_ctx_struc md5_ctx1;
134 struct rt_md5_ctx_struc md5_ctx2;
135 u8 K0[MD5_BLOCK_SIZE];
136 u8 Digest[MD5_DIGEST_SIZE];
137 u32 index;
138
139 NdisZeroMemory(&md5_ctx1, sizeof(struct rt_md5_ctx_struc));
140 NdisZeroMemory(&md5_ctx2, sizeof(struct rt_md5_ctx_struc));
141 /*
142 * If the length of K = B(Block size): K0 = K.
143 * If the length of K > B: hash K to obtain an L byte string,
144 * then append (B-L) zeros to create a B-byte string K0 (i.e., K0 = H(K) || 00...00).
145 * If the length of K < B: append zeros to the end of K to create a B-byte string K0
146 */
147 NdisZeroMemory(K0, MD5_BLOCK_SIZE);
148 if (KeyLen <= MD5_BLOCK_SIZE) {
149 NdisMoveMemory(K0, Key, KeyLen);
150 } else {
151 RT_MD5(Key, KeyLen, K0);
152 }
153
154 /* Exclusive-Or K0 with ipad */
155 /* ipad: Inner pad; the byte x¡¦36¡¦ repeated B times. */
156 for (index = 0; index < MD5_BLOCK_SIZE; index++)
157 K0[index] ^= 0x36;
158 /* End of for */
159
160 MD5_Init(&md5_ctx1);
161 /* H(K0^ipad) */
162 MD5_Append(&md5_ctx1, K0, sizeof(K0));
163 /* H((K0^ipad)||text) */
164 MD5_Append(&md5_ctx1, Message, MessageLen);
165 MD5_End(&md5_ctx1, Digest);
166
167 /* Exclusive-Or K0 with opad and remove ipad */
168 /* opad: Outer pad; the byte x¡¦5c¡¦ repeated B times. */
169 for (index = 0; index < MD5_BLOCK_SIZE; index++)
170 K0[index] ^= 0x36 ^ 0x5c;
171 /* End of for */
172
173 MD5_Init(&md5_ctx2);
174 /* H(K0^opad) */
175 MD5_Append(&md5_ctx2, K0, sizeof(K0));
176 /* H( (K0^opad) || H((K0^ipad)||text) ) */
177 MD5_Append(&md5_ctx2, Digest, MD5_DIGEST_SIZE);
178 MD5_End(&md5_ctx2, Digest);
179
180 if (MACLen > MD5_DIGEST_SIZE)
181 NdisMoveMemory(MAC, Digest, MD5_DIGEST_SIZE);
182 else
183 NdisMoveMemory(MAC, Digest, MACLen);
184} /* End of HMAC_SHA256 */
185#endif /* HMAC_MD5_SUPPORT */
186
187/* End of crypt_hmac.c */
diff --git a/drivers/staging/rt2860/common/crypt_md5.c b/drivers/staging/rt2860/common/crypt_md5.c
deleted file mode 100644
index 6deab659c22..00000000000
--- a/drivers/staging/rt2860/common/crypt_md5.c
+++ /dev/null
@@ -1,339 +0,0 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************/
26
27#include "../crypt_md5.h"
28
29#ifdef MD5_SUPPORT
30/*
31 * F, G, H and I are basic MD5 functions.
32 */
33#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
34#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
35#define H(x, y, z) ((x) ^ (y) ^ (z))
36#define I(x, y, z) ((y) ^ ((x) | (~z)))
37
38#define ROTL(x,n,w) ((x << n) | (x >> (w - n)))
39#define ROTL32(x,n) ROTL(x,n,32) /* 32 bits word */
40
41#define ROUND1(a, b, c, d, x, s, ac) { \
42 (a) += F((b),(c),(d)) + (x) + (u32)(ac); \
43 (a) = ROTL32((a),(s)); \
44 (a) += (b); \
45}
46#define ROUND2(a, b, c, d, x, s, ac) { \
47 (a) += G((b),(c),(d)) + (x) + (u32)(ac); \
48 (a) = ROTL32((a),(s)); \
49 (a) += (b); \
50}
51#define ROUND3(a, b, c, d, x, s, ac) { \
52 (a) += H((b),(c),(d)) + (x) + (u32)(ac); \
53 (a) = ROTL32((a),(s)); \
54 (a) += (b); \
55}
56#define ROUND4(a, b, c, d, x, s, ac) { \
57 (a) += I((b),(c),(d)) + (x) + (u32)(ac); \
58 (a) = ROTL32((a),(s)); \
59 (a) += (b); \
60}
61static const u32 MD5_DefaultHashValue[4] = {
62 0x67452301UL, 0xefcdab89UL, 0x98badcfeUL, 0x10325476UL
63};
64#endif /* MD5_SUPPORT */
65
66#ifdef MD5_SUPPORT
67/*
68========================================================================
69Routine Description:
70 Initial Md5_CTX_STRUC
71
72Arguments:
73 pMD5_CTX Pointer to Md5_CTX_STRUC
74
75Return Value:
76 None
77
78Note:
79 None
80========================================================================
81*/
82void MD5_Init(struct rt_md5_ctx_struc *pMD5_CTX)
83{
84 NdisMoveMemory(pMD5_CTX->HashValue, MD5_DefaultHashValue,
85 sizeof(MD5_DefaultHashValue));
86 NdisZeroMemory(pMD5_CTX->Block, MD5_BLOCK_SIZE);
87 pMD5_CTX->BlockLen = 0;
88 pMD5_CTX->MessageLen = 0;
89} /* End of MD5_Init */
90
91/*
92========================================================================
93Routine Description:
94 MD5 computation for one block (512 bits)
95
96Arguments:
97 pMD5_CTX Pointer to Md5_CTX_STRUC
98
99Return Value:
100 None
101
102Note:
103 T[i] := floor(abs(sin(i + 1)) * (2 pow 32)), i is number of round
104========================================================================
105*/
106void MD5_Hash(struct rt_md5_ctx_struc *pMD5_CTX)
107{
108 u32 X_i;
109 u32 X[16];
110 u32 a, b, c, d;
111
112 /* Prepare the message schedule, {X_i} */
113 NdisMoveMemory(X, pMD5_CTX->Block, MD5_BLOCK_SIZE);
114 for (X_i = 0; X_i < 16; X_i++)
115 X[X_i] = cpu2le32(X[X_i]); /* Endian Swap */
116 /* End of for */
117
118 /* MD5 hash computation */
119 /* Initialize the working variables */
120 a = pMD5_CTX->HashValue[0];
121 b = pMD5_CTX->HashValue[1];
122 c = pMD5_CTX->HashValue[2];
123 d = pMD5_CTX->HashValue[3];
124
125 /*
126 * Round 1
127 * Let [abcd k s i] denote the operation
128 * a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s)
129 */
130 ROUND1(a, b, c, d, X[0], 7, 0xd76aa478); /* 1 */
131 ROUND1(d, a, b, c, X[1], 12, 0xe8c7b756); /* 2 */
132 ROUND1(c, d, a, b, X[2], 17, 0x242070db); /* 3 */
133 ROUND1(b, c, d, a, X[3], 22, 0xc1bdceee); /* 4 */
134 ROUND1(a, b, c, d, X[4], 7, 0xf57c0faf); /* 5 */
135 ROUND1(d, a, b, c, X[5], 12, 0x4787c62a); /* 6 */
136 ROUND1(c, d, a, b, X[6], 17, 0xa8304613); /* 7 */
137 ROUND1(b, c, d, a, X[7], 22, 0xfd469501); /* 8 */
138 ROUND1(a, b, c, d, X[8], 7, 0x698098d8); /* 9 */
139 ROUND1(d, a, b, c, X[9], 12, 0x8b44f7af); /* 10 */
140 ROUND1(c, d, a, b, X[10], 17, 0xffff5bb1); /* 11 */
141 ROUND1(b, c, d, a, X[11], 22, 0x895cd7be); /* 12 */
142 ROUND1(a, b, c, d, X[12], 7, 0x6b901122); /* 13 */
143 ROUND1(d, a, b, c, X[13], 12, 0xfd987193); /* 14 */
144 ROUND1(c, d, a, b, X[14], 17, 0xa679438e); /* 15 */
145 ROUND1(b, c, d, a, X[15], 22, 0x49b40821); /* 16 */
146
147 /*
148 * Round 2
149 * Let [abcd k s i] denote the operation
150 * a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s)
151 */
152 ROUND2(a, b, c, d, X[1], 5, 0xf61e2562); /* 17 */
153 ROUND2(d, a, b, c, X[6], 9, 0xc040b340); /* 18 */
154 ROUND2(c, d, a, b, X[11], 14, 0x265e5a51); /* 19 */
155 ROUND2(b, c, d, a, X[0], 20, 0xe9b6c7aa); /* 20 */
156 ROUND2(a, b, c, d, X[5], 5, 0xd62f105d); /* 21 */
157 ROUND2(d, a, b, c, X[10], 9, 0x2441453); /* 22 */
158 ROUND2(c, d, a, b, X[15], 14, 0xd8a1e681); /* 23 */
159 ROUND2(b, c, d, a, X[4], 20, 0xe7d3fbc8); /* 24 */
160 ROUND2(a, b, c, d, X[9], 5, 0x21e1cde6); /* 25 */
161 ROUND2(d, a, b, c, X[14], 9, 0xc33707d6); /* 26 */
162 ROUND2(c, d, a, b, X[3], 14, 0xf4d50d87); /* 27 */
163 ROUND2(b, c, d, a, X[8], 20, 0x455a14ed); /* 28 */
164 ROUND2(a, b, c, d, X[13], 5, 0xa9e3e905); /* 29 */
165 ROUND2(d, a, b, c, X[2], 9, 0xfcefa3f8); /* 30 */
166 ROUND2(c, d, a, b, X[7], 14, 0x676f02d9); /* 31 */
167 ROUND2(b, c, d, a, X[12], 20, 0x8d2a4c8a); /* 32 */
168
169 /*
170 * Round 3
171 * Let [abcd k s t] denote the operation
172 * a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s)
173 */
174 ROUND3(a, b, c, d, X[5], 4, 0xfffa3942); /* 33 */
175 ROUND3(d, a, b, c, X[8], 11, 0x8771f681); /* 34 */
176 ROUND3(c, d, a, b, X[11], 16, 0x6d9d6122); /* 35 */
177 ROUND3(b, c, d, a, X[14], 23, 0xfde5380c); /* 36 */
178 ROUND3(a, b, c, d, X[1], 4, 0xa4beea44); /* 37 */
179 ROUND3(d, a, b, c, X[4], 11, 0x4bdecfa9); /* 38 */
180 ROUND3(c, d, a, b, X[7], 16, 0xf6bb4b60); /* 39 */
181 ROUND3(b, c, d, a, X[10], 23, 0xbebfbc70); /* 40 */
182 ROUND3(a, b, c, d, X[13], 4, 0x289b7ec6); /* 41 */
183 ROUND3(d, a, b, c, X[0], 11, 0xeaa127fa); /* 42 */
184 ROUND3(c, d, a, b, X[3], 16, 0xd4ef3085); /* 43 */
185 ROUND3(b, c, d, a, X[6], 23, 0x4881d05); /* 44 */
186 ROUND3(a, b, c, d, X[9], 4, 0xd9d4d039); /* 45 */
187 ROUND3(d, a, b, c, X[12], 11, 0xe6db99e5); /* 46 */
188 ROUND3(c, d, a, b, X[15], 16, 0x1fa27cf8); /* 47 */
189 ROUND3(b, c, d, a, X[2], 23, 0xc4ac5665); /* 48 */
190
191 /*
192 * Round 4
193 * Let [abcd k s t] denote the operation
194 * a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s)
195 */
196 ROUND4(a, b, c, d, X[0], 6, 0xf4292244); /* 49 */
197 ROUND4(d, a, b, c, X[7], 10, 0x432aff97); /* 50 */
198 ROUND4(c, d, a, b, X[14], 15, 0xab9423a7); /* 51 */
199 ROUND4(b, c, d, a, X[5], 21, 0xfc93a039); /* 52 */
200 ROUND4(a, b, c, d, X[12], 6, 0x655b59c3); /* 53 */
201 ROUND4(d, a, b, c, X[3], 10, 0x8f0ccc92); /* 54 */
202 ROUND4(c, d, a, b, X[10], 15, 0xffeff47d); /* 55 */
203 ROUND4(b, c, d, a, X[1], 21, 0x85845dd1); /* 56 */
204 ROUND4(a, b, c, d, X[8], 6, 0x6fa87e4f); /* 57 */
205 ROUND4(d, a, b, c, X[15], 10, 0xfe2ce6e0); /* 58 */
206 ROUND4(c, d, a, b, X[6], 15, 0xa3014314); /* 59 */
207 ROUND4(b, c, d, a, X[13], 21, 0x4e0811a1); /* 60 */
208 ROUND4(a, b, c, d, X[4], 6, 0xf7537e82); /* 61 */
209 ROUND4(d, a, b, c, X[11], 10, 0xbd3af235); /* 62 */
210 ROUND4(c, d, a, b, X[2], 15, 0x2ad7d2bb); /* 63 */
211 ROUND4(b, c, d, a, X[9], 21, 0xeb86d391); /* 64 */
212
213 /* Compute the i^th intermediate hash value H^(i) */
214 pMD5_CTX->HashValue[0] += a;
215 pMD5_CTX->HashValue[1] += b;
216 pMD5_CTX->HashValue[2] += c;
217 pMD5_CTX->HashValue[3] += d;
218
219 NdisZeroMemory(pMD5_CTX->Block, MD5_BLOCK_SIZE);
220 pMD5_CTX->BlockLen = 0;
221} /* End of MD5_Hash */
222
223/*
224========================================================================
225Routine Description:
226 The message is appended to block. If block size > 64 bytes, the MD5_Hash
227will be called.
228
229Arguments:
230 pMD5_CTX Pointer to struct rt_md5_ctx_struc
231 message Message context
232 messageLen The length of message in bytes
233
234Return Value:
235 None
236
237Note:
238 None
239========================================================================
240*/
241void MD5_Append(struct rt_md5_ctx_struc *pMD5_CTX,
242 IN const u8 Message[], u32 MessageLen)
243{
244 u32 appendLen = 0;
245 u32 diffLen = 0;
246
247 while (appendLen != MessageLen) {
248 diffLen = MessageLen - appendLen;
249 if ((pMD5_CTX->BlockLen + diffLen) < MD5_BLOCK_SIZE) {
250 NdisMoveMemory(pMD5_CTX->Block + pMD5_CTX->BlockLen,
251 Message + appendLen, diffLen);
252 pMD5_CTX->BlockLen += diffLen;
253 appendLen += diffLen;
254 } else {
255 NdisMoveMemory(pMD5_CTX->Block + pMD5_CTX->BlockLen,
256 Message + appendLen,
257 MD5_BLOCK_SIZE - pMD5_CTX->BlockLen);
258 appendLen += (MD5_BLOCK_SIZE - pMD5_CTX->BlockLen);
259 pMD5_CTX->BlockLen = MD5_BLOCK_SIZE;
260 MD5_Hash(pMD5_CTX);
261 } /* End of if */
262 } /* End of while */
263 pMD5_CTX->MessageLen += MessageLen;
264} /* End of MD5_Append */
265
266/*
267========================================================================
268Routine Description:
269 1. Append bit 1 to end of the message
270 2. Append the length of message in rightmost 64 bits
271 3. Transform the Hash Value to digest message
272
273Arguments:
274 pMD5_CTX Pointer to struct rt_md5_ctx_struc
275
276Return Value:
277 digestMessage Digest message
278
279Note:
280 None
281========================================================================
282*/
283void MD5_End(struct rt_md5_ctx_struc *pMD5_CTX, u8 DigestMessage[])
284{
285 u32 index;
286 u64 message_length_bits;
287
288 /* append 1 bits to end of the message */
289 NdisFillMemory(pMD5_CTX->Block + pMD5_CTX->BlockLen, 1, 0x80);
290
291 /* 55 = 64 - 8 - 1: append 1 bit(1 byte) and message length (8 bytes) */
292 if (pMD5_CTX->BlockLen > 55)
293 MD5_Hash(pMD5_CTX);
294 /* End of if */
295
296 /* Append the length of message in rightmost 64 bits */
297 message_length_bits = pMD5_CTX->MessageLen * 8;
298 message_length_bits = cpu2le64(message_length_bits);
299 NdisMoveMemory(&pMD5_CTX->Block[56], &message_length_bits, 8);
300 MD5_Hash(pMD5_CTX);
301
302 /* Return message digest, transform the u32 hash value to bytes */
303 for (index = 0; index < 4; index++)
304 pMD5_CTX->HashValue[index] =
305 cpu2le32(pMD5_CTX->HashValue[index]);
306 /* End of for */
307 NdisMoveMemory(DigestMessage, pMD5_CTX->HashValue, MD5_DIGEST_SIZE);
308} /* End of MD5_End */
309
310/*
311========================================================================
312Routine Description:
313 MD5 algorithm
314
315Arguments:
316 message Message context
317 messageLen The length of message in bytes
318
319Return Value:
320 digestMessage Digest message
321
322Note:
323 None
324========================================================================
325*/
326void RT_MD5(IN const u8 Message[],
327 u32 MessageLen, u8 DigestMessage[])
328{
329 struct rt_md5_ctx_struc md5_ctx;
330
331 NdisZeroMemory(&md5_ctx, sizeof(struct rt_md5_ctx_struc));
332 MD5_Init(&md5_ctx);
333 MD5_Append(&md5_ctx, Message, MessageLen);
334 MD5_End(&md5_ctx, DigestMessage);
335} /* End of RT_MD5 */
336
337#endif /* MD5_SUPPORT */
338
339/* End of crypt_md5.c */
diff --git a/drivers/staging/rt2860/common/crypt_sha2.c b/drivers/staging/rt2860/common/crypt_sha2.c
deleted file mode 100644
index fa83fb287fe..00000000000
--- a/drivers/staging/rt2860/common/crypt_sha2.c
+++ /dev/null
@@ -1,269 +0,0 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************/
26
27#include "../crypt_sha2.h"
28
29/* Basic operations */
30#define SHR(x,n) (x >> n) /* SHR(x)^n, right shift n bits , x is w-bit word, 0 <= n <= w */
31#define ROTR(x,n,w) ((x >> n) | (x << (w - n))) /* ROTR(x)^n, circular right shift n bits , x is w-bit word, 0 <= n <= w */
32#define ROTL(x,n,w) ((x << n) | (x >> (w - n))) /* ROTL(x)^n, circular left shift n bits , x is w-bit word, 0 <= n <= w */
33#define ROTR32(x,n) ROTR(x,n,32) /* 32 bits word */
34#define ROTL32(x,n) ROTL(x,n,32) /* 32 bits word */
35
36/* Basic functions */
37#define Ch(x,y,z) ((x & y) ^ ((~x) & z))
38#define Maj(x,y,z) ((x & y) ^ (x & z) ^ (y & z))
39#define Parity(x,y,z) (x ^ y ^ z)
40
41#ifdef SHA1_SUPPORT
42/* SHA1 constants */
43#define SHA1_MASK 0x0000000f
44static const u32 SHA1_K[4] = {
45 0x5a827999UL, 0x6ed9eba1UL, 0x8f1bbcdcUL, 0xca62c1d6UL
46};
47
48static const u32 SHA1_DefaultHashValue[5] = {
49 0x67452301UL, 0xefcdab89UL, 0x98badcfeUL, 0x10325476UL, 0xc3d2e1f0UL
50};
51
52/*
53========================================================================
54Routine Description:
55 Initial struct rt_sha1_ctx
56
57Arguments:
58 pSHA_CTX Pointer to struct rt_sha1_ctx
59
60Return Value:
61 None
62
63Note:
64 None
65========================================================================
66*/
67void RT_SHA1_Init(struct rt_sha1_ctx *pSHA_CTX)
68{
69 NdisMoveMemory(pSHA_CTX->HashValue, SHA1_DefaultHashValue,
70 sizeof(SHA1_DefaultHashValue));
71 NdisZeroMemory(pSHA_CTX->Block, SHA1_BLOCK_SIZE);
72 pSHA_CTX->MessageLen = 0;
73 pSHA_CTX->BlockLen = 0;
74} /* End of RT_SHA1_Init */
75
76/*
77========================================================================
78Routine Description:
79 SHA1 computation for one block (512 bits)
80
81Arguments:
82 pSHA_CTX Pointer to struct rt_sha1_ctx
83
84Return Value:
85 None
86
87Note:
88 None
89========================================================================
90*/
91void SHA1_Hash(struct rt_sha1_ctx *pSHA_CTX)
92{
93 u32 W_i, t, s;
94 u32 W[16];
95 u32 a, b, c, d, e, T, f_t = 0;
96
97 /* Prepare the message schedule, {W_i}, 0 < t < 15 */
98 NdisMoveMemory(W, pSHA_CTX->Block, SHA1_BLOCK_SIZE);
99 for (W_i = 0; W_i < 16; W_i++)
100 W[W_i] = cpu2be32(W[W_i]); /* Endian Swap */
101 /* End of for */
102
103 /* SHA256 hash computation */
104 /* Initialize the working variables */
105 a = pSHA_CTX->HashValue[0];
106 b = pSHA_CTX->HashValue[1];
107 c = pSHA_CTX->HashValue[2];
108 d = pSHA_CTX->HashValue[3];
109 e = pSHA_CTX->HashValue[4];
110
111 /* 80 rounds */
112 for (t = 0; t < 80; t++) {
113 s = t & SHA1_MASK;
114 if (t > 15) { /* Prepare the message schedule, {W_i}, 16 < t < 79 */
115 W[s] =
116 (W[(s + 13) & SHA1_MASK]) ^ (W[(s + 8) & SHA1_MASK])
117 ^ (W[(s + 2) & SHA1_MASK]) ^ W[s];
118 W[s] = ROTL32(W[s], 1);
119 } /* End of if */
120 switch (t / 20) {
121 case 0:
122 f_t = Ch(b, c, d);
123 break;
124 case 1:
125 f_t = Parity(b, c, d);
126 break;
127 case 2:
128 f_t = Maj(b, c, d);
129 break;
130 case 3:
131 f_t = Parity(b, c, d);
132 break;
133 } /* End of switch */
134 T = ROTL32(a, 5) + f_t + e + SHA1_K[t / 20] + W[s];
135 e = d;
136 d = c;
137 c = ROTL32(b, 30);
138 b = a;
139 a = T;
140 } /* End of for */
141
142 /* Compute the i^th intermediate hash value H^(i) */
143 pSHA_CTX->HashValue[0] += a;
144 pSHA_CTX->HashValue[1] += b;
145 pSHA_CTX->HashValue[2] += c;
146 pSHA_CTX->HashValue[3] += d;
147 pSHA_CTX->HashValue[4] += e;
148
149 NdisZeroMemory(pSHA_CTX->Block, SHA1_BLOCK_SIZE);
150 pSHA_CTX->BlockLen = 0;
151} /* End of SHA1_Hash */
152
153/*
154========================================================================
155Routine Description:
156 The message is appended to block. If block size > 64 bytes, the SHA1_Hash
157will be called.
158
159Arguments:
160 pSHA_CTX Pointer to struct rt_sha1_ctx
161 message Message context
162 messageLen The length of message in bytes
163
164Return Value:
165 None
166
167Note:
168 None
169========================================================================
170*/
171void SHA1_Append(struct rt_sha1_ctx *pSHA_CTX,
172 IN const u8 Message[], u32 MessageLen)
173{
174 u32 appendLen = 0;
175 u32 diffLen = 0;
176
177 while (appendLen != MessageLen) {
178 diffLen = MessageLen - appendLen;
179 if ((pSHA_CTX->BlockLen + diffLen) < SHA1_BLOCK_SIZE) {
180 NdisMoveMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen,
181 Message + appendLen, diffLen);
182 pSHA_CTX->BlockLen += diffLen;
183 appendLen += diffLen;
184 } else {
185 NdisMoveMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen,
186 Message + appendLen,
187 SHA1_BLOCK_SIZE - pSHA_CTX->BlockLen);
188 appendLen += (SHA1_BLOCK_SIZE - pSHA_CTX->BlockLen);
189 pSHA_CTX->BlockLen = SHA1_BLOCK_SIZE;
190 SHA1_Hash(pSHA_CTX);
191 } /* End of if */
192 } /* End of while */
193 pSHA_CTX->MessageLen += MessageLen;
194} /* End of SHA1_Append */
195
196/*
197========================================================================
198Routine Description:
199 1. Append bit 1 to end of the message
200 2. Append the length of message in rightmost 64 bits
201 3. Transform the Hash Value to digest message
202
203Arguments:
204 pSHA_CTX Pointer to struct rt_sha1_ctx
205
206Return Value:
207 digestMessage Digest message
208
209Note:
210 None
211========================================================================
212*/
213void SHA1_End(struct rt_sha1_ctx *pSHA_CTX, u8 DigestMessage[])
214{
215 u32 index;
216 u64 message_length_bits;
217
218 /* Append bit 1 to end of the message */
219 NdisFillMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen, 1, 0x80);
220
221 /* 55 = 64 - 8 - 1: append 1 bit(1 byte) and message length (8 bytes) */
222 if (pSHA_CTX->BlockLen > 55)
223 SHA1_Hash(pSHA_CTX);
224 /* End of if */
225
226 /* Append the length of message in rightmost 64 bits */
227 message_length_bits = pSHA_CTX->MessageLen * 8;
228 message_length_bits = cpu2be64(message_length_bits);
229 NdisMoveMemory(&pSHA_CTX->Block[56], &message_length_bits, 8);
230 SHA1_Hash(pSHA_CTX);
231
232 /* Return message digest, transform the u32 hash value to bytes */
233 for (index = 0; index < 5; index++)
234 pSHA_CTX->HashValue[index] =
235 cpu2be32(pSHA_CTX->HashValue[index]);
236 /* End of for */
237 NdisMoveMemory(DigestMessage, pSHA_CTX->HashValue, SHA1_DIGEST_SIZE);
238} /* End of SHA1_End */
239
240/*
241========================================================================
242Routine Description:
243 SHA1 algorithm
244
245Arguments:
246 message Message context
247 messageLen The length of message in bytes
248
249Return Value:
250 digestMessage Digest message
251
252Note:
253 None
254========================================================================
255*/
256void RT_SHA1(IN const u8 Message[],
257 u32 MessageLen, u8 DigestMessage[])
258{
259
260 struct rt_sha1_ctx sha_ctx;
261
262 NdisZeroMemory(&sha_ctx, sizeof(struct rt_sha1_ctx));
263 RT_SHA1_Init(&sha_ctx);
264 SHA1_Append(&sha_ctx, Message, MessageLen);
265 SHA1_End(&sha_ctx, DigestMessage);
266} /* End of RT_SHA1 */
267#endif /* SHA1_SUPPORT */
268
269/* End of crypt_sha2.c */
diff --git a/drivers/staging/rt2860/common/dfs.c b/drivers/staging/rt2860/common/dfs.c
deleted file mode 100644
index 71cbb266524..00000000000
--- a/drivers/staging/rt2860/common/dfs.c
+++ /dev/null
@@ -1,68 +0,0 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 ap_dfs.c
29
30 Abstract:
31 Support DFS function.
32
33 Revision History:
34 Who When What
35 -------- ---------- ----------------------------------------------
36*/
37
38#include "../rt_config.h"
39
40/*
41 ========================================================================
42
43 Routine Description:
44 Radar channel check routine
45
46 Arguments:
47 pAd Pointer to our adapter
48
49 Return Value:
50 TRUE need to do radar detect
51 FALSE need not to do radar detect
52
53 ========================================================================
54*/
55BOOLEAN RadarChannelCheck(struct rt_rtmp_adapter *pAd, u8 Ch)
56{
57 int i;
58 BOOLEAN result = FALSE;
59
60 for (i = 0; i < pAd->ChannelListNum; i++) {
61 if (Ch == pAd->ChannelList[i].Channel) {
62 result = pAd->ChannelList[i].DfsReq;
63 break;
64 }
65 }
66
67 return result;
68}
diff --git a/drivers/staging/rt2860/common/ee_efuse.c b/drivers/staging/rt2860/common/ee_efuse.c
deleted file mode 100644
index fed0ba45227..00000000000
--- a/drivers/staging/rt2860/common/ee_efuse.c
+++ /dev/null
@@ -1,351 +0,0 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 ee_efuse.c
29
30 Abstract:
31 Miniport generic portion header file
32
33 Revision History:
34 Who When What
35 -------- ---------- ----------------------------------------------
36*/
37
38#include "../rt_config.h"
39
40#define EFUSE_USAGE_MAP_START 0x2d0
41#define EFUSE_USAGE_MAP_END 0x2fc
42#define EFUSE_USAGE_MAP_SIZE 45
43
44#define EFUSE_EEPROM_DEFULT_FILE "RT30xxEEPROM.bin"
45#define MAX_EEPROM_BIN_FILE_SIZE 1024
46
47#define EFUSE_TAG 0x2fe
48
49typedef union _EFUSE_CTRL_STRUC {
50 struct {
51 u32 EFSROM_AOUT:6;
52 u32 EFSROM_MODE:2;
53 u32 EFSROM_LDO_OFF_TIME:6;
54 u32 EFSROM_LDO_ON_TIME:2;
55 u32 EFSROM_AIN:10;
56 u32 RESERVED:4;
57 u32 EFSROM_KICK:1;
58 u32 SEL_EFUSE:1;
59 } field;
60 u32 word;
61} EFUSE_CTRL_STRUC, *PEFUSE_CTRL_STRUC;
62
63/*
64========================================================================
65
66 Routine Description:
67
68 Arguments:
69
70 Return Value:
71
72 Note:
73
74========================================================================
75*/
76u8 eFuseReadRegisters(struct rt_rtmp_adapter *pAd,
77 u16 Offset, u16 Length, u16 * pData)
78{
79 EFUSE_CTRL_STRUC eFuseCtrlStruc;
80 int i;
81 u16 efuseDataOffset;
82 u32 data;
83
84 RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
85
86 /*Step0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment. */
87 /*Use the eeprom logical address and covert to address to block number */
88 eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
89
90 /*Step1. Write EFSROM_MODE (0x580, bit7:bit6) to 0. */
91 eFuseCtrlStruc.field.EFSROM_MODE = 0;
92
93 /*Step2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure. */
94 eFuseCtrlStruc.field.EFSROM_KICK = 1;
95
96 NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
97 RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
98
99 /*Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again. */
100 i = 0;
101 while (i < 500) {
102 /*rtmp.HwMemoryReadDword(EFUSE_CTRL, (DWORD *) &eFuseCtrlStruc, 4); */
103 RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
104 if (eFuseCtrlStruc.field.EFSROM_KICK == 0) {
105 break;
106 }
107 RTMPusecDelay(2);
108 i++;
109 }
110
111 /*if EFSROM_AOUT is not found in physical address, write 0xffff */
112 if (eFuseCtrlStruc.field.EFSROM_AOUT == 0x3f) {
113 for (i = 0; i < Length / 2; i++)
114 *(pData + 2 * i) = 0xffff;
115 } else {
116 /*Step4. Read 16-byte of data from EFUSE_DATA0-3 (0x590-0x59C) */
117 efuseDataOffset = EFUSE_DATA3 - (Offset & 0xC);
118 /*data hold 4 bytes data. */
119 /*In RTMP_IO_READ32 will automatically execute 32-bytes swapping */
120 RTMP_IO_READ32(pAd, efuseDataOffset, &data);
121 /*Decide the upper 2 bytes or the bottom 2 bytes. */
122 /* Little-endian S | S Big-endian */
123 /* addr 3 2 1 0 | 0 1 2 3 */
124 /* Ori-V D C B A | A B C D */
125 /*After swapping */
126 /* D C B A | D C B A */
127 /*Return 2-bytes */
128 /*The return byte statrs from S. Therefore, the little-endian will return BA, the Big-endian will return DC. */
129 /*For returning the bottom 2 bytes, the Big-endian should shift right 2-bytes. */
130 data = data >> (8 * (Offset & 0x3));
131
132 NdisMoveMemory(pData, &data, Length);
133 }
134
135 return (u8)eFuseCtrlStruc.field.EFSROM_AOUT;
136
137}
138
139/*
140========================================================================
141
142 Routine Description:
143
144 Arguments:
145
146 Return Value:
147
148 Note:
149
150========================================================================
151*/
152void eFusePhysicalReadRegisters(struct rt_rtmp_adapter *pAd,
153 u16 Offset,
154 u16 Length, u16 * pData)
155{
156 EFUSE_CTRL_STRUC eFuseCtrlStruc;
157 int i;
158 u16 efuseDataOffset;
159 u32 data;
160
161 RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
162
163 /*Step0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment. */
164 eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
165
166 /*Step1. Write EFSROM_MODE (0x580, bit7:bit6) to 1. */
167 /*Read in physical view */
168 eFuseCtrlStruc.field.EFSROM_MODE = 1;
169
170 /*Step2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure. */
171 eFuseCtrlStruc.field.EFSROM_KICK = 1;
172
173 NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
174 RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
175
176 /*Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again. */
177 i = 0;
178 while (i < 500) {
179 RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
180 if (eFuseCtrlStruc.field.EFSROM_KICK == 0)
181 break;
182 RTMPusecDelay(2);
183 i++;
184 }
185
186 /*Step4. Read 16-byte of data from EFUSE_DATA0-3 (0x59C-0x590) */
187 /*Because the size of each EFUSE_DATA is 4 Bytes, the size of address of each is 2 bits. */
188 /*The previous 2 bits is the EFUSE_DATA number, the last 2 bits is used to decide which bytes */
189 /*Decide which EFUSE_DATA to read */
190 /*590:F E D C */
191 /*594:B A 9 8 */
192 /*598:7 6 5 4 */
193 /*59C:3 2 1 0 */
194 efuseDataOffset = EFUSE_DATA3 - (Offset & 0xC);
195
196 RTMP_IO_READ32(pAd, efuseDataOffset, &data);
197
198 data = data >> (8 * (Offset & 0x3));
199
200 NdisMoveMemory(pData, &data, Length);
201
202}
203
204/*
205========================================================================
206
207 Routine Description:
208
209 Arguments:
210
211 Return Value:
212
213 Note:
214
215========================================================================
216*/
217static void eFuseReadPhysical(struct rt_rtmp_adapter *pAd,
218 u16 *lpInBuffer,
219 unsigned long nInBufferSize,
220 u16 *lpOutBuffer, unsigned long nOutBufferSize)
221{
222 u16 *pInBuf = (u16 *) lpInBuffer;
223 u16 *pOutBuf = (u16 *) lpOutBuffer;
224
225 u16 Offset = pInBuf[0]; /*addr */
226 u16 Length = pInBuf[1]; /*length */
227 int i;
228
229 for (i = 0; i < Length; i += 2) {
230 eFusePhysicalReadRegisters(pAd, Offset + i, 2, &pOutBuf[i / 2]);
231 }
232}
233
234/*
235========================================================================
236
237 Routine Description:
238
239 Arguments:
240
241 Return Value:
242
243 Note:
244
245========================================================================
246*/
247int set_eFuseGetFreeBlockCount_Proc(struct rt_rtmp_adapter *pAd, char *arg)
248{
249 u16 i;
250 u16 LogicalAddress;
251 u16 efusefreenum = 0;
252 if (!pAd->bUseEfuse)
253 return FALSE;
254 for (i = EFUSE_USAGE_MAP_START; i <= EFUSE_USAGE_MAP_END; i += 2) {
255 eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
256 if ((LogicalAddress & 0xff) == 0) {
257 efusefreenum = (u8)(EFUSE_USAGE_MAP_END - i + 1);
258 break;
259 } else if (((LogicalAddress >> 8) & 0xff) == 0) {
260 efusefreenum = (u8)(EFUSE_USAGE_MAP_END - i);
261 break;
262 }
263
264 if (i == EFUSE_USAGE_MAP_END)
265 efusefreenum = 0;
266 }
267 printk(KERN_DEBUG "efuseFreeNumber is %d\n", efusefreenum);
268 return TRUE;
269}
270
271int set_eFusedump_Proc(struct rt_rtmp_adapter *pAd, char *arg)
272{
273 u16 InBuf[3];
274 int i = 0;
275 if (!pAd->bUseEfuse)
276 return FALSE;
277
278 printk(KERN_DEBUG "Block 0: ");
279
280 for (i = 0; i < EFUSE_USAGE_MAP_END / 2; i++) {
281 InBuf[0] = 2 * i;
282 InBuf[1] = 2;
283 InBuf[2] = 0x0;
284
285 eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
286 if (i && i % 4 == 0) {
287 printk(KERN_CONT "\n");
288 printk(KERN_DEBUG "Block %x:", i / 8);
289 }
290 printk(KERN_CONT "%04x ", InBuf[2]);
291 }
292 printk(KERN_CONT "\n");
293
294 return TRUE;
295}
296
297int rtmp_ee_efuse_read16(struct rt_rtmp_adapter *pAd,
298 u16 Offset, u16 * pValue)
299{
300 eFuseReadRegisters(pAd, Offset, 2, pValue);
301 return (*pValue);
302}
303
304int RtmpEfuseSupportCheck(struct rt_rtmp_adapter *pAd)
305{
306 u16 value;
307
308 if (IS_RT30xx(pAd)) {
309 eFusePhysicalReadRegisters(pAd, EFUSE_TAG, 2, &value);
310 pAd->EFuseTag = (value & 0xff);
311 }
312 return 0;
313}
314
315void eFuseGetFreeBlockCount(struct rt_rtmp_adapter *pAd, u32 *EfuseFreeBlock)
316{
317 u16 i;
318 u16 LogicalAddress;
319 if (!pAd->bUseEfuse) {
320 DBGPRINT(RT_DEBUG_TRACE,
321 ("eFuseGetFreeBlockCount Only supports efuse Mode\n"));
322 return;
323 }
324 for (i = EFUSE_USAGE_MAP_START; i <= EFUSE_USAGE_MAP_END; i += 2) {
325 eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
326 if ((LogicalAddress & 0xff) == 0) {
327 *EfuseFreeBlock = (u8)(EFUSE_USAGE_MAP_END - i + 1);
328 break;
329 } else if (((LogicalAddress >> 8) & 0xff) == 0) {
330 *EfuseFreeBlock = (u8)(EFUSE_USAGE_MAP_END - i);
331 break;
332 }
333
334 if (i == EFUSE_USAGE_MAP_END)
335 *EfuseFreeBlock = 0;
336 }
337 DBGPRINT(RT_DEBUG_TRACE,
338 ("eFuseGetFreeBlockCount is 0x%x\n", *EfuseFreeBlock));
339}
340
341int eFuse_init(struct rt_rtmp_adapter *pAd)
342{
343 u32 EfuseFreeBlock = 0;
344 DBGPRINT(RT_DEBUG_ERROR,
345 ("NVM is Efuse and its size =%x[%x-%x] \n",
346 EFUSE_USAGE_MAP_SIZE, EFUSE_USAGE_MAP_START,
347 EFUSE_USAGE_MAP_END));
348 eFuseGetFreeBlockCount(pAd, &EfuseFreeBlock);
349
350 return 0;
351}
diff --git a/drivers/staging/rt2860/common/ee_prom.c b/drivers/staging/rt2860/common/ee_prom.c
deleted file mode 100644
index 2083740a844..00000000000
--- a/drivers/staging/rt2860/common/ee_prom.c
+++ /dev/null
@@ -1,197 +0,0 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 ee_prom.c
29
30 Abstract:
31 Miniport generic portion header file
32
33 Revision History:
34 Who When What
35 -------- ---------- ----------------------------------------------
36*/
37
38#include "../rt_config.h"
39
40/* IRQL = PASSIVE_LEVEL */
41static inline void RaiseClock(struct rt_rtmp_adapter *pAd, u32 * x)
42{
43 *x = *x | EESK;
44 RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x);
45 RTMPusecDelay(1); /* Max frequency = 1MHz in Spec. definition */
46}
47
48/* IRQL = PASSIVE_LEVEL */
49static inline void LowerClock(struct rt_rtmp_adapter *pAd, u32 * x)
50{
51 *x = *x & ~EESK;
52 RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x);
53 RTMPusecDelay(1);
54}
55
56/* IRQL = PASSIVE_LEVEL */
57static inline u16 ShiftInBits(struct rt_rtmp_adapter *pAd)
58{
59 u32 x, i;
60 u16 data = 0;
61
62 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
63
64 x &= ~(EEDO | EEDI);
65
66 for (i = 0; i < 16; i++) {
67 data = data << 1;
68 RaiseClock(pAd, &x);
69
70 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
71 LowerClock(pAd, &x); /*prevent read failed */
72
73 x &= ~(EEDI);
74 if (x & EEDO)
75 data |= 1;
76 }
77
78 return data;
79}
80
81/* IRQL = PASSIVE_LEVEL */
82static inline void ShiftOutBits(struct rt_rtmp_adapter *pAd,
83 u16 data, u16 count)
84{
85 u32 x, mask;
86
87 mask = 0x01 << (count - 1);
88 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
89
90 x &= ~(EEDO | EEDI);
91
92 do {
93 x &= ~EEDI;
94 if (data & mask)
95 x |= EEDI;
96
97 RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
98
99 RaiseClock(pAd, &x);
100 LowerClock(pAd, &x);
101
102 mask = mask >> 1;
103 } while (mask);
104
105 x &= ~EEDI;
106 RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
107}
108
109/* IRQL = PASSIVE_LEVEL */
110static inline void EEpromCleanup(struct rt_rtmp_adapter *pAd)
111{
112 u32 x;
113
114 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
115
116 x &= ~(EECS | EEDI);
117 RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
118
119 RaiseClock(pAd, &x);
120 LowerClock(pAd, &x);
121}
122
123static inline void EWEN(struct rt_rtmp_adapter *pAd)
124{
125 u32 x;
126
127 /* reset bits and set EECS */
128 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
129 x &= ~(EEDI | EEDO | EESK);
130 x |= EECS;
131 RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
132
133 /* kick a pulse */
134 RaiseClock(pAd, &x);
135 LowerClock(pAd, &x);
136
137 /* output the read_opcode and six pulse in that order */
138 ShiftOutBits(pAd, EEPROM_EWEN_OPCODE, 5);
139 ShiftOutBits(pAd, 0, 6);
140
141 EEpromCleanup(pAd);
142}
143
144static inline void EWDS(struct rt_rtmp_adapter *pAd)
145{
146 u32 x;
147
148 /* reset bits and set EECS */
149 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
150 x &= ~(EEDI | EEDO | EESK);
151 x |= EECS;
152 RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
153
154 /* kick a pulse */
155 RaiseClock(pAd, &x);
156 LowerClock(pAd, &x);
157
158 /* output the read_opcode and six pulse in that order */
159 ShiftOutBits(pAd, EEPROM_EWDS_OPCODE, 5);
160 ShiftOutBits(pAd, 0, 6);
161
162 EEpromCleanup(pAd);
163}
164
165/* IRQL = PASSIVE_LEVEL */
166int rtmp_ee_prom_read16(struct rt_rtmp_adapter *pAd,
167 u16 Offset, u16 * pValue)
168{
169 u32 x;
170 u16 data;
171
172 Offset /= 2;
173 /* reset bits and set EECS */
174 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
175 x &= ~(EEDI | EEDO | EESK);
176 x |= EECS;
177 RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
178
179 /* patch can not access e-Fuse issue */
180 if (!(IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))) {
181 /* kick a pulse */
182 RaiseClock(pAd, &x);
183 LowerClock(pAd, &x);
184 }
185 /* output the read_opcode and register number in that order */
186 ShiftOutBits(pAd, EEPROM_READ_OPCODE, 3);
187 ShiftOutBits(pAd, Offset, pAd->EEPROMAddressNum);
188
189 /* Now read the data (16 bits) in from the selected EEPROM word */
190 data = ShiftInBits(pAd);
191
192 EEpromCleanup(pAd);
193
194 *pValue = data;
195
196 return NDIS_STATUS_SUCCESS;
197}
diff --git a/drivers/staging/rt2860/common/eeprom.c b/drivers/staging/rt2860/common/eeprom.c
deleted file mode 100644
index 94670076d32..00000000000
--- a/drivers/staging/rt2860/common/eeprom.c
+++ /dev/null
@@ -1,91 +0,0 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 eeprom.c
29
30 Abstract:
31
32 Revision History:
33 Who When What
34 -------- ---------- ----------------------------------------------
35 Name Date Modification logs
36*/
37#include "../rt_config.h"
38
39int RtmpChipOpsEepromHook(struct rt_rtmp_adapter *pAd, int infType)
40{
41 struct rt_rtmp_chip_op *pChipOps = &pAd->chipOps;
42#ifdef RT30xx
43#ifdef RTMP_EFUSE_SUPPORT
44 u32 eFuseCtrl, MacCsr0;
45 int index;
46
47 index = 0;
48 do {
49 RTMP_IO_READ32(pAd, MAC_CSR0, &MacCsr0);
50 pAd->MACVersion = MacCsr0;
51
52 if ((pAd->MACVersion != 0x00)
53 && (pAd->MACVersion != 0xFFFFFFFF))
54 break;
55
56 RTMPusecDelay(10);
57 } while (index++ < 100);
58
59 pAd->bUseEfuse = FALSE;
60 RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrl);
61 pAd->bUseEfuse = ((eFuseCtrl & 0x80000000) == 0x80000000) ? 1 : 0;
62 if (pAd->bUseEfuse) {
63 pChipOps->eeinit = eFuse_init;
64 pChipOps->eeread = rtmp_ee_efuse_read16;
65 return 0;
66 } else
67 DBGPRINT(RT_DEBUG_TRACE, ("NVM is EEPROM\n"));
68#endif /* RTMP_EFUSE_SUPPORT // */
69#endif /* RT30xx // */
70
71 switch (infType) {
72#ifdef RTMP_PCI_SUPPORT
73 case RTMP_DEV_INF_PCI:
74 pChipOps->eeinit = NULL;
75 pChipOps->eeread = rtmp_ee_prom_read16;
76 break;
77#endif /* RTMP_PCI_SUPPORT // */
78#ifdef RTMP_USB_SUPPORT
79 case RTMP_DEV_INF_USB:
80 pChipOps->eeinit = NULL;
81 pChipOps->eeread = RTUSBReadEEPROM16;
82 break;
83#endif /* RTMP_USB_SUPPORT // */
84
85 default:
86 DBGPRINT(RT_DEBUG_ERROR, ("RtmpChipOpsEepromHook() failed!\n"));
87 break;
88 }
89
90 return 0;
91}
diff --git a/drivers/staging/rt2860/common/mlme.c b/drivers/staging/rt2860/common/mlme.c
deleted file mode 100644
index e48eac0f3a2..00000000000
--- a/drivers/staging/rt2860/common/mlme.c
+++ /dev/null
@@ -1,6068 +0,0 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 mlme.c
29
30 Abstract:
31
32 Revision History:
33 Who When What
34 -------- ---------- ----------------------------------------------
35 John Chang 2004-08-25 Modify from RT2500 code base
36 John Chang 2004-09-06 modified for RT2600
37*/
38
39#include "../rt_config.h"
40#include <stdarg.h>
41#include <linux/kernel.h>
42
43u8 CISCO_OUI[] = { 0x00, 0x40, 0x96 };
44
45u8 WPA_OUI[] = { 0x00, 0x50, 0xf2, 0x01 };
46u8 RSN_OUI[] = { 0x00, 0x0f, 0xac };
47u8 WME_INFO_ELEM[] = { 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01 };
48u8 WME_PARM_ELEM[] = { 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01 };
49u8 Ccx2QosInfo[] = { 0x00, 0x40, 0x96, 0x04 };
50u8 RALINK_OUI[] = { 0x00, 0x0c, 0x43 };
51u8 BROADCOM_OUI[] = { 0x00, 0x90, 0x4c };
52u8 WPS_OUI[] = { 0x00, 0x50, 0xf2, 0x04 };
53u8 PRE_N_HT_OUI[] = { 0x00, 0x90, 0x4c };
54
55u8 RateSwitchTable[] = {
56/* Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */
57 0x11, 0x00, 0, 0, 0, /* Initial used item after association */
58 0x00, 0x00, 0, 40, 101,
59 0x01, 0x00, 1, 40, 50,
60 0x02, 0x00, 2, 35, 45,
61 0x03, 0x00, 3, 20, 45,
62 0x04, 0x21, 0, 30, 50,
63 0x05, 0x21, 1, 20, 50,
64 0x06, 0x21, 2, 20, 50,
65 0x07, 0x21, 3, 15, 50,
66 0x08, 0x21, 4, 15, 30,
67 0x09, 0x21, 5, 10, 25,
68 0x0a, 0x21, 6, 8, 25,
69 0x0b, 0x21, 7, 8, 25,
70 0x0c, 0x20, 12, 15, 30,
71 0x0d, 0x20, 13, 8, 20,
72 0x0e, 0x20, 14, 8, 20,
73 0x0f, 0x20, 15, 8, 25,
74 0x10, 0x22, 15, 8, 25,
75 0x11, 0x00, 0, 0, 0,
76 0x12, 0x00, 0, 0, 0,
77 0x13, 0x00, 0, 0, 0,
78 0x14, 0x00, 0, 0, 0,
79 0x15, 0x00, 0, 0, 0,
80 0x16, 0x00, 0, 0, 0,
81 0x17, 0x00, 0, 0, 0,
82 0x18, 0x00, 0, 0, 0,
83 0x19, 0x00, 0, 0, 0,
84 0x1a, 0x00, 0, 0, 0,
85 0x1b, 0x00, 0, 0, 0,
86 0x1c, 0x00, 0, 0, 0,
87 0x1d, 0x00, 0, 0, 0,
88 0x1e, 0x00, 0, 0, 0,
89 0x1f, 0x00, 0, 0, 0,
90};
91
92u8 RateSwitchTable11B[] = {
93/* Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */
94 0x04, 0x03, 0, 0, 0, /* Initial used item after association */
95 0x00, 0x00, 0, 40, 101,
96 0x01, 0x00, 1, 40, 50,
97 0x02, 0x00, 2, 35, 45,
98 0x03, 0x00, 3, 20, 45,
99};
100
101u8 RateSwitchTable11BG[] = {
102/* Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */
103 0x0a, 0x00, 0, 0, 0, /* Initial used item after association */
104 0x00, 0x00, 0, 40, 101,
105 0x01, 0x00, 1, 40, 50,
106 0x02, 0x00, 2, 35, 45,
107 0x03, 0x00, 3, 20, 45,
108 0x04, 0x10, 2, 20, 35,
109 0x05, 0x10, 3, 16, 35,
110 0x06, 0x10, 4, 10, 25,
111 0x07, 0x10, 5, 16, 25,
112 0x08, 0x10, 6, 10, 25,
113 0x09, 0x10, 7, 10, 13,
114};
115
116u8 RateSwitchTable11G[] = {
117/* Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */
118 0x08, 0x00, 0, 0, 0, /* Initial used item after association */
119 0x00, 0x10, 0, 20, 101,
120 0x01, 0x10, 1, 20, 35,
121 0x02, 0x10, 2, 20, 35,
122 0x03, 0x10, 3, 16, 35,
123 0x04, 0x10, 4, 10, 25,
124 0x05, 0x10, 5, 16, 25,
125 0x06, 0x10, 6, 10, 25,
126 0x07, 0x10, 7, 10, 13,
127};
128
129u8 RateSwitchTable11N1S[] = {
130/* Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */
131 0x0c, 0x0a, 0, 0, 0, /* Initial used item after association */
132 0x00, 0x00, 0, 40, 101,
133 0x01, 0x00, 1, 40, 50,
134 0x02, 0x00, 2, 25, 45,
135 0x03, 0x21, 0, 20, 35,
136 0x04, 0x21, 1, 20, 35,
137 0x05, 0x21, 2, 20, 35,
138 0x06, 0x21, 3, 15, 35,
139 0x07, 0x21, 4, 15, 30,
140 0x08, 0x21, 5, 10, 25,
141 0x09, 0x21, 6, 8, 14,
142 0x0a, 0x21, 7, 8, 14,
143 0x0b, 0x23, 7, 8, 14,
144};
145
146u8 RateSwitchTable11N2S[] = {
147/* Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */
148 0x0e, 0x0c, 0, 0, 0, /* Initial used item after association */
149 0x00, 0x00, 0, 40, 101,
150 0x01, 0x00, 1, 40, 50,
151 0x02, 0x00, 2, 25, 45,
152 0x03, 0x21, 0, 20, 35,
153 0x04, 0x21, 1, 20, 35,
154 0x05, 0x21, 2, 20, 35,
155 0x06, 0x21, 3, 15, 35,
156 0x07, 0x21, 4, 15, 30,
157 0x08, 0x20, 11, 15, 30,
158 0x09, 0x20, 12, 15, 30,
159 0x0a, 0x20, 13, 8, 20,
160 0x0b, 0x20, 14, 8, 20,
161 0x0c, 0x20, 15, 8, 25,
162 0x0d, 0x22, 15, 8, 15,
163};
164
165u8 RateSwitchTable11N3S[] = {
166/* Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */
167 0x0b, 0x00, 0, 0, 0, /* 0x0a, 0x00, 0, 0, 0, // Initial used item after association */
168 0x00, 0x21, 0, 30, 101,
169 0x01, 0x21, 1, 20, 50,
170 0x02, 0x21, 2, 20, 50,
171 0x03, 0x21, 3, 15, 50,
172 0x04, 0x21, 4, 15, 30,
173 0x05, 0x20, 11, 15, 30, /* Required by System-Alan @ 20080812 */
174 0x06, 0x20, 12, 15, 30, /* 0x05, 0x20, 12, 15, 30, */
175 0x07, 0x20, 13, 8, 20, /* 0x06, 0x20, 13, 8, 20, */
176 0x08, 0x20, 14, 8, 20, /* 0x07, 0x20, 14, 8, 20, */
177 0x09, 0x20, 15, 8, 25, /* 0x08, 0x20, 15, 8, 25, */
178 0x0a, 0x22, 15, 8, 25, /* 0x09, 0x22, 15, 8, 25, */
179};
180
181u8 RateSwitchTable11N2SForABand[] = {
182/* Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */
183 0x0b, 0x09, 0, 0, 0, /* Initial used item after association */
184 0x00, 0x21, 0, 30, 101,
185 0x01, 0x21, 1, 20, 50,
186 0x02, 0x21, 2, 20, 50,
187 0x03, 0x21, 3, 15, 50,
188 0x04, 0x21, 4, 15, 30,
189 0x05, 0x21, 5, 15, 30,
190 0x06, 0x20, 12, 15, 30,
191 0x07, 0x20, 13, 8, 20,
192 0x08, 0x20, 14, 8, 20,
193 0x09, 0x20, 15, 8, 25,
194 0x0a, 0x22, 15, 8, 25,
195};
196
197u8 RateSwitchTable11N3SForABand[] = { /* 3*3 */
198/* Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */
199 0x0b, 0x09, 0, 0, 0, /* Initial used item after association */
200 0x00, 0x21, 0, 30, 101,
201 0x01, 0x21, 1, 20, 50,
202 0x02, 0x21, 2, 20, 50,
203 0x03, 0x21, 3, 15, 50,
204 0x04, 0x21, 4, 15, 30,
205 0x05, 0x21, 5, 15, 30,
206 0x06, 0x20, 12, 15, 30,
207 0x07, 0x20, 13, 8, 20,
208 0x08, 0x20, 14, 8, 20,
209 0x09, 0x20, 15, 8, 25,
210 0x0a, 0x22, 15, 8, 25,
211};
212
213u8 RateSwitchTable11BGN1S[] = {
214/* Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */
215 0x0c, 0x0a, 0, 0, 0, /* Initial used item after association */
216 0x00, 0x00, 0, 40, 101,
217 0x01, 0x00, 1, 40, 50,
218 0x02, 0x00, 2, 25, 45,
219 0x03, 0x21, 0, 20, 35,
220 0x04, 0x21, 1, 20, 35,
221 0x05, 0x21, 2, 20, 35,
222 0x06, 0x21, 3, 15, 35,
223 0x07, 0x21, 4, 15, 30,
224 0x08, 0x21, 5, 10, 25,
225 0x09, 0x21, 6, 8, 14,
226 0x0a, 0x21, 7, 8, 14,
227 0x0b, 0x23, 7, 8, 14,
228};
229
230u8 RateSwitchTable11BGN2S[] = {
231/* Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */
232 0x0e, 0x0c, 0, 0, 0, /* Initial used item after association */
233 0x00, 0x00, 0, 40, 101,
234 0x01, 0x00, 1, 40, 50,
235 0x02, 0x00, 2, 25, 45,
236 0x03, 0x21, 0, 20, 35,
237 0x04, 0x21, 1, 20, 35,
238 0x05, 0x21, 2, 20, 35,
239 0x06, 0x21, 3, 15, 35,
240 0x07, 0x21, 4, 15, 30,
241 0x08, 0x20, 11, 15, 30,
242 0x09, 0x20, 12, 15, 30,
243 0x0a, 0x20, 13, 8, 20,
244 0x0b, 0x20, 14, 8, 20,
245 0x0c, 0x20, 15, 8, 25,
246 0x0d, 0x22, 15, 8, 15,
247};
248
249u8 RateSwitchTable11BGN3S[] = { /* 3*3 */
250/* Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */
251 0x0a, 0x00, 0, 0, 0, /* Initial used item after association */
252 0x00, 0x21, 0, 30, 101, /*50 */
253 0x01, 0x21, 1, 20, 50,
254 0x02, 0x21, 2, 20, 50,
255 0x03, 0x21, 3, 20, 50,
256 0x04, 0x21, 4, 15, 50,
257 0x05, 0x20, 20, 15, 30,
258 0x06, 0x20, 21, 8, 20,
259 0x07, 0x20, 22, 8, 20,
260 0x08, 0x20, 23, 8, 25,
261 0x09, 0x22, 23, 8, 25,
262};
263
264u8 RateSwitchTable11BGN2SForABand[] = {
265/* Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */
266 0x0b, 0x09, 0, 0, 0, /* Initial used item after association */
267 0x00, 0x21, 0, 30, 101, /*50 */
268 0x01, 0x21, 1, 20, 50,
269 0x02, 0x21, 2, 20, 50,
270 0x03, 0x21, 3, 15, 50,
271 0x04, 0x21, 4, 15, 30,
272 0x05, 0x21, 5, 15, 30,
273 0x06, 0x20, 12, 15, 30,
274 0x07, 0x20, 13, 8, 20,
275 0x08, 0x20, 14, 8, 20,
276 0x09, 0x20, 15, 8, 25,
277 0x0a, 0x22, 15, 8, 25,
278};
279
280u8 RateSwitchTable11BGN3SForABand[] = { /* 3*3 */
281/* Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */
282 0x0c, 0x09, 0, 0, 0, /* Initial used item after association */
283 0x00, 0x21, 0, 30, 101, /*50 */
284 0x01, 0x21, 1, 20, 50,
285 0x02, 0x21, 2, 20, 50,
286 0x03, 0x21, 3, 15, 50,
287 0x04, 0x21, 4, 15, 30,
288 0x05, 0x21, 5, 15, 30,
289 0x06, 0x21, 12, 15, 30,
290 0x07, 0x20, 20, 15, 30,
291 0x08, 0x20, 21, 8, 20,
292 0x09, 0x20, 22, 8, 20,
293 0x0a, 0x20, 23, 8, 25,
294 0x0b, 0x22, 23, 8, 25,
295};
296
297extern u8 OfdmRateToRxwiMCS[];
298/* since RT61 has better RX sensibility, we have to limit TX ACK rate not to exceed our normal data TX rate. */
299/* otherwise the WLAN peer may not be able to receive the ACK thus downgrade its data TX rate */
300unsigned long BasicRateMask[12] =
301 { 0xfffff001 /* 1-Mbps */ , 0xfffff003 /* 2 Mbps */ , 0xfffff007 /* 5.5 */ ,
3020xfffff00f /* 11 */ ,
303 0xfffff01f /* 6 */ , 0xfffff03f /* 9 */ , 0xfffff07f /* 12 */ ,
304 0xfffff0ff /* 18 */ ,
305 0xfffff1ff /* 24 */ , 0xfffff3ff /* 36 */ , 0xfffff7ff /* 48 */ ,
306 0xffffffff /* 54 */
307};
308
309u8 BROADCAST_ADDR[MAC_ADDR_LEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
310u8 ZERO_MAC_ADDR[MAC_ADDR_LEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
311
312/* e.g. RssiSafeLevelForTxRate[RATE_36]" means if the current RSSI is greater than */
313/* this value, then it's quaranteed capable of operating in 36 mbps TX rate in */
314/* clean environment. */
315/* TxRate: 1 2 5.5 11 6 9 12 18 24 36 48 54 72 100 */
316char RssiSafeLevelForTxRate[] =
317 { -92, -91, -90, -87, -88, -86, -85, -83, -81, -78, -72, -71, -40, -40 };
318
319u8 RateIdToMbps[] = { 1, 2, 5, 11, 6, 9, 12, 18, 24, 36, 48, 54, 72, 100 };
320u16 RateIdTo500Kbps[] =
321 { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108, 144, 200 };
322
323u8 SsidIe = IE_SSID;
324u8 SupRateIe = IE_SUPP_RATES;
325u8 ExtRateIe = IE_EXT_SUPP_RATES;
326u8 HtCapIe = IE_HT_CAP;
327u8 AddHtInfoIe = IE_ADD_HT;
328u8 NewExtChanIe = IE_SECONDARY_CH_OFFSET;
329u8 ErpIe = IE_ERP;
330u8 DsIe = IE_DS_PARM;
331u8 TimIe = IE_TIM;
332u8 WpaIe = IE_WPA;
333u8 Wpa2Ie = IE_WPA2;
334u8 IbssIe = IE_IBSS_PARM;
335
336extern u8 WPA_OUI[];
337
338u8 SES_OUI[] = { 0x00, 0x90, 0x4c };
339
340u8 ZeroSsid[32] =
341 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3420x00, 0x00, 0x00, 0x00,
343 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
344 0x00, 0x00, 0x00, 0x00
345};
346
347/*
348 ==========================================================================
349 Description:
350 initialize the MLME task and its data structure (queue, spinlock,
351 timer, state machines).
352
353 IRQL = PASSIVE_LEVEL
354
355 Return:
356 always return NDIS_STATUS_SUCCESS
357
358 ==========================================================================
359*/
360int MlmeInit(struct rt_rtmp_adapter *pAd)
361{
362 int Status = NDIS_STATUS_SUCCESS;
363
364 DBGPRINT(RT_DEBUG_TRACE, ("--> MLME Initialize\n"));
365
366 do {
367 Status = MlmeQueueInit(&pAd->Mlme.Queue);
368 if (Status != NDIS_STATUS_SUCCESS)
369 break;
370
371 pAd->Mlme.bRunning = FALSE;
372 NdisAllocateSpinLock(&pAd->Mlme.TaskLock);
373
374 {
375 BssTableInit(&pAd->ScanTab);
376
377 /* init STA state machines */
378 AssocStateMachineInit(pAd, &pAd->Mlme.AssocMachine,
379 pAd->Mlme.AssocFunc);
380 AuthStateMachineInit(pAd, &pAd->Mlme.AuthMachine,
381 pAd->Mlme.AuthFunc);
382 AuthRspStateMachineInit(pAd, &pAd->Mlme.AuthRspMachine,
383 pAd->Mlme.AuthRspFunc);
384 SyncStateMachineInit(pAd, &pAd->Mlme.SyncMachine,
385 pAd->Mlme.SyncFunc);
386
387 /* Since we are using switch/case to implement it, the init is different from the above */
388 /* state machine init */
389 MlmeCntlInit(pAd, &pAd->Mlme.CntlMachine, NULL);
390 }
391
392 WpaStateMachineInit(pAd, &pAd->Mlme.WpaMachine,
393 pAd->Mlme.WpaFunc);
394
395 ActionStateMachineInit(pAd, &pAd->Mlme.ActMachine,
396 pAd->Mlme.ActFunc);
397
398 /* Init mlme periodic timer */
399 RTMPInitTimer(pAd, &pAd->Mlme.PeriodicTimer,
400 GET_TIMER_FUNCTION(MlmePeriodicExec), pAd, TRUE);
401
402 /* Set mlme periodic timer */
403 RTMPSetTimer(&pAd->Mlme.PeriodicTimer, MLME_TASK_EXEC_INTV);
404
405 /* software-based RX Antenna diversity */
406 RTMPInitTimer(pAd, &pAd->Mlme.RxAntEvalTimer,
407 GET_TIMER_FUNCTION(AsicRxAntEvalTimeout), pAd,
408 FALSE);
409
410 {
411#ifdef RTMP_PCI_SUPPORT
412 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) {
413 /* only PCIe cards need these two timers */
414 RTMPInitTimer(pAd, &pAd->Mlme.PsPollTimer,
415 GET_TIMER_FUNCTION
416 (PsPollWakeExec), pAd, FALSE);
417 RTMPInitTimer(pAd, &pAd->Mlme.RadioOnOffTimer,
418 GET_TIMER_FUNCTION(RadioOnExec),
419 pAd, FALSE);
420 }
421#endif /* RTMP_PCI_SUPPORT // */
422
423 RTMPInitTimer(pAd, &pAd->Mlme.LinkDownTimer,
424 GET_TIMER_FUNCTION(LinkDownExec), pAd,
425 FALSE);
426
427#ifdef RTMP_MAC_USB
428 RTMPInitTimer(pAd, &pAd->Mlme.AutoWakeupTimer,
429 GET_TIMER_FUNCTION
430 (RtmpUsbStaAsicForceWakeupTimeout), pAd,
431 FALSE);
432 pAd->Mlme.AutoWakeupTimerRunning = FALSE;
433#endif /* RTMP_MAC_USB // */
434 }
435
436 } while (FALSE);
437
438 DBGPRINT(RT_DEBUG_TRACE, ("<-- MLME Initialize\n"));
439
440 return Status;
441}
442
443/*
444 ==========================================================================
445 Description:
446 main loop of the MLME
447 Pre:
448 Mlme has to be initialized, and there are something inside the queue
449 Note:
450 This function is invoked from MPSetInformation and MPReceive;
451 This task guarantee only one MlmeHandler will run.
452
453 IRQL = DISPATCH_LEVEL
454
455 ==========================================================================
456 */
457void MlmeHandler(struct rt_rtmp_adapter *pAd)
458{
459 struct rt_mlme_queue_elem *Elem = NULL;
460
461 /* Only accept MLME and Frame from peer side, no other (control/data) frame should */
462 /* get into this state machine */
463
464 NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
465 if (pAd->Mlme.bRunning) {
466 NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
467 return;
468 } else {
469 pAd->Mlme.bRunning = TRUE;
470 }
471 NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
472
473 while (!MlmeQueueEmpty(&pAd->Mlme.Queue)) {
474 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_MLME_RESET_IN_PROGRESS) ||
475 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS) ||
476 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) {
477 DBGPRINT(RT_DEBUG_TRACE,
478 ("Device Halted or Removed or MlmeRest, exit MlmeHandler! (queue num = %ld)\n",
479 pAd->Mlme.Queue.Num));
480 break;
481 }
482 /*From message type, determine which state machine I should drive */
483 if (MlmeDequeue(&pAd->Mlme.Queue, &Elem)) {
484#ifdef RTMP_MAC_USB
485 if (Elem->MsgType == MT2_RESET_CONF) {
486 DBGPRINT_RAW(RT_DEBUG_TRACE,
487 ("reset MLME state machine!\n"));
488 MlmeRestartStateMachine(pAd);
489 Elem->Occupied = FALSE;
490 Elem->MsgLen = 0;
491 continue;
492 }
493#endif /* RTMP_MAC_USB // */
494
495 /* if dequeue success */
496 switch (Elem->Machine) {
497 /* STA state machines */
498 case ASSOC_STATE_MACHINE:
499 StateMachinePerformAction(pAd,
500 &pAd->Mlme.
501 AssocMachine, Elem);
502 break;
503 case AUTH_STATE_MACHINE:
504 StateMachinePerformAction(pAd,
505 &pAd->Mlme.
506 AuthMachine, Elem);
507 break;
508 case AUTH_RSP_STATE_MACHINE:
509 StateMachinePerformAction(pAd,
510 &pAd->Mlme.
511 AuthRspMachine, Elem);
512 break;
513 case SYNC_STATE_MACHINE:
514 StateMachinePerformAction(pAd,
515 &pAd->Mlme.
516 SyncMachine, Elem);
517 break;
518 case MLME_CNTL_STATE_MACHINE:
519 MlmeCntlMachinePerformAction(pAd,
520 &pAd->Mlme.
521 CntlMachine, Elem);
522 break;
523 case WPA_PSK_STATE_MACHINE:
524 StateMachinePerformAction(pAd,
525 &pAd->Mlme.
526 WpaPskMachine, Elem);
527 break;
528
529 case ACTION_STATE_MACHINE:
530 StateMachinePerformAction(pAd,
531 &pAd->Mlme.ActMachine,
532 Elem);
533 break;
534
535 case WPA_STATE_MACHINE:
536 StateMachinePerformAction(pAd,
537 &pAd->Mlme.WpaMachine,
538 Elem);
539 break;
540
541 default:
542 DBGPRINT(RT_DEBUG_TRACE,
543 ("ERROR: Illegal machine %ld in MlmeHandler()\n",
544 Elem->Machine));
545 break;
546 } /* end of switch */
547
548 /* free MLME element */
549 Elem->Occupied = FALSE;
550 Elem->MsgLen = 0;
551
552 } else {
553 DBGPRINT_ERR("MlmeHandler: MlmeQueue empty\n");
554 }
555 }
556
557 NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
558 pAd->Mlme.bRunning = FALSE;
559 NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
560}
561
562/*
563 ==========================================================================
564 Description:
565 Destructor of MLME (Destroy queue, state machine, spin lock and timer)
566 Parameters:
567 Adapter - NIC Adapter pointer
568 Post:
569 The MLME task will no longer work properly
570
571 IRQL = PASSIVE_LEVEL
572
573 ==========================================================================
574 */
575void MlmeHalt(struct rt_rtmp_adapter *pAd)
576{
577 BOOLEAN Cancelled;
578
579 DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeHalt\n"));
580
581 if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) {
582 /* disable BEACON generation and other BEACON related hardware timers */
583 AsicDisableSync(pAd);
584 }
585
586 {
587 /* Cancel pending timers */
588 RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &Cancelled);
589 RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &Cancelled);
590 RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled);
591 RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &Cancelled);
592 RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &Cancelled);
593 RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled);
594
595#ifdef RTMP_MAC_PCI
596 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)
597 && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)) {
598 RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
599 RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer, &Cancelled);
600 }
601#endif /* RTMP_MAC_PCI // */
602
603 RTMPCancelTimer(&pAd->Mlme.LinkDownTimer, &Cancelled);
604
605#ifdef RTMP_MAC_USB
606 RTMPCancelTimer(&pAd->Mlme.AutoWakeupTimer, &Cancelled);
607#endif /* RTMP_MAC_USB // */
608 }
609
610 RTMPCancelTimer(&pAd->Mlme.PeriodicTimer, &Cancelled);
611 RTMPCancelTimer(&pAd->Mlme.RxAntEvalTimer, &Cancelled);
612
613 if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) {
614 struct rt_rtmp_chip_op *pChipOps = &pAd->chipOps;
615
616 /* Set LED */
617 RTMPSetLED(pAd, LED_HALT);
618 RTMPSetSignalLED(pAd, -100); /* Force signal strength Led to be turned off, firmware is not done it. */
619#ifdef RTMP_MAC_USB
620 {
621 LED_CFG_STRUC LedCfg;
622 RTMP_IO_READ32(pAd, LED_CFG, &LedCfg.word);
623 LedCfg.field.LedPolar = 0;
624 LedCfg.field.RLedMode = 0;
625 LedCfg.field.GLedMode = 0;
626 LedCfg.field.YLedMode = 0;
627 RTMP_IO_WRITE32(pAd, LED_CFG, LedCfg.word);
628 }
629#endif /* RTMP_MAC_USB // */
630
631 if (pChipOps->AsicHaltAction)
632 pChipOps->AsicHaltAction(pAd);
633 }
634
635 RTMPusecDelay(5000); /* 5 msec to guarantee Ant Diversity timer canceled */
636
637 MlmeQueueDestroy(&pAd->Mlme.Queue);
638 NdisFreeSpinLock(&pAd->Mlme.TaskLock);
639
640 DBGPRINT(RT_DEBUG_TRACE, ("<== MlmeHalt\n"));
641}
642
643void MlmeResetRalinkCounters(struct rt_rtmp_adapter *pAd)
644{
645 pAd->RalinkCounters.LastOneSecRxOkDataCnt =
646 pAd->RalinkCounters.OneSecRxOkDataCnt;
647 /* clear all OneSecxxx counters. */
648 pAd->RalinkCounters.OneSecBeaconSentCnt = 0;
649 pAd->RalinkCounters.OneSecFalseCCACnt = 0;
650 pAd->RalinkCounters.OneSecRxFcsErrCnt = 0;
651 pAd->RalinkCounters.OneSecRxOkCnt = 0;
652 pAd->RalinkCounters.OneSecTxFailCount = 0;
653 pAd->RalinkCounters.OneSecTxNoRetryOkCount = 0;
654 pAd->RalinkCounters.OneSecTxRetryOkCount = 0;
655 pAd->RalinkCounters.OneSecRxOkDataCnt = 0;
656 pAd->RalinkCounters.OneSecReceivedByteCount = 0;
657 pAd->RalinkCounters.OneSecTransmittedByteCount = 0;
658
659 /* TODO: for debug only. to be removed */
660 pAd->RalinkCounters.OneSecOsTxCount[QID_AC_BE] = 0;
661 pAd->RalinkCounters.OneSecOsTxCount[QID_AC_BK] = 0;
662 pAd->RalinkCounters.OneSecOsTxCount[QID_AC_VI] = 0;
663 pAd->RalinkCounters.OneSecOsTxCount[QID_AC_VO] = 0;
664 pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_BE] = 0;
665 pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_BK] = 0;
666 pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_VI] = 0;
667 pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_VO] = 0;
668 pAd->RalinkCounters.OneSecTxDoneCount = 0;
669 pAd->RalinkCounters.OneSecRxCount = 0;
670 pAd->RalinkCounters.OneSecTxAggregationCount = 0;
671 pAd->RalinkCounters.OneSecRxAggregationCount = 0;
672
673 return;
674}
675
676/*
677 ==========================================================================
678 Description:
679 This routine is executed periodically to -
680 1. Decide if it's a right time to turn on PwrMgmt bit of all
681 outgoiing frames
682 2. Calculate ChannelQuality based on statistics of the last
683 period, so that TX rate won't toggling very frequently between a
684 successful TX and a failed TX.
685 3. If the calculated ChannelQuality indicated current connection not
686 healthy, then a ROAMing attempt is tried here.
687
688 IRQL = DISPATCH_LEVEL
689
690 ==========================================================================
691 */
692#define ADHOC_BEACON_LOST_TIME (8*OS_HZ) /* 8 sec */
693void MlmePeriodicExec(void *SystemSpecific1,
694 void *FunctionContext,
695 void *SystemSpecific2, void *SystemSpecific3)
696{
697 unsigned long TxTotalCnt;
698 struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext;
699
700#ifdef RTMP_MAC_PCI
701 {
702 /* If Hardware controlled Radio enabled, we have to check GPIO pin2 every 2 second. */
703 /* Move code to here, because following code will return when radio is off */
704 if ((pAd->Mlme.PeriodicRound % (MLME_TASK_EXEC_MULTIPLE * 2) ==
705 0) && (pAd->StaCfg.bHardwareRadio == TRUE)
706 && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
707 && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))
708 /*&&(pAd->bPCIclkOff == FALSE) */
709 ) {
710 u32 data = 0;
711
712 /* Read GPIO pin2 as Hardware controlled radio state */
713#ifndef RT3090
714 RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &data);
715#endif /* RT3090 // */
716/*KH(PCIE PS):Added based on Jane<-- */
717#ifdef RT3090
718/* Read GPIO pin2 as Hardware controlled radio state */
719/* We need to Read GPIO if HW said so no mater what advance power saving */
720 if ((pAd->OpMode == OPMODE_STA) && (IDLE_ON(pAd))
721 &&
722 (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))
723 && (pAd->StaCfg.PSControl.field.EnablePSinIdle ==
724 TRUE)) {
725 /* Want to make sure device goes to L0 state before reading register. */
726 RTMPPCIeLinkCtrlValueRestore(pAd, 0);
727 RTMP_IO_FORCE_READ32(pAd, GPIO_CTRL_CFG, &data);
728 RTMPPCIeLinkCtrlSetting(pAd, 3);
729 } else
730 RTMP_IO_FORCE_READ32(pAd, GPIO_CTRL_CFG, &data);
731#endif /* RT3090 // */
732/*KH(PCIE PS):Added based on Jane--> */
733
734 if (data & 0x04) {
735 pAd->StaCfg.bHwRadio = TRUE;
736 } else {
737 pAd->StaCfg.bHwRadio = FALSE;
738 }
739 if (pAd->StaCfg.bRadio !=
740 (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio)) {
741 pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio
742 && pAd->StaCfg.bSwRadio);
743 if (pAd->StaCfg.bRadio == TRUE) {
744 MlmeRadioOn(pAd);
745 /* Update extra information */
746 pAd->ExtraInfo = EXTRA_INFO_CLEAR;
747 } else {
748 MlmeRadioOff(pAd);
749 /* Update extra information */
750 pAd->ExtraInfo = HW_RADIO_OFF;
751 }
752 }
753 }
754 }
755#endif /* RTMP_MAC_PCI // */
756
757 /* Do nothing if the driver is starting halt state. */
758 /* This might happen when timer already been fired before cancel timer with mlmehalt */
759 if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_HALT_IN_PROGRESS |
760 fRTMP_ADAPTER_RADIO_OFF |
761 fRTMP_ADAPTER_RADIO_MEASUREMENT |
762 fRTMP_ADAPTER_RESET_IN_PROGRESS))))
763 return;
764
765 RTMP_MLME_PRE_SANITY_CHECK(pAd);
766
767 {
768 /* Do nothing if monitor mode is on */
769 if (MONITOR_ON(pAd))
770 return;
771
772 if (pAd->Mlme.PeriodicRound & 0x1) {
773 /* This is the fix for wifi 11n extension channel overlapping test case. for 2860D */
774 if (((pAd->MACVersion & 0xffff) == 0x0101) &&
775 (STA_TGN_WIFI_ON(pAd)) &&
776 (pAd->CommonCfg.IOTestParm.bToggle == FALSE))
777 {
778 RTMP_IO_WRITE32(pAd, TXOP_CTRL_CFG, 0x24Bf);
779 pAd->CommonCfg.IOTestParm.bToggle = TRUE;
780 } else if ((STA_TGN_WIFI_ON(pAd)) &&
781 ((pAd->MACVersion & 0xffff) == 0x0101)) {
782 RTMP_IO_WRITE32(pAd, TXOP_CTRL_CFG, 0x243f);
783 pAd->CommonCfg.IOTestParm.bToggle = FALSE;
784 }
785 }
786 }
787
788 pAd->bUpdateBcnCntDone = FALSE;
789
790/* RECBATimerTimeout(SystemSpecific1,FunctionContext,SystemSpecific2,SystemSpecific3); */
791 pAd->Mlme.PeriodicRound++;
792
793#ifdef RTMP_MAC_USB
794 /* execute every 100ms, update the Tx FIFO Cnt for update Tx Rate. */
795 NICUpdateFifoStaCounters(pAd);
796#endif /* RTMP_MAC_USB // */
797
798 /* execute every 500ms */
799 if ((pAd->Mlme.PeriodicRound % 5 == 0)
800 && RTMPAutoRateSwitchCheck(pAd)
801 /*(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)) */ )
802 {
803 /* perform dynamic tx rate switching based on past TX history */
804 {
805 if ((OPSTATUS_TEST_FLAG
806 (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
807 )
808 && (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)))
809 MlmeDynamicTxRateSwitching(pAd);
810 }
811 }
812 /* Normal 1 second Mlme PeriodicExec. */
813 if (pAd->Mlme.PeriodicRound % MLME_TASK_EXEC_MULTIPLE == 0) {
814 pAd->Mlme.OneSecPeriodicRound++;
815
816 /*ORIBATimerTimeout(pAd); */
817
818 /* Media status changed, report to NDIS */
819 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE)) {
820 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE);
821 if (OPSTATUS_TEST_FLAG
822 (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) {
823 pAd->IndicateMediaState =
824 NdisMediaStateConnected;
825 RTMP_IndicateMediaState(pAd);
826
827 } else {
828 pAd->IndicateMediaState =
829 NdisMediaStateDisconnected;
830 RTMP_IndicateMediaState(pAd);
831 }
832 }
833
834 NdisGetSystemUpTime(&pAd->Mlme.Now32);
835
836 /* add the most up-to-date h/w raw counters into software variable, so that */
837 /* the dynamic tuning mechanism below are based on most up-to-date information */
838 NICUpdateRawCounters(pAd);
839
840#ifdef RTMP_MAC_USB
841 RTUSBWatchDog(pAd);
842#endif /* RTMP_MAC_USB // */
843
844 /* Need statistics after read counter. So put after NICUpdateRawCounters */
845 ORIBATimerTimeout(pAd);
846
847 /* if MGMT RING is full more than twice within 1 second, we consider there's */
848 /* a hardware problem stucking the TX path. In this case, try a hardware reset */
849 /* to recover the system */
850 /* if (pAd->RalinkCounters.MgmtRingFullCount >= 2) */
851 /* RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HARDWARE_ERROR); */
852 /* else */
853 /* pAd->RalinkCounters.MgmtRingFullCount = 0; */
854
855 /* The time period for checking antenna is according to traffic */
856 {
857 if (pAd->Mlme.bEnableAutoAntennaCheck) {
858 TxTotalCnt =
859 pAd->RalinkCounters.OneSecTxNoRetryOkCount +
860 pAd->RalinkCounters.OneSecTxRetryOkCount +
861 pAd->RalinkCounters.OneSecTxFailCount;
862
863 /* dynamic adjust antenna evaluation period according to the traffic */
864 if (TxTotalCnt > 50) {
865 if (pAd->Mlme.OneSecPeriodicRound %
866 10 == 0) {
867 AsicEvaluateRxAnt(pAd);
868 }
869 } else {
870 if (pAd->Mlme.OneSecPeriodicRound % 3 ==
871 0) {
872 AsicEvaluateRxAnt(pAd);
873 }
874 }
875 }
876 }
877
878 STAMlmePeriodicExec(pAd);
879
880 MlmeResetRalinkCounters(pAd);
881
882 {
883#ifdef RTMP_MAC_PCI
884 if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)
885 && (pAd->bPCIclkOff == FALSE))
886#endif /* RTMP_MAC_PCI // */
887 {
888 /* When Adhoc beacon is enabled and RTS/CTS is enabled, there is a chance that hardware MAC FSM will run into a deadlock */
889 /* and sending CTS-to-self over and over. */
890 /* Software Patch Solution: */
891 /* 1. Polling debug state register 0x10F4 every one second. */
892 /* 2. If in 0x10F4 the ((bit29==1) && (bit7==1)) OR ((bit29==1) && (bit5==1)), it means the deadlock has occurred. */
893 /* 3. If the deadlock occurred, reset MAC/BBP by setting 0x1004 to 0x0001 for a while then setting it back to 0x000C again. */
894
895 u32 MacReg = 0;
896
897 RTMP_IO_READ32(pAd, 0x10F4, &MacReg);
898 if (((MacReg & 0x20000000) && (MacReg & 0x80))
899 || ((MacReg & 0x20000000)
900 && (MacReg & 0x20))) {
901 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x1);
902 RTMPusecDelay(1);
903 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0xC);
904
905 DBGPRINT(RT_DEBUG_WARN,
906 ("Warning, MAC specific condition occurs \n"));
907 }
908 }
909 }
910
911 RTMP_MLME_HANDLER(pAd);
912 }
913
914 pAd->bUpdateBcnCntDone = FALSE;
915}
916
917/*
918 ==========================================================================
919 Validate SSID for connection try and rescan purpose
920 Valid SSID will have visible chars only.
921 The valid length is from 0 to 32.
922 IRQL = DISPATCH_LEVEL
923 ==========================================================================
924 */
925BOOLEAN MlmeValidateSSID(u8 *pSsid, u8 SsidLen)
926{
927 int index;
928
929 if (SsidLen > MAX_LEN_OF_SSID)
930 return (FALSE);
931
932 /* Check each character value */
933 for (index = 0; index < SsidLen; index++) {
934 if (pSsid[index] < 0x20)
935 return (FALSE);
936 }
937
938 /* All checked */
939 return (TRUE);
940}
941
942void MlmeSelectTxRateTable(struct rt_rtmp_adapter *pAd,
943 struct rt_mac_table_entry *pEntry,
944 u8 ** ppTable,
945 u8 *pTableSize, u8 *pInitTxRateIdx)
946{
947 do {
948 /* decide the rate table for tuning */
949 if (pAd->CommonCfg.TxRateTableSize > 0) {
950 *ppTable = RateSwitchTable;
951 *pTableSize = RateSwitchTable[0];
952 *pInitTxRateIdx = RateSwitchTable[1];
953
954 break;
955 }
956
957 if ((pAd->OpMode == OPMODE_STA) && ADHOC_ON(pAd)) {
958 if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) && (pEntry->HTCapability.MCSSet[0] == 0xff) && ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1))) { /* 11N 1S Adhoc */
959 *ppTable = RateSwitchTable11N1S;
960 *pTableSize = RateSwitchTable11N1S[0];
961 *pInitTxRateIdx = RateSwitchTable11N1S[1];
962
963 } else if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) && (pEntry->HTCapability.MCSSet[0] == 0xff) && (pEntry->HTCapability.MCSSet[1] == 0xff) && (pAd->Antenna.field.TxPath == 2)) { /* 11N 2S Adhoc */
964 if (pAd->LatchRfRegs.Channel <= 14) {
965 *ppTable = RateSwitchTable11N2S;
966 *pTableSize = RateSwitchTable11N2S[0];
967 *pInitTxRateIdx =
968 RateSwitchTable11N2S[1];
969 } else {
970 *ppTable = RateSwitchTable11N2SForABand;
971 *pTableSize =
972 RateSwitchTable11N2SForABand[0];
973 *pInitTxRateIdx =
974 RateSwitchTable11N2SForABand[1];
975 }
976
977 } else if ((pEntry->RateLen == 4)
978 && (pEntry->HTCapability.MCSSet[0] == 0)
979 && (pEntry->HTCapability.MCSSet[1] == 0)
980 ) {
981 *ppTable = RateSwitchTable11B;
982 *pTableSize = RateSwitchTable11B[0];
983 *pInitTxRateIdx = RateSwitchTable11B[1];
984
985 } else if (pAd->LatchRfRegs.Channel <= 14) {
986 *ppTable = RateSwitchTable11BG;
987 *pTableSize = RateSwitchTable11BG[0];
988 *pInitTxRateIdx = RateSwitchTable11BG[1];
989
990 } else {
991 *ppTable = RateSwitchTable11G;
992 *pTableSize = RateSwitchTable11G[0];
993 *pInitTxRateIdx = RateSwitchTable11G[1];
994
995 }
996 break;
997 }
998 /*if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 12) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) && */
999 /* ((pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1))) */
1000 if (((pEntry->RateLen == 12) || (pAd->OpMode == OPMODE_STA)) && (pEntry->HTCapability.MCSSet[0] == 0xff) && ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->CommonCfg.TxStream == 1))) { /* 11BGN 1S AP */
1001 *ppTable = RateSwitchTable11BGN1S;
1002 *pTableSize = RateSwitchTable11BGN1S[0];
1003 *pInitTxRateIdx = RateSwitchTable11BGN1S[1];
1004
1005 break;
1006 }
1007 /*else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 12) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) && */
1008 /* (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0xff) && (pAd->Antenna.field.TxPath == 2)) */
1009 if (((pEntry->RateLen == 12) || (pAd->OpMode == OPMODE_STA)) && (pEntry->HTCapability.MCSSet[0] == 0xff) && (pEntry->HTCapability.MCSSet[1] == 0xff) && (pAd->CommonCfg.TxStream == 2)) { /* 11BGN 2S AP */
1010 if (pAd->LatchRfRegs.Channel <= 14) {
1011 *ppTable = RateSwitchTable11BGN2S;
1012 *pTableSize = RateSwitchTable11BGN2S[0];
1013 *pInitTxRateIdx = RateSwitchTable11BGN2S[1];
1014
1015 } else {
1016 *ppTable = RateSwitchTable11BGN2SForABand;
1017 *pTableSize = RateSwitchTable11BGN2SForABand[0];
1018 *pInitTxRateIdx =
1019 RateSwitchTable11BGN2SForABand[1];
1020
1021 }
1022 break;
1023 }
1024 /*else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) && ((pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1))) */
1025 if ((pEntry->HTCapability.MCSSet[0] == 0xff) && ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->CommonCfg.TxStream == 1))) { /* 11N 1S AP */
1026 *ppTable = RateSwitchTable11N1S;
1027 *pTableSize = RateSwitchTable11N1S[0];
1028 *pInitTxRateIdx = RateSwitchTable11N1S[1];
1029
1030 break;
1031 }
1032 /*else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0xff) && (pAd->Antenna.field.TxPath == 2)) */
1033 if ((pEntry->HTCapability.MCSSet[0] == 0xff) && (pEntry->HTCapability.MCSSet[1] == 0xff) && (pAd->CommonCfg.TxStream == 2)) { /* 11N 2S AP */
1034 if (pAd->LatchRfRegs.Channel <= 14) {
1035 *ppTable = RateSwitchTable11N2S;
1036 *pTableSize = RateSwitchTable11N2S[0];
1037 *pInitTxRateIdx = RateSwitchTable11N2S[1];
1038 } else {
1039 *ppTable = RateSwitchTable11N2SForABand;
1040 *pTableSize = RateSwitchTable11N2SForABand[0];
1041 *pInitTxRateIdx =
1042 RateSwitchTable11N2SForABand[1];
1043 }
1044
1045 break;
1046 }
1047 /*else if ((pAd->StaActive.SupRateLen == 4) && (pAd->StaActive.ExtRateLen == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0)) */
1048 if ((pEntry->RateLen == 4 || pAd->CommonCfg.PhyMode == PHY_11B)
1049 /*Iverson mark for Adhoc b mode,sta will use rate 54 Mbps when connect with sta b/g/n mode */
1050 /* && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0) */
1051 ) { /* B only AP */
1052 *ppTable = RateSwitchTable11B;
1053 *pTableSize = RateSwitchTable11B[0];
1054 *pInitTxRateIdx = RateSwitchTable11B[1];
1055
1056 break;
1057 }
1058 /*else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen > 8) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0)) */
1059 if ((pEntry->RateLen > 8)
1060 && (pEntry->HTCapability.MCSSet[0] == 0)
1061 && (pEntry->HTCapability.MCSSet[1] == 0)
1062 ) { /* B/G mixed AP */
1063 *ppTable = RateSwitchTable11BG;
1064 *pTableSize = RateSwitchTable11BG[0];
1065 *pInitTxRateIdx = RateSwitchTable11BG[1];
1066
1067 break;
1068 }
1069 /*else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 8) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0)) */
1070 if ((pEntry->RateLen == 8)
1071 && (pEntry->HTCapability.MCSSet[0] == 0)
1072 && (pEntry->HTCapability.MCSSet[1] == 0)
1073 ) { /* G only AP */
1074 *ppTable = RateSwitchTable11G;
1075 *pTableSize = RateSwitchTable11G[0];
1076 *pInitTxRateIdx = RateSwitchTable11G[1];
1077
1078 break;
1079 }
1080
1081 {
1082 /*else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0)) */
1083 if ((pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)) { /* Legacy mode */
1084 if (pAd->CommonCfg.MaxTxRate <= RATE_11) {
1085 *ppTable = RateSwitchTable11B;
1086 *pTableSize = RateSwitchTable11B[0];
1087 *pInitTxRateIdx = RateSwitchTable11B[1];
1088 } else if ((pAd->CommonCfg.MaxTxRate > RATE_11)
1089 && (pAd->CommonCfg.MinTxRate >
1090 RATE_11)) {
1091 *ppTable = RateSwitchTable11G;
1092 *pTableSize = RateSwitchTable11G[0];
1093 *pInitTxRateIdx = RateSwitchTable11G[1];
1094
1095 } else {
1096 *ppTable = RateSwitchTable11BG;
1097 *pTableSize = RateSwitchTable11BG[0];
1098 *pInitTxRateIdx =
1099 RateSwitchTable11BG[1];
1100 }
1101 break;
1102 }
1103 if (pAd->LatchRfRegs.Channel <= 14) {
1104 if (pAd->CommonCfg.TxStream == 1) {
1105 *ppTable = RateSwitchTable11N1S;
1106 *pTableSize = RateSwitchTable11N1S[0];
1107 *pInitTxRateIdx =
1108 RateSwitchTable11N1S[1];
1109 DBGPRINT_RAW(RT_DEBUG_ERROR,
1110 ("DRS: unknown mode,default use 11N 1S AP \n"));
1111 } else {
1112 *ppTable = RateSwitchTable11N2S;
1113 *pTableSize = RateSwitchTable11N2S[0];
1114 *pInitTxRateIdx =
1115 RateSwitchTable11N2S[1];
1116 DBGPRINT_RAW(RT_DEBUG_ERROR,
1117 ("DRS: unknown mode,default use 11N 2S AP \n"));
1118 }
1119 } else {
1120 if (pAd->CommonCfg.TxStream == 1) {
1121 *ppTable = RateSwitchTable11N1S;
1122 *pTableSize = RateSwitchTable11N1S[0];
1123 *pInitTxRateIdx =
1124 RateSwitchTable11N1S[1];
1125 DBGPRINT_RAW(RT_DEBUG_ERROR,
1126 ("DRS: unknown mode,default use 11N 1S AP \n"));
1127 } else {
1128 *ppTable = RateSwitchTable11N2SForABand;
1129 *pTableSize =
1130 RateSwitchTable11N2SForABand[0];
1131 *pInitTxRateIdx =
1132 RateSwitchTable11N2SForABand[1];
1133 DBGPRINT_RAW(RT_DEBUG_ERROR,
1134 ("DRS: unknown mode,default use 11N 2S AP \n"));
1135 }
1136 }
1137 DBGPRINT_RAW(RT_DEBUG_ERROR,
1138 ("DRS: unknown mode (SupRateLen=%d, ExtRateLen=%d, MCSSet[0]=0x%x, MCSSet[1]=0x%x)\n",
1139 pAd->StaActive.SupRateLen,
1140 pAd->StaActive.ExtRateLen,
1141 pAd->StaActive.SupportedPhyInfo.MCSSet[0],
1142 pAd->StaActive.SupportedPhyInfo.
1143 MCSSet[1]));
1144 }
1145 } while (FALSE);
1146}
1147
1148void STAMlmePeriodicExec(struct rt_rtmp_adapter *pAd)
1149{
1150 unsigned long TxTotalCnt;
1151 int i;
1152
1153 /*
1154 We return here in ATE mode, because the statistics
1155 that ATE need are not collected via this routine.
1156 */
1157#if defined(RT305x)||defined(RT3070)
1158 /* request by Gary, if Rssi0 > -42, BBP 82 need to be changed from 0x62 to 0x42, , bbp 67 need to be changed from 0x20 to 0x18 */
1159 if (!pAd->CommonCfg.HighPowerPatchDisabled) {
1160#ifdef RT3070
1161 if ((IS_RT3070(pAd) && ((pAd->MACVersion & 0xffff) < 0x0201)))
1162#endif /* RT3070 // */
1163 {
1164 if ((pAd->StaCfg.RssiSample.AvgRssi0 != 0)
1165 && (pAd->StaCfg.RssiSample.AvgRssi0 >
1166 (pAd->BbpRssiToDbmDelta - 35))) {
1167 RT30xxWriteRFRegister(pAd, RF_R27, 0x20);
1168 } else {
1169 RT30xxWriteRFRegister(pAd, RF_R27, 0x23);
1170 }
1171 }
1172 }
1173#endif
1174#ifdef PCIE_PS_SUPPORT
1175/* don't perform idle-power-save mechanism within 3 min after driver initialization. */
1176/* This can make rebooter test more robust */
1177 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) {
1178 if ((pAd->OpMode == OPMODE_STA) && (IDLE_ON(pAd))
1179 && (pAd->Mlme.SyncMachine.CurrState == SYNC_IDLE)
1180 && (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
1181 && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))) {
1182 if (IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) {
1183 if (pAd->StaCfg.PSControl.field.EnableNewPS ==
1184 TRUE) {
1185 DBGPRINT(RT_DEBUG_TRACE,
1186 ("%s\n", __func__));
1187 RT28xxPciAsicRadioOff(pAd,
1188 GUI_IDLE_POWER_SAVE,
1189 0);
1190 } else {
1191 AsicSendCommandToMcu(pAd, 0x30,
1192 PowerSafeCID, 0xff,
1193 0x2);
1194 /* Wait command success */
1195 AsicCheckCommanOk(pAd, PowerSafeCID);
1196 RTMP_SET_FLAG(pAd,
1197 fRTMP_ADAPTER_IDLE_RADIO_OFF);
1198 DBGPRINT(RT_DEBUG_TRACE,
1199 ("PSM - rt30xx Issue Sleep command)\n"));
1200 }
1201 } else if (pAd->Mlme.OneSecPeriodicRound > 180) {
1202 if (pAd->StaCfg.PSControl.field.EnableNewPS ==
1203 TRUE) {
1204 DBGPRINT(RT_DEBUG_TRACE,
1205 ("%s\n", __func__));
1206 RT28xxPciAsicRadioOff(pAd,
1207 GUI_IDLE_POWER_SAVE,
1208 0);
1209 } else {
1210 AsicSendCommandToMcu(pAd, 0x30,
1211 PowerSafeCID, 0xff,
1212 0x02);
1213 /* Wait command success */
1214 AsicCheckCommanOk(pAd, PowerSafeCID);
1215 RTMP_SET_FLAG(pAd,
1216 fRTMP_ADAPTER_IDLE_RADIO_OFF);
1217 DBGPRINT(RT_DEBUG_TRACE,
1218 ("PSM - rt28xx Issue Sleep command)\n"));
1219 }
1220 }
1221 } else {
1222 DBGPRINT(RT_DEBUG_TRACE,
1223 ("STAMlmePeriodicExec MMCHK - CommonCfg.Ssid[%d]=%c%c%c%c... MlmeAux.Ssid[%d]=%c%c%c%c...\n",
1224 pAd->CommonCfg.SsidLen,
1225 pAd->CommonCfg.Ssid[0],
1226 pAd->CommonCfg.Ssid[1],
1227 pAd->CommonCfg.Ssid[2],
1228 pAd->CommonCfg.Ssid[3], pAd->MlmeAux.SsidLen,
1229 pAd->MlmeAux.Ssid[0], pAd->MlmeAux.Ssid[1],
1230 pAd->MlmeAux.Ssid[2], pAd->MlmeAux.Ssid[3]));
1231 }
1232 }
1233#endif /* PCIE_PS_SUPPORT // */
1234
1235 if (pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE) {
1236 /* WPA MIC error should block association attempt for 60 seconds */
1237 if (pAd->StaCfg.bBlockAssoc &&
1238 RTMP_TIME_AFTER(pAd->Mlme.Now32,
1239 pAd->StaCfg.LastMicErrorTime +
1240 (60 * OS_HZ)))
1241 pAd->StaCfg.bBlockAssoc = FALSE;
1242 }
1243
1244 if ((pAd->PreMediaState != pAd->IndicateMediaState)
1245 && (pAd->CommonCfg.bWirelessEvent)) {
1246 if (pAd->IndicateMediaState == NdisMediaStateConnected) {
1247 RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG,
1248 pAd->MacTab.Content[BSSID_WCID].
1249 Addr, BSS0, 0);
1250 }
1251 pAd->PreMediaState = pAd->IndicateMediaState;
1252 }
1253
1254 if (pAd->CommonCfg.PSPXlink && ADHOC_ON(pAd)) {
1255 } else {
1256 AsicStaBbpTuning(pAd);
1257 }
1258
1259 TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
1260 pAd->RalinkCounters.OneSecTxRetryOkCount +
1261 pAd->RalinkCounters.OneSecTxFailCount;
1262
1263 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) {
1264 /* update channel quality for Roaming and UI LinkQuality display */
1265 MlmeCalculateChannelQuality(pAd, NULL, pAd->Mlme.Now32);
1266 }
1267 /* must be AFTER MlmeDynamicTxRateSwitching() because it needs to know if */
1268 /* Radio is currently in noisy environment */
1269 if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
1270 AsicAdjustTxPower(pAd);
1271
1272 if (INFRA_ON(pAd)) {
1273
1274 /* Is PSM bit consistent with user power management policy? */
1275 /* This is the only place that will set PSM bit ON. */
1276 if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
1277 MlmeCheckPsmChange(pAd, pAd->Mlme.Now32);
1278
1279 pAd->RalinkCounters.LastOneSecTotalTxCount = TxTotalCnt;
1280
1281 if ((RTMP_TIME_AFTER
1282 (pAd->Mlme.Now32,
1283 pAd->StaCfg.LastBeaconRxTime + (1 * OS_HZ)))
1284 &&
1285 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
1286 &&
1287 (((TxTotalCnt + pAd->RalinkCounters.OneSecRxOkCnt) <
1288 600))) {
1289 RTMPSetAGCInitValue(pAd, BW_20);
1290 DBGPRINT(RT_DEBUG_TRACE,
1291 ("MMCHK - No BEACON. restore R66 to the low bound(%d) \n",
1292 (0x2E + GET_LNA_GAIN(pAd))));
1293 }
1294 /*if ((pAd->RalinkCounters.OneSecTxNoRetryOkCount == 0) && */
1295 /* (pAd->RalinkCounters.OneSecTxRetryOkCount == 0)) */
1296 {
1297 if (pAd->CommonCfg.bAPSDCapable
1298 && pAd->CommonCfg.APEdcaParm.bAPSDCapable) {
1299 /* When APSD is enabled, the period changes as 20 sec */
1300 if ((pAd->Mlme.OneSecPeriodicRound % 20) == 8)
1301 RTMPSendNullFrame(pAd,
1302 pAd->CommonCfg.TxRate,
1303 TRUE);
1304 } else {
1305 /* Send out a NULL frame every 10 sec to inform AP that STA is still alive (Avoid being age out) */
1306 if ((pAd->Mlme.OneSecPeriodicRound % 10) == 8) {
1307 if (pAd->CommonCfg.bWmmCapable)
1308 RTMPSendNullFrame(pAd,
1309 pAd->
1310 CommonCfg.
1311 TxRate, TRUE);
1312 else
1313 RTMPSendNullFrame(pAd,
1314 pAd->
1315 CommonCfg.
1316 TxRate,
1317 FALSE);
1318 }
1319 }
1320 }
1321
1322 if (CQI_IS_DEAD(pAd->Mlme.ChannelQuality)) {
1323 DBGPRINT(RT_DEBUG_TRACE,
1324 ("MMCHK - No BEACON. Dead CQI. Auto Recovery attempt #%ld\n",
1325 pAd->RalinkCounters.BadCQIAutoRecoveryCount));
1326
1327 /* Lost AP, send disconnect & link down event */
1328 LinkDown(pAd, FALSE);
1329
1330 RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1, NULL, NULL,
1331 0);
1332
1333 /* RTMPPatchMacBbpBug(pAd); */
1334 MlmeAutoReconnectLastSSID(pAd);
1335 } else if (CQI_IS_BAD(pAd->Mlme.ChannelQuality)) {
1336 pAd->RalinkCounters.BadCQIAutoRecoveryCount++;
1337 DBGPRINT(RT_DEBUG_TRACE,
1338 ("MMCHK - Bad CQI. Auto Recovery attempt #%ld\n",
1339 pAd->RalinkCounters.BadCQIAutoRecoveryCount));
1340 MlmeAutoReconnectLastSSID(pAd);
1341 }
1342
1343 if (pAd->StaCfg.bAutoRoaming) {
1344 BOOLEAN rv = FALSE;
1345 char dBmToRoam = pAd->StaCfg.dBmToRoam;
1346 char MaxRssi = RTMPMaxRssi(pAd,
1347 pAd->StaCfg.RssiSample.
1348 LastRssi0,
1349 pAd->StaCfg.RssiSample.
1350 LastRssi1,
1351 pAd->StaCfg.RssiSample.
1352 LastRssi2);
1353
1354 /* Scanning, ignore Roaming */
1355 if (!RTMP_TEST_FLAG
1356 (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)
1357 && (pAd->Mlme.SyncMachine.CurrState == SYNC_IDLE)
1358 && (MaxRssi <= dBmToRoam)) {
1359 DBGPRINT(RT_DEBUG_TRACE,
1360 ("Rssi=%d, dBmToRoam=%d\n", MaxRssi,
1361 (char)dBmToRoam));
1362
1363 /* Add auto seamless roaming */
1364 if (rv == FALSE)
1365 rv = MlmeCheckForFastRoaming(pAd);
1366
1367 if (rv == FALSE) {
1368 if ((pAd->StaCfg.LastScanTime +
1369 10 * OS_HZ) < pAd->Mlme.Now32) {
1370 DBGPRINT(RT_DEBUG_TRACE,
1371 ("MMCHK - Roaming, No eligible entry, try new scan!\n"));
1372 pAd->StaCfg.ScanCnt = 2;
1373 pAd->StaCfg.LastScanTime =
1374 pAd->Mlme.Now32;
1375 MlmeAutoScan(pAd);
1376 }
1377 }
1378 }
1379 }
1380 } else if (ADHOC_ON(pAd)) {
1381 /* If all peers leave, and this STA becomes the last one in this IBSS, then change MediaState */
1382 /* to DISCONNECTED. But still holding this IBSS (i.e. sending BEACON) so that other STAs can */
1383 /* join later. */
1384 if (RTMP_TIME_AFTER
1385 (pAd->Mlme.Now32,
1386 pAd->StaCfg.LastBeaconRxTime + ADHOC_BEACON_LOST_TIME)
1387 && OPSTATUS_TEST_FLAG(pAd,
1388 fOP_STATUS_MEDIA_STATE_CONNECTED)) {
1389 struct rt_mlme_start_req StartReq;
1390
1391 DBGPRINT(RT_DEBUG_TRACE,
1392 ("MMCHK - excessive BEACON lost, last STA in this IBSS, MediaState=Disconnected\n"));
1393 LinkDown(pAd, FALSE);
1394
1395 StartParmFill(pAd, &StartReq,
1396 (char *) pAd->MlmeAux.Ssid,
1397 pAd->MlmeAux.SsidLen);
1398 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ,
1399 sizeof(struct rt_mlme_start_req), &StartReq);
1400 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
1401 }
1402
1403 for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++) {
1404 struct rt_mac_table_entry *pEntry = &pAd->MacTab.Content[i];
1405
1406 if (pEntry->ValidAsCLI == FALSE)
1407 continue;
1408
1409 if (RTMP_TIME_AFTER
1410 (pAd->Mlme.Now32,
1411 pEntry->LastBeaconRxTime + ADHOC_BEACON_LOST_TIME))
1412 MacTableDeleteEntry(pAd, pEntry->Aid,
1413 pEntry->Addr);
1414 }
1415 } else /* no INFRA nor ADHOC connection */
1416 {
1417
1418 if (pAd->StaCfg.bScanReqIsFromWebUI &&
1419 RTMP_TIME_BEFORE(pAd->Mlme.Now32,
1420 pAd->StaCfg.LastScanTime + (30 * OS_HZ)))
1421 goto SKIP_AUTO_SCAN_CONN;
1422 else
1423 pAd->StaCfg.bScanReqIsFromWebUI = FALSE;
1424
1425 if ((pAd->StaCfg.bAutoReconnect == TRUE)
1426 && RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP)
1427 &&
1428 (MlmeValidateSSID
1429 (pAd->MlmeAux.AutoReconnectSsid,
1430 pAd->MlmeAux.AutoReconnectSsidLen) == TRUE)) {
1431 if ((pAd->ScanTab.BssNr == 0)
1432 && (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)) {
1433 struct rt_mlme_scan_req ScanReq;
1434
1435 if (RTMP_TIME_AFTER
1436 (pAd->Mlme.Now32,
1437 pAd->StaCfg.LastScanTime + (10 * OS_HZ))) {
1438 DBGPRINT(RT_DEBUG_TRACE,
1439 ("STAMlmePeriodicExec():CNTL - ScanTab.BssNr==0, start a new ACTIVE scan SSID[%s]\n",
1440 pAd->MlmeAux.
1441 AutoReconnectSsid));
1442 ScanParmFill(pAd, &ScanReq,
1443 (char *)pAd->MlmeAux.
1444 AutoReconnectSsid,
1445 pAd->MlmeAux.
1446 AutoReconnectSsidLen,
1447 BSS_ANY, SCAN_ACTIVE);
1448 MlmeEnqueue(pAd, SYNC_STATE_MACHINE,
1449 MT2_MLME_SCAN_REQ,
1450 sizeof
1451 (struct rt_mlme_scan_req),
1452 &ScanReq);
1453 pAd->Mlme.CntlMachine.CurrState =
1454 CNTL_WAIT_OID_LIST_SCAN;
1455 /* Reset Missed scan number */
1456 pAd->StaCfg.LastScanTime =
1457 pAd->Mlme.Now32;
1458 } else if (pAd->StaCfg.BssType == BSS_ADHOC) /* Quit the forever scan when in a very clean room */
1459 MlmeAutoReconnectLastSSID(pAd);
1460 } else if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) {
1461 if ((pAd->Mlme.OneSecPeriodicRound % 7) == 0) {
1462 MlmeAutoScan(pAd);
1463 pAd->StaCfg.LastScanTime =
1464 pAd->Mlme.Now32;
1465 } else {
1466 MlmeAutoReconnectLastSSID(pAd);
1467 }
1468 }
1469 }
1470 }
1471
1472SKIP_AUTO_SCAN_CONN:
1473
1474 if ((pAd->MacTab.Content[BSSID_WCID].TXBAbitmap != 0)
1475 && (pAd->MacTab.fAnyBASession == FALSE)) {
1476 pAd->MacTab.fAnyBASession = TRUE;
1477 AsicUpdateProtect(pAd, HT_FORCERTSCTS, ALLN_SETPROTECT, FALSE,
1478 FALSE);
1479 } else if ((pAd->MacTab.Content[BSSID_WCID].TXBAbitmap == 0)
1480 && (pAd->MacTab.fAnyBASession == TRUE)) {
1481 pAd->MacTab.fAnyBASession = FALSE;
1482 AsicUpdateProtect(pAd,
1483 pAd->MlmeAux.AddHtInfo.AddHtInfo2.
1484 OperaionMode, ALLN_SETPROTECT, FALSE, FALSE);
1485 }
1486
1487 return;
1488}
1489
1490/* Link down report */
1491void LinkDownExec(void *SystemSpecific1,
1492 void *FunctionContext,
1493 void *SystemSpecific2, void *SystemSpecific3)
1494{
1495 struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext;
1496
1497 if (pAd != NULL) {
1498 struct rt_mlme_disassoc_req DisassocReq;
1499
1500 if ((pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED) &&
1501 (INFRA_ON(pAd))) {
1502 DBGPRINT(RT_DEBUG_TRACE,
1503 ("LinkDownExec(): disassociate with current AP...\n"));
1504 DisassocParmFill(pAd, &DisassocReq,
1505 pAd->CommonCfg.Bssid,
1506 REASON_DISASSOC_STA_LEAVING);
1507 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE,
1508 MT2_MLME_DISASSOC_REQ,
1509 sizeof(struct rt_mlme_disassoc_req),
1510 &DisassocReq);
1511 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
1512
1513 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1514 RTMP_IndicateMediaState(pAd);
1515 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1516 }
1517 }
1518}
1519
1520/* IRQL = DISPATCH_LEVEL */
1521void MlmeAutoScan(struct rt_rtmp_adapter *pAd)
1522{
1523 /* check CntlMachine.CurrState to avoid collision with NDIS SetOID request */
1524 if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) {
1525 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Driver auto scan\n"));
1526 MlmeEnqueue(pAd,
1527 MLME_CNTL_STATE_MACHINE,
1528 OID_802_11_BSSID_LIST_SCAN,
1529 pAd->MlmeAux.AutoReconnectSsidLen,
1530 pAd->MlmeAux.AutoReconnectSsid);
1531 RTMP_MLME_HANDLER(pAd);
1532 }
1533}
1534
1535/* IRQL = DISPATCH_LEVEL */
1536void MlmeAutoReconnectLastSSID(struct rt_rtmp_adapter *pAd)
1537{
1538 if (pAd->StaCfg.bAutoConnectByBssid) {
1539 DBGPRINT(RT_DEBUG_TRACE,
1540 ("Driver auto reconnect to last OID_802_11_BSSID "
1541 "setting - %pM\n", pAd->MlmeAux.Bssid));
1542
1543 pAd->MlmeAux.Channel = pAd->CommonCfg.Channel;
1544 MlmeEnqueue(pAd,
1545 MLME_CNTL_STATE_MACHINE,
1546 OID_802_11_BSSID, MAC_ADDR_LEN, pAd->MlmeAux.Bssid);
1547
1548 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1549
1550 RTMP_MLME_HANDLER(pAd);
1551 }
1552 /* check CntlMachine.CurrState to avoid collision with NDIS SetOID request */
1553 else if ((pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) &&
1554 (MlmeValidateSSID
1555 (pAd->MlmeAux.AutoReconnectSsid,
1556 pAd->MlmeAux.AutoReconnectSsidLen) == TRUE)) {
1557 struct rt_ndis_802_11_ssid OidSsid;
1558 OidSsid.SsidLength = pAd->MlmeAux.AutoReconnectSsidLen;
1559 NdisMoveMemory(OidSsid.Ssid, pAd->MlmeAux.AutoReconnectSsid,
1560 pAd->MlmeAux.AutoReconnectSsidLen);
1561
1562 DBGPRINT(RT_DEBUG_TRACE,
1563 ("Driver auto reconnect to last OID_802_11_SSID setting - %s, len - %d\n",
1564 pAd->MlmeAux.AutoReconnectSsid,
1565 pAd->MlmeAux.AutoReconnectSsidLen));
1566 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, OID_802_11_SSID,
1567 sizeof(struct rt_ndis_802_11_ssid), &OidSsid);
1568 RTMP_MLME_HANDLER(pAd);
1569 }
1570}
1571
1572/*
1573 ==========================================================================
1574 Description:
1575 This routine checks if there're other APs out there capable for
1576 roaming. Caller should call this routine only when Link up in INFRA mode
1577 and channel quality is below CQI_GOOD_THRESHOLD.
1578
1579 IRQL = DISPATCH_LEVEL
1580
1581 Output:
1582 ==========================================================================
1583 */
1584void MlmeCheckForRoaming(struct rt_rtmp_adapter *pAd, unsigned long Now32)
1585{
1586 u16 i;
1587 struct rt_bss_table *pRoamTab = &pAd->MlmeAux.RoamTab;
1588 struct rt_bss_entry *pBss;
1589
1590 DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeCheckForRoaming\n"));
1591 /* put all roaming candidates into RoamTab, and sort in RSSI order */
1592 BssTableInit(pRoamTab);
1593 for (i = 0; i < pAd->ScanTab.BssNr; i++) {
1594 pBss = &pAd->ScanTab.BssEntry[i];
1595
1596 if ((pBss->LastBeaconRxTime + pAd->StaCfg.BeaconLostTime) <
1597 Now32)
1598 continue; /* AP disappear */
1599 if (pBss->Rssi <= RSSI_THRESHOLD_FOR_ROAMING)
1600 continue; /* RSSI too weak. forget it. */
1601 if (MAC_ADDR_EQUAL(pBss->Bssid, pAd->CommonCfg.Bssid))
1602 continue; /* skip current AP */
1603 if (pBss->Rssi <
1604 (pAd->StaCfg.RssiSample.LastRssi0 + RSSI_DELTA))
1605 continue; /* only AP with stronger RSSI is eligible for roaming */
1606
1607 /* AP passing all above rules is put into roaming candidate table */
1608 NdisMoveMemory(&pRoamTab->BssEntry[pRoamTab->BssNr], pBss,
1609 sizeof(struct rt_bss_entry));
1610 pRoamTab->BssNr += 1;
1611 }
1612
1613 if (pRoamTab->BssNr > 0) {
1614 /* check CntlMachine.CurrState to avoid collision with NDIS SetOID request */
1615 if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) {
1616 pAd->RalinkCounters.PoorCQIRoamingCount++;
1617 DBGPRINT(RT_DEBUG_TRACE,
1618 ("MMCHK - Roaming attempt #%ld\n",
1619 pAd->RalinkCounters.PoorCQIRoamingCount));
1620 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE,
1621 MT2_MLME_ROAMING_REQ, 0, NULL);
1622 RTMP_MLME_HANDLER(pAd);
1623 }
1624 }
1625 DBGPRINT(RT_DEBUG_TRACE,
1626 ("<== MlmeCheckForRoaming(# of candidate= %d)\n",
1627 pRoamTab->BssNr));
1628}
1629
1630/*
1631 ==========================================================================
1632 Description:
1633 This routine checks if there're other APs out there capable for
1634 roaming. Caller should call this routine only when link up in INFRA mode
1635 and channel quality is below CQI_GOOD_THRESHOLD.
1636
1637 IRQL = DISPATCH_LEVEL
1638
1639 Output:
1640 ==========================================================================
1641 */
1642BOOLEAN MlmeCheckForFastRoaming(struct rt_rtmp_adapter *pAd)
1643{
1644 u16 i;
1645 struct rt_bss_table *pRoamTab = &pAd->MlmeAux.RoamTab;
1646 struct rt_bss_entry *pBss;
1647
1648 DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeCheckForFastRoaming\n"));
1649 /* put all roaming candidates into RoamTab, and sort in RSSI order */
1650 BssTableInit(pRoamTab);
1651 for (i = 0; i < pAd->ScanTab.BssNr; i++) {
1652 pBss = &pAd->ScanTab.BssEntry[i];
1653
1654 if ((pBss->Rssi <= -50)
1655 && (pBss->Channel == pAd->CommonCfg.Channel))
1656 continue; /* RSSI too weak. forget it. */
1657 if (MAC_ADDR_EQUAL(pBss->Bssid, pAd->CommonCfg.Bssid))
1658 continue; /* skip current AP */
1659 if (!SSID_EQUAL
1660 (pBss->Ssid, pBss->SsidLen, pAd->CommonCfg.Ssid,
1661 pAd->CommonCfg.SsidLen))
1662 continue; /* skip different SSID */
1663 if (pBss->Rssi <
1664 (RTMPMaxRssi
1665 (pAd, pAd->StaCfg.RssiSample.LastRssi0,
1666 pAd->StaCfg.RssiSample.LastRssi1,
1667 pAd->StaCfg.RssiSample.LastRssi2) + RSSI_DELTA))
1668 continue; /* skip AP without better RSSI */
1669
1670 DBGPRINT(RT_DEBUG_TRACE,
1671 ("LastRssi0 = %d, pBss->Rssi = %d\n",
1672 RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0,
1673 pAd->StaCfg.RssiSample.LastRssi1,
1674 pAd->StaCfg.RssiSample.LastRssi2),
1675 pBss->Rssi));
1676 /* AP passing all above rules is put into roaming candidate table */
1677 NdisMoveMemory(&pRoamTab->BssEntry[pRoamTab->BssNr], pBss,
1678 sizeof(struct rt_bss_entry));
1679 pRoamTab->BssNr += 1;
1680 }
1681
1682 DBGPRINT(RT_DEBUG_TRACE,
1683 ("<== MlmeCheckForFastRoaming (BssNr=%d)\n", pRoamTab->BssNr));
1684 if (pRoamTab->BssNr > 0) {
1685 /* check CntlMachine.CurrState to avoid collision with NDIS SetOID request */
1686 if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) {
1687 pAd->RalinkCounters.PoorCQIRoamingCount++;
1688 DBGPRINT(RT_DEBUG_TRACE,
1689 ("MMCHK - Roaming attempt #%ld\n",
1690 pAd->RalinkCounters.PoorCQIRoamingCount));
1691 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE,
1692 MT2_MLME_ROAMING_REQ, 0, NULL);
1693 RTMP_MLME_HANDLER(pAd);
1694 return TRUE;
1695 }
1696 }
1697
1698 return FALSE;
1699}
1700
1701void MlmeSetTxRate(struct rt_rtmp_adapter *pAd,
1702 struct rt_mac_table_entry *pEntry, struct rt_rtmp_tx_rate_switch * pTxRate)
1703{
1704 u8 MaxMode = MODE_OFDM;
1705
1706 MaxMode = MODE_HTGREENFIELD;
1707
1708 if (pTxRate->STBC && (pAd->StaCfg.MaxHTPhyMode.field.STBC)
1709 && (pAd->Antenna.field.TxPath == 2))
1710 pAd->StaCfg.HTPhyMode.field.STBC = STBC_USE;
1711 else
1712 pAd->StaCfg.HTPhyMode.field.STBC = STBC_NONE;
1713
1714 if (pTxRate->CurrMCS < MCS_AUTO)
1715 pAd->StaCfg.HTPhyMode.field.MCS = pTxRate->CurrMCS;
1716
1717 if (pAd->StaCfg.HTPhyMode.field.MCS > 7)
1718 pAd->StaCfg.HTPhyMode.field.STBC = STBC_NONE;
1719
1720 if (ADHOC_ON(pAd)) {
1721 /* If peer adhoc is b-only mode, we can't send 11g rate. */
1722 pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
1723 pEntry->HTPhyMode.field.STBC = STBC_NONE;
1724
1725 /* */
1726 /* For Adhoc MODE_CCK, driver will use AdhocBOnlyJoined flag to roll back to B only if necessary */
1727 /* */
1728 pEntry->HTPhyMode.field.MODE = pTxRate->Mode;
1729 pEntry->HTPhyMode.field.ShortGI =
1730 pAd->StaCfg.HTPhyMode.field.ShortGI;
1731 pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
1732
1733 /* Patch speed error in status page */
1734 pAd->StaCfg.HTPhyMode.field.MODE = pEntry->HTPhyMode.field.MODE;
1735 } else {
1736 if (pTxRate->Mode <= MaxMode)
1737 pAd->StaCfg.HTPhyMode.field.MODE = pTxRate->Mode;
1738
1739 if (pTxRate->ShortGI
1740 && (pAd->StaCfg.MaxHTPhyMode.field.ShortGI))
1741 pAd->StaCfg.HTPhyMode.field.ShortGI = GI_400;
1742 else
1743 pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
1744
1745 /* Reexam each bandwidth's SGI support. */
1746 if (pAd->StaCfg.HTPhyMode.field.ShortGI == GI_400) {
1747 if ((pEntry->HTPhyMode.field.BW == BW_20)
1748 &&
1749 (!CLIENT_STATUS_TEST_FLAG
1750 (pEntry, fCLIENT_STATUS_SGI20_CAPABLE)))
1751 pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
1752 if ((pEntry->HTPhyMode.field.BW == BW_40)
1753 &&
1754 (!CLIENT_STATUS_TEST_FLAG
1755 (pEntry, fCLIENT_STATUS_SGI40_CAPABLE)))
1756 pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
1757 }
1758 /* Turn RTS/CTS rate to 6Mbps. */
1759 if ((pEntry->HTPhyMode.field.MCS == 0)
1760 && (pAd->StaCfg.HTPhyMode.field.MCS != 0)) {
1761 pEntry->HTPhyMode.field.MCS =
1762 pAd->StaCfg.HTPhyMode.field.MCS;
1763 if (pAd->MacTab.fAnyBASession) {
1764 AsicUpdateProtect(pAd, HT_FORCERTSCTS,
1765 ALLN_SETPROTECT, TRUE,
1766 (BOOLEAN) pAd->MlmeAux.
1767 AddHtInfo.AddHtInfo2.
1768 NonGfPresent);
1769 } else {
1770 AsicUpdateProtect(pAd,
1771 pAd->MlmeAux.AddHtInfo.
1772 AddHtInfo2.OperaionMode,
1773 ALLN_SETPROTECT, TRUE,
1774 (BOOLEAN) pAd->MlmeAux.
1775 AddHtInfo.AddHtInfo2.
1776 NonGfPresent);
1777 }
1778 } else if ((pEntry->HTPhyMode.field.MCS == 8)
1779 && (pAd->StaCfg.HTPhyMode.field.MCS != 8)) {
1780 pEntry->HTPhyMode.field.MCS =
1781 pAd->StaCfg.HTPhyMode.field.MCS;
1782 if (pAd->MacTab.fAnyBASession) {
1783 AsicUpdateProtect(pAd, HT_FORCERTSCTS,
1784 ALLN_SETPROTECT, TRUE,
1785 (BOOLEAN) pAd->MlmeAux.
1786 AddHtInfo.AddHtInfo2.
1787 NonGfPresent);
1788 } else {
1789 AsicUpdateProtect(pAd,
1790 pAd->MlmeAux.AddHtInfo.
1791 AddHtInfo2.OperaionMode,
1792 ALLN_SETPROTECT, TRUE,
1793 (BOOLEAN) pAd->MlmeAux.
1794 AddHtInfo.AddHtInfo2.
1795 NonGfPresent);
1796 }
1797 } else if ((pEntry->HTPhyMode.field.MCS != 0)
1798 && (pAd->StaCfg.HTPhyMode.field.MCS == 0)) {
1799 AsicUpdateProtect(pAd, HT_RTSCTS_6M, ALLN_SETPROTECT,
1800 TRUE,
1801 (BOOLEAN) pAd->MlmeAux.AddHtInfo.
1802 AddHtInfo2.NonGfPresent);
1803
1804 } else if ((pEntry->HTPhyMode.field.MCS != 8)
1805 && (pAd->StaCfg.HTPhyMode.field.MCS == 8)) {
1806 AsicUpdateProtect(pAd, HT_RTSCTS_6M, ALLN_SETPROTECT,
1807 TRUE,
1808 (BOOLEAN) pAd->MlmeAux.AddHtInfo.
1809 AddHtInfo2.NonGfPresent);
1810 }
1811
1812 pEntry->HTPhyMode.field.STBC = pAd->StaCfg.HTPhyMode.field.STBC;
1813 pEntry->HTPhyMode.field.ShortGI =
1814 pAd->StaCfg.HTPhyMode.field.ShortGI;
1815 pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
1816 pEntry->HTPhyMode.field.MODE = pAd->StaCfg.HTPhyMode.field.MODE;
1817 if ((pAd->StaCfg.MaxHTPhyMode.field.MODE == MODE_HTGREENFIELD)
1818 && pAd->WIFItestbed.bGreenField)
1819 pEntry->HTPhyMode.field.MODE = MODE_HTGREENFIELD;
1820 }
1821
1822 pAd->LastTxRate = (u16)(pEntry->HTPhyMode.word);
1823}
1824
1825/*
1826 ==========================================================================
1827 Description:
1828 This routine calculates the acumulated TxPER of eaxh TxRate. And
1829 according to the calculation result, change CommonCfg.TxRate which
1830 is the stable TX Rate we expect the Radio situation could sustained.
1831
1832 CommonCfg.TxRate will change dynamically within {RATE_1/RATE_6, MaxTxRate}
1833 Output:
1834 CommonCfg.TxRate -
1835
1836 IRQL = DISPATCH_LEVEL
1837
1838 NOTE:
1839 call this routine every second
1840 ==========================================================================
1841 */
1842void MlmeDynamicTxRateSwitching(struct rt_rtmp_adapter *pAd)
1843{
1844 u8 UpRateIdx = 0, DownRateIdx = 0, CurrRateIdx;
1845 unsigned long i, AccuTxTotalCnt = 0, TxTotalCnt;
1846 unsigned long TxErrorRatio = 0;
1847 BOOLEAN bTxRateChanged = FALSE, bUpgradeQuality = FALSE;
1848 struct rt_rtmp_tx_rate_switch *pCurrTxRate, *pNextTxRate = NULL;
1849 u8 *pTable;
1850 u8 TableSize = 0;
1851 u8 InitTxRateIdx = 0, TrainUp, TrainDown;
1852 char Rssi, RssiOffset = 0;
1853 TX_STA_CNT1_STRUC StaTx1;
1854 TX_STA_CNT0_STRUC TxStaCnt0;
1855 unsigned long TxRetransmit = 0, TxSuccess = 0, TxFailCount = 0;
1856 struct rt_mac_table_entry *pEntry;
1857 struct rt_rssi_sample *pRssi = &pAd->StaCfg.RssiSample;
1858
1859 /* */
1860 /* walk through MAC table, see if need to change AP's TX rate toward each entry */
1861 /* */
1862 for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++) {
1863 pEntry = &pAd->MacTab.Content[i];
1864
1865 /* check if this entry need to switch rate automatically */
1866 if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pEntry) == FALSE)
1867 continue;
1868
1869 if ((pAd->MacTab.Size == 1) || (pEntry->ValidAsDls)) {
1870 Rssi = RTMPMaxRssi(pAd,
1871 pRssi->AvgRssi0,
1872 pRssi->AvgRssi1, pRssi->AvgRssi2);
1873
1874 /* Update statistic counter */
1875 RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word);
1876 RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word);
1877 pAd->bUpdateBcnCntDone = TRUE;
1878 TxRetransmit = StaTx1.field.TxRetransmit;
1879 TxSuccess = StaTx1.field.TxSuccess;
1880 TxFailCount = TxStaCnt0.field.TxFailCount;
1881 TxTotalCnt = TxRetransmit + TxSuccess + TxFailCount;
1882
1883 pAd->RalinkCounters.OneSecTxRetryOkCount +=
1884 StaTx1.field.TxRetransmit;
1885 pAd->RalinkCounters.OneSecTxNoRetryOkCount +=
1886 StaTx1.field.TxSuccess;
1887 pAd->RalinkCounters.OneSecTxFailCount +=
1888 TxStaCnt0.field.TxFailCount;
1889 pAd->WlanCounters.TransmittedFragmentCount.u.LowPart +=
1890 StaTx1.field.TxSuccess;
1891 pAd->WlanCounters.RetryCount.u.LowPart +=
1892 StaTx1.field.TxRetransmit;
1893 pAd->WlanCounters.FailedCount.u.LowPart +=
1894 TxStaCnt0.field.TxFailCount;
1895
1896 /* if no traffic in the past 1-sec period, don't change TX rate, */
1897 /* but clear all bad history. because the bad history may affect the next */
1898 /* Chariot throughput test */
1899 AccuTxTotalCnt =
1900 pAd->RalinkCounters.OneSecTxNoRetryOkCount +
1901 pAd->RalinkCounters.OneSecTxRetryOkCount +
1902 pAd->RalinkCounters.OneSecTxFailCount;
1903
1904 if (TxTotalCnt)
1905 TxErrorRatio =
1906 ((TxRetransmit +
1907 TxFailCount) * 100) / TxTotalCnt;
1908 } else {
1909 if (INFRA_ON(pAd) && (i == 1))
1910 Rssi = RTMPMaxRssi(pAd,
1911 pRssi->AvgRssi0,
1912 pRssi->AvgRssi1,
1913 pRssi->AvgRssi2);
1914 else
1915 Rssi = RTMPMaxRssi(pAd,
1916 pEntry->RssiSample.AvgRssi0,
1917 pEntry->RssiSample.AvgRssi1,
1918 pEntry->RssiSample.AvgRssi2);
1919
1920 TxTotalCnt = pEntry->OneSecTxNoRetryOkCount +
1921 pEntry->OneSecTxRetryOkCount +
1922 pEntry->OneSecTxFailCount;
1923
1924 if (TxTotalCnt)
1925 TxErrorRatio =
1926 ((pEntry->OneSecTxRetryOkCount +
1927 pEntry->OneSecTxFailCount) * 100) /
1928 TxTotalCnt;
1929 }
1930
1931 if (TxTotalCnt) {
1932 /*
1933 Three AdHoc connections can not work normally if one AdHoc connection is disappeared from a heavy traffic environment generated by ping tool
1934 We force to set LongRtyLimit and ShortRtyLimit to 0 to stop retransmitting packet, after a while, resoring original settings
1935 */
1936 if (TxErrorRatio == 100) {
1937 TX_RTY_CFG_STRUC TxRtyCfg, TxRtyCfgtmp;
1938 unsigned long Index;
1939 unsigned long MACValue;
1940
1941 RTMP_IO_READ32(pAd, TX_RTY_CFG, &TxRtyCfg.word);
1942 TxRtyCfgtmp.word = TxRtyCfg.word;
1943 TxRtyCfg.field.LongRtyLimit = 0x0;
1944 TxRtyCfg.field.ShortRtyLimit = 0x0;
1945 RTMP_IO_WRITE32(pAd, TX_RTY_CFG, TxRtyCfg.word);
1946
1947 RTMPusecDelay(1);
1948
1949 Index = 0;
1950 MACValue = 0;
1951 do {
1952 RTMP_IO_READ32(pAd, TXRXQ_PCNT,
1953 &MACValue);
1954 if ((MACValue & 0xffffff) == 0)
1955 break;
1956 Index++;
1957 RTMPusecDelay(1000);
1958 } while ((Index < 330)
1959 &&
1960 (!RTMP_TEST_FLAG
1961 (pAd,
1962 fRTMP_ADAPTER_HALT_IN_PROGRESS)));
1963
1964 RTMP_IO_READ32(pAd, TX_RTY_CFG, &TxRtyCfg.word);
1965 TxRtyCfg.field.LongRtyLimit =
1966 TxRtyCfgtmp.field.LongRtyLimit;
1967 TxRtyCfg.field.ShortRtyLimit =
1968 TxRtyCfgtmp.field.ShortRtyLimit;
1969 RTMP_IO_WRITE32(pAd, TX_RTY_CFG, TxRtyCfg.word);
1970 }
1971 }
1972
1973 CurrRateIdx = pEntry->CurrTxRateIndex;
1974
1975 MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize,
1976 &InitTxRateIdx);
1977
1978 if (CurrRateIdx >= TableSize) {
1979 CurrRateIdx = TableSize - 1;
1980 }
1981 /* When switch from Fixed rate -> auto rate, the REAL TX rate might be different from pAd->CommonCfg.TxRateIndex. */
1982 /* So need to sync here. */
1983 pCurrTxRate =
1984 (struct rt_rtmp_tx_rate_switch *) & pTable[(CurrRateIdx + 1) * 5];
1985 if ((pEntry->HTPhyMode.field.MCS != pCurrTxRate->CurrMCS)
1986 /*&& (pAd->StaCfg.bAutoTxRateSwitch == TRUE) */
1987 ) {
1988
1989 /* Need to sync Real Tx rate and our record. */
1990 /* Then return for next DRS. */
1991 pCurrTxRate =
1992 (struct rt_rtmp_tx_rate_switch *) & pTable[(InitTxRateIdx + 1)
1993 * 5];
1994 pEntry->CurrTxRateIndex = InitTxRateIdx;
1995 MlmeSetTxRate(pAd, pEntry, pCurrTxRate);
1996
1997 /* reset all OneSecTx counters */
1998 RESET_ONE_SEC_TX_CNT(pEntry);
1999 continue;
2000 }
2001 /* decide the next upgrade rate and downgrade rate, if any */
2002 if ((CurrRateIdx > 0) && (CurrRateIdx < (TableSize - 1))) {
2003 UpRateIdx = CurrRateIdx + 1;
2004 DownRateIdx = CurrRateIdx - 1;
2005 } else if (CurrRateIdx == 0) {
2006 UpRateIdx = CurrRateIdx + 1;
2007 DownRateIdx = CurrRateIdx;
2008 } else if (CurrRateIdx == (TableSize - 1)) {
2009 UpRateIdx = CurrRateIdx;
2010 DownRateIdx = CurrRateIdx - 1;
2011 }
2012
2013 pCurrTxRate =
2014 (struct rt_rtmp_tx_rate_switch *) & pTable[(CurrRateIdx + 1) * 5];
2015
2016 if ((Rssi > -65) && (pCurrTxRate->Mode >= MODE_HTMIX)) {
2017 TrainUp =
2018 (pCurrTxRate->TrainUp +
2019 (pCurrTxRate->TrainUp >> 1));
2020 TrainDown =
2021 (pCurrTxRate->TrainDown +
2022 (pCurrTxRate->TrainDown >> 1));
2023 } else {
2024 TrainUp = pCurrTxRate->TrainUp;
2025 TrainDown = pCurrTxRate->TrainDown;
2026 }
2027
2028 /*pAd->DrsCounters.LastTimeTxRateChangeAction = pAd->DrsCounters.LastSecTxRateChangeAction; */
2029
2030 /* */
2031 /* Keep the last time TxRateChangeAction status. */
2032 /* */
2033 pEntry->LastTimeTxRateChangeAction =
2034 pEntry->LastSecTxRateChangeAction;
2035
2036 /* */
2037 /* CASE 1. when TX samples are fewer than 15, then decide TX rate solely on RSSI */
2038 /* (criteria copied from RT2500 for Netopia case) */
2039 /* */
2040 if (TxTotalCnt <= 15) {
2041 char idx = 0;
2042 u8 TxRateIdx;
2043 u8 MCS0 = 0, MCS1 = 0, MCS2 = 0, MCS3 = 0, MCS4 =
2044 0, MCS5 = 0, MCS6 = 0, MCS7 = 0;
2045 u8 MCS12 = 0, MCS13 = 0, MCS14 = 0, MCS15 = 0;
2046 u8 MCS20 = 0, MCS21 = 0, MCS22 = 0, MCS23 = 0; /* 3*3 */
2047
2048 /* check the existence and index of each needed MCS */
2049 while (idx < pTable[0]) {
2050 pCurrTxRate =
2051 (struct rt_rtmp_tx_rate_switch *) & pTable[(idx + 1) *
2052 5];
2053
2054 if (pCurrTxRate->CurrMCS == MCS_0) {
2055 MCS0 = idx;
2056 } else if (pCurrTxRate->CurrMCS == MCS_1) {
2057 MCS1 = idx;
2058 } else if (pCurrTxRate->CurrMCS == MCS_2) {
2059 MCS2 = idx;
2060 } else if (pCurrTxRate->CurrMCS == MCS_3) {
2061 MCS3 = idx;
2062 } else if (pCurrTxRate->CurrMCS == MCS_4) {
2063 MCS4 = idx;
2064 } else if (pCurrTxRate->CurrMCS == MCS_5) {
2065 MCS5 = idx;
2066 } else if (pCurrTxRate->CurrMCS == MCS_6) {
2067 MCS6 = idx;
2068 }
2069 /*else if (pCurrTxRate->CurrMCS == MCS_7) */
2070 else if ((pCurrTxRate->CurrMCS == MCS_7) && (pCurrTxRate->ShortGI == GI_800)) /* prevent the highest MCS using short GI when 1T and low throughput */
2071 {
2072 MCS7 = idx;
2073 } else if (pCurrTxRate->CurrMCS == MCS_12) {
2074 MCS12 = idx;
2075 } else if (pCurrTxRate->CurrMCS == MCS_13) {
2076 MCS13 = idx;
2077 } else if (pCurrTxRate->CurrMCS == MCS_14) {
2078 MCS14 = idx;
2079 }
2080 else if ((pCurrTxRate->CurrMCS == MCS_15) && (pCurrTxRate->ShortGI == GI_800)) /*we hope to use ShortGI as initial rate, however Atheros's chip has bugs when short GI */
2081 {
2082 MCS15 = idx;
2083 } else if (pCurrTxRate->CurrMCS == MCS_20) /* 3*3 */
2084 {
2085 MCS20 = idx;
2086 } else if (pCurrTxRate->CurrMCS == MCS_21) {
2087 MCS21 = idx;
2088 } else if (pCurrTxRate->CurrMCS == MCS_22) {
2089 MCS22 = idx;
2090 } else if (pCurrTxRate->CurrMCS == MCS_23) {
2091 MCS23 = idx;
2092 }
2093 idx++;
2094 }
2095
2096 if (pAd->LatchRfRegs.Channel <= 14) {
2097 if (pAd->NicConfig2.field.ExternalLNAForG) {
2098 RssiOffset = 2;
2099 } else {
2100 RssiOffset = 5;
2101 }
2102 } else {
2103 if (pAd->NicConfig2.field.ExternalLNAForA) {
2104 RssiOffset = 5;
2105 } else {
2106 RssiOffset = 8;
2107 }
2108 }
2109
2110 /*if (MCS15) */
2111 if ((pTable == RateSwitchTable11BGN3S) || (pTable == RateSwitchTable11N3S) || (pTable == RateSwitchTable)) { /* N mode with 3 stream // 3*3 */
2112 if (MCS23 && (Rssi >= -70))
2113 TxRateIdx = MCS23;
2114 else if (MCS22 && (Rssi >= -72))
2115 TxRateIdx = MCS22;
2116 else if (MCS21 && (Rssi >= -76))
2117 TxRateIdx = MCS21;
2118 else if (MCS20 && (Rssi >= -78))
2119 TxRateIdx = MCS20;
2120 else if (MCS4 && (Rssi >= -82))
2121 TxRateIdx = MCS4;
2122 else if (MCS3 && (Rssi >= -84))
2123 TxRateIdx = MCS3;
2124 else if (MCS2 && (Rssi >= -86))
2125 TxRateIdx = MCS2;
2126 else if (MCS1 && (Rssi >= -88))
2127 TxRateIdx = MCS1;
2128 else
2129 TxRateIdx = MCS0;
2130 }
2131/* else if ((pTable == RateSwitchTable11BGN2S) || (pTable == RateSwitchTable11BGN2SForABand) ||(pTable == RateSwitchTable11N2S) ||(pTable == RateSwitchTable11N2SForABand) || (pTable == RateSwitchTable)) */
2132 else if ((pTable == RateSwitchTable11BGN2S) || (pTable == RateSwitchTable11BGN2SForABand) || (pTable == RateSwitchTable11N2S) || (pTable == RateSwitchTable11N2SForABand)) /* 3*3 */
2133 { /* N mode with 2 stream */
2134 if (MCS15 && (Rssi >= (-70 + RssiOffset)))
2135 TxRateIdx = MCS15;
2136 else if (MCS14 && (Rssi >= (-72 + RssiOffset)))
2137 TxRateIdx = MCS14;
2138 else if (MCS13 && (Rssi >= (-76 + RssiOffset)))
2139 TxRateIdx = MCS13;
2140 else if (MCS12 && (Rssi >= (-78 + RssiOffset)))
2141 TxRateIdx = MCS12;
2142 else if (MCS4 && (Rssi >= (-82 + RssiOffset)))
2143 TxRateIdx = MCS4;
2144 else if (MCS3 && (Rssi >= (-84 + RssiOffset)))
2145 TxRateIdx = MCS3;
2146 else if (MCS2 && (Rssi >= (-86 + RssiOffset)))
2147 TxRateIdx = MCS2;
2148 else if (MCS1 && (Rssi >= (-88 + RssiOffset)))
2149 TxRateIdx = MCS1;
2150 else
2151 TxRateIdx = MCS0;
2152 } else if ((pTable == RateSwitchTable11BGN1S) || (pTable == RateSwitchTable11N1S)) { /* N mode with 1 stream */
2153 if (MCS7 && (Rssi > (-72 + RssiOffset)))
2154 TxRateIdx = MCS7;
2155 else if (MCS6 && (Rssi > (-74 + RssiOffset)))
2156 TxRateIdx = MCS6;
2157 else if (MCS5 && (Rssi > (-77 + RssiOffset)))
2158 TxRateIdx = MCS5;
2159 else if (MCS4 && (Rssi > (-79 + RssiOffset)))
2160 TxRateIdx = MCS4;
2161 else if (MCS3 && (Rssi > (-81 + RssiOffset)))
2162 TxRateIdx = MCS3;
2163 else if (MCS2 && (Rssi > (-83 + RssiOffset)))
2164 TxRateIdx = MCS2;
2165 else if (MCS1 && (Rssi > (-86 + RssiOffset)))
2166 TxRateIdx = MCS1;
2167 else
2168 TxRateIdx = MCS0;
2169 } else { /* Legacy mode */
2170 if (MCS7 && (Rssi > -70))
2171 TxRateIdx = MCS7;
2172 else if (MCS6 && (Rssi > -74))
2173 TxRateIdx = MCS6;
2174 else if (MCS5 && (Rssi > -78))
2175 TxRateIdx = MCS5;
2176 else if (MCS4 && (Rssi > -82))
2177 TxRateIdx = MCS4;
2178 else if (MCS4 == 0) /* for B-only mode */
2179 TxRateIdx = MCS3;
2180 else if (MCS3 && (Rssi > -85))
2181 TxRateIdx = MCS3;
2182 else if (MCS2 && (Rssi > -87))
2183 TxRateIdx = MCS2;
2184 else if (MCS1 && (Rssi > -90))
2185 TxRateIdx = MCS1;
2186 else
2187 TxRateIdx = MCS0;
2188 }
2189
2190 /* if (TxRateIdx != pAd->CommonCfg.TxRateIndex) */
2191 {
2192 pEntry->CurrTxRateIndex = TxRateIdx;
2193 pNextTxRate =
2194 (struct rt_rtmp_tx_rate_switch *) &
2195 pTable[(pEntry->CurrTxRateIndex + 1) * 5];
2196 MlmeSetTxRate(pAd, pEntry, pNextTxRate);
2197 }
2198
2199 NdisZeroMemory(pEntry->TxQuality,
2200 sizeof(u16)*
2201 MAX_STEP_OF_TX_RATE_SWITCH);
2202 NdisZeroMemory(pEntry->PER,
2203 sizeof(u8)*
2204 MAX_STEP_OF_TX_RATE_SWITCH);
2205 pEntry->fLastSecAccordingRSSI = TRUE;
2206 /* reset all OneSecTx counters */
2207 RESET_ONE_SEC_TX_CNT(pEntry);
2208
2209 continue;
2210 }
2211
2212 if (pEntry->fLastSecAccordingRSSI == TRUE) {
2213 pEntry->fLastSecAccordingRSSI = FALSE;
2214 pEntry->LastSecTxRateChangeAction = 0;
2215 /* reset all OneSecTx counters */
2216 RESET_ONE_SEC_TX_CNT(pEntry);
2217
2218 continue;
2219 }
2220
2221 do {
2222 BOOLEAN bTrainUpDown = FALSE;
2223
2224 pEntry->CurrTxRateStableTime++;
2225
2226 /* downgrade TX quality if PER >= Rate-Down threshold */
2227 if (TxErrorRatio >= TrainDown) {
2228 bTrainUpDown = TRUE;
2229 pEntry->TxQuality[CurrRateIdx] =
2230 DRS_TX_QUALITY_WORST_BOUND;
2231 }
2232 /* upgrade TX quality if PER <= Rate-Up threshold */
2233 else if (TxErrorRatio <= TrainUp) {
2234 bTrainUpDown = TRUE;
2235 bUpgradeQuality = TRUE;
2236 if (pEntry->TxQuality[CurrRateIdx])
2237 pEntry->TxQuality[CurrRateIdx]--; /* quality very good in CurrRate */
2238
2239 if (pEntry->TxRateUpPenalty)
2240 pEntry->TxRateUpPenalty--;
2241 else if (pEntry->TxQuality[UpRateIdx])
2242 pEntry->TxQuality[UpRateIdx]--; /* may improve next UP rate's quality */
2243 }
2244
2245 pEntry->PER[CurrRateIdx] = (u8)TxErrorRatio;
2246
2247 if (bTrainUpDown) {
2248 /* perform DRS - consider TxRate Down first, then rate up. */
2249 if ((CurrRateIdx != DownRateIdx)
2250 && (pEntry->TxQuality[CurrRateIdx] >=
2251 DRS_TX_QUALITY_WORST_BOUND)) {
2252 pEntry->CurrTxRateIndex = DownRateIdx;
2253 } else if ((CurrRateIdx != UpRateIdx)
2254 && (pEntry->TxQuality[UpRateIdx] <=
2255 0)) {
2256 pEntry->CurrTxRateIndex = UpRateIdx;
2257 }
2258 }
2259 } while (FALSE);
2260
2261 /* if rate-up happen, clear all bad history of all TX rates */
2262 if (pEntry->CurrTxRateIndex > CurrRateIdx) {
2263 pEntry->CurrTxRateStableTime = 0;
2264 pEntry->TxRateUpPenalty = 0;
2265 pEntry->LastSecTxRateChangeAction = 1; /* rate UP */
2266 NdisZeroMemory(pEntry->TxQuality,
2267 sizeof(u16)*
2268 MAX_STEP_OF_TX_RATE_SWITCH);
2269 NdisZeroMemory(pEntry->PER,
2270 sizeof(u8)*
2271 MAX_STEP_OF_TX_RATE_SWITCH);
2272
2273 /* */
2274 /* For TxRate fast train up */
2275 /* */
2276 if (!pAd->StaCfg.StaQuickResponeForRateUpTimerRunning) {
2277 RTMPSetTimer(&pAd->StaCfg.
2278 StaQuickResponeForRateUpTimer,
2279 100);
2280
2281 pAd->StaCfg.
2282 StaQuickResponeForRateUpTimerRunning = TRUE;
2283 }
2284 bTxRateChanged = TRUE;
2285 }
2286 /* if rate-down happen, only clear DownRate's bad history */
2287 else if (pEntry->CurrTxRateIndex < CurrRateIdx) {
2288 pEntry->CurrTxRateStableTime = 0;
2289 pEntry->TxRateUpPenalty = 0; /* no penalty */
2290 pEntry->LastSecTxRateChangeAction = 2; /* rate DOWN */
2291 pEntry->TxQuality[pEntry->CurrTxRateIndex] = 0;
2292 pEntry->PER[pEntry->CurrTxRateIndex] = 0;
2293
2294 /* */
2295 /* For TxRate fast train down */
2296 /* */
2297 if (!pAd->StaCfg.StaQuickResponeForRateUpTimerRunning) {
2298 RTMPSetTimer(&pAd->StaCfg.
2299 StaQuickResponeForRateUpTimer,
2300 100);
2301
2302 pAd->StaCfg.
2303 StaQuickResponeForRateUpTimerRunning = TRUE;
2304 }
2305 bTxRateChanged = TRUE;
2306 } else {
2307 pEntry->LastSecTxRateChangeAction = 0; /* rate no change */
2308 bTxRateChanged = FALSE;
2309 }
2310
2311 pEntry->LastTxOkCount = TxSuccess;
2312 {
2313 u8 tmpTxRate;
2314
2315 /* to fix tcp ack issue */
2316 if (!bTxRateChanged
2317 && (pAd->RalinkCounters.OneSecReceivedByteCount >
2318 (pAd->RalinkCounters.
2319 OneSecTransmittedByteCount * 5))) {
2320 tmpTxRate = DownRateIdx;
2321 DBGPRINT_RAW(RT_DEBUG_TRACE,
2322 ("DRS: Rx(%d) is 5 times larger than Tx(%d), use low rate (curr=%d, tmp=%d)\n",
2323 pAd->RalinkCounters.
2324 OneSecReceivedByteCount,
2325 pAd->RalinkCounters.
2326 OneSecTransmittedByteCount,
2327 pEntry->CurrTxRateIndex,
2328 tmpTxRate));
2329 } else {
2330 tmpTxRate = pEntry->CurrTxRateIndex;
2331 }
2332
2333 pNextTxRate =
2334 (struct rt_rtmp_tx_rate_switch *) & pTable[(tmpTxRate + 1) *
2335 5];
2336 }
2337 if (bTxRateChanged && pNextTxRate) {
2338 MlmeSetTxRate(pAd, pEntry, pNextTxRate);
2339 }
2340 /* reset all OneSecTx counters */
2341 RESET_ONE_SEC_TX_CNT(pEntry);
2342 }
2343}
2344
2345/*
2346 ========================================================================
2347 Routine Description:
2348 Station side, Auto TxRate faster train up timer call back function.
2349
2350 Arguments:
2351 SystemSpecific1 - Not used.
2352 FunctionContext - Pointer to our Adapter context.
2353 SystemSpecific2 - Not used.
2354 SystemSpecific3 - Not used.
2355
2356 Return Value:
2357 None
2358
2359 ========================================================================
2360*/
2361void StaQuickResponeForRateUpExec(void *SystemSpecific1,
2362 void *FunctionContext,
2363 void *SystemSpecific2,
2364 void *SystemSpecific3)
2365{
2366 struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext;
2367 u8 UpRateIdx = 0, DownRateIdx = 0, CurrRateIdx = 0;
2368 unsigned long TxTotalCnt;
2369 unsigned long TxErrorRatio = 0;
2370 BOOLEAN bTxRateChanged; /*, bUpgradeQuality = FALSE; */
2371 struct rt_rtmp_tx_rate_switch *pCurrTxRate, *pNextTxRate = NULL;
2372 u8 *pTable;
2373 u8 TableSize = 0;
2374 u8 InitTxRateIdx = 0, TrainUp, TrainDown;
2375 TX_STA_CNT1_STRUC StaTx1;
2376 TX_STA_CNT0_STRUC TxStaCnt0;
2377 char Rssi, ratio;
2378 unsigned long TxRetransmit = 0, TxSuccess = 0, TxFailCount = 0;
2379 struct rt_mac_table_entry *pEntry;
2380 unsigned long i;
2381
2382 pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = FALSE;
2383
2384 /* */
2385 /* walk through MAC table, see if need to change AP's TX rate toward each entry */
2386 /* */
2387 for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++) {
2388 pEntry = &pAd->MacTab.Content[i];
2389
2390 /* check if this entry need to switch rate automatically */
2391 if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pEntry) == FALSE)
2392 continue;
2393
2394 if (INFRA_ON(pAd) && (i == 1))
2395 Rssi = RTMPMaxRssi(pAd,
2396 pAd->StaCfg.RssiSample.AvgRssi0,
2397 pAd->StaCfg.RssiSample.AvgRssi1,
2398 pAd->StaCfg.RssiSample.AvgRssi2);
2399 else
2400 Rssi = RTMPMaxRssi(pAd,
2401 pEntry->RssiSample.AvgRssi0,
2402 pEntry->RssiSample.AvgRssi1,
2403 pEntry->RssiSample.AvgRssi2);
2404
2405 CurrRateIdx = pAd->CommonCfg.TxRateIndex;
2406
2407 MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize,
2408 &InitTxRateIdx);
2409
2410 /* decide the next upgrade rate and downgrade rate, if any */
2411 if ((CurrRateIdx > 0) && (CurrRateIdx < (TableSize - 1))) {
2412 UpRateIdx = CurrRateIdx + 1;
2413 DownRateIdx = CurrRateIdx - 1;
2414 } else if (CurrRateIdx == 0) {
2415 UpRateIdx = CurrRateIdx + 1;
2416 DownRateIdx = CurrRateIdx;
2417 } else if (CurrRateIdx == (TableSize - 1)) {
2418 UpRateIdx = CurrRateIdx;
2419 DownRateIdx = CurrRateIdx - 1;
2420 }
2421
2422 pCurrTxRate =
2423 (struct rt_rtmp_tx_rate_switch *) & pTable[(CurrRateIdx + 1) * 5];
2424
2425 if ((Rssi > -65) && (pCurrTxRate->Mode >= MODE_HTMIX)) {
2426 TrainUp =
2427 (pCurrTxRate->TrainUp +
2428 (pCurrTxRate->TrainUp >> 1));
2429 TrainDown =
2430 (pCurrTxRate->TrainDown +
2431 (pCurrTxRate->TrainDown >> 1));
2432 } else {
2433 TrainUp = pCurrTxRate->TrainUp;
2434 TrainDown = pCurrTxRate->TrainDown;
2435 }
2436
2437 if (pAd->MacTab.Size == 1) {
2438 /* Update statistic counter */
2439 RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word);
2440 RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word);
2441
2442 TxRetransmit = StaTx1.field.TxRetransmit;
2443 TxSuccess = StaTx1.field.TxSuccess;
2444 TxFailCount = TxStaCnt0.field.TxFailCount;
2445 TxTotalCnt = TxRetransmit + TxSuccess + TxFailCount;
2446
2447 pAd->RalinkCounters.OneSecTxRetryOkCount +=
2448 StaTx1.field.TxRetransmit;
2449 pAd->RalinkCounters.OneSecTxNoRetryOkCount +=
2450 StaTx1.field.TxSuccess;
2451 pAd->RalinkCounters.OneSecTxFailCount +=
2452 TxStaCnt0.field.TxFailCount;
2453 pAd->WlanCounters.TransmittedFragmentCount.u.LowPart +=
2454 StaTx1.field.TxSuccess;
2455 pAd->WlanCounters.RetryCount.u.LowPart +=
2456 StaTx1.field.TxRetransmit;
2457 pAd->WlanCounters.FailedCount.u.LowPart +=
2458 TxStaCnt0.field.TxFailCount;
2459
2460 if (TxTotalCnt)
2461 TxErrorRatio =
2462 ((TxRetransmit +
2463 TxFailCount) * 100) / TxTotalCnt;
2464 } else {
2465 TxTotalCnt = pEntry->OneSecTxNoRetryOkCount +
2466 pEntry->OneSecTxRetryOkCount +
2467 pEntry->OneSecTxFailCount;
2468
2469 if (TxTotalCnt)
2470 TxErrorRatio =
2471 ((pEntry->OneSecTxRetryOkCount +
2472 pEntry->OneSecTxFailCount) * 100) /
2473 TxTotalCnt;
2474 }
2475
2476 /* */
2477 /* CASE 1. when TX samples are fewer than 15, then decide TX rate solely on RSSI */
2478 /* (criteria copied from RT2500 for Netopia case) */
2479 /* */
2480 if (TxTotalCnt <= 12) {
2481 NdisZeroMemory(pAd->DrsCounters.TxQuality,
2482 sizeof(u16)*
2483 MAX_STEP_OF_TX_RATE_SWITCH);
2484 NdisZeroMemory(pAd->DrsCounters.PER,
2485 sizeof(u8)*
2486 MAX_STEP_OF_TX_RATE_SWITCH);
2487
2488 if ((pAd->DrsCounters.LastSecTxRateChangeAction == 1)
2489 && (CurrRateIdx != DownRateIdx)) {
2490 pAd->CommonCfg.TxRateIndex = DownRateIdx;
2491 pAd->DrsCounters.TxQuality[CurrRateIdx] =
2492 DRS_TX_QUALITY_WORST_BOUND;
2493 } else
2494 if ((pAd->DrsCounters.LastSecTxRateChangeAction ==
2495 2) && (CurrRateIdx != UpRateIdx)) {
2496 pAd->CommonCfg.TxRateIndex = UpRateIdx;
2497 }
2498
2499 DBGPRINT_RAW(RT_DEBUG_TRACE,
2500 ("QuickDRS: TxTotalCnt <= 15, train back to original rate \n"));
2501 return;
2502 }
2503
2504 do {
2505 unsigned long OneSecTxNoRetryOKRationCount;
2506
2507 if (pAd->DrsCounters.LastTimeTxRateChangeAction == 0)
2508 ratio = 5;
2509 else
2510 ratio = 4;
2511
2512 /* downgrade TX quality if PER >= Rate-Down threshold */
2513 if (TxErrorRatio >= TrainDown) {
2514 pAd->DrsCounters.TxQuality[CurrRateIdx] =
2515 DRS_TX_QUALITY_WORST_BOUND;
2516 }
2517
2518 pAd->DrsCounters.PER[CurrRateIdx] =
2519 (u8)TxErrorRatio;
2520
2521 OneSecTxNoRetryOKRationCount = (TxSuccess * ratio);
2522
2523 /* perform DRS - consider TxRate Down first, then rate up. */
2524 if ((pAd->DrsCounters.LastSecTxRateChangeAction == 1)
2525 && (CurrRateIdx != DownRateIdx)) {
2526 if ((pAd->DrsCounters.LastTxOkCount + 2) >=
2527 OneSecTxNoRetryOKRationCount) {
2528 pAd->CommonCfg.TxRateIndex =
2529 DownRateIdx;
2530 pAd->DrsCounters.
2531 TxQuality[CurrRateIdx] =
2532 DRS_TX_QUALITY_WORST_BOUND;
2533
2534 }
2535
2536 } else
2537 if ((pAd->DrsCounters.LastSecTxRateChangeAction ==
2538 2) && (CurrRateIdx != UpRateIdx)) {
2539 if ((TxErrorRatio >= 50)
2540 || (TxErrorRatio >= TrainDown)) {
2541
2542 } else if ((pAd->DrsCounters.LastTxOkCount + 2)
2543 >= OneSecTxNoRetryOKRationCount) {
2544 pAd->CommonCfg.TxRateIndex = UpRateIdx;
2545 }
2546 }
2547 } while (FALSE);
2548
2549 /* if rate-up happen, clear all bad history of all TX rates */
2550 if (pAd->CommonCfg.TxRateIndex > CurrRateIdx) {
2551 pAd->DrsCounters.TxRateUpPenalty = 0;
2552 NdisZeroMemory(pAd->DrsCounters.TxQuality,
2553 sizeof(u16)*
2554 MAX_STEP_OF_TX_RATE_SWITCH);
2555 NdisZeroMemory(pAd->DrsCounters.PER,
2556 sizeof(u8)*
2557 MAX_STEP_OF_TX_RATE_SWITCH);
2558 bTxRateChanged = TRUE;
2559 }
2560 /* if rate-down happen, only clear DownRate's bad history */
2561 else if (pAd->CommonCfg.TxRateIndex < CurrRateIdx) {
2562 DBGPRINT_RAW(RT_DEBUG_TRACE,
2563 ("QuickDRS: --TX rate from %d to %d \n",
2564 CurrRateIdx, pAd->CommonCfg.TxRateIndex));
2565
2566 pAd->DrsCounters.TxRateUpPenalty = 0; /* no penalty */
2567 pAd->DrsCounters.TxQuality[pAd->CommonCfg.TxRateIndex] =
2568 0;
2569 pAd->DrsCounters.PER[pAd->CommonCfg.TxRateIndex] = 0;
2570 bTxRateChanged = TRUE;
2571 } else {
2572 bTxRateChanged = FALSE;
2573 }
2574
2575 pNextTxRate =
2576 (struct rt_rtmp_tx_rate_switch *) &
2577 pTable[(pAd->CommonCfg.TxRateIndex + 1) * 5];
2578 if (bTxRateChanged && pNextTxRate) {
2579 MlmeSetTxRate(pAd, pEntry, pNextTxRate);
2580 }
2581 }
2582}
2583
2584/*
2585 ==========================================================================
2586 Description:
2587 This routine is executed periodically inside MlmePeriodicExec() after
2588 association with an AP.
2589 It checks if StaCfg.Psm is consistent with user policy (recorded in
2590 StaCfg.WindowsPowerMode). If not, enforce user policy. However,
2591 there're some conditions to consider:
2592 1. we don't support power-saving in ADHOC mode, so Psm=PWR_ACTIVE all
2593 the time when Mibss==TRUE
2594 2. When link up in INFRA mode, Psm should not be switch to PWR_SAVE
2595 if outgoing traffic available in TxRing or MgmtRing.
2596 Output:
2597 1. change pAd->StaCfg.Psm to PWR_SAVE or leave it untouched
2598
2599 IRQL = DISPATCH_LEVEL
2600
2601 ==========================================================================
2602 */
2603void MlmeCheckPsmChange(struct rt_rtmp_adapter *pAd, unsigned long Now32)
2604{
2605 unsigned long PowerMode;
2606
2607 /* condition - */
2608 /* 1. Psm maybe ON only happen in INFRASTRUCTURE mode */
2609 /* 2. user wants either MAX_PSP or FAST_PSP */
2610 /* 3. but current psm is not in PWR_SAVE */
2611 /* 4. CNTL state machine is not doing SCANning */
2612 /* 5. no TX SUCCESS event for the past 1-sec period */
2613 PowerMode = pAd->StaCfg.WindowsPowerMode;
2614
2615 if (INFRA_ON(pAd) &&
2616 (PowerMode != Ndis802_11PowerModeCAM) &&
2617 (pAd->StaCfg.Psm == PWR_ACTIVE) &&
2618/* (! RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) */
2619 (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) &&
2620 RTMP_TEST_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP)
2621 /*&&
2622 (pAd->RalinkCounters.OneSecTxNoRetryOkCount == 0) &&
2623 (pAd->RalinkCounters.OneSecTxRetryOkCount == 0) */
2624 ) {
2625 NdisGetSystemUpTime(&pAd->Mlme.LastSendNULLpsmTime);
2626 pAd->RalinkCounters.RxCountSinceLastNULL = 0;
2627 RTMP_SET_PSM_BIT(pAd, PWR_SAVE);
2628 if (!
2629 (pAd->CommonCfg.bAPSDCapable
2630 && pAd->CommonCfg.APEdcaParm.bAPSDCapable)) {
2631 RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, FALSE);
2632 } else {
2633 RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
2634 }
2635 }
2636}
2637
2638/* IRQL = PASSIVE_LEVEL */
2639/* IRQL = DISPATCH_LEVEL */
2640void MlmeSetPsmBit(struct rt_rtmp_adapter *pAd, u16 psm)
2641{
2642 AUTO_RSP_CFG_STRUC csr4;
2643
2644 pAd->StaCfg.Psm = psm;
2645 RTMP_IO_READ32(pAd, AUTO_RSP_CFG, &csr4.word);
2646 csr4.field.AckCtsPsmBit = (psm == PWR_SAVE) ? 1 : 0;
2647 RTMP_IO_WRITE32(pAd, AUTO_RSP_CFG, csr4.word);
2648
2649 DBGPRINT(RT_DEBUG_TRACE, ("MlmeSetPsmBit = %d\n", psm));
2650}
2651
2652/*
2653 ==========================================================================
2654 Description:
2655 This routine calculates TxPER, RxPER of the past N-sec period. And
2656 according to the calculation result, ChannelQuality is calculated here
2657 to decide if current AP is still doing the job.
2658
2659 If ChannelQuality is not good, a ROAMing attempt may be tried later.
2660 Output:
2661 StaCfg.ChannelQuality - 0..100
2662
2663 IRQL = DISPATCH_LEVEL
2664
2665 NOTE: This routine decide channle quality based on RX CRC error ratio.
2666 Caller should make sure a function call to NICUpdateRawCounters(pAd)
2667 is performed right before this routine, so that this routine can decide
2668 channel quality based on the most up-to-date information
2669 ==========================================================================
2670 */
2671void MlmeCalculateChannelQuality(struct rt_rtmp_adapter *pAd,
2672 struct rt_mac_table_entry *pMacEntry, unsigned long Now32)
2673{
2674 unsigned long TxOkCnt, TxCnt, TxPER, TxPRR;
2675 unsigned long RxCnt, RxPER;
2676 u8 NorRssi;
2677 char MaxRssi;
2678 struct rt_rssi_sample *pRssiSample = NULL;
2679 u32 OneSecTxNoRetryOkCount = 0;
2680 u32 OneSecTxRetryOkCount = 0;
2681 u32 OneSecTxFailCount = 0;
2682 u32 OneSecRxOkCnt = 0;
2683 u32 OneSecRxFcsErrCnt = 0;
2684 unsigned long ChannelQuality = 0; /* 0..100, Channel Quality Indication for Roaming */
2685 unsigned long BeaconLostTime = pAd->StaCfg.BeaconLostTime;
2686
2687 if (pAd->OpMode == OPMODE_STA) {
2688 pRssiSample = &pAd->StaCfg.RssiSample;
2689 OneSecTxNoRetryOkCount =
2690 pAd->RalinkCounters.OneSecTxNoRetryOkCount;
2691 OneSecTxRetryOkCount = pAd->RalinkCounters.OneSecTxRetryOkCount;
2692 OneSecTxFailCount = pAd->RalinkCounters.OneSecTxFailCount;
2693 OneSecRxOkCnt = pAd->RalinkCounters.OneSecRxOkCnt;
2694 OneSecRxFcsErrCnt = pAd->RalinkCounters.OneSecRxFcsErrCnt;
2695 }
2696
2697 MaxRssi = RTMPMaxRssi(pAd, pRssiSample->LastRssi0,
2698 pRssiSample->LastRssi1, pRssiSample->LastRssi2);
2699
2700 /* */
2701 /* calculate TX packet error ratio and TX retry ratio - if too few TX samples, skip TX related statistics */
2702 /* */
2703 TxOkCnt = OneSecTxNoRetryOkCount + OneSecTxRetryOkCount;
2704 TxCnt = TxOkCnt + OneSecTxFailCount;
2705 if (TxCnt < 5) {
2706 TxPER = 0;
2707 TxPRR = 0;
2708 } else {
2709 TxPER = (OneSecTxFailCount * 100) / TxCnt;
2710 TxPRR = ((TxCnt - OneSecTxNoRetryOkCount) * 100) / TxCnt;
2711 }
2712
2713 /* */
2714 /* calculate RX PER - don't take RxPER into consideration if too few sample */
2715 /* */
2716 RxCnt = OneSecRxOkCnt + OneSecRxFcsErrCnt;
2717 if (RxCnt < 5)
2718 RxPER = 0;
2719 else
2720 RxPER = (OneSecRxFcsErrCnt * 100) / RxCnt;
2721
2722 /* */
2723 /* decide ChannelQuality based on: 1)last BEACON received time, 2)last RSSI, 3)TxPER, and 4)RxPER */
2724 /* */
2725 if ((pAd->OpMode == OPMODE_STA) && INFRA_ON(pAd) && (OneSecTxNoRetryOkCount < 2) && /* no heavy traffic */
2726 ((pAd->StaCfg.LastBeaconRxTime + BeaconLostTime) < Now32)) {
2727 DBGPRINT(RT_DEBUG_TRACE,
2728 ("BEACON lost > %ld msec with TxOkCnt=%ld -> CQI=0\n",
2729 BeaconLostTime, TxOkCnt));
2730 ChannelQuality = 0;
2731 } else {
2732 /* Normalize Rssi */
2733 if (MaxRssi > -40)
2734 NorRssi = 100;
2735 else if (MaxRssi < -90)
2736 NorRssi = 0;
2737 else
2738 NorRssi = (MaxRssi + 90) * 2;
2739
2740 /* ChannelQuality = W1*RSSI + W2*TxPRR + W3*RxPER (RSSI 0..100), (TxPER 100..0), (RxPER 100..0) */
2741 ChannelQuality = (RSSI_WEIGHTING * NorRssi +
2742 TX_WEIGHTING * (100 - TxPRR) +
2743 RX_WEIGHTING * (100 - RxPER)) / 100;
2744 }
2745
2746 if (pAd->OpMode == OPMODE_STA)
2747 pAd->Mlme.ChannelQuality =
2748 (ChannelQuality > 100) ? 100 : ChannelQuality;
2749
2750}
2751
2752/* IRQL = DISPATCH_LEVEL */
2753void MlmeSetTxPreamble(struct rt_rtmp_adapter *pAd, u16 TxPreamble)
2754{
2755 AUTO_RSP_CFG_STRUC csr4;
2756
2757 /* */
2758 /* Always use Long preamble before verifiation short preamble functionality works well. */
2759 /* Todo: remove the following line if short preamble functionality works */
2760 /* */
2761 /*TxPreamble = Rt802_11PreambleLong; */
2762
2763 RTMP_IO_READ32(pAd, AUTO_RSP_CFG, &csr4.word);
2764 if (TxPreamble == Rt802_11PreambleLong) {
2765 DBGPRINT(RT_DEBUG_TRACE,
2766 ("MlmeSetTxPreamble (= long PREAMBLE)\n"));
2767 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
2768 csr4.field.AutoResponderPreamble = 0;
2769 } else {
2770 /* NOTE: 1Mbps should always use long preamble */
2771 DBGPRINT(RT_DEBUG_TRACE,
2772 ("MlmeSetTxPreamble (= short PREAMBLE)\n"));
2773 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
2774 csr4.field.AutoResponderPreamble = 1;
2775 }
2776
2777 RTMP_IO_WRITE32(pAd, AUTO_RSP_CFG, csr4.word);
2778}
2779
2780/*
2781 ==========================================================================
2782 Description:
2783 Update basic rate bitmap
2784 ==========================================================================
2785 */
2786
2787void UpdateBasicRateBitmap(struct rt_rtmp_adapter *pAdapter)
2788{
2789 int i, j;
2790 /* 1 2 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54 */
2791 u8 rate[] = { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 };
2792 u8 *sup_p = pAdapter->CommonCfg.SupRate;
2793 u8 *ext_p = pAdapter->CommonCfg.ExtRate;
2794 unsigned long bitmap = pAdapter->CommonCfg.BasicRateBitmap;
2795
2796 /* if A mode, always use fix BasicRateBitMap */
2797 /*if (pAdapter->CommonCfg.Channel == PHY_11A) */
2798 if (pAdapter->CommonCfg.Channel > 14)
2799 pAdapter->CommonCfg.BasicRateBitmap = 0x150; /* 6, 12, 24M */
2800 /* End of if */
2801
2802 if (pAdapter->CommonCfg.BasicRateBitmap > 4095) {
2803 /* (2 ^ MAX_LEN_OF_SUPPORTED_RATES) -1 */
2804 return;
2805 }
2806 /* End of if */
2807 for (i = 0; i < MAX_LEN_OF_SUPPORTED_RATES; i++) {
2808 sup_p[i] &= 0x7f;
2809 ext_p[i] &= 0x7f;
2810 } /* End of for */
2811
2812 for (i = 0; i < MAX_LEN_OF_SUPPORTED_RATES; i++) {
2813 if (bitmap & (1 << i)) {
2814 for (j = 0; j < MAX_LEN_OF_SUPPORTED_RATES; j++) {
2815 if (sup_p[j] == rate[i])
2816 sup_p[j] |= 0x80;
2817 /* End of if */
2818 } /* End of for */
2819
2820 for (j = 0; j < MAX_LEN_OF_SUPPORTED_RATES; j++) {
2821 if (ext_p[j] == rate[i])
2822 ext_p[j] |= 0x80;
2823 /* End of if */
2824 } /* End of for */
2825 } /* End of if */
2826 } /* End of for */
2827} /* End of UpdateBasicRateBitmap */
2828
2829/* IRQL = PASSIVE_LEVEL */
2830/* IRQL = DISPATCH_LEVEL */
2831/* bLinkUp is to identify the initial link speed. */
2832/* TRUE indicates the rate update at linkup, we should not try to set the rate at 54Mbps. */
2833void MlmeUpdateTxRates(struct rt_rtmp_adapter *pAd, IN BOOLEAN bLinkUp, u8 apidx)
2834{
2835 int i, num;
2836 u8 Rate = RATE_6, MaxDesire = RATE_1, MaxSupport = RATE_1;
2837 u8 MinSupport = RATE_54;
2838 unsigned long BasicRateBitmap = 0;
2839 u8 CurrBasicRate = RATE_1;
2840 u8 *pSupRate, SupRateLen, *pExtRate, ExtRateLen;
2841 PHTTRANSMIT_SETTING pHtPhy = NULL;
2842 PHTTRANSMIT_SETTING pMaxHtPhy = NULL;
2843 PHTTRANSMIT_SETTING pMinHtPhy = NULL;
2844 BOOLEAN *auto_rate_cur_p;
2845 u8 HtMcs = MCS_AUTO;
2846
2847 /* find max desired rate */
2848 UpdateBasicRateBitmap(pAd);
2849
2850 num = 0;
2851 auto_rate_cur_p = NULL;
2852 for (i = 0; i < MAX_LEN_OF_SUPPORTED_RATES; i++) {
2853 switch (pAd->CommonCfg.DesireRate[i] & 0x7f) {
2854 case 2:
2855 Rate = RATE_1;
2856 num++;
2857 break;
2858 case 4:
2859 Rate = RATE_2;
2860 num++;
2861 break;
2862 case 11:
2863 Rate = RATE_5_5;
2864 num++;
2865 break;
2866 case 22:
2867 Rate = RATE_11;
2868 num++;
2869 break;
2870 case 12:
2871 Rate = RATE_6;
2872 num++;
2873 break;
2874 case 18:
2875 Rate = RATE_9;
2876 num++;
2877 break;
2878 case 24:
2879 Rate = RATE_12;
2880 num++;
2881 break;
2882 case 36:
2883 Rate = RATE_18;
2884 num++;
2885 break;
2886 case 48:
2887 Rate = RATE_24;
2888 num++;
2889 break;
2890 case 72:
2891 Rate = RATE_36;
2892 num++;
2893 break;
2894 case 96:
2895 Rate = RATE_48;
2896 num++;
2897 break;
2898 case 108:
2899 Rate = RATE_54;
2900 num++;
2901 break;
2902 /*default: Rate = RATE_1; break; */
2903 }
2904 if (MaxDesire < Rate)
2905 MaxDesire = Rate;
2906 }
2907
2908/*=========================================================================== */
2909/*=========================================================================== */
2910 {
2911 pHtPhy = &pAd->StaCfg.HTPhyMode;
2912 pMaxHtPhy = &pAd->StaCfg.MaxHTPhyMode;
2913 pMinHtPhy = &pAd->StaCfg.MinHTPhyMode;
2914
2915 auto_rate_cur_p = &pAd->StaCfg.bAutoTxRateSwitch;
2916 HtMcs = pAd->StaCfg.DesiredTransmitSetting.field.MCS;
2917
2918 if ((pAd->StaCfg.BssType == BSS_ADHOC) &&
2919 (pAd->CommonCfg.PhyMode == PHY_11B) &&
2920 (MaxDesire > RATE_11)) {
2921 MaxDesire = RATE_11;
2922 }
2923 }
2924
2925 pAd->CommonCfg.MaxDesiredRate = MaxDesire;
2926 pMinHtPhy->word = 0;
2927 pMaxHtPhy->word = 0;
2928 pHtPhy->word = 0;
2929
2930 /* Auto rate switching is enabled only if more than one DESIRED RATES are */
2931 /* specified; otherwise disabled */
2932 if (num <= 1) {
2933 /*OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED); */
2934 /*pAd->CommonCfg.bAutoTxRateSwitch = FALSE; */
2935 *auto_rate_cur_p = FALSE;
2936 } else {
2937 /*OPSTATUS_SET_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED); */
2938 /*pAd->CommonCfg.bAutoTxRateSwitch = TRUE; */
2939 *auto_rate_cur_p = TRUE;
2940 }
2941
2942 if (HtMcs != MCS_AUTO) {
2943 /*OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED); */
2944 /*pAd->CommonCfg.bAutoTxRateSwitch = FALSE; */
2945 *auto_rate_cur_p = FALSE;
2946 } else {
2947 /*OPSTATUS_SET_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED); */
2948 /*pAd->CommonCfg.bAutoTxRateSwitch = TRUE; */
2949 *auto_rate_cur_p = TRUE;
2950 }
2951
2952 if ((ADHOC_ON(pAd) || INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA)) {
2953 pSupRate = &pAd->StaActive.SupRate[0];
2954 pExtRate = &pAd->StaActive.ExtRate[0];
2955 SupRateLen = pAd->StaActive.SupRateLen;
2956 ExtRateLen = pAd->StaActive.ExtRateLen;
2957 } else {
2958 pSupRate = &pAd->CommonCfg.SupRate[0];
2959 pExtRate = &pAd->CommonCfg.ExtRate[0];
2960 SupRateLen = pAd->CommonCfg.SupRateLen;
2961 ExtRateLen = pAd->CommonCfg.ExtRateLen;
2962 }
2963
2964 /* find max supported rate */
2965 for (i = 0; i < SupRateLen; i++) {
2966 switch (pSupRate[i] & 0x7f) {
2967 case 2:
2968 Rate = RATE_1;
2969 if (pSupRate[i] & 0x80)
2970 BasicRateBitmap |= 0x0001;
2971 break;
2972 case 4:
2973 Rate = RATE_2;
2974 if (pSupRate[i] & 0x80)
2975 BasicRateBitmap |= 0x0002;
2976 break;
2977 case 11:
2978 Rate = RATE_5_5;
2979 if (pSupRate[i] & 0x80)
2980 BasicRateBitmap |= 0x0004;
2981 break;
2982 case 22:
2983 Rate = RATE_11;
2984 if (pSupRate[i] & 0x80)
2985 BasicRateBitmap |= 0x0008;
2986 break;
2987 case 12:
2988 Rate = RATE_6; /*if (pSupRate[i] & 0x80) */
2989 BasicRateBitmap |= 0x0010;
2990 break;
2991 case 18:
2992 Rate = RATE_9;
2993 if (pSupRate[i] & 0x80)
2994 BasicRateBitmap |= 0x0020;
2995 break;
2996 case 24:
2997 Rate = RATE_12; /*if (pSupRate[i] & 0x80) */
2998 BasicRateBitmap |= 0x0040;
2999 break;
3000 case 36:
3001 Rate = RATE_18;
3002 if (pSupRate[i] & 0x80)
3003 BasicRateBitmap |= 0x0080;
3004 break;
3005 case 48:
3006 Rate = RATE_24; /*if (pSupRate[i] & 0x80) */
3007 BasicRateBitmap |= 0x0100;
3008 break;
3009 case 72:
3010 Rate = RATE_36;
3011 if (pSupRate[i] & 0x80)
3012 BasicRateBitmap |= 0x0200;
3013 break;
3014 case 96:
3015 Rate = RATE_48;
3016 if (pSupRate[i] & 0x80)
3017 BasicRateBitmap |= 0x0400;
3018 break;
3019 case 108:
3020 Rate = RATE_54;
3021 if (pSupRate[i] & 0x80)
3022 BasicRateBitmap |= 0x0800;
3023 break;
3024 default:
3025 Rate = RATE_1;
3026 break;
3027 }
3028 if (MaxSupport < Rate)
3029 MaxSupport = Rate;
3030
3031 if (MinSupport > Rate)
3032 MinSupport = Rate;
3033 }
3034
3035 for (i = 0; i < ExtRateLen; i++) {
3036 switch (pExtRate[i] & 0x7f) {
3037 case 2:
3038 Rate = RATE_1;
3039 if (pExtRate[i] & 0x80)
3040 BasicRateBitmap |= 0x0001;
3041 break;
3042 case 4:
3043 Rate = RATE_2;
3044 if (pExtRate[i] & 0x80)
3045 BasicRateBitmap |= 0x0002;
3046 break;
3047 case 11:
3048 Rate = RATE_5_5;
3049 if (pExtRate[i] & 0x80)
3050 BasicRateBitmap |= 0x0004;
3051 break;
3052 case 22:
3053 Rate = RATE_11;
3054 if (pExtRate[i] & 0x80)
3055 BasicRateBitmap |= 0x0008;
3056 break;
3057 case 12:
3058 Rate = RATE_6; /*if (pExtRate[i] & 0x80) */
3059 BasicRateBitmap |= 0x0010;
3060 break;
3061 case 18:
3062 Rate = RATE_9;
3063 if (pExtRate[i] & 0x80)
3064 BasicRateBitmap |= 0x0020;
3065 break;
3066 case 24:
3067 Rate = RATE_12; /*if (pExtRate[i] & 0x80) */
3068 BasicRateBitmap |= 0x0040;
3069 break;
3070 case 36:
3071 Rate = RATE_18;
3072 if (pExtRate[i] & 0x80)
3073 BasicRateBitmap |= 0x0080;
3074 break;
3075 case 48:
3076 Rate = RATE_24; /*if (pExtRate[i] & 0x80) */
3077 BasicRateBitmap |= 0x0100;
3078 break;
3079 case 72:
3080 Rate = RATE_36;
3081 if (pExtRate[i] & 0x80)
3082 BasicRateBitmap |= 0x0200;
3083 break;
3084 case 96:
3085 Rate = RATE_48;
3086 if (pExtRate[i] & 0x80)
3087 BasicRateBitmap |= 0x0400;
3088 break;
3089 case 108:
3090 Rate = RATE_54;
3091 if (pExtRate[i] & 0x80)
3092 BasicRateBitmap |= 0x0800;
3093 break;
3094 default:
3095 Rate = RATE_1;
3096 break;
3097 }
3098 if (MaxSupport < Rate)
3099 MaxSupport = Rate;
3100
3101 if (MinSupport > Rate)
3102 MinSupport = Rate;
3103 }
3104
3105 RTMP_IO_WRITE32(pAd, LEGACY_BASIC_RATE, BasicRateBitmap);
3106
3107 /* bug fix */
3108 /* pAd->CommonCfg.BasicRateBitmap = BasicRateBitmap; */
3109
3110 /* calculate the exptected ACK rate for each TX rate. This info is used to caculate */
3111 /* the DURATION field of outgoing uniicast DATA/MGMT frame */
3112 for (i = 0; i < MAX_LEN_OF_SUPPORTED_RATES; i++) {
3113 if (BasicRateBitmap & (0x01 << i))
3114 CurrBasicRate = (u8)i;
3115 pAd->CommonCfg.ExpectedACKRate[i] = CurrBasicRate;
3116 }
3117
3118 DBGPRINT(RT_DEBUG_TRACE,
3119 ("MlmeUpdateTxRates[MaxSupport = %d] = MaxDesire %d Mbps\n",
3120 RateIdToMbps[MaxSupport], RateIdToMbps[MaxDesire]));
3121 /* max tx rate = min {max desire rate, max supported rate} */
3122 if (MaxSupport < MaxDesire)
3123 pAd->CommonCfg.MaxTxRate = MaxSupport;
3124 else
3125 pAd->CommonCfg.MaxTxRate = MaxDesire;
3126
3127 pAd->CommonCfg.MinTxRate = MinSupport;
3128 /* 2003-07-31 john - 2500 doesn't have good sensitivity at high OFDM rates. to increase the success */
3129 /* ratio of initial DHCP packet exchange, TX rate starts from a lower rate depending */
3130 /* on average RSSI */
3131 /* 1. RSSI >= -70db, start at 54 Mbps (short distance) */
3132 /* 2. -70 > RSSI >= -75, start at 24 Mbps (mid distance) */
3133 /* 3. -75 > RSSI, start at 11 Mbps (long distance) */
3134 if (*auto_rate_cur_p) {
3135 short dbm = 0;
3136
3137 dbm = pAd->StaCfg.RssiSample.AvgRssi0 - pAd->BbpRssiToDbmDelta;
3138
3139 if (bLinkUp == TRUE)
3140 pAd->CommonCfg.TxRate = RATE_24;
3141 else
3142 pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate;
3143
3144 if (dbm < -75)
3145 pAd->CommonCfg.TxRate = RATE_11;
3146 else if (dbm < -70)
3147 pAd->CommonCfg.TxRate = RATE_24;
3148
3149 /* should never exceed MaxTxRate (consider 11B-only mode) */
3150 if (pAd->CommonCfg.TxRate > pAd->CommonCfg.MaxTxRate)
3151 pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate;
3152
3153 pAd->CommonCfg.TxRateIndex = 0;
3154 } else {
3155 pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate;
3156 pHtPhy->field.MCS =
3157 (pAd->CommonCfg.MaxTxRate >
3158 3) ? (pAd->CommonCfg.MaxTxRate -
3159 4) : pAd->CommonCfg.MaxTxRate;
3160 pHtPhy->field.MODE =
3161 (pAd->CommonCfg.MaxTxRate > 3) ? MODE_OFDM : MODE_CCK;
3162
3163 pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.STBC =
3164 pHtPhy->field.STBC;
3165 pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.ShortGI =
3166 pHtPhy->field.ShortGI;
3167 pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MCS =
3168 pHtPhy->field.MCS;
3169 pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE =
3170 pHtPhy->field.MODE;
3171 }
3172
3173 if (pAd->CommonCfg.TxRate <= RATE_11) {
3174 pMaxHtPhy->field.MODE = MODE_CCK;
3175 pMaxHtPhy->field.MCS = pAd->CommonCfg.TxRate;
3176 pMinHtPhy->field.MCS = pAd->CommonCfg.MinTxRate;
3177 } else {
3178 pMaxHtPhy->field.MODE = MODE_OFDM;
3179 pMaxHtPhy->field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.TxRate];
3180 if (pAd->CommonCfg.MinTxRate >= RATE_6
3181 && (pAd->CommonCfg.MinTxRate <= RATE_54)) {
3182 pMinHtPhy->field.MCS =
3183 OfdmRateToRxwiMCS[pAd->CommonCfg.MinTxRate];
3184 } else {
3185 pMinHtPhy->field.MCS = pAd->CommonCfg.MinTxRate;
3186 }
3187 }
3188
3189 pHtPhy->word = (pMaxHtPhy->word);
3190 if (bLinkUp && (pAd->OpMode == OPMODE_STA)) {
3191 pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word = pHtPhy->word;
3192 pAd->MacTab.Content[BSSID_WCID].MaxHTPhyMode.word =
3193 pMaxHtPhy->word;
3194 pAd->MacTab.Content[BSSID_WCID].MinHTPhyMode.word =
3195 pMinHtPhy->word;
3196 } else {
3197 switch (pAd->CommonCfg.PhyMode) {
3198 case PHY_11BG_MIXED:
3199 case PHY_11B:
3200 case PHY_11BGN_MIXED:
3201 pAd->CommonCfg.MlmeRate = RATE_1;
3202 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
3203 pAd->CommonCfg.MlmeTransmit.field.MCS = RATE_1;
3204
3205/*#ifdef WIFI_TEST */
3206 pAd->CommonCfg.RtsRate = RATE_11;
3207/*#else */
3208/* pAd->CommonCfg.RtsRate = RATE_1; */
3209/*#endif */
3210 break;
3211 case PHY_11G:
3212 case PHY_11A:
3213 case PHY_11AGN_MIXED:
3214 case PHY_11GN_MIXED:
3215 case PHY_11N_2_4G:
3216 case PHY_11AN_MIXED:
3217 case PHY_11N_5G:
3218 pAd->CommonCfg.MlmeRate = RATE_6;
3219 pAd->CommonCfg.RtsRate = RATE_6;
3220 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
3221 pAd->CommonCfg.MlmeTransmit.field.MCS =
3222 OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
3223 break;
3224 case PHY_11ABG_MIXED:
3225 case PHY_11ABGN_MIXED:
3226 if (pAd->CommonCfg.Channel <= 14) {
3227 pAd->CommonCfg.MlmeRate = RATE_1;
3228 pAd->CommonCfg.RtsRate = RATE_1;
3229 pAd->CommonCfg.MlmeTransmit.field.MODE =
3230 MODE_CCK;
3231 pAd->CommonCfg.MlmeTransmit.field.MCS = RATE_1;
3232 } else {
3233 pAd->CommonCfg.MlmeRate = RATE_6;
3234 pAd->CommonCfg.RtsRate = RATE_6;
3235 pAd->CommonCfg.MlmeTransmit.field.MODE =
3236 MODE_OFDM;
3237 pAd->CommonCfg.MlmeTransmit.field.MCS =
3238 OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
3239 }
3240 break;
3241 default: /* error */
3242 pAd->CommonCfg.MlmeRate = RATE_6;
3243 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
3244 pAd->CommonCfg.MlmeTransmit.field.MCS =
3245 OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
3246 pAd->CommonCfg.RtsRate = RATE_1;
3247 break;
3248 }
3249 /* */
3250 /* Keep Basic Mlme Rate. */
3251 /* */
3252 pAd->MacTab.Content[MCAST_WCID].HTPhyMode.word =
3253 pAd->CommonCfg.MlmeTransmit.word;
3254 if (pAd->CommonCfg.MlmeTransmit.field.MODE == MODE_OFDM)
3255 pAd->MacTab.Content[MCAST_WCID].HTPhyMode.field.MCS =
3256 OfdmRateToRxwiMCS[RATE_24];
3257 else
3258 pAd->MacTab.Content[MCAST_WCID].HTPhyMode.field.MCS =
3259 RATE_1;
3260 pAd->CommonCfg.BasicMlmeRate = pAd->CommonCfg.MlmeRate;
3261 }
3262
3263 DBGPRINT(RT_DEBUG_TRACE,
3264 (" MlmeUpdateTxRates (MaxDesire=%d, MaxSupport=%d, MaxTxRate=%d, MinRate=%d, Rate Switching =%d)\n",
3265 RateIdToMbps[MaxDesire], RateIdToMbps[MaxSupport],
3266 RateIdToMbps[pAd->CommonCfg.MaxTxRate],
3267 RateIdToMbps[pAd->CommonCfg.MinTxRate],
3268 /*OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED) */
3269 *auto_rate_cur_p));
3270 DBGPRINT(RT_DEBUG_TRACE,
3271 (" MlmeUpdateTxRates (TxRate=%d, RtsRate=%d, BasicRateBitmap=0x%04lx)\n",
3272 RateIdToMbps[pAd->CommonCfg.TxRate],
3273 RateIdToMbps[pAd->CommonCfg.RtsRate], BasicRateBitmap));
3274 DBGPRINT(RT_DEBUG_TRACE,
3275 ("MlmeUpdateTxRates (MlmeTransmit=0x%x, MinHTPhyMode=%x, MaxHTPhyMode=0x%x, HTPhyMode=0x%x)\n",
3276 pAd->CommonCfg.MlmeTransmit.word,
3277 pAd->MacTab.Content[BSSID_WCID].MinHTPhyMode.word,
3278 pAd->MacTab.Content[BSSID_WCID].MaxHTPhyMode.word,
3279 pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word));
3280}
3281
3282/*
3283 ==========================================================================
3284 Description:
3285 This function update HT Rate setting.
3286 Input Wcid value is valid for 2 case :
3287 1. it's used for Station in infra mode that copy AP rate to Mactable.
3288 2. OR Station in adhoc mode to copy peer's HT rate to Mactable.
3289
3290 IRQL = DISPATCH_LEVEL
3291
3292 ==========================================================================
3293 */
3294void MlmeUpdateHtTxRates(struct rt_rtmp_adapter *pAd, u8 apidx)
3295{
3296 u8 StbcMcs; /*j, StbcMcs, bitmask; */
3297 char i; /* 3*3 */
3298 struct rt_ht_capability *pRtHtCap = NULL;
3299 struct rt_ht_phy_info *pActiveHtPhy = NULL;
3300 unsigned long BasicMCS;
3301 u8 j, bitmask;
3302 struct rt_ht_phy_info *pDesireHtPhy = NULL;
3303 PHTTRANSMIT_SETTING pHtPhy = NULL;
3304 PHTTRANSMIT_SETTING pMaxHtPhy = NULL;
3305 PHTTRANSMIT_SETTING pMinHtPhy = NULL;
3306 BOOLEAN *auto_rate_cur_p;
3307
3308 DBGPRINT(RT_DEBUG_TRACE, ("MlmeUpdateHtTxRates===> \n"));
3309
3310 auto_rate_cur_p = NULL;
3311
3312 {
3313 pDesireHtPhy = &pAd->StaCfg.DesiredHtPhyInfo;
3314 pActiveHtPhy = &pAd->StaCfg.DesiredHtPhyInfo;
3315 pHtPhy = &pAd->StaCfg.HTPhyMode;
3316 pMaxHtPhy = &pAd->StaCfg.MaxHTPhyMode;
3317 pMinHtPhy = &pAd->StaCfg.MinHTPhyMode;
3318
3319 auto_rate_cur_p = &pAd->StaCfg.bAutoTxRateSwitch;
3320 }
3321
3322 if ((ADHOC_ON(pAd) || INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA)) {
3323 if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
3324 return;
3325
3326 pRtHtCap = &pAd->StaActive.SupportedHtPhy;
3327 pActiveHtPhy = &pAd->StaActive.SupportedPhyInfo;
3328 StbcMcs = (u8)pAd->MlmeAux.AddHtInfo.AddHtInfo3.StbcMcs;
3329 BasicMCS =
3330 pAd->MlmeAux.AddHtInfo.MCSSet[0] +
3331 (pAd->MlmeAux.AddHtInfo.MCSSet[1] << 8) + (StbcMcs << 16);
3332 if ((pAd->CommonCfg.DesiredHtPhy.TxSTBC) && (pRtHtCap->RxSTBC)
3333 && (pAd->Antenna.field.TxPath == 2))
3334 pMaxHtPhy->field.STBC = STBC_USE;
3335 else
3336 pMaxHtPhy->field.STBC = STBC_NONE;
3337 } else {
3338 if (pDesireHtPhy->bHtEnable == FALSE)
3339 return;
3340
3341 pRtHtCap = &pAd->CommonCfg.DesiredHtPhy;
3342 StbcMcs = (u8)pAd->CommonCfg.AddHTInfo.AddHtInfo3.StbcMcs;
3343 BasicMCS =
3344 pAd->CommonCfg.AddHTInfo.MCSSet[0] +
3345 (pAd->CommonCfg.AddHTInfo.MCSSet[1] << 8) + (StbcMcs << 16);
3346 if ((pAd->CommonCfg.DesiredHtPhy.TxSTBC) && (pRtHtCap->RxSTBC)
3347 && (pAd->Antenna.field.TxPath == 2))
3348 pMaxHtPhy->field.STBC = STBC_USE;
3349 else
3350 pMaxHtPhy->field.STBC = STBC_NONE;
3351 }
3352
3353 /* Decide MAX ht rate. */
3354 if ((pRtHtCap->GF) && (pAd->CommonCfg.DesiredHtPhy.GF))
3355 pMaxHtPhy->field.MODE = MODE_HTGREENFIELD;
3356 else
3357 pMaxHtPhy->field.MODE = MODE_HTMIX;
3358
3359 if ((pAd->CommonCfg.DesiredHtPhy.ChannelWidth)
3360 && (pRtHtCap->ChannelWidth))
3361 pMaxHtPhy->field.BW = BW_40;
3362 else
3363 pMaxHtPhy->field.BW = BW_20;
3364
3365 if (pMaxHtPhy->field.BW == BW_20)
3366 pMaxHtPhy->field.ShortGI =
3367 (pAd->CommonCfg.DesiredHtPhy.ShortGIfor20 & pRtHtCap->
3368 ShortGIfor20);
3369 else
3370 pMaxHtPhy->field.ShortGI =
3371 (pAd->CommonCfg.DesiredHtPhy.ShortGIfor40 & pRtHtCap->
3372 ShortGIfor40);
3373
3374 if (pDesireHtPhy->MCSSet[4] != 0) {
3375 pMaxHtPhy->field.MCS = 32;
3376 }
3377
3378 for (i = 23; i >= 0; i--) /* 3*3 */
3379 {
3380 j = i / 8;
3381 bitmask = (1 << (i - (j * 8)));
3382
3383 if ((pActiveHtPhy->MCSSet[j] & bitmask)
3384 && (pDesireHtPhy->MCSSet[j] & bitmask)) {
3385 pMaxHtPhy->field.MCS = i;
3386 break;
3387 }
3388
3389 if (i == 0)
3390 break;
3391 }
3392
3393 /* Copy MIN ht rate. rt2860??? */
3394 pMinHtPhy->field.BW = BW_20;
3395 pMinHtPhy->field.MCS = 0;
3396 pMinHtPhy->field.STBC = 0;
3397 pMinHtPhy->field.ShortGI = 0;
3398 /*If STA assigns fixed rate. update to fixed here. */
3399 if ((pAd->OpMode == OPMODE_STA) && (pDesireHtPhy->MCSSet[0] != 0xff)) {
3400 if (pDesireHtPhy->MCSSet[4] != 0) {
3401 pMaxHtPhy->field.MCS = 32;
3402 pMinHtPhy->field.MCS = 32;
3403 DBGPRINT(RT_DEBUG_TRACE,
3404 ("MlmeUpdateHtTxRates<=== Use Fixed MCS = %d\n",
3405 pMinHtPhy->field.MCS));
3406 }
3407
3408 for (i = 23; (char)i >= 0; i--) /* 3*3 */
3409 {
3410 j = i / 8;
3411 bitmask = (1 << (i - (j * 8)));
3412 if ((pDesireHtPhy->MCSSet[j] & bitmask)
3413 && (pActiveHtPhy->MCSSet[j] & bitmask)) {
3414 pMaxHtPhy->field.MCS = i;
3415 pMinHtPhy->field.MCS = i;
3416 break;
3417 }
3418 if (i == 0)
3419 break;
3420 }
3421 }
3422
3423 /* Decide ht rate */
3424 pHtPhy->field.STBC = pMaxHtPhy->field.STBC;
3425 pHtPhy->field.BW = pMaxHtPhy->field.BW;
3426 pHtPhy->field.MODE = pMaxHtPhy->field.MODE;
3427 pHtPhy->field.MCS = pMaxHtPhy->field.MCS;
3428 pHtPhy->field.ShortGI = pMaxHtPhy->field.ShortGI;
3429
3430 /* use default now. rt2860 */
3431 if (pDesireHtPhy->MCSSet[0] != 0xff)
3432 *auto_rate_cur_p = FALSE;
3433 else
3434 *auto_rate_cur_p = TRUE;
3435
3436 DBGPRINT(RT_DEBUG_TRACE,
3437 (" MlmeUpdateHtTxRates<---.AMsduSize = %d \n",
3438 pAd->CommonCfg.DesiredHtPhy.AmsduSize));
3439 DBGPRINT(RT_DEBUG_TRACE,
3440 ("TX: MCS[0] = %x (choose %d), BW = %d, ShortGI = %d, MODE = %d, \n",
3441 pActiveHtPhy->MCSSet[0], pHtPhy->field.MCS, pHtPhy->field.BW,
3442 pHtPhy->field.ShortGI, pHtPhy->field.MODE));
3443 DBGPRINT(RT_DEBUG_TRACE, ("MlmeUpdateHtTxRates<=== \n"));
3444}
3445
3446void BATableInit(struct rt_rtmp_adapter *pAd, struct rt_ba_table *Tab)
3447{
3448 int i;
3449
3450 Tab->numAsOriginator = 0;
3451 Tab->numAsRecipient = 0;
3452 Tab->numDoneOriginator = 0;
3453 NdisAllocateSpinLock(&pAd->BATabLock);
3454 for (i = 0; i < MAX_LEN_OF_BA_REC_TABLE; i++) {
3455 Tab->BARecEntry[i].REC_BA_Status = Recipient_NONE;
3456 NdisAllocateSpinLock(&(Tab->BARecEntry[i].RxReRingLock));
3457 }
3458 for (i = 0; i < MAX_LEN_OF_BA_ORI_TABLE; i++) {
3459 Tab->BAOriEntry[i].ORI_BA_Status = Originator_NONE;
3460 }
3461}
3462
3463/* IRQL = DISPATCH_LEVEL */
3464void MlmeRadioOff(struct rt_rtmp_adapter *pAd)
3465{
3466 RTMP_MLME_RADIO_OFF(pAd);
3467}
3468
3469/* IRQL = DISPATCH_LEVEL */
3470void MlmeRadioOn(struct rt_rtmp_adapter *pAd)
3471{
3472 RTMP_MLME_RADIO_ON(pAd);
3473}
3474
3475/* =========================================================================================== */
3476/* bss_table.c */
3477/* =========================================================================================== */
3478
3479/*! \brief initialize BSS table
3480 * \param p_tab pointer to the table
3481 * \return none
3482 * \pre
3483 * \post
3484
3485 IRQL = PASSIVE_LEVEL
3486 IRQL = DISPATCH_LEVEL
3487
3488 */
3489void BssTableInit(struct rt_bss_table *Tab)
3490{
3491 int i;
3492
3493 Tab->BssNr = 0;
3494 Tab->BssOverlapNr = 0;
3495 for (i = 0; i < MAX_LEN_OF_BSS_TABLE; i++) {
3496 NdisZeroMemory(&Tab->BssEntry[i], sizeof(struct rt_bss_entry));
3497 Tab->BssEntry[i].Rssi = -127; /* initial the rssi as a minimum value */
3498 }
3499}
3500
3501/*! \brief search the BSS table by SSID
3502 * \param p_tab pointer to the bss table
3503 * \param ssid SSID string
3504 * \return index of the table, BSS_NOT_FOUND if not in the table
3505 * \pre
3506 * \post
3507 * \note search by sequential search
3508
3509 IRQL = DISPATCH_LEVEL
3510
3511 */
3512unsigned long BssTableSearch(struct rt_bss_table *Tab, u8 *pBssid, u8 Channel)
3513{
3514 u8 i;
3515
3516 for (i = 0; i < Tab->BssNr; i++) {
3517 /* */
3518 /* Some AP that support A/B/G mode that may used the same BSSID on 11A and 11B/G. */
3519 /* We should distinguish this case. */
3520 /* */
3521 if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) ||
3522 ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) &&
3523 MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid)) {
3524 return i;
3525 }
3526 }
3527 return (unsigned long)BSS_NOT_FOUND;
3528}
3529
3530unsigned long BssSsidTableSearch(struct rt_bss_table *Tab,
3531 u8 *pBssid,
3532 u8 *pSsid, u8 SsidLen, u8 Channel)
3533{
3534 u8 i;
3535
3536 for (i = 0; i < Tab->BssNr; i++) {
3537 /* */
3538 /* Some AP that support A/B/G mode that may used the same BSSID on 11A and 11B/G. */
3539 /* We should distinguish this case. */
3540 /* */
3541 if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) ||
3542 ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) &&
3543 MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid) &&
3544 SSID_EQUAL(pSsid, SsidLen, Tab->BssEntry[i].Ssid,
3545 Tab->BssEntry[i].SsidLen)) {
3546 return i;
3547 }
3548 }
3549 return (unsigned long)BSS_NOT_FOUND;
3550}
3551
3552unsigned long BssTableSearchWithSSID(struct rt_bss_table *Tab,
3553 u8 *Bssid,
3554 u8 *pSsid,
3555 u8 SsidLen, u8 Channel)
3556{
3557 u8 i;
3558
3559 for (i = 0; i < Tab->BssNr; i++) {
3560 if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) ||
3561 ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) &&
3562 MAC_ADDR_EQUAL(&(Tab->BssEntry[i].Bssid), Bssid) &&
3563 (SSID_EQUAL
3564 (pSsid, SsidLen, Tab->BssEntry[i].Ssid,
3565 Tab->BssEntry[i].SsidLen)
3566 || (NdisEqualMemory(pSsid, ZeroSsid, SsidLen))
3567 ||
3568 (NdisEqualMemory
3569 (Tab->BssEntry[i].Ssid, ZeroSsid,
3570 Tab->BssEntry[i].SsidLen)))) {
3571 return i;
3572 }
3573 }
3574 return (unsigned long)BSS_NOT_FOUND;
3575}
3576
3577unsigned long BssSsidTableSearchBySSID(struct rt_bss_table *Tab,
3578 u8 *pSsid, u8 SsidLen)
3579{
3580 u8 i;
3581
3582 for (i = 0; i < Tab->BssNr; i++) {
3583 if (SSID_EQUAL
3584 (pSsid, SsidLen, Tab->BssEntry[i].Ssid,
3585 Tab->BssEntry[i].SsidLen)) {
3586 return i;
3587 }
3588 }
3589 return (unsigned long)BSS_NOT_FOUND;
3590}
3591
3592/* IRQL = DISPATCH_LEVEL */
3593void BssTableDeleteEntry(struct rt_bss_table *Tab,
3594 u8 *pBssid, u8 Channel)
3595{
3596 u8 i, j;
3597
3598 for (i = 0; i < Tab->BssNr; i++) {
3599 if ((Tab->BssEntry[i].Channel == Channel) &&
3600 (MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid))) {
3601 for (j = i; j < Tab->BssNr - 1; j++) {
3602 NdisMoveMemory(&(Tab->BssEntry[j]),
3603 &(Tab->BssEntry[j + 1]),
3604 sizeof(struct rt_bss_entry));
3605 }
3606 NdisZeroMemory(&(Tab->BssEntry[Tab->BssNr - 1]),
3607 sizeof(struct rt_bss_entry));
3608 Tab->BssNr -= 1;
3609 return;
3610 }
3611 }
3612}
3613
3614/*
3615 ========================================================================
3616 Routine Description:
3617 Delete the Originator Entry in BAtable. Or decrease numAs Originator by 1 if needed.
3618
3619 Arguments:
3620 // IRQL = DISPATCH_LEVEL
3621 ========================================================================
3622*/
3623void BATableDeleteORIEntry(struct rt_rtmp_adapter *pAd,
3624 struct rt_ba_ori_entry *pBAORIEntry)
3625{
3626
3627 if (pBAORIEntry->ORI_BA_Status != Originator_NONE) {
3628 NdisAcquireSpinLock(&pAd->BATabLock);
3629 if (pBAORIEntry->ORI_BA_Status == Originator_Done) {
3630 pAd->BATable.numAsOriginator -= 1;
3631 DBGPRINT(RT_DEBUG_TRACE,
3632 ("BATableDeleteORIEntry numAsOriginator= %ld\n",
3633 pAd->BATable.numAsRecipient));
3634 /* Erase Bitmap flag. */
3635 }
3636 pAd->MacTab.Content[pBAORIEntry->Wcid].TXBAbitmap &= (~(1 << (pBAORIEntry->TID))); /* If STA mode, erase flag here */
3637 pAd->MacTab.Content[pBAORIEntry->Wcid].BAOriWcidArray[pBAORIEntry->TID] = 0; /* If STA mode, erase flag here */
3638 pBAORIEntry->ORI_BA_Status = Originator_NONE;
3639 pBAORIEntry->Token = 1;
3640 /* Not clear Sequence here. */
3641 NdisReleaseSpinLock(&pAd->BATabLock);
3642 }
3643}
3644
3645/*! \brief
3646 * \param
3647 * \return
3648 * \pre
3649 * \post
3650
3651 IRQL = DISPATCH_LEVEL
3652
3653 */
3654void BssEntrySet(struct rt_rtmp_adapter *pAd, struct rt_bss_entry *pBss, u8 *pBssid, char Ssid[], u8 SsidLen, u8 BssType, u16 BeaconPeriod, struct rt_cf_parm * pCfParm, u16 AtimWin, u16 CapabilityInfo, u8 SupRate[], u8 SupRateLen, u8 ExtRate[], u8 ExtRateLen, struct rt_ht_capability_ie * pHtCapability, struct rt_add_ht_info_ie * pAddHtInfo, /* AP might use this additional ht info IE */
3655 u8 HtCapabilityLen,
3656 u8 AddHtInfoLen,
3657 u8 NewExtChanOffset,
3658 u8 Channel,
3659 char Rssi,
3660 IN LARGE_INTEGER TimeStamp,
3661 u8 CkipFlag,
3662 struct rt_edca_parm *pEdcaParm,
3663 struct rt_qos_capability_parm *pQosCapability,
3664 struct rt_qbss_load_parm *pQbssLoad,
3665 u16 LengthVIE, struct rt_ndis_802_11_variable_ies *pVIE)
3666{
3667 COPY_MAC_ADDR(pBss->Bssid, pBssid);
3668 /* Default Hidden SSID to be TRUE, it will be turned to FALSE after coping SSID */
3669 pBss->Hidden = 1;
3670 if (SsidLen > 0) {
3671 /* For hidden SSID AP, it might send beacon with SSID len equal to 0 */
3672 /* Or send beacon /probe response with SSID len matching real SSID length, */
3673 /* but SSID is all zero. such as "00-00-00-00" with length 4. */
3674 /* We have to prevent this case overwrite correct table */
3675 if (NdisEqualMemory(Ssid, ZeroSsid, SsidLen) == 0) {
3676 NdisZeroMemory(pBss->Ssid, MAX_LEN_OF_SSID);
3677 NdisMoveMemory(pBss->Ssid, Ssid, SsidLen);
3678 pBss->SsidLen = SsidLen;
3679 pBss->Hidden = 0;
3680 }
3681 } else
3682 pBss->SsidLen = 0;
3683 pBss->BssType = BssType;
3684 pBss->BeaconPeriod = BeaconPeriod;
3685 if (BssType == BSS_INFRA) {
3686 if (pCfParm->bValid) {
3687 pBss->CfpCount = pCfParm->CfpCount;
3688 pBss->CfpPeriod = pCfParm->CfpPeriod;
3689 pBss->CfpMaxDuration = pCfParm->CfpMaxDuration;
3690 pBss->CfpDurRemaining = pCfParm->CfpDurRemaining;
3691 }
3692 } else {
3693 pBss->AtimWin = AtimWin;
3694 }
3695
3696 pBss->CapabilityInfo = CapabilityInfo;
3697 /* The privacy bit indicate security is ON, it maight be WEP, TKIP or AES */
3698 /* Combine with AuthMode, they will decide the connection methods. */
3699 pBss->Privacy = CAP_IS_PRIVACY_ON(pBss->CapabilityInfo);
3700 ASSERT(SupRateLen <= MAX_LEN_OF_SUPPORTED_RATES);
3701 if (SupRateLen <= MAX_LEN_OF_SUPPORTED_RATES)
3702 NdisMoveMemory(pBss->SupRate, SupRate, SupRateLen);
3703 else
3704 NdisMoveMemory(pBss->SupRate, SupRate,
3705 MAX_LEN_OF_SUPPORTED_RATES);
3706 pBss->SupRateLen = SupRateLen;
3707 ASSERT(ExtRateLen <= MAX_LEN_OF_SUPPORTED_RATES);
3708 NdisMoveMemory(pBss->ExtRate, ExtRate, ExtRateLen);
3709 pBss->NewExtChanOffset = NewExtChanOffset;
3710 pBss->ExtRateLen = ExtRateLen;
3711 pBss->Channel = Channel;
3712 pBss->CentralChannel = Channel;
3713 pBss->Rssi = Rssi;
3714 /* Update CkipFlag. if not exists, the value is 0x0 */
3715 pBss->CkipFlag = CkipFlag;
3716
3717 /* New for microsoft Fixed IEs */
3718 NdisMoveMemory(pBss->FixIEs.Timestamp, &TimeStamp, 8);
3719 pBss->FixIEs.BeaconInterval = BeaconPeriod;
3720 pBss->FixIEs.Capabilities = CapabilityInfo;
3721
3722 /* New for microsoft Variable IEs */
3723 if (LengthVIE != 0) {
3724 pBss->VarIELen = LengthVIE;
3725 NdisMoveMemory(pBss->VarIEs, pVIE, pBss->VarIELen);
3726 } else {
3727 pBss->VarIELen = 0;
3728 }
3729
3730 pBss->AddHtInfoLen = 0;
3731 pBss->HtCapabilityLen = 0;
3732 if (HtCapabilityLen > 0) {
3733 pBss->HtCapabilityLen = HtCapabilityLen;
3734 NdisMoveMemory(&pBss->HtCapability, pHtCapability,
3735 HtCapabilityLen);
3736 if (AddHtInfoLen > 0) {
3737 pBss->AddHtInfoLen = AddHtInfoLen;
3738 NdisMoveMemory(&pBss->AddHtInfo, pAddHtInfo,
3739 AddHtInfoLen);
3740
3741 if ((pAddHtInfo->ControlChan > 2)
3742 && (pAddHtInfo->AddHtInfo.ExtChanOffset ==
3743 EXTCHA_BELOW)
3744 && (pHtCapability->HtCapInfo.ChannelWidth ==
3745 BW_40)) {
3746 pBss->CentralChannel =
3747 pAddHtInfo->ControlChan - 2;
3748 } else
3749 if ((pAddHtInfo->AddHtInfo.ExtChanOffset ==
3750 EXTCHA_ABOVE)
3751 && (pHtCapability->HtCapInfo.ChannelWidth ==
3752 BW_40)) {
3753 pBss->CentralChannel =
3754 pAddHtInfo->ControlChan + 2;
3755 }
3756 }
3757 }
3758
3759 BssCipherParse(pBss);
3760
3761 /* new for QOS */
3762 if (pEdcaParm)
3763 NdisMoveMemory(&pBss->EdcaParm, pEdcaParm, sizeof(struct rt_edca_parm));
3764 else
3765 pBss->EdcaParm.bValid = FALSE;
3766 if (pQosCapability)
3767 NdisMoveMemory(&pBss->QosCapability, pQosCapability,
3768 sizeof(struct rt_qos_capability_parm));
3769 else
3770 pBss->QosCapability.bValid = FALSE;
3771 if (pQbssLoad)
3772 NdisMoveMemory(&pBss->QbssLoad, pQbssLoad,
3773 sizeof(struct rt_qbss_load_parm));
3774 else
3775 pBss->QbssLoad.bValid = FALSE;
3776
3777 {
3778 struct rt_eid * pEid;
3779 u16 Length = 0;
3780
3781 NdisZeroMemory(&pBss->WpaIE.IE[0], MAX_CUSTOM_LEN);
3782 NdisZeroMemory(&pBss->RsnIE.IE[0], MAX_CUSTOM_LEN);
3783 pEid = (struct rt_eid *) pVIE;
3784 while ((Length + 2 + (u16)pEid->Len) <= LengthVIE) {
3785 switch (pEid->Eid) {
3786 case IE_WPA:
3787 if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4)) {
3788 if ((pEid->Len + 2) > MAX_CUSTOM_LEN) {
3789 pBss->WpaIE.IELen = 0;
3790 break;
3791 }
3792 pBss->WpaIE.IELen = pEid->Len + 2;
3793 NdisMoveMemory(pBss->WpaIE.IE, pEid,
3794 pBss->WpaIE.IELen);
3795 }
3796 break;
3797 case IE_RSN:
3798 if (NdisEqualMemory
3799 (pEid->Octet + 2, RSN_OUI, 3)) {
3800 if ((pEid->Len + 2) > MAX_CUSTOM_LEN) {
3801 pBss->RsnIE.IELen = 0;
3802 break;
3803 }
3804 pBss->RsnIE.IELen = pEid->Len + 2;
3805 NdisMoveMemory(pBss->RsnIE.IE, pEid,
3806 pBss->RsnIE.IELen);
3807 }
3808 break;
3809 }
3810 Length = Length + 2 + (u16)pEid->Len; /* Eid[1] + Len[1]+ content[Len] */
3811 pEid = (struct rt_eid *) ((u8 *) pEid + 2 + pEid->Len);
3812 }
3813 }
3814}
3815
3816/*!
3817 * \brief insert an entry into the bss table
3818 * \param p_tab The BSS table
3819 * \param Bssid BSSID
3820 * \param ssid SSID
3821 * \param ssid_len Length of SSID
3822 * \param bss_type
3823 * \param beacon_period
3824 * \param timestamp
3825 * \param p_cf
3826 * \param atim_win
3827 * \param cap
3828 * \param rates
3829 * \param rates_len
3830 * \param channel_idx
3831 * \return none
3832 * \pre
3833 * \post
3834 * \note If SSID is identical, the old entry will be replaced by the new one
3835
3836 IRQL = DISPATCH_LEVEL
3837
3838 */
3839unsigned long BssTableSetEntry(struct rt_rtmp_adapter *pAd, struct rt_bss_table *Tab, u8 *pBssid, char Ssid[], u8 SsidLen, u8 BssType, u16 BeaconPeriod, struct rt_cf_parm * CfParm, u16 AtimWin, u16 CapabilityInfo, u8 SupRate[], u8 SupRateLen, u8 ExtRate[], u8 ExtRateLen, struct rt_ht_capability_ie * pHtCapability, struct rt_add_ht_info_ie * pAddHtInfo, /* AP might use this additional ht info IE */
3840 u8 HtCapabilityLen,
3841 u8 AddHtInfoLen,
3842 u8 NewExtChanOffset,
3843 u8 ChannelNo,
3844 char Rssi,
3845 IN LARGE_INTEGER TimeStamp,
3846 u8 CkipFlag,
3847 struct rt_edca_parm *pEdcaParm,
3848 struct rt_qos_capability_parm *pQosCapability,
3849 struct rt_qbss_load_parm *pQbssLoad,
3850 u16 LengthVIE, struct rt_ndis_802_11_variable_ies *pVIE)
3851{
3852 unsigned long Idx;
3853
3854 Idx =
3855 BssTableSearchWithSSID(Tab, pBssid, (u8 *) Ssid, SsidLen,
3856 ChannelNo);
3857 if (Idx == BSS_NOT_FOUND) {
3858 if (Tab->BssNr >= MAX_LEN_OF_BSS_TABLE) {
3859 /* */
3860 /* It may happen when BSS Table was full. */
3861 /* The desired AP will not be added into BSS Table */
3862 /* In this case, if we found the desired AP then overwrite BSS Table. */
3863 /* */
3864 if (!OPSTATUS_TEST_FLAG
3865 (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) {
3866 if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, pBssid)
3867 || SSID_EQUAL(pAd->MlmeAux.Ssid,
3868 pAd->MlmeAux.SsidLen, Ssid,
3869 SsidLen)) {
3870 Idx = Tab->BssOverlapNr;
3871 BssEntrySet(pAd, &Tab->BssEntry[Idx],
3872 pBssid, Ssid, SsidLen,
3873 BssType, BeaconPeriod,
3874 CfParm, AtimWin,
3875 CapabilityInfo, SupRate,
3876 SupRateLen, ExtRate,
3877 ExtRateLen, pHtCapability,
3878 pAddHtInfo, HtCapabilityLen,
3879 AddHtInfoLen,
3880 NewExtChanOffset, ChannelNo,
3881 Rssi, TimeStamp, CkipFlag,
3882 pEdcaParm, pQosCapability,
3883 pQbssLoad, LengthVIE, pVIE);
3884 Tab->BssOverlapNr =
3885 (Tab->BssOverlapNr++) %
3886 MAX_LEN_OF_BSS_TABLE;
3887 }
3888 return Idx;
3889 } else {
3890 return BSS_NOT_FOUND;
3891 }
3892 }
3893 Idx = Tab->BssNr;
3894 BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen,
3895 BssType, BeaconPeriod, CfParm, AtimWin,
3896 CapabilityInfo, SupRate, SupRateLen, ExtRate,
3897 ExtRateLen, pHtCapability, pAddHtInfo,
3898 HtCapabilityLen, AddHtInfoLen, NewExtChanOffset,
3899 ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm,
3900 pQosCapability, pQbssLoad, LengthVIE, pVIE);
3901 Tab->BssNr++;
3902 } else {
3903 /* avoid Hidden SSID form beacon to overwirite correct SSID from probe response */
3904 if ((SSID_EQUAL
3905 (Ssid, SsidLen, Tab->BssEntry[Idx].Ssid,
3906 Tab->BssEntry[Idx].SsidLen))
3907 ||
3908 (NdisEqualMemory
3909 (Tab->BssEntry[Idx].Ssid, ZeroSsid,
3910 Tab->BssEntry[Idx].SsidLen))) {
3911 BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid,
3912 SsidLen, BssType, BeaconPeriod, CfParm,
3913 AtimWin, CapabilityInfo, SupRate,
3914 SupRateLen, ExtRate, ExtRateLen,
3915 pHtCapability, pAddHtInfo, HtCapabilityLen,
3916 AddHtInfoLen, NewExtChanOffset, ChannelNo,
3917 Rssi, TimeStamp, CkipFlag, pEdcaParm,
3918 pQosCapability, pQbssLoad, LengthVIE, pVIE);
3919 }
3920 }
3921
3922 return Idx;
3923}
3924
3925/* IRQL = DISPATCH_LEVEL */
3926void BssTableSsidSort(struct rt_rtmp_adapter *pAd,
3927 struct rt_bss_table *OutTab, char Ssid[], u8 SsidLen)
3928{
3929 int i;
3930 BssTableInit(OutTab);
3931
3932 for (i = 0; i < pAd->ScanTab.BssNr; i++) {
3933 struct rt_bss_entry *pInBss = &pAd->ScanTab.BssEntry[i];
3934 BOOLEAN bIsHiddenApIncluded = FALSE;
3935
3936 if (((pAd->CommonCfg.bIEEE80211H == 1) &&
3937 (pAd->MlmeAux.Channel > 14) &&
3938 RadarChannelCheck(pAd, pInBss->Channel))
3939 ) {
3940 if (pInBss->Hidden)
3941 bIsHiddenApIncluded = TRUE;
3942 }
3943
3944 if ((pInBss->BssType == pAd->StaCfg.BssType) &&
3945 (SSID_EQUAL(Ssid, SsidLen, pInBss->Ssid, pInBss->SsidLen)
3946 || bIsHiddenApIncluded)) {
3947 struct rt_bss_entry *pOutBss = &OutTab->BssEntry[OutTab->BssNr];
3948
3949 /* 2.4G/5G N only mode */
3950 if ((pInBss->HtCapabilityLen == 0) &&
3951 ((pAd->CommonCfg.PhyMode == PHY_11N_2_4G)
3952 || (pAd->CommonCfg.PhyMode == PHY_11N_5G))) {
3953 DBGPRINT(RT_DEBUG_TRACE,
3954 ("STA is in N-only Mode, this AP don't have Ht capability in Beacon.\n"));
3955 continue;
3956 }
3957 /* New for WPA2 */
3958 /* Check the Authmode first */
3959 if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) {
3960 /* Check AuthMode and AuthModeAux for matching, in case AP support dual-mode */
3961 if ((pAd->StaCfg.AuthMode != pInBss->AuthMode)
3962 && (pAd->StaCfg.AuthMode !=
3963 pInBss->AuthModeAux))
3964 /* None matched */
3965 continue;
3966
3967 /* Check cipher suite, AP must have more secured cipher than station setting */
3968 if ((pAd->StaCfg.AuthMode ==
3969 Ndis802_11AuthModeWPA)
3970 || (pAd->StaCfg.AuthMode ==
3971 Ndis802_11AuthModeWPAPSK)) {
3972 /* If it's not mixed mode, we should only let BSS pass with the same encryption */
3973 if (pInBss->WPA.bMixMode == FALSE)
3974 if (pAd->StaCfg.WepStatus !=
3975 pInBss->WPA.GroupCipher)
3976 continue;
3977
3978 /* check group cipher */
3979 if ((pAd->StaCfg.WepStatus <
3980 pInBss->WPA.GroupCipher)
3981 && (pInBss->WPA.GroupCipher !=
3982 Ndis802_11GroupWEP40Enabled)
3983 && (pInBss->WPA.GroupCipher !=
3984 Ndis802_11GroupWEP104Enabled))
3985 continue;
3986
3987 /* check pairwise cipher, skip if none matched */
3988 /* If profile set to AES, let it pass without question. */
3989 /* If profile set to TKIP, we must find one mateched */
3990 if ((pAd->StaCfg.WepStatus ==
3991 Ndis802_11Encryption2Enabled)
3992 && (pAd->StaCfg.WepStatus !=
3993 pInBss->WPA.PairCipher)
3994 && (pAd->StaCfg.WepStatus !=
3995 pInBss->WPA.PairCipherAux))
3996 continue;
3997 } else
3998 if ((pAd->StaCfg.AuthMode ==
3999 Ndis802_11AuthModeWPA2)
4000 || (pAd->StaCfg.AuthMode ==
4001 Ndis802_11AuthModeWPA2PSK)) {
4002 /* If it's not mixed mode, we should only let BSS pass with the same encryption */
4003 if (pInBss->WPA2.bMixMode == FALSE)
4004 if (pAd->StaCfg.WepStatus !=
4005 pInBss->WPA2.GroupCipher)
4006 continue;
4007
4008 /* check group cipher */
4009 if ((pAd->StaCfg.WepStatus <
4010 pInBss->WPA.GroupCipher)
4011 && (pInBss->WPA2.GroupCipher !=
4012 Ndis802_11GroupWEP40Enabled)
4013 && (pInBss->WPA2.GroupCipher !=
4014 Ndis802_11GroupWEP104Enabled))
4015 continue;
4016
4017 /* check pairwise cipher, skip if none matched */
4018 /* If profile set to AES, let it pass without question. */
4019 /* If profile set to TKIP, we must find one mateched */
4020 if ((pAd->StaCfg.WepStatus ==
4021 Ndis802_11Encryption2Enabled)
4022 && (pAd->StaCfg.WepStatus !=
4023 pInBss->WPA2.PairCipher)
4024 && (pAd->StaCfg.WepStatus !=
4025 pInBss->WPA2.PairCipherAux))
4026 continue;
4027 }
4028 }
4029 /* Bss Type matched, SSID matched. */
4030 /* We will check wepstatus for qualification Bss */
4031 else if (pAd->StaCfg.WepStatus != pInBss->WepStatus) {
4032 DBGPRINT(RT_DEBUG_TRACE,
4033 ("StaCfg.WepStatus=%d, while pInBss->WepStatus=%d\n",
4034 pAd->StaCfg.WepStatus,
4035 pInBss->WepStatus));
4036 /* */
4037 /* For the SESv2 case, we will not qualify WepStatus. */
4038 /* */
4039 if (!pInBss->bSES)
4040 continue;
4041 }
4042 /* Since the AP is using hidden SSID, and we are trying to connect to ANY */
4043 /* It definitely will fail. So, skip it. */
4044 /* CCX also require not even try to connect it! */
4045 if (SsidLen == 0)
4046 continue;
4047
4048 /* If both station and AP use 40MHz, still need to check if the 40MHZ band's legality in my country region */
4049 /* If this 40MHz wideband is not allowed in my country list, use bandwidth 20MHZ instead, */
4050 if ((pInBss->CentralChannel != pInBss->Channel) &&
4051 (pAd->CommonCfg.RegTransmitSetting.field.BW ==
4052 BW_40)) {
4053 if (RTMPCheckChannel
4054 (pAd, pInBss->CentralChannel,
4055 pInBss->Channel) == FALSE) {
4056 pAd->CommonCfg.RegTransmitSetting.field.
4057 BW = BW_20;
4058 SetCommonHT(pAd);
4059 pAd->CommonCfg.RegTransmitSetting.field.
4060 BW = BW_40;
4061 } else {
4062 if (pAd->CommonCfg.DesiredHtPhy.
4063 ChannelWidth == BAND_WIDTH_20) {
4064 SetCommonHT(pAd);
4065 }
4066 }
4067 }
4068 /* copy matching BSS from InTab to OutTab */
4069 NdisMoveMemory(pOutBss, pInBss, sizeof(struct rt_bss_entry));
4070
4071 OutTab->BssNr++;
4072 } else if ((pInBss->BssType == pAd->StaCfg.BssType)
4073 && (SsidLen == 0)) {
4074 struct rt_bss_entry *pOutBss = &OutTab->BssEntry[OutTab->BssNr];
4075
4076 /* 2.4G/5G N only mode */
4077 if ((pInBss->HtCapabilityLen == 0) &&
4078 ((pAd->CommonCfg.PhyMode == PHY_11N_2_4G)
4079 || (pAd->CommonCfg.PhyMode == PHY_11N_5G))) {
4080 DBGPRINT(RT_DEBUG_TRACE,
4081 ("STA is in N-only Mode, this AP don't have Ht capability in Beacon.\n"));
4082 continue;
4083 }
4084 /* New for WPA2 */
4085 /* Check the Authmode first */
4086 if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) {
4087 /* Check AuthMode and AuthModeAux for matching, in case AP support dual-mode */
4088 if ((pAd->StaCfg.AuthMode != pInBss->AuthMode)
4089 && (pAd->StaCfg.AuthMode !=
4090 pInBss->AuthModeAux))
4091 /* None matched */
4092 continue;
4093
4094 /* Check cipher suite, AP must have more secured cipher than station setting */
4095 if ((pAd->StaCfg.AuthMode ==
4096 Ndis802_11AuthModeWPA)
4097 || (pAd->StaCfg.AuthMode ==
4098 Ndis802_11AuthModeWPAPSK)) {
4099 /* If it's not mixed mode, we should only let BSS pass with the same encryption */
4100 if (pInBss->WPA.bMixMode == FALSE)
4101 if (pAd->StaCfg.WepStatus !=
4102 pInBss->WPA.GroupCipher)
4103 continue;
4104
4105 /* check group cipher */
4106 if (pAd->StaCfg.WepStatus <
4107 pInBss->WPA.GroupCipher)
4108 continue;
4109
4110 /* check pairwise cipher, skip if none matched */
4111 /* If profile set to AES, let it pass without question. */
4112 /* If profile set to TKIP, we must find one mateched */
4113 if ((pAd->StaCfg.WepStatus ==
4114 Ndis802_11Encryption2Enabled)
4115 && (pAd->StaCfg.WepStatus !=
4116 pInBss->WPA.PairCipher)
4117 && (pAd->StaCfg.WepStatus !=
4118 pInBss->WPA.PairCipherAux))
4119 continue;
4120 } else
4121 if ((pAd->StaCfg.AuthMode ==
4122 Ndis802_11AuthModeWPA2)
4123 || (pAd->StaCfg.AuthMode ==
4124 Ndis802_11AuthModeWPA2PSK)) {
4125 /* If it's not mixed mode, we should only let BSS pass with the same encryption */
4126 if (pInBss->WPA2.bMixMode == FALSE)
4127 if (pAd->StaCfg.WepStatus !=
4128 pInBss->WPA2.GroupCipher)
4129 continue;
4130
4131 /* check group cipher */
4132 if (pAd->StaCfg.WepStatus <
4133 pInBss->WPA2.GroupCipher)
4134 continue;
4135
4136 /* check pairwise cipher, skip if none matched */
4137 /* If profile set to AES, let it pass without question. */
4138 /* If profile set to TKIP, we must find one mateched */
4139 if ((pAd->StaCfg.WepStatus ==
4140 Ndis802_11Encryption2Enabled)
4141 && (pAd->StaCfg.WepStatus !=
4142 pInBss->WPA2.PairCipher)
4143 && (pAd->StaCfg.WepStatus !=
4144 pInBss->WPA2.PairCipherAux))
4145 continue;
4146 }
4147 }
4148 /* Bss Type matched, SSID matched. */
4149 /* We will check wepstatus for qualification Bss */
4150 else if (pAd->StaCfg.WepStatus != pInBss->WepStatus)
4151 continue;
4152
4153 /* If both station and AP use 40MHz, still need to check if the 40MHZ band's legality in my country region */
4154 /* If this 40MHz wideband is not allowed in my country list, use bandwidth 20MHZ instead, */
4155 if ((pInBss->CentralChannel != pInBss->Channel) &&
4156 (pAd->CommonCfg.RegTransmitSetting.field.BW ==
4157 BW_40)) {
4158 if (RTMPCheckChannel
4159 (pAd, pInBss->CentralChannel,
4160 pInBss->Channel) == FALSE) {
4161 pAd->CommonCfg.RegTransmitSetting.field.
4162 BW = BW_20;
4163 SetCommonHT(pAd);
4164 pAd->CommonCfg.RegTransmitSetting.field.
4165 BW = BW_40;
4166 }
4167 }
4168 /* copy matching BSS from InTab to OutTab */
4169 NdisMoveMemory(pOutBss, pInBss, sizeof(struct rt_bss_entry));
4170
4171 OutTab->BssNr++;
4172 }
4173
4174 if (OutTab->BssNr >= MAX_LEN_OF_BSS_TABLE)
4175 break;
4176 }
4177
4178 BssTableSortByRssi(OutTab);
4179}
4180
4181/* IRQL = DISPATCH_LEVEL */
4182void BssTableSortByRssi(struct rt_bss_table *OutTab)
4183{
4184 int i, j;
4185 struct rt_bss_entry TmpBss;
4186
4187 for (i = 0; i < OutTab->BssNr - 1; i++) {
4188 for (j = i + 1; j < OutTab->BssNr; j++) {
4189 if (OutTab->BssEntry[j].Rssi > OutTab->BssEntry[i].Rssi) {
4190 NdisMoveMemory(&TmpBss, &OutTab->BssEntry[j],
4191 sizeof(struct rt_bss_entry));
4192 NdisMoveMemory(&OutTab->BssEntry[j],
4193 &OutTab->BssEntry[i],
4194 sizeof(struct rt_bss_entry));
4195 NdisMoveMemory(&OutTab->BssEntry[i], &TmpBss,
4196 sizeof(struct rt_bss_entry));
4197 }
4198 }
4199 }
4200}
4201
4202void BssCipherParse(struct rt_bss_entry *pBss)
4203{
4204 struct rt_eid * pEid;
4205 u8 *pTmp;
4206 struct rt_rsn_ie_header * pRsnHeader;
4207 struct rt_cipher_suite_struct * pCipher;
4208 struct rt_akm_suite * pAKM;
4209 u16 Count;
4210 int Length;
4211 NDIS_802_11_ENCRYPTION_STATUS TmpCipher;
4212
4213 /* */
4214 /* WepStatus will be reset later, if AP announce TKIP or AES on the beacon frame. */
4215 /* */
4216 if (pBss->Privacy) {
4217 pBss->WepStatus = Ndis802_11WEPEnabled;
4218 } else {
4219 pBss->WepStatus = Ndis802_11WEPDisabled;
4220 }
4221 /* Set default to disable & open authentication before parsing variable IE */
4222 pBss->AuthMode = Ndis802_11AuthModeOpen;
4223 pBss->AuthModeAux = Ndis802_11AuthModeOpen;
4224
4225 /* Init WPA setting */
4226 pBss->WPA.PairCipher = Ndis802_11WEPDisabled;
4227 pBss->WPA.PairCipherAux = Ndis802_11WEPDisabled;
4228 pBss->WPA.GroupCipher = Ndis802_11WEPDisabled;
4229 pBss->WPA.RsnCapability = 0;
4230 pBss->WPA.bMixMode = FALSE;
4231
4232 /* Init WPA2 setting */
4233 pBss->WPA2.PairCipher = Ndis802_11WEPDisabled;
4234 pBss->WPA2.PairCipherAux = Ndis802_11WEPDisabled;
4235 pBss->WPA2.GroupCipher = Ndis802_11WEPDisabled;
4236 pBss->WPA2.RsnCapability = 0;
4237 pBss->WPA2.bMixMode = FALSE;
4238
4239 Length = (int)pBss->VarIELen;
4240
4241 while (Length > 0) {
4242 /* Parse cipher suite base on WPA1 & WPA2, they should be parsed differently */
4243 pTmp = ((u8 *)pBss->VarIEs) + pBss->VarIELen - Length;
4244 pEid = (struct rt_eid *) pTmp;
4245 switch (pEid->Eid) {
4246 case IE_WPA:
4247 if (NdisEqualMemory(pEid->Octet, SES_OUI, 3)
4248 && (pEid->Len == 7)) {
4249 pBss->bSES = TRUE;
4250 break;
4251 } else if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4) !=
4252 1) {
4253 /* if unsupported vendor specific IE */
4254 break;
4255 }
4256 /* Skip OUI, version, and multicast suite */
4257 /* This part should be improved in the future when AP supported multiple cipher suite. */
4258 /* For now, it's OK since almost all APs have fixed cipher suite supported. */
4259 /* pTmp = (u8 *)pEid->Octet; */
4260 pTmp += 11;
4261
4262 /* Cipher Suite Selectors from Spec P802.11i/D3.2 P26. */
4263 /* Value Meaning */
4264 /* 0 None */
4265 /* 1 WEP-40 */
4266 /* 2 Tkip */
4267 /* 3 WRAP */
4268 /* 4 AES */
4269 /* 5 WEP-104 */
4270 /* Parse group cipher */
4271 switch (*pTmp) {
4272 case 1:
4273 pBss->WPA.GroupCipher =
4274 Ndis802_11GroupWEP40Enabled;
4275 break;
4276 case 5:
4277 pBss->WPA.GroupCipher =
4278 Ndis802_11GroupWEP104Enabled;
4279 break;
4280 case 2:
4281 pBss->WPA.GroupCipher =
4282 Ndis802_11Encryption2Enabled;
4283 break;
4284 case 4:
4285 pBss->WPA.GroupCipher =
4286 Ndis802_11Encryption3Enabled;
4287 break;
4288 default:
4289 break;
4290 }
4291 /* number of unicast suite */
4292 pTmp += 1;
4293
4294 /* skip all unicast cipher suites */
4295 /*Count = *(u16 *)pTmp; */
4296 Count = (pTmp[1] << 8) + pTmp[0];
4297 pTmp += sizeof(u16);
4298
4299 /* Parsing all unicast cipher suite */
4300 while (Count > 0) {
4301 /* Skip OUI */
4302 pTmp += 3;
4303 TmpCipher = Ndis802_11WEPDisabled;
4304 switch (*pTmp) {
4305 case 1:
4306 case 5: /* Although WEP is not allowed in WPA related auth mode, we parse it anyway */
4307 TmpCipher =
4308 Ndis802_11Encryption1Enabled;
4309 break;
4310 case 2:
4311 TmpCipher =
4312 Ndis802_11Encryption2Enabled;
4313 break;
4314 case 4:
4315 TmpCipher =
4316 Ndis802_11Encryption3Enabled;
4317 break;
4318 default:
4319 break;
4320 }
4321 if (TmpCipher > pBss->WPA.PairCipher) {
4322 /* Move the lower cipher suite to PairCipherAux */
4323 pBss->WPA.PairCipherAux =
4324 pBss->WPA.PairCipher;
4325 pBss->WPA.PairCipher = TmpCipher;
4326 } else {
4327 pBss->WPA.PairCipherAux = TmpCipher;
4328 }
4329 pTmp++;
4330 Count--;
4331 }
4332
4333 /* 4. get AKM suite counts */
4334 /*Count = *(u16 *)pTmp; */
4335 Count = (pTmp[1] << 8) + pTmp[0];
4336 pTmp += sizeof(u16);
4337 pTmp += 3;
4338
4339 switch (*pTmp) {
4340 case 1:
4341 /* Set AP support WPA-enterprise mode */
4342 if (pBss->AuthMode == Ndis802_11AuthModeOpen)
4343 pBss->AuthMode = Ndis802_11AuthModeWPA;
4344 else
4345 pBss->AuthModeAux =
4346 Ndis802_11AuthModeWPA;
4347 break;
4348 case 2:
4349 /* Set AP support WPA-PSK mode */
4350 if (pBss->AuthMode == Ndis802_11AuthModeOpen)
4351 pBss->AuthMode =
4352 Ndis802_11AuthModeWPAPSK;
4353 else
4354 pBss->AuthModeAux =
4355 Ndis802_11AuthModeWPAPSK;
4356 break;
4357 default:
4358 break;
4359 }
4360 pTmp += 1;
4361
4362 /* Fixed for WPA-None */
4363 if (pBss->BssType == BSS_ADHOC) {
4364 pBss->AuthMode = Ndis802_11AuthModeWPANone;
4365 pBss->AuthModeAux = Ndis802_11AuthModeWPANone;
4366 pBss->WepStatus = pBss->WPA.GroupCipher;
4367 /* Patched bugs for old driver */
4368 if (pBss->WPA.PairCipherAux ==
4369 Ndis802_11WEPDisabled)
4370 pBss->WPA.PairCipherAux =
4371 pBss->WPA.GroupCipher;
4372 } else
4373 pBss->WepStatus = pBss->WPA.PairCipher;
4374
4375 /* Check the Pair & Group, if different, turn on mixed mode flag */
4376 if (pBss->WPA.GroupCipher != pBss->WPA.PairCipher)
4377 pBss->WPA.bMixMode = TRUE;
4378
4379 break;
4380
4381 case IE_RSN:
4382 pRsnHeader = (struct rt_rsn_ie_header *) pTmp;
4383
4384 /* 0. Version must be 1 */
4385 if (le2cpu16(pRsnHeader->Version) != 1)
4386 break;
4387 pTmp += sizeof(struct rt_rsn_ie_header);
4388
4389 /* 1. Check group cipher */
4390 pCipher = (struct rt_cipher_suite_struct *) pTmp;
4391 if (!RTMPEqualMemory(pTmp, RSN_OUI, 3))
4392 break;
4393
4394 /* Parse group cipher */
4395 switch (pCipher->Type) {
4396 case 1:
4397 pBss->WPA2.GroupCipher =
4398 Ndis802_11GroupWEP40Enabled;
4399 break;
4400 case 5:
4401 pBss->WPA2.GroupCipher =
4402 Ndis802_11GroupWEP104Enabled;
4403 break;
4404 case 2:
4405 pBss->WPA2.GroupCipher =
4406 Ndis802_11Encryption2Enabled;
4407 break;
4408 case 4:
4409 pBss->WPA2.GroupCipher =
4410 Ndis802_11Encryption3Enabled;
4411 break;
4412 default:
4413 break;
4414 }
4415 /* set to correct offset for next parsing */
4416 pTmp += sizeof(struct rt_cipher_suite_struct);
4417
4418 /* 2. Get pairwise cipher counts */
4419 /*Count = *(u16 *)pTmp; */
4420 Count = (pTmp[1] << 8) + pTmp[0];
4421 pTmp += sizeof(u16);
4422
4423 /* 3. Get pairwise cipher */
4424 /* Parsing all unicast cipher suite */
4425 while (Count > 0) {
4426 /* Skip OUI */
4427 pCipher = (struct rt_cipher_suite_struct *) pTmp;
4428 TmpCipher = Ndis802_11WEPDisabled;
4429 switch (pCipher->Type) {
4430 case 1:
4431 case 5: /* Although WEP is not allowed in WPA related auth mode, we parse it anyway */
4432 TmpCipher =
4433 Ndis802_11Encryption1Enabled;
4434 break;
4435 case 2:
4436 TmpCipher =
4437 Ndis802_11Encryption2Enabled;
4438 break;
4439 case 4:
4440 TmpCipher =
4441 Ndis802_11Encryption3Enabled;
4442 break;
4443 default:
4444 break;
4445 }
4446 if (TmpCipher > pBss->WPA2.PairCipher) {
4447 /* Move the lower cipher suite to PairCipherAux */
4448 pBss->WPA2.PairCipherAux =
4449 pBss->WPA2.PairCipher;
4450 pBss->WPA2.PairCipher = TmpCipher;
4451 } else {
4452 pBss->WPA2.PairCipherAux = TmpCipher;
4453 }
4454 pTmp += sizeof(struct rt_cipher_suite_struct);
4455 Count--;
4456 }
4457
4458 /* 4. get AKM suite counts */
4459 /*Count = *(u16 *)pTmp; */
4460 Count = (pTmp[1] << 8) + pTmp[0];
4461 pTmp += sizeof(u16);
4462
4463 /* 5. Get AKM ciphers */
4464 /* Parsing all AKM ciphers */
4465 while (Count > 0) {
4466 pAKM = (struct rt_akm_suite *) pTmp;
4467 if (!RTMPEqualMemory(pTmp, RSN_OUI, 3))
4468 break;
4469
4470 switch (pAKM->Type) {
4471 case 1:
4472 /* Set AP support WPA-enterprise mode */
4473 if (pBss->AuthMode ==
4474 Ndis802_11AuthModeOpen)
4475 pBss->AuthMode =
4476 Ndis802_11AuthModeWPA2;
4477 else
4478 pBss->AuthModeAux =
4479 Ndis802_11AuthModeWPA2;
4480 break;
4481 case 2:
4482 /* Set AP support WPA-PSK mode */
4483 if (pBss->AuthMode ==
4484 Ndis802_11AuthModeOpen)
4485 pBss->AuthMode =
4486 Ndis802_11AuthModeWPA2PSK;
4487 else
4488 pBss->AuthModeAux =
4489 Ndis802_11AuthModeWPA2PSK;
4490 break;
4491 default:
4492 if (pBss->AuthMode ==
4493 Ndis802_11AuthModeOpen)
4494 pBss->AuthMode =
4495 Ndis802_11AuthModeMax;
4496 else
4497 pBss->AuthModeAux =
4498 Ndis802_11AuthModeMax;
4499 break;
4500 }
4501 pTmp += (Count * sizeof(struct rt_akm_suite));
4502 Count--;
4503 }
4504
4505 /* Fixed for WPA-None */
4506 if (pBss->BssType == BSS_ADHOC) {
4507 pBss->AuthMode = Ndis802_11AuthModeWPANone;
4508 pBss->AuthModeAux = Ndis802_11AuthModeWPANone;
4509 pBss->WPA.PairCipherAux =
4510 pBss->WPA2.PairCipherAux;
4511 pBss->WPA.GroupCipher = pBss->WPA2.GroupCipher;
4512 pBss->WepStatus = pBss->WPA.GroupCipher;
4513 /* Patched bugs for old driver */
4514 if (pBss->WPA.PairCipherAux ==
4515 Ndis802_11WEPDisabled)
4516 pBss->WPA.PairCipherAux =
4517 pBss->WPA.GroupCipher;
4518 }
4519 pBss->WepStatus = pBss->WPA2.PairCipher;
4520
4521 /* 6. Get RSN capability */
4522 /*pBss->WPA2.RsnCapability = *(u16 *)pTmp; */
4523 pBss->WPA2.RsnCapability = (pTmp[1] << 8) + pTmp[0];
4524 pTmp += sizeof(u16);
4525
4526 /* Check the Pair & Group, if different, turn on mixed mode flag */
4527 if (pBss->WPA2.GroupCipher != pBss->WPA2.PairCipher)
4528 pBss->WPA2.bMixMode = TRUE;
4529
4530 break;
4531 default:
4532 break;
4533 }
4534 Length -= (pEid->Len + 2);
4535 }
4536}
4537
4538/* =========================================================================================== */
4539/* mac_table.c */
4540/* =========================================================================================== */
4541
4542/*! \brief generates a random mac address value for IBSS BSSID
4543 * \param Addr the bssid location
4544 * \return none
4545 * \pre
4546 * \post
4547 */
4548void MacAddrRandomBssid(struct rt_rtmp_adapter *pAd, u8 *pAddr)
4549{
4550 int i;
4551
4552 for (i = 0; i < MAC_ADDR_LEN; i++) {
4553 pAddr[i] = RandomByte(pAd);
4554 }
4555
4556 pAddr[0] = (pAddr[0] & 0xfe) | 0x02; /* the first 2 bits must be 01xxxxxxxx */
4557}
4558
4559/*! \brief init the management mac frame header
4560 * \param p_hdr mac header
4561 * \param subtype subtype of the frame
4562 * \param p_ds destination address, don't care if it is a broadcast address
4563 * \return none
4564 * \pre the station has the following information in the pAd->StaCfg
4565 * - bssid
4566 * - station address
4567 * \post
4568 * \note this function initializes the following field
4569
4570 IRQL = PASSIVE_LEVEL
4571 IRQL = DISPATCH_LEVEL
4572
4573 */
4574void MgtMacHeaderInit(struct rt_rtmp_adapter *pAd,
4575 struct rt_header_802_11 * pHdr80211,
4576 u8 SubType,
4577 u8 ToDs, u8 *pDA, u8 *pBssid)
4578{
4579 NdisZeroMemory(pHdr80211, sizeof(struct rt_header_802_11));
4580
4581 pHdr80211->FC.Type = BTYPE_MGMT;
4582 pHdr80211->FC.SubType = SubType;
4583/* if (SubType == SUBTYPE_ACK) // sample, no use, it will conflict with ACTION frame sub type */
4584/* pHdr80211->FC.Type = BTYPE_CNTL; */
4585 pHdr80211->FC.ToDs = ToDs;
4586 COPY_MAC_ADDR(pHdr80211->Addr1, pDA);
4587 COPY_MAC_ADDR(pHdr80211->Addr2, pAd->CurrentAddress);
4588 COPY_MAC_ADDR(pHdr80211->Addr3, pBssid);
4589}
4590
4591/* =========================================================================================== */
4592/* mem_mgmt.c */
4593/* =========================================================================================== */
4594
4595/*!***************************************************************************
4596 * This routine build an outgoing frame, and fill all information specified
4597 * in argument list to the frame body. The actual frame size is the summation
4598 * of all arguments.
4599 * input params:
4600 * Buffer - pointer to a pre-allocated memory segment
4601 * args - a list of <int arg_size, arg> pairs.
4602 * NOTE NOTE NOTE! the last argument must be NULL, otherwise this
4603 * function will FAIL!
4604 * return:
4605 * Size of the buffer
4606 * usage:
4607 * MakeOutgoingFrame(Buffer, output_length, 2, &fc, 2, &dur, 6, p_addr1, 6,p_addr2, END_OF_ARGS);
4608
4609 IRQL = PASSIVE_LEVEL
4610 IRQL = DISPATCH_LEVEL
4611
4612 ****************************************************************************/
4613unsigned long MakeOutgoingFrame(u8 * Buffer, unsigned long * FrameLen, ...)
4614{
4615 u8 *p;
4616 int leng;
4617 unsigned long TotLeng;
4618 va_list Args;
4619
4620 /* calculates the total length */
4621 TotLeng = 0;
4622 va_start(Args, FrameLen);
4623 do {
4624 leng = va_arg(Args, int);
4625 if (leng == END_OF_ARGS) {
4626 break;
4627 }
4628 p = va_arg(Args, void *);
4629 NdisMoveMemory(&Buffer[TotLeng], p, leng);
4630 TotLeng = TotLeng + leng;
4631 } while (TRUE);
4632
4633 va_end(Args); /* clean up */
4634 *FrameLen = TotLeng;
4635 return TotLeng;
4636}
4637
4638/* =========================================================================================== */
4639/* mlme_queue.c */
4640/* =========================================================================================== */
4641
4642/*! \brief Initialize The MLME Queue, used by MLME Functions
4643 * \param *Queue The MLME Queue
4644 * \return Always Return NDIS_STATE_SUCCESS in this implementation
4645 * \pre
4646 * \post
4647 * \note Because this is done only once (at the init stage), no need to be locked
4648
4649 IRQL = PASSIVE_LEVEL
4650
4651 */
4652int MlmeQueueInit(struct rt_mlme_queue *Queue)
4653{
4654 int i;
4655
4656 NdisAllocateSpinLock(&Queue->Lock);
4657
4658 Queue->Num = 0;
4659 Queue->Head = 0;
4660 Queue->Tail = 0;
4661
4662 for (i = 0; i < MAX_LEN_OF_MLME_QUEUE; i++) {
4663 Queue->Entry[i].Occupied = FALSE;
4664 Queue->Entry[i].MsgLen = 0;
4665 NdisZeroMemory(Queue->Entry[i].Msg, MGMT_DMA_BUFFER_SIZE);
4666 }
4667
4668 return NDIS_STATUS_SUCCESS;
4669}
4670
4671/*! \brief Enqueue a message for other threads, if they want to send messages to MLME thread
4672 * \param *Queue The MLME Queue
4673 * \param Machine The State Machine Id
4674 * \param MsgType The Message Type
4675 * \param MsgLen The Message length
4676 * \param *Msg The message pointer
4677 * \return TRUE if enqueue is successful, FALSE if the queue is full
4678 * \pre
4679 * \post
4680 * \note The message has to be initialized
4681
4682 IRQL = PASSIVE_LEVEL
4683 IRQL = DISPATCH_LEVEL
4684
4685 */
4686BOOLEAN MlmeEnqueue(struct rt_rtmp_adapter *pAd,
4687 unsigned long Machine,
4688 unsigned long MsgType, unsigned long MsgLen, void * Msg)
4689{
4690 int Tail;
4691 struct rt_mlme_queue *Queue = (struct rt_mlme_queue *)& pAd->Mlme.Queue;
4692
4693 /* Do nothing if the driver is starting halt state. */
4694 /* This might happen when timer already been fired before cancel timer with mlmehalt */
4695 if (RTMP_TEST_FLAG
4696 (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
4697 return FALSE;
4698
4699 /* First check the size, it MUST not exceed the mlme queue size */
4700 if (MsgLen > MGMT_DMA_BUFFER_SIZE) {
4701 DBGPRINT_ERR("MlmeEnqueue: msg too large, size = %ld \n", MsgLen);
4702 return FALSE;
4703 }
4704
4705 if (MlmeQueueFull(Queue)) {
4706 return FALSE;
4707 }
4708
4709 NdisAcquireSpinLock(&(Queue->Lock));
4710 Tail = Queue->Tail;
4711 Queue->Tail++;
4712 Queue->Num++;
4713 if (Queue->Tail == MAX_LEN_OF_MLME_QUEUE) {
4714 Queue->Tail = 0;
4715 }
4716
4717 Queue->Entry[Tail].Wcid = RESERVED_WCID;
4718 Queue->Entry[Tail].Occupied = TRUE;
4719 Queue->Entry[Tail].Machine = Machine;
4720 Queue->Entry[Tail].MsgType = MsgType;
4721 Queue->Entry[Tail].MsgLen = MsgLen;
4722
4723 if (Msg != NULL) {
4724 NdisMoveMemory(Queue->Entry[Tail].Msg, Msg, MsgLen);
4725 }
4726
4727 NdisReleaseSpinLock(&(Queue->Lock));
4728 return TRUE;
4729}
4730
4731/*! \brief This function is used when Recv gets a MLME message
4732 * \param *Queue The MLME Queue
4733 * \param TimeStampHigh The upper 32 bit of timestamp
4734 * \param TimeStampLow The lower 32 bit of timestamp
4735 * \param Rssi The receiving RSSI strength
4736 * \param MsgLen The length of the message
4737 * \param *Msg The message pointer
4738 * \return TRUE if everything ok, FALSE otherwise (like Queue Full)
4739 * \pre
4740 * \post
4741
4742 IRQL = DISPATCH_LEVEL
4743
4744 */
4745BOOLEAN MlmeEnqueueForRecv(struct rt_rtmp_adapter *pAd,
4746 unsigned long Wcid,
4747 unsigned long TimeStampHigh,
4748 unsigned long TimeStampLow,
4749 u8 Rssi0,
4750 u8 Rssi1,
4751 u8 Rssi2,
4752 unsigned long MsgLen, void * Msg, u8 Signal)
4753{
4754 int Tail, Machine;
4755 struct rt_frame_802_11 * pFrame = (struct rt_frame_802_11 *) Msg;
4756 int MsgType;
4757 struct rt_mlme_queue *Queue = (struct rt_mlme_queue *)& pAd->Mlme.Queue;
4758
4759 /* Do nothing if the driver is starting halt state. */
4760 /* This might happen when timer already been fired before cancel timer with mlmehalt */
4761 if (RTMP_TEST_FLAG
4762 (pAd,
4763 fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)) {
4764 DBGPRINT_ERR("MlmeEnqueueForRecv: fRTMP_ADAPTER_HALT_IN_PROGRESS\n");
4765 return FALSE;
4766 }
4767 /* First check the size, it MUST not exceed the mlme queue size */
4768 if (MsgLen > MGMT_DMA_BUFFER_SIZE) {
4769 DBGPRINT_ERR("MlmeEnqueueForRecv: frame too large, size = %ld \n", MsgLen);
4770 return FALSE;
4771 }
4772
4773 if (MlmeQueueFull(Queue)) {
4774 return FALSE;
4775 }
4776
4777 {
4778 if (!MsgTypeSubst(pAd, pFrame, &Machine, &MsgType)) {
4779 DBGPRINT_ERR("MlmeEnqueueForRecv: un-recongnized mgmt->subtype=%d\n", pFrame->Hdr.FC.SubType);
4780 return FALSE;
4781 }
4782 }
4783
4784 /* OK, we got all the informations, it is time to put things into queue */
4785 NdisAcquireSpinLock(&(Queue->Lock));
4786 Tail = Queue->Tail;
4787 Queue->Tail++;
4788 Queue->Num++;
4789 if (Queue->Tail == MAX_LEN_OF_MLME_QUEUE) {
4790 Queue->Tail = 0;
4791 }
4792 Queue->Entry[Tail].Occupied = TRUE;
4793 Queue->Entry[Tail].Machine = Machine;
4794 Queue->Entry[Tail].MsgType = MsgType;
4795 Queue->Entry[Tail].MsgLen = MsgLen;
4796 Queue->Entry[Tail].TimeStamp.u.LowPart = TimeStampLow;
4797 Queue->Entry[Tail].TimeStamp.u.HighPart = TimeStampHigh;
4798 Queue->Entry[Tail].Rssi0 = Rssi0;
4799 Queue->Entry[Tail].Rssi1 = Rssi1;
4800 Queue->Entry[Tail].Rssi2 = Rssi2;
4801 Queue->Entry[Tail].Signal = Signal;
4802 Queue->Entry[Tail].Wcid = (u8)Wcid;
4803
4804 Queue->Entry[Tail].Channel = pAd->LatchRfRegs.Channel;
4805
4806 if (Msg != NULL) {
4807 NdisMoveMemory(Queue->Entry[Tail].Msg, Msg, MsgLen);
4808 }
4809
4810 NdisReleaseSpinLock(&(Queue->Lock));
4811
4812 RTMP_MLME_HANDLER(pAd);
4813
4814 return TRUE;
4815}
4816
4817/*! \brief Dequeue a message from the MLME Queue
4818 * \param *Queue The MLME Queue
4819 * \param *Elem The message dequeued from MLME Queue
4820 * \return TRUE if the Elem contains something, FALSE otherwise
4821 * \pre
4822 * \post
4823
4824 IRQL = DISPATCH_LEVEL
4825
4826 */
4827BOOLEAN MlmeDequeue(struct rt_mlme_queue *Queue, struct rt_mlme_queue_elem ** Elem)
4828{
4829 NdisAcquireSpinLock(&(Queue->Lock));
4830 *Elem = &(Queue->Entry[Queue->Head]);
4831 Queue->Num--;
4832 Queue->Head++;
4833 if (Queue->Head == MAX_LEN_OF_MLME_QUEUE) {
4834 Queue->Head = 0;
4835 }
4836 NdisReleaseSpinLock(&(Queue->Lock));
4837 return TRUE;
4838}
4839
4840/* IRQL = DISPATCH_LEVEL */
4841void MlmeRestartStateMachine(struct rt_rtmp_adapter *pAd)
4842{
4843#ifdef RTMP_MAC_PCI
4844 struct rt_mlme_queue_elem *Elem = NULL;
4845#endif /* RTMP_MAC_PCI // */
4846 BOOLEAN Cancelled;
4847
4848 DBGPRINT(RT_DEBUG_TRACE, ("MlmeRestartStateMachine \n"));
4849
4850#ifdef RTMP_MAC_PCI
4851 NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
4852 if (pAd->Mlme.bRunning) {
4853 NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
4854 return;
4855 } else {
4856 pAd->Mlme.bRunning = TRUE;
4857 }
4858 NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
4859
4860 /* Remove all Mlme queues elements */
4861 while (!MlmeQueueEmpty(&pAd->Mlme.Queue)) {
4862 /*From message type, determine which state machine I should drive */
4863 if (MlmeDequeue(&pAd->Mlme.Queue, &Elem)) {
4864 /* free MLME element */
4865 Elem->Occupied = FALSE;
4866 Elem->MsgLen = 0;
4867
4868 } else {
4869 DBGPRINT_ERR("MlmeRestartStateMachine: MlmeQueue empty\n");
4870 }
4871 }
4872#endif /* RTMP_MAC_PCI // */
4873
4874 {
4875 /* Cancel all timer events */
4876 /* Be careful to cancel new added timer */
4877 RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &Cancelled);
4878 RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &Cancelled);
4879 RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled);
4880 RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &Cancelled);
4881 RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &Cancelled);
4882 RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled);
4883
4884 }
4885
4886 /* Change back to original channel in case of doing scan */
4887 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
4888 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
4889
4890 /* Resume MSDU which is turned off durning scan */
4891 RTMPResumeMsduTransmission(pAd);
4892
4893 {
4894 /* Set all state machines back IDLE */
4895 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
4896 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
4897 pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
4898 pAd->Mlme.AuthRspMachine.CurrState = AUTH_RSP_IDLE;
4899 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
4900 pAd->Mlme.ActMachine.CurrState = ACT_IDLE;
4901 }
4902
4903#ifdef RTMP_MAC_PCI
4904 /* Remove running state */
4905 NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
4906 pAd->Mlme.bRunning = FALSE;
4907 NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
4908#endif /* RTMP_MAC_PCI // */
4909}
4910
4911/*! \brief test if the MLME Queue is empty
4912 * \param *Queue The MLME Queue
4913 * \return TRUE if the Queue is empty, FALSE otherwise
4914 * \pre
4915 * \post
4916
4917 IRQL = DISPATCH_LEVEL
4918
4919 */
4920BOOLEAN MlmeQueueEmpty(struct rt_mlme_queue *Queue)
4921{
4922 BOOLEAN Ans;
4923
4924 NdisAcquireSpinLock(&(Queue->Lock));
4925 Ans = (Queue->Num == 0);
4926 NdisReleaseSpinLock(&(Queue->Lock));
4927
4928 return Ans;
4929}
4930
4931/*! \brief test if the MLME Queue is full
4932 * \param *Queue The MLME Queue
4933 * \return TRUE if the Queue is empty, FALSE otherwise
4934 * \pre
4935 * \post
4936
4937 IRQL = PASSIVE_LEVEL
4938 IRQL = DISPATCH_LEVEL
4939
4940 */
4941BOOLEAN MlmeQueueFull(struct rt_mlme_queue *Queue)
4942{
4943 BOOLEAN Ans;
4944
4945 NdisAcquireSpinLock(&(Queue->Lock));
4946 Ans = (Queue->Num == MAX_LEN_OF_MLME_QUEUE
4947 || Queue->Entry[Queue->Tail].Occupied);
4948 NdisReleaseSpinLock(&(Queue->Lock));
4949
4950 return Ans;
4951}
4952
4953/*! \brief The destructor of MLME Queue
4954 * \param
4955 * \return
4956 * \pre
4957 * \post
4958 * \note Clear Mlme Queue, Set Queue->Num to Zero.
4959
4960 IRQL = PASSIVE_LEVEL
4961
4962 */
4963void MlmeQueueDestroy(struct rt_mlme_queue *pQueue)
4964{
4965 NdisAcquireSpinLock(&(pQueue->Lock));
4966 pQueue->Num = 0;
4967 pQueue->Head = 0;
4968 pQueue->Tail = 0;
4969 NdisReleaseSpinLock(&(pQueue->Lock));
4970 NdisFreeSpinLock(&(pQueue->Lock));
4971}
4972
4973/*! \brief To substitute the message type if the message is coming from external
4974 * \param pFrame The frame received
4975 * \param *Machine The state machine
4976 * \param *MsgType the message type for the state machine
4977 * \return TRUE if the substitution is successful, FALSE otherwise
4978 * \pre
4979 * \post
4980
4981 IRQL = DISPATCH_LEVEL
4982
4983 */
4984BOOLEAN MsgTypeSubst(struct rt_rtmp_adapter *pAd,
4985 struct rt_frame_802_11 * pFrame,
4986 int * Machine, int * MsgType)
4987{
4988 u16 Seq, Alg;
4989 u8 EAPType;
4990 u8 *pData;
4991
4992 /* Pointer to start of data frames including SNAP header */
4993 pData = (u8 *)pFrame + LENGTH_802_11;
4994
4995 /* The only data type will pass to this function is EAPOL frame */
4996 if (pFrame->Hdr.FC.Type == BTYPE_DATA) {
4997 {
4998 *Machine = WPA_STATE_MACHINE;
4999 EAPType =
5000 *((u8 *) pFrame + LENGTH_802_11 +
5001 LENGTH_802_1_H + 1);
5002 return (WpaMsgTypeSubst(EAPType, (int *) MsgType));
5003 }
5004 }
5005
5006 switch (pFrame->Hdr.FC.SubType) {
5007 case SUBTYPE_ASSOC_REQ:
5008 *Machine = ASSOC_STATE_MACHINE;
5009 *MsgType = MT2_PEER_ASSOC_REQ;
5010 break;
5011 case SUBTYPE_ASSOC_RSP:
5012 *Machine = ASSOC_STATE_MACHINE;
5013 *MsgType = MT2_PEER_ASSOC_RSP;
5014 break;
5015 case SUBTYPE_REASSOC_REQ:
5016 *Machine = ASSOC_STATE_MACHINE;
5017 *MsgType = MT2_PEER_REASSOC_REQ;
5018 break;
5019 case SUBTYPE_REASSOC_RSP:
5020 *Machine = ASSOC_STATE_MACHINE;
5021 *MsgType = MT2_PEER_REASSOC_RSP;
5022 break;
5023 case SUBTYPE_PROBE_REQ:
5024 *Machine = SYNC_STATE_MACHINE;
5025 *MsgType = MT2_PEER_PROBE_REQ;
5026 break;
5027 case SUBTYPE_PROBE_RSP:
5028 *Machine = SYNC_STATE_MACHINE;
5029 *MsgType = MT2_PEER_PROBE_RSP;
5030 break;
5031 case SUBTYPE_BEACON:
5032 *Machine = SYNC_STATE_MACHINE;
5033 *MsgType = MT2_PEER_BEACON;
5034 break;
5035 case SUBTYPE_ATIM:
5036 *Machine = SYNC_STATE_MACHINE;
5037 *MsgType = MT2_PEER_ATIM;
5038 break;
5039 case SUBTYPE_DISASSOC:
5040 *Machine = ASSOC_STATE_MACHINE;
5041 *MsgType = MT2_PEER_DISASSOC_REQ;
5042 break;
5043 case SUBTYPE_AUTH:
5044 /* get the sequence number from payload 24 Mac Header + 2 bytes algorithm */
5045 NdisMoveMemory(&Seq, &pFrame->Octet[2], sizeof(u16));
5046 NdisMoveMemory(&Alg, &pFrame->Octet[0], sizeof(u16));
5047 if (Seq == 1 || Seq == 3) {
5048 *Machine = AUTH_RSP_STATE_MACHINE;
5049 *MsgType = MT2_PEER_AUTH_ODD;
5050 } else if (Seq == 2 || Seq == 4) {
5051 if (Alg == AUTH_MODE_OPEN || Alg == AUTH_MODE_KEY) {
5052 *Machine = AUTH_STATE_MACHINE;
5053 *MsgType = MT2_PEER_AUTH_EVEN;
5054 }
5055 } else {
5056 return FALSE;
5057 }
5058 break;
5059 case SUBTYPE_DEAUTH:
5060 *Machine = AUTH_RSP_STATE_MACHINE;
5061 *MsgType = MT2_PEER_DEAUTH;
5062 break;
5063 case SUBTYPE_ACTION:
5064 *Machine = ACTION_STATE_MACHINE;
5065 /* Sometimes Sta will return with category bytes with MSB = 1, if they receive catogory out of their support */
5066 if ((pFrame->Octet[0] & 0x7F) > MAX_PEER_CATE_MSG) {
5067 *MsgType = MT2_ACT_INVALID;
5068 } else {
5069 *MsgType = (pFrame->Octet[0] & 0x7F);
5070 }
5071 break;
5072 default:
5073 return FALSE;
5074 break;
5075 }
5076
5077 return TRUE;
5078}
5079
5080/* =========================================================================================== */
5081/* state_machine.c */
5082/* =========================================================================================== */
5083
5084/*! \brief Initialize the state machine.
5085 * \param *S pointer to the state machine
5086 * \param Trans State machine transition function
5087 * \param StNr number of states
5088 * \param MsgNr number of messages
5089 * \param DefFunc default function, when there is invalid state/message combination
5090 * \param InitState initial state of the state machine
5091 * \param Base StateMachine base, internal use only
5092 * \pre p_sm should be a legal pointer
5093 * \post
5094
5095 IRQL = PASSIVE_LEVEL
5096
5097 */
5098void StateMachineInit(struct rt_state_machine *S,
5099 IN STATE_MACHINE_FUNC Trans[],
5100 unsigned long StNr,
5101 unsigned long MsgNr,
5102 IN STATE_MACHINE_FUNC DefFunc,
5103 unsigned long InitState, unsigned long Base)
5104{
5105 unsigned long i, j;
5106
5107 /* set number of states and messages */
5108 S->NrState = StNr;
5109 S->NrMsg = MsgNr;
5110 S->Base = Base;
5111
5112 S->TransFunc = Trans;
5113
5114 /* init all state transition to default function */
5115 for (i = 0; i < StNr; i++) {
5116 for (j = 0; j < MsgNr; j++) {
5117 S->TransFunc[i * MsgNr + j] = DefFunc;
5118 }
5119 }
5120
5121 /* set the starting state */
5122 S->CurrState = InitState;
5123}
5124
5125/*! \brief This function fills in the function pointer into the cell in the state machine
5126 * \param *S pointer to the state machine
5127 * \param St state
5128 * \param Msg incoming message
5129 * \param f the function to be executed when (state, message) combination occurs at the state machine
5130 * \pre *S should be a legal pointer to the state machine, st, msg, should be all within the range, Base should be set in the initial state
5131 * \post
5132
5133 IRQL = PASSIVE_LEVEL
5134
5135 */
5136void StateMachineSetAction(struct rt_state_machine *S,
5137 unsigned long St,
5138 unsigned long Msg, IN STATE_MACHINE_FUNC Func)
5139{
5140 unsigned long MsgIdx;
5141
5142 MsgIdx = Msg - S->Base;
5143
5144 if (St < S->NrState && MsgIdx < S->NrMsg) {
5145 /* boundary checking before setting the action */
5146 S->TransFunc[St * S->NrMsg + MsgIdx] = Func;
5147 }
5148}
5149
5150/*! \brief This function does the state transition
5151 * \param *Adapter the NIC adapter pointer
5152 * \param *S the state machine
5153 * \param *Elem the message to be executed
5154 * \return None
5155
5156 IRQL = DISPATCH_LEVEL
5157
5158 */
5159void StateMachinePerformAction(struct rt_rtmp_adapter *pAd,
5160 struct rt_state_machine *S, struct rt_mlme_queue_elem *Elem)
5161{
5162 (*(S->TransFunc[S->CurrState * S->NrMsg + Elem->MsgType - S->Base]))
5163 (pAd, Elem);
5164}
5165
5166/*
5167 ==========================================================================
5168 Description:
5169 The drop function, when machine executes this, the message is simply
5170 ignored. This function does nothing, the message is freed in
5171 StateMachinePerformAction()
5172 ==========================================================================
5173 */
5174void Drop(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
5175{
5176}
5177
5178/* =========================================================================================== */
5179/* lfsr.c */
5180/* =========================================================================================== */
5181
5182/*
5183 ==========================================================================
5184 Description:
5185
5186 IRQL = PASSIVE_LEVEL
5187
5188 ==========================================================================
5189 */
5190void LfsrInit(struct rt_rtmp_adapter *pAd, unsigned long Seed)
5191{
5192 if (Seed == 0)
5193 pAd->Mlme.ShiftReg = 1;
5194 else
5195 pAd->Mlme.ShiftReg = Seed;
5196}
5197
5198/*
5199 ==========================================================================
5200 Description:
5201 ==========================================================================
5202 */
5203u8 RandomByte(struct rt_rtmp_adapter *pAd)
5204{
5205 unsigned long i;
5206 u8 R, Result;
5207
5208 R = 0;
5209
5210 if (pAd->Mlme.ShiftReg == 0)
5211 NdisGetSystemUpTime((unsigned long *) & pAd->Mlme.ShiftReg);
5212
5213 for (i = 0; i < 8; i++) {
5214 if (pAd->Mlme.ShiftReg & 0x00000001) {
5215 pAd->Mlme.ShiftReg =
5216 ((pAd->Mlme.
5217 ShiftReg ^ LFSR_MASK) >> 1) | 0x80000000;
5218 Result = 1;
5219 } else {
5220 pAd->Mlme.ShiftReg = pAd->Mlme.ShiftReg >> 1;
5221 Result = 0;
5222 }
5223 R = (R << 1) | Result;
5224 }
5225
5226 return R;
5227}
5228
5229/*
5230 ========================================================================
5231
5232 Routine Description:
5233 Verify the support rate for different PHY type
5234
5235 Arguments:
5236 pAd Pointer to our adapter
5237
5238 Return Value:
5239 None
5240
5241 IRQL = PASSIVE_LEVEL
5242
5243 ========================================================================
5244*/
5245void RTMPCheckRates(struct rt_rtmp_adapter *pAd,
5246 IN u8 SupRate[], IN u8 * SupRateLen)
5247{
5248 u8 RateIdx, i, j;
5249 u8 NewRate[12], NewRateLen;
5250
5251 NewRateLen = 0;
5252
5253 if (pAd->CommonCfg.PhyMode == PHY_11B)
5254 RateIdx = 4;
5255 else
5256 RateIdx = 12;
5257
5258 /* Check for support rates exclude basic rate bit */
5259 for (i = 0; i < *SupRateLen; i++)
5260 for (j = 0; j < RateIdx; j++)
5261 if ((SupRate[i] & 0x7f) == RateIdTo500Kbps[j])
5262 NewRate[NewRateLen++] = SupRate[i];
5263
5264 *SupRateLen = NewRateLen;
5265 NdisMoveMemory(SupRate, NewRate, NewRateLen);
5266}
5267
5268BOOLEAN RTMPCheckChannel(struct rt_rtmp_adapter *pAd,
5269 u8 CentralChannel, u8 Channel)
5270{
5271 u8 k;
5272 u8 UpperChannel = 0, LowerChannel = 0;
5273 u8 NoEffectChannelinList = 0;
5274
5275 /* Find upper and lower channel according to 40MHz current operation. */
5276 if (CentralChannel < Channel) {
5277 UpperChannel = Channel;
5278 if (CentralChannel > 2)
5279 LowerChannel = CentralChannel - 2;
5280 else
5281 return FALSE;
5282 } else if (CentralChannel > Channel) {
5283 UpperChannel = CentralChannel + 2;
5284 LowerChannel = Channel;
5285 }
5286
5287 for (k = 0; k < pAd->ChannelListNum; k++) {
5288 if (pAd->ChannelList[k].Channel == UpperChannel) {
5289 NoEffectChannelinList++;
5290 }
5291 if (pAd->ChannelList[k].Channel == LowerChannel) {
5292 NoEffectChannelinList++;
5293 }
5294 }
5295
5296 DBGPRINT(RT_DEBUG_TRACE,
5297 ("Total Channel in Channel List = [%d]\n",
5298 NoEffectChannelinList));
5299 if (NoEffectChannelinList == 2)
5300 return TRUE;
5301 else
5302 return FALSE;
5303}
5304
5305/*
5306 ========================================================================
5307
5308 Routine Description:
5309 Verify the support rate for HT phy type
5310
5311 Arguments:
5312 pAd Pointer to our adapter
5313
5314 Return Value:
5315 FALSE if pAd->CommonCfg.SupportedHtPhy doesn't accept the pHtCapability. (AP Mode)
5316
5317 IRQL = PASSIVE_LEVEL
5318
5319 ========================================================================
5320*/
5321BOOLEAN RTMPCheckHt(struct rt_rtmp_adapter *pAd,
5322 u8 Wcid,
5323 struct rt_ht_capability_ie * pHtCapability,
5324 struct rt_add_ht_info_ie * pAddHtInfo)
5325{
5326 if (Wcid >= MAX_LEN_OF_MAC_TABLE)
5327 return FALSE;
5328
5329 /* If use AMSDU, set flag. */
5330 if (pAd->CommonCfg.DesiredHtPhy.AmsduEnable)
5331 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid],
5332 fCLIENT_STATUS_AMSDU_INUSED);
5333 /* Save Peer Capability */
5334 if (pHtCapability->HtCapInfo.ShortGIfor20)
5335 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid],
5336 fCLIENT_STATUS_SGI20_CAPABLE);
5337 if (pHtCapability->HtCapInfo.ShortGIfor40)
5338 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid],
5339 fCLIENT_STATUS_SGI40_CAPABLE);
5340 if (pHtCapability->HtCapInfo.TxSTBC)
5341 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid],
5342 fCLIENT_STATUS_TxSTBC_CAPABLE);
5343 if (pHtCapability->HtCapInfo.RxSTBC)
5344 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid],
5345 fCLIENT_STATUS_RxSTBC_CAPABLE);
5346 if (pAd->CommonCfg.bRdg && pHtCapability->ExtHtCapInfo.RDGSupport) {
5347 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid],
5348 fCLIENT_STATUS_RDG_CAPABLE);
5349 }
5350
5351 if (Wcid < MAX_LEN_OF_MAC_TABLE) {
5352 pAd->MacTab.Content[Wcid].MpduDensity =
5353 pHtCapability->HtCapParm.MpduDensity;
5354 }
5355 /* Will check ChannelWidth for MCSSet[4] below */
5356 pAd->MlmeAux.HtCapability.MCSSet[4] = 0x1;
5357 switch (pAd->CommonCfg.RxStream) {
5358 case 1:
5359 pAd->MlmeAux.HtCapability.MCSSet[0] = 0xff;
5360 pAd->MlmeAux.HtCapability.MCSSet[1] = 0x00;
5361 pAd->MlmeAux.HtCapability.MCSSet[2] = 0x00;
5362 pAd->MlmeAux.HtCapability.MCSSet[3] = 0x00;
5363 break;
5364 case 2:
5365 pAd->MlmeAux.HtCapability.MCSSet[0] = 0xff;
5366 pAd->MlmeAux.HtCapability.MCSSet[1] = 0xff;
5367 pAd->MlmeAux.HtCapability.MCSSet[2] = 0x00;
5368 pAd->MlmeAux.HtCapability.MCSSet[3] = 0x00;
5369 break;
5370 case 3:
5371 pAd->MlmeAux.HtCapability.MCSSet[0] = 0xff;
5372 pAd->MlmeAux.HtCapability.MCSSet[1] = 0xff;
5373 pAd->MlmeAux.HtCapability.MCSSet[2] = 0xff;
5374 pAd->MlmeAux.HtCapability.MCSSet[3] = 0x00;
5375 break;
5376 }
5377
5378 pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth =
5379 pAddHtInfo->AddHtInfo.RecomWidth & pAd->CommonCfg.DesiredHtPhy.
5380 ChannelWidth;
5381
5382 DBGPRINT(RT_DEBUG_TRACE,
5383 ("RTMPCheckHt:: HtCapInfo.ChannelWidth=%d, RecomWidth=%d, DesiredHtPhy.ChannelWidth=%d, BW40MAvailForA/G=%d/%d, PhyMode=%d \n",
5384 pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth,
5385 pAddHtInfo->AddHtInfo.RecomWidth,
5386 pAd->CommonCfg.DesiredHtPhy.ChannelWidth,
5387 pAd->NicConfig2.field.BW40MAvailForA,
5388 pAd->NicConfig2.field.BW40MAvailForG,
5389 pAd->CommonCfg.PhyMode));
5390
5391 pAd->MlmeAux.HtCapability.HtCapInfo.GF =
5392 pHtCapability->HtCapInfo.GF & pAd->CommonCfg.DesiredHtPhy.GF;
5393
5394 /* Send Assoc Req with my HT capability. */
5395 pAd->MlmeAux.HtCapability.HtCapInfo.AMsduSize =
5396 pAd->CommonCfg.DesiredHtPhy.AmsduSize;
5397 pAd->MlmeAux.HtCapability.HtCapInfo.MimoPs =
5398 pAd->CommonCfg.DesiredHtPhy.MimoPs;
5399 pAd->MlmeAux.HtCapability.HtCapInfo.ShortGIfor20 =
5400 (pAd->CommonCfg.DesiredHtPhy.ShortGIfor20) & (pHtCapability->
5401 HtCapInfo.
5402 ShortGIfor20);
5403 pAd->MlmeAux.HtCapability.HtCapInfo.ShortGIfor40 =
5404 (pAd->CommonCfg.DesiredHtPhy.ShortGIfor40) & (pHtCapability->
5405 HtCapInfo.
5406 ShortGIfor40);
5407 pAd->MlmeAux.HtCapability.HtCapInfo.TxSTBC =
5408 (pAd->CommonCfg.DesiredHtPhy.TxSTBC) & (pHtCapability->HtCapInfo.
5409 RxSTBC);
5410 pAd->MlmeAux.HtCapability.HtCapInfo.RxSTBC =
5411 (pAd->CommonCfg.DesiredHtPhy.RxSTBC) & (pHtCapability->HtCapInfo.
5412 TxSTBC);
5413 pAd->MlmeAux.HtCapability.HtCapParm.MaxRAmpduFactor =
5414 pAd->CommonCfg.DesiredHtPhy.MaxRAmpduFactor;
5415 pAd->MlmeAux.HtCapability.HtCapParm.MpduDensity =
5416 pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity;
5417 pAd->MlmeAux.HtCapability.ExtHtCapInfo.PlusHTC =
5418 pHtCapability->ExtHtCapInfo.PlusHTC;
5419 pAd->MacTab.Content[Wcid].HTCapability.ExtHtCapInfo.PlusHTC =
5420 pHtCapability->ExtHtCapInfo.PlusHTC;
5421 if (pAd->CommonCfg.bRdg) {
5422 pAd->MlmeAux.HtCapability.ExtHtCapInfo.RDGSupport =
5423 pHtCapability->ExtHtCapInfo.RDGSupport;
5424 pAd->MlmeAux.HtCapability.ExtHtCapInfo.PlusHTC = 1;
5425 }
5426
5427 if (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_20)
5428 pAd->MlmeAux.HtCapability.MCSSet[4] = 0x0; /* BW20 can't transmit MCS32 */
5429
5430 COPY_AP_HTSETTINGS_FROM_BEACON(pAd, pHtCapability);
5431 return TRUE;
5432}
5433
5434/*
5435 ========================================================================
5436
5437 Routine Description:
5438 Verify the support rate for different PHY type
5439
5440 Arguments:
5441 pAd Pointer to our adapter
5442
5443 Return Value:
5444 None
5445
5446 IRQL = PASSIVE_LEVEL
5447
5448 ========================================================================
5449*/
5450void RTMPUpdateMlmeRate(struct rt_rtmp_adapter *pAd)
5451{
5452 u8 MinimumRate;
5453 u8 ProperMlmeRate; /*= RATE_54; */
5454 u8 i, j, RateIdx = 12; /*1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54 */
5455 BOOLEAN bMatch = FALSE;
5456
5457 switch (pAd->CommonCfg.PhyMode) {
5458 case PHY_11B:
5459 ProperMlmeRate = RATE_11;
5460 MinimumRate = RATE_1;
5461 break;
5462 case PHY_11BG_MIXED:
5463 case PHY_11ABGN_MIXED:
5464 case PHY_11BGN_MIXED:
5465 if ((pAd->MlmeAux.SupRateLen == 4) &&
5466 (pAd->MlmeAux.ExtRateLen == 0))
5467 /* B only AP */
5468 ProperMlmeRate = RATE_11;
5469 else
5470 ProperMlmeRate = RATE_24;
5471
5472 if (pAd->MlmeAux.Channel <= 14)
5473 MinimumRate = RATE_1;
5474 else
5475 MinimumRate = RATE_6;
5476 break;
5477 case PHY_11A:
5478 case PHY_11N_2_4G: /* rt2860 need to check mlmerate for 802.11n */
5479 case PHY_11GN_MIXED:
5480 case PHY_11AGN_MIXED:
5481 case PHY_11AN_MIXED:
5482 case PHY_11N_5G:
5483 ProperMlmeRate = RATE_24;
5484 MinimumRate = RATE_6;
5485 break;
5486 case PHY_11ABG_MIXED:
5487 ProperMlmeRate = RATE_24;
5488 if (pAd->MlmeAux.Channel <= 14)
5489 MinimumRate = RATE_1;
5490 else
5491 MinimumRate = RATE_6;
5492 break;
5493 default: /* error */
5494 ProperMlmeRate = RATE_1;
5495 MinimumRate = RATE_1;
5496 break;
5497 }
5498
5499 for (i = 0; i < pAd->MlmeAux.SupRateLen; i++) {
5500 for (j = 0; j < RateIdx; j++) {
5501 if ((pAd->MlmeAux.SupRate[i] & 0x7f) ==
5502 RateIdTo500Kbps[j]) {
5503 if (j == ProperMlmeRate) {
5504 bMatch = TRUE;
5505 break;
5506 }
5507 }
5508 }
5509
5510 if (bMatch)
5511 break;
5512 }
5513
5514 if (bMatch == FALSE) {
5515 for (i = 0; i < pAd->MlmeAux.ExtRateLen; i++) {
5516 for (j = 0; j < RateIdx; j++) {
5517 if ((pAd->MlmeAux.ExtRate[i] & 0x7f) ==
5518 RateIdTo500Kbps[j]) {
5519 if (j == ProperMlmeRate) {
5520 bMatch = TRUE;
5521 break;
5522 }
5523 }
5524 }
5525
5526 if (bMatch)
5527 break;
5528 }
5529 }
5530
5531 if (bMatch == FALSE) {
5532 ProperMlmeRate = MinimumRate;
5533 }
5534
5535 pAd->CommonCfg.MlmeRate = MinimumRate;
5536 pAd->CommonCfg.RtsRate = ProperMlmeRate;
5537 if (pAd->CommonCfg.MlmeRate >= RATE_6) {
5538 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
5539 pAd->CommonCfg.MlmeTransmit.field.MCS =
5540 OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
5541 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE =
5542 MODE_OFDM;
5543 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS =
5544 OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
5545 } else {
5546 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
5547 pAd->CommonCfg.MlmeTransmit.field.MCS = pAd->CommonCfg.MlmeRate;
5548 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE =
5549 MODE_CCK;
5550 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS =
5551 pAd->CommonCfg.MlmeRate;
5552 }
5553
5554 DBGPRINT(RT_DEBUG_TRACE,
5555 ("RTMPUpdateMlmeRate ==> MlmeTransmit = 0x%x \n",
5556 pAd->CommonCfg.MlmeTransmit.word));
5557}
5558
5559char RTMPMaxRssi(struct rt_rtmp_adapter *pAd,
5560 char Rssi0, char Rssi1, char Rssi2)
5561{
5562 char larger = -127;
5563
5564 if ((pAd->Antenna.field.RxPath == 1) && (Rssi0 != 0)) {
5565 larger = Rssi0;
5566 }
5567
5568 if ((pAd->Antenna.field.RxPath >= 2) && (Rssi1 != 0)) {
5569 larger = max(Rssi0, Rssi1);
5570 }
5571
5572 if ((pAd->Antenna.field.RxPath == 3) && (Rssi2 != 0)) {
5573 larger = max(larger, Rssi2);
5574 }
5575
5576 if (larger == -127)
5577 larger = 0;
5578
5579 return larger;
5580}
5581
5582/*
5583 ========================================================================
5584 Routine Description:
5585 Periodic evaluate antenna link status
5586
5587 Arguments:
5588 pAd - Adapter pointer
5589
5590 Return Value:
5591 None
5592
5593 ========================================================================
5594*/
5595void AsicEvaluateRxAnt(struct rt_rtmp_adapter *pAd)
5596{
5597 u8 BBPR3 = 0;
5598
5599 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS |
5600 fRTMP_ADAPTER_HALT_IN_PROGRESS |
5601 fRTMP_ADAPTER_RADIO_OFF |
5602 fRTMP_ADAPTER_NIC_NOT_EXIST |
5603 fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS) ||
5604 OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)
5605#ifdef RT30xx
5606 || (pAd->EepromAccess)
5607#endif /* RT30xx // */
5608#ifdef RT3090
5609 || (pAd->bPCIclkOff == TRUE)
5610#endif /* RT3090 // */
5611 )
5612 return;
5613
5614 {
5615 /*if (pAd->StaCfg.Psm == PWR_SAVE) */
5616 /* return; */
5617
5618 {
5619
5620 if (pAd->StaCfg.Psm == PWR_SAVE)
5621 return;
5622
5623 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPR3);
5624 BBPR3 &= (~0x18);
5625 if (pAd->Antenna.field.RxPath == 3) {
5626 BBPR3 |= (0x10);
5627 } else if (pAd->Antenna.field.RxPath == 2) {
5628 BBPR3 |= (0x8);
5629 } else if (pAd->Antenna.field.RxPath == 1) {
5630 BBPR3 |= (0x0);
5631 }
5632 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
5633#ifdef RTMP_MAC_PCI
5634 pAd->StaCfg.BBPR3 = BBPR3;
5635#endif /* RTMP_MAC_PCI // */
5636 if (OPSTATUS_TEST_FLAG
5637 (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
5638 ) {
5639 unsigned long TxTotalCnt =
5640 pAd->RalinkCounters.OneSecTxNoRetryOkCount +
5641 pAd->RalinkCounters.OneSecTxRetryOkCount +
5642 pAd->RalinkCounters.OneSecTxFailCount;
5643
5644 /* dynamic adjust antenna evaluation period according to the traffic */
5645 if (TxTotalCnt > 50) {
5646 RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer,
5647 20);
5648 pAd->Mlme.bLowThroughput = FALSE;
5649 } else {
5650 RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer,
5651 300);
5652 pAd->Mlme.bLowThroughput = TRUE;
5653 }
5654 }
5655 }
5656
5657 }
5658
5659}
5660
5661/*
5662 ========================================================================
5663 Routine Description:
5664 After evaluation, check antenna link status
5665
5666 Arguments:
5667 pAd - Adapter pointer
5668
5669 Return Value:
5670 None
5671
5672 ========================================================================
5673*/
5674void AsicRxAntEvalTimeout(void *SystemSpecific1,
5675 void *FunctionContext,
5676 void *SystemSpecific2, void *SystemSpecific3)
5677{
5678 struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext;
5679 u8 BBPR3 = 0;
5680 char larger = -127, rssi0, rssi1, rssi2;
5681
5682 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS |
5683 fRTMP_ADAPTER_HALT_IN_PROGRESS |
5684 fRTMP_ADAPTER_RADIO_OFF |
5685 fRTMP_ADAPTER_NIC_NOT_EXIST) ||
5686 OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)
5687#ifdef RT30xx
5688 || (pAd->EepromAccess)
5689#endif /* RT30xx // */
5690#ifdef RT3090
5691 || (pAd->bPCIclkOff == TRUE)
5692#endif /* RT3090 // */
5693 )
5694 return;
5695
5696 {
5697 /*if (pAd->StaCfg.Psm == PWR_SAVE) */
5698 /* return; */
5699 {
5700 if (pAd->StaCfg.Psm == PWR_SAVE)
5701 return;
5702
5703 /* if the traffic is low, use average rssi as the criteria */
5704 if (pAd->Mlme.bLowThroughput == TRUE) {
5705 rssi0 = pAd->StaCfg.RssiSample.LastRssi0;
5706 rssi1 = pAd->StaCfg.RssiSample.LastRssi1;
5707 rssi2 = pAd->StaCfg.RssiSample.LastRssi2;
5708 } else {
5709 rssi0 = pAd->StaCfg.RssiSample.AvgRssi0;
5710 rssi1 = pAd->StaCfg.RssiSample.AvgRssi1;
5711 rssi2 = pAd->StaCfg.RssiSample.AvgRssi2;
5712 }
5713
5714 if (pAd->Antenna.field.RxPath == 3) {
5715 larger = max(rssi0, rssi1);
5716
5717 if (larger > (rssi2 + 20))
5718 pAd->Mlme.RealRxPath = 2;
5719 else
5720 pAd->Mlme.RealRxPath = 3;
5721 } else if (pAd->Antenna.field.RxPath == 2) {
5722 if (rssi0 > (rssi1 + 20))
5723 pAd->Mlme.RealRxPath = 1;
5724 else
5725 pAd->Mlme.RealRxPath = 2;
5726 }
5727
5728 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPR3);
5729 BBPR3 &= (~0x18);
5730 if (pAd->Mlme.RealRxPath == 3) {
5731 BBPR3 |= (0x10);
5732 } else if (pAd->Mlme.RealRxPath == 2) {
5733 BBPR3 |= (0x8);
5734 } else if (pAd->Mlme.RealRxPath == 1) {
5735 BBPR3 |= (0x0);
5736 }
5737 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
5738#ifdef RTMP_MAC_PCI
5739 pAd->StaCfg.BBPR3 = BBPR3;
5740#endif /* RTMP_MAC_PCI // */
5741 }
5742 }
5743
5744}
5745
5746void APSDPeriodicExec(void *SystemSpecific1,
5747 void *FunctionContext,
5748 void *SystemSpecific2, void *SystemSpecific3)
5749{
5750 struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext;
5751
5752 if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
5753 return;
5754
5755 pAd->CommonCfg.TriggerTimerCount++;
5756
5757/* Driver should not send trigger frame, it should be send by application layer */
5758/*
5759 if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable
5760 && (pAd->CommonCfg.bNeedSendTriggerFrame ||
5761 (((pAd->CommonCfg.TriggerTimerCount%20) == 19) && (!pAd->CommonCfg.bAPSDAC_BE || !pAd->CommonCfg.bAPSDAC_BK || !pAd->CommonCfg.bAPSDAC_VI || !pAd->CommonCfg.bAPSDAC_VO))))
5762 {
5763 DBGPRINT(RT_DEBUG_TRACE,("Sending trigger frame and enter service period when support APSD\n"));
5764 RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
5765 pAd->CommonCfg.bNeedSendTriggerFrame = FALSE;
5766 pAd->CommonCfg.TriggerTimerCount = 0;
5767 pAd->CommonCfg.bInServicePeriod = TRUE;
5768 }*/
5769}
5770
5771/*
5772 ========================================================================
5773 Routine Description:
5774 Set/reset MAC registers according to bPiggyBack parameter
5775
5776 Arguments:
5777 pAd - Adapter pointer
5778 bPiggyBack - Enable / Disable Piggy-Back
5779
5780 Return Value:
5781 None
5782
5783 ========================================================================
5784*/
5785void RTMPSetPiggyBack(struct rt_rtmp_adapter *pAd, IN BOOLEAN bPiggyBack)
5786{
5787 TX_LINK_CFG_STRUC TxLinkCfg;
5788
5789 RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word);
5790
5791 TxLinkCfg.field.TxCFAckEn = bPiggyBack;
5792 RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word);
5793}
5794
5795/*
5796 ========================================================================
5797 Routine Description:
5798 check if this entry need to switch rate automatically
5799
5800 Arguments:
5801 pAd
5802 pEntry
5803
5804 Return Value:
5805 TURE
5806 FALSE
5807
5808 ========================================================================
5809*/
5810BOOLEAN RTMPCheckEntryEnableAutoRateSwitch(struct rt_rtmp_adapter *pAd,
5811 struct rt_mac_table_entry *pEntry)
5812{
5813 BOOLEAN result = TRUE;
5814
5815 {
5816 /* only associated STA counts */
5817 if (pEntry && (pEntry->ValidAsCLI)
5818 && (pEntry->Sst == SST_ASSOC)) {
5819 result = pAd->StaCfg.bAutoTxRateSwitch;
5820 } else
5821 result = FALSE;
5822 }
5823
5824 return result;
5825}
5826
5827BOOLEAN RTMPAutoRateSwitchCheck(struct rt_rtmp_adapter *pAd)
5828{
5829 {
5830 if (pAd->StaCfg.bAutoTxRateSwitch)
5831 return TRUE;
5832 }
5833 return FALSE;
5834}
5835
5836/*
5837 ========================================================================
5838 Routine Description:
5839 check if this entry need to fix tx legacy rate
5840
5841 Arguments:
5842 pAd
5843 pEntry
5844
5845 Return Value:
5846 TURE
5847 FALSE
5848
5849 ========================================================================
5850*/
5851u8 RTMPStaFixedTxMode(struct rt_rtmp_adapter *pAd, struct rt_mac_table_entry *pEntry)
5852{
5853 u8 tx_mode = FIXED_TXMODE_HT;
5854
5855 {
5856 tx_mode =
5857 (u8)pAd->StaCfg.DesiredTransmitSetting.field.
5858 FixedTxMode;
5859 }
5860
5861 return tx_mode;
5862}
5863
5864/*
5865 ========================================================================
5866 Routine Description:
5867 Overwrite HT Tx Mode by Fixed Legency Tx Mode, if specified.
5868
5869 Arguments:
5870 pAd
5871 pEntry
5872
5873 Return Value:
5874 TURE
5875 FALSE
5876
5877 ========================================================================
5878*/
5879void RTMPUpdateLegacyTxSetting(u8 fixed_tx_mode, struct rt_mac_table_entry *pEntry)
5880{
5881 HTTRANSMIT_SETTING TransmitSetting;
5882
5883 if (fixed_tx_mode == FIXED_TXMODE_HT)
5884 return;
5885
5886 TransmitSetting.word = 0;
5887
5888 TransmitSetting.field.MODE = pEntry->HTPhyMode.field.MODE;
5889 TransmitSetting.field.MCS = pEntry->HTPhyMode.field.MCS;
5890
5891 if (fixed_tx_mode == FIXED_TXMODE_CCK) {
5892 TransmitSetting.field.MODE = MODE_CCK;
5893 /* CCK mode allow MCS 0~3 */
5894 if (TransmitSetting.field.MCS > MCS_3)
5895 TransmitSetting.field.MCS = MCS_3;
5896 } else {
5897 TransmitSetting.field.MODE = MODE_OFDM;
5898 /* OFDM mode allow MCS 0~7 */
5899 if (TransmitSetting.field.MCS > MCS_7)
5900 TransmitSetting.field.MCS = MCS_7;
5901 }
5902
5903 if (pEntry->HTPhyMode.field.MODE >= TransmitSetting.field.MODE) {
5904 pEntry->HTPhyMode.word = TransmitSetting.word;
5905 DBGPRINT(RT_DEBUG_TRACE,
5906 ("RTMPUpdateLegacyTxSetting : wcid-%d, MODE=%s, MCS=%d \n",
5907 pEntry->Aid, GetPhyMode(pEntry->HTPhyMode.field.MODE),
5908 pEntry->HTPhyMode.field.MCS));
5909 }
5910}
5911
5912/*
5913 ==========================================================================
5914 Description:
5915 dynamic tune BBP R66 to find a balance between sensibility and
5916 noise isolation
5917
5918 IRQL = DISPATCH_LEVEL
5919
5920 ==========================================================================
5921 */
5922void AsicStaBbpTuning(struct rt_rtmp_adapter *pAd)
5923{
5924 u8 OrigR66Value = 0, R66; /*, R66UpperBound = 0x30, R66LowerBound = 0x30; */
5925 char Rssi;
5926
5927 /* 2860C did not support Fase CCA, therefore can't tune */
5928 if (pAd->MACVersion == 0x28600100)
5929 return;
5930
5931 /* */
5932 /* work as a STA */
5933 /* */
5934 if (pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE) /* no R66 tuning when SCANNING */
5935 return;
5936
5937 if ((pAd->OpMode == OPMODE_STA)
5938 && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
5939 )
5940 && !(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
5941#ifdef RTMP_MAC_PCI
5942 && (pAd->bPCIclkOff == FALSE)
5943#endif /* RTMP_MAC_PCI // */
5944 ) {
5945 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &OrigR66Value);
5946 R66 = OrigR66Value;
5947
5948 if (pAd->Antenna.field.RxPath > 1)
5949 Rssi =
5950 (pAd->StaCfg.RssiSample.AvgRssi0 +
5951 pAd->StaCfg.RssiSample.AvgRssi1) >> 1;
5952 else
5953 Rssi = pAd->StaCfg.RssiSample.AvgRssi0;
5954
5955 if (pAd->LatchRfRegs.Channel <= 14) { /*BG band */
5956#ifdef RT30xx
5957 /* RT3070 is a no LNA solution, it should have different control regarding to AGC gain control */
5958 /* Otherwise, it will have some throughput side effect when low RSSI */
5959
5960 if (IS_RT3070(pAd) || IS_RT3090(pAd) || IS_RT3572(pAd)
5961 || IS_RT3390(pAd)) {
5962 if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY) {
5963 R66 =
5964 0x1C + 2 * GET_LNA_GAIN(pAd) + 0x20;
5965 if (OrigR66Value != R66) {
5966 RTMP_BBP_IO_WRITE8_BY_REG_ID
5967 (pAd, BBP_R66, R66);
5968 }
5969 } else {
5970 R66 = 0x1C + 2 * GET_LNA_GAIN(pAd);
5971 if (OrigR66Value != R66) {
5972 RTMP_BBP_IO_WRITE8_BY_REG_ID
5973 (pAd, BBP_R66, R66);
5974 }
5975 }
5976 } else
5977#endif /* RT30xx // */
5978 {
5979 if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY) {
5980 R66 = (0x2E + GET_LNA_GAIN(pAd)) + 0x10;
5981 if (OrigR66Value != R66) {
5982 RTMP_BBP_IO_WRITE8_BY_REG_ID
5983 (pAd, BBP_R66, R66);
5984 }
5985 } else {
5986 R66 = 0x2E + GET_LNA_GAIN(pAd);
5987 if (OrigR66Value != R66) {
5988 RTMP_BBP_IO_WRITE8_BY_REG_ID
5989 (pAd, BBP_R66, R66);
5990 }
5991 }
5992 }
5993 } else { /*A band */
5994 if (pAd->CommonCfg.BBPCurrentBW == BW_20) {
5995 if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY) {
5996 R66 =
5997 0x32 + (GET_LNA_GAIN(pAd) * 5) / 3 +
5998 0x10;
5999 if (OrigR66Value != R66) {
6000 RTMP_BBP_IO_WRITE8_BY_REG_ID
6001 (pAd, BBP_R66, R66);
6002 }
6003 } else {
6004 R66 =
6005 0x32 + (GET_LNA_GAIN(pAd) * 5) / 3;
6006 if (OrigR66Value != R66) {
6007 RTMP_BBP_IO_WRITE8_BY_REG_ID
6008 (pAd, BBP_R66, R66);
6009 }
6010 }
6011 } else {
6012 if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY) {
6013 R66 =
6014 0x3A + (GET_LNA_GAIN(pAd) * 5) / 3 +
6015 0x10;
6016 if (OrigR66Value != R66) {
6017 RTMP_BBP_IO_WRITE8_BY_REG_ID
6018 (pAd, BBP_R66, R66);
6019 }
6020 } else {
6021 R66 =
6022 0x3A + (GET_LNA_GAIN(pAd) * 5) / 3;
6023 if (OrigR66Value != R66) {
6024 RTMP_BBP_IO_WRITE8_BY_REG_ID
6025 (pAd, BBP_R66, R66);
6026 }
6027 }
6028 }
6029 }
6030
6031 }
6032}
6033
6034void RTMPSetAGCInitValue(struct rt_rtmp_adapter *pAd, u8 BandWidth)
6035{
6036 u8 R66 = 0x30;
6037
6038 if (pAd->LatchRfRegs.Channel <= 14) { /* BG band */
6039#ifdef RT30xx
6040 /* Gary was verified Amazon AP and find that RT307x has BBP_R66 invalid default value */
6041
6042 if (IS_RT3070(pAd) || IS_RT3090(pAd) || IS_RT3572(pAd)
6043 || IS_RT3390(pAd)) {
6044 R66 = 0x1C + 2 * GET_LNA_GAIN(pAd);
6045 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
6046 } else
6047#endif /* RT30xx // */
6048 {
6049 R66 = 0x2E + GET_LNA_GAIN(pAd);
6050 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
6051 }
6052 } else { /*A band */
6053 {
6054 if (BandWidth == BW_20) {
6055 R66 =
6056 (u8)(0x32 +
6057 (GET_LNA_GAIN(pAd) * 5) / 3);
6058 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
6059 } else {
6060 R66 =
6061 (u8)(0x3A +
6062 (GET_LNA_GAIN(pAd) * 5) / 3);
6063 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
6064 }
6065 }
6066 }
6067
6068}
diff --git a/drivers/staging/rt2860/common/rt_channel.c b/drivers/staging/rt2860/common/rt_channel.c
deleted file mode 100644
index 53879898117..00000000000
--- a/drivers/staging/rt2860/common/rt_channel.c
+++ /dev/null
@@ -1,1705 +0,0 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26*/
27#include "../rt_config.h"
28
29struct rt_ch_freq_map CH_HZ_ID_MAP[] = {
30 {1, 2412}
31 ,
32 {2, 2417}
33 ,
34 {3, 2422}
35 ,
36 {4, 2427}
37 ,
38 {5, 2432}
39 ,
40 {6, 2437}
41 ,
42 {7, 2442}
43 ,
44 {8, 2447}
45 ,
46 {9, 2452}
47 ,
48 {10, 2457}
49 ,
50 {11, 2462}
51 ,
52 {12, 2467}
53 ,
54 {13, 2472}
55 ,
56 {14, 2484}
57 ,
58
59 /* UNII */
60 {36, 5180}
61 ,
62 {40, 5200}
63 ,
64 {44, 5220}
65 ,
66 {48, 5240}
67 ,
68 {52, 5260}
69 ,
70 {56, 5280}
71 ,
72 {60, 5300}
73 ,
74 {64, 5320}
75 ,
76 {149, 5745}
77 ,
78 {153, 5765}
79 ,
80 {157, 5785}
81 ,
82 {161, 5805}
83 ,
84 {165, 5825}
85 ,
86 {167, 5835}
87 ,
88 {169, 5845}
89 ,
90 {171, 5855}
91 ,
92 {173, 5865}
93 ,
94
95 /* HiperLAN2 */
96 {100, 5500}
97 ,
98 {104, 5520}
99 ,
100 {108, 5540}
101 ,
102 {112, 5560}
103 ,
104 {116, 5580}
105 ,
106 {120, 5600}
107 ,
108 {124, 5620}
109 ,
110 {128, 5640}
111 ,
112 {132, 5660}
113 ,
114 {136, 5680}
115 ,
116 {140, 5700}
117 ,
118
119 /* Japan MMAC */
120 {34, 5170}
121 ,
122 {38, 5190}
123 ,
124 {42, 5210}
125 ,
126 {46, 5230}
127 ,
128
129 /* Japan */
130 {184, 4920}
131 ,
132 {188, 4940}
133 ,
134 {192, 4960}
135 ,
136 {196, 4980}
137 ,
138
139 {208, 5040}
140 , /* Japan, means J08 */
141 {212, 5060}
142 , /* Japan, means J12 */
143 {216, 5080}
144 , /* Japan, means J16 */
145};
146
147int CH_HZ_ID_MAP_NUM = (sizeof(CH_HZ_ID_MAP) / sizeof(struct rt_ch_freq_map));
148
149struct rt_ch_region ChRegion[] = {
150 { /* Antigua and Berbuda */
151 "AG",
152 CE,
153 {
154 {1, 13, 20, BOTH, FALSE}
155 , /* 2.4 G, ch 1~13 */
156 {36, 4, 23, BOTH, FALSE}
157 , /* 5G, ch 36~48 */
158 {52, 4, 23, BOTH, FALSE}
159 , /* 5G, ch 52~64 */
160 {100, 11, 30, BOTH, FALSE}
161 , /* 5G, ch 100~140 */
162 {0}
163 , /* end */
164 }
165 }
166 ,
167
168 { /* Argentina */
169 "AR",
170 CE,
171 {
172 {1, 13, 20, BOTH, FALSE}
173 , /* 2.4 G, ch 1~13 */
174 {52, 4, 24, BOTH, FALSE}
175 , /* 5G, ch 52~64 */
176 {149, 4, 30, BOTH, FALSE}
177 , /* 5G, ch 149~161 */
178 {0}
179 , /* end */
180 }
181 }
182 ,
183
184 { /* Aruba */
185 "AW",
186 CE,
187 {
188 {1, 13, 20, BOTH, FALSE}
189 , /* 2.4 G, ch 1~13 */
190 {36, 4, 23, BOTH, FALSE}
191 , /* 5G, ch 36~48 */
192 {52, 4, 23, BOTH, FALSE}
193 , /* 5G, ch 52~64 */
194 {100, 11, 30, BOTH, FALSE}
195 , /* 5G, ch 100~140 */
196 {0}
197 , /* end */
198 }
199 }
200 ,
201
202 { /* Australia */
203 "AU",
204 CE,
205 {
206 {1, 13, 20, BOTH, FALSE}
207 , /* 2.4 G, ch 1~13 */
208 {36, 4, 23, BOTH, FALSE}
209 , /* 5G, ch 36~48 */
210 {52, 4, 24, BOTH, FALSE}
211 , /* 5G, ch 52~64 */
212 {149, 5, 30, BOTH, FALSE}
213 , /* 5G, ch 149~165 */
214 {0}
215 , /* end */
216 }
217 }
218 ,
219
220 { /* Austria */
221 "AT",
222 CE,
223 {
224 {1, 13, 20, BOTH, FALSE}
225 , /* 2.4 G, ch 1~13 */
226 {36, 4, 23, IDOR, TRUE}
227 , /* 5G, ch 36~48 */
228 {52, 4, 23, IDOR, TRUE}
229 , /* 5G, ch 52~64 */
230 {100, 11, 30, BOTH, TRUE}
231 , /* 5G, ch 100~140 */
232 {0}
233 , /* end */
234 }
235 }
236 ,
237
238 { /* Bahamas */
239 "BS",
240 CE,
241 {
242 {1, 13, 20, BOTH, FALSE}
243 , /* 2.4 G, ch 1~13 */
244 {36, 4, 23, BOTH, FALSE}
245 , /* 5G, ch 36~48 */
246 {52, 4, 24, BOTH, FALSE}
247 , /* 5G, ch 52~64 */
248 {149, 5, 30, BOTH, FALSE}
249 , /* 5G, ch 149~165 */
250 {0}
251 , /* end */
252 }
253 }
254 ,
255
256 { /* Barbados */
257 "BB",
258 CE,
259 {
260 {1, 13, 20, BOTH, FALSE}
261 , /* 2.4 G, ch 1~13 */
262 {36, 4, 23, BOTH, FALSE}
263 , /* 5G, ch 36~48 */
264 {52, 4, 24, BOTH, FALSE}
265 , /* 5G, ch 52~64 */
266 {100, 11, 30, BOTH, FALSE}
267 , /* 5G, ch 100~140 */
268 {0}
269 , /* end */
270 }
271 }
272 ,
273
274 { /* Bermuda */
275 "BM",
276 CE,
277 {
278 {1, 13, 20, BOTH, FALSE}
279 , /* 2.4 G, ch 1~13 */
280 {36, 4, 23, BOTH, FALSE}
281 , /* 5G, ch 36~48 */
282 {52, 4, 24, BOTH, FALSE}
283 , /* 5G, ch 52~64 */
284 {100, 11, 30, BOTH, FALSE}
285 , /* 5G, ch 100~140 */
286 {0}
287 , /* end */
288 }
289 }
290 ,
291
292 { /* Brazil */
293 "BR",
294 CE,
295 {
296 {1, 13, 20, BOTH, FALSE}
297 , /* 2.4 G, ch 1~13 */
298 {36, 4, 23, BOTH, FALSE}
299 , /* 5G, ch 36~48 */
300 {52, 4, 24, BOTH, FALSE}
301 , /* 5G, ch 52~64 */
302 {100, 11, 24, BOTH, FALSE}
303 , /* 5G, ch 100~140 */
304 {149, 5, 30, BOTH, FALSE}
305 , /* 5G, ch 100~140 */
306 {0}
307 , /* end */
308 }
309 }
310 ,
311
312 { /* Belgium */
313 "BE",
314 CE,
315 {
316 {1, 13, 20, BOTH, FALSE}
317 , /* 2.4 G, ch 1~13 */
318 {36, 4, 18, IDOR, FALSE}
319 , /* 5G, ch 36~48 */
320 {52, 4, 18, IDOR, FALSE}
321 , /* 5G, ch 52~64 */
322 {0}
323 , /* end */
324 }
325 }
326 ,
327
328 { /* Bulgaria */
329 "BG",
330 CE,
331 {
332 {1, 13, 20, BOTH, FALSE}
333 , /* 2.4 G, ch 1~13 */
334 {36, 4, 23, IDOR, FALSE}
335 , /* 5G, ch 36~48 */
336 {52, 4, 23, IDOR, TRUE}
337 , /* 5G, ch 52~64 */
338 {100, 11, 30, ODOR, TRUE}
339 , /* 5G, ch 100~140 */
340 {0}
341 , /* end */
342 }
343 }
344 ,
345
346 { /* Canada */
347 "CA",
348 CE,
349 {
350 {1, 13, 20, BOTH, FALSE}
351 , /* 2.4 G, ch 1~13 */
352 {36, 4, 23, BOTH, FALSE}
353 , /* 5G, ch 36~48 */
354 {52, 4, 23, BOTH, FALSE}
355 , /* 5G, ch 52~64 */
356 {149, 5, 30, BOTH, FALSE}
357 , /* 5G, ch 149~165 */
358 {0}
359 , /* end */
360 }
361 }
362 ,
363
364 { /* Cayman IsLands */
365 "KY",
366 CE,
367 {
368 {1, 13, 20, BOTH, FALSE}
369 , /* 2.4 G, ch 1~13 */
370 {36, 4, 23, BOTH, FALSE}
371 , /* 5G, ch 36~48 */
372 {52, 4, 24, BOTH, FALSE}
373 , /* 5G, ch 52~64 */
374 {100, 11, 30, BOTH, FALSE}
375 , /* 5G, ch 100~140 */
376 {0}
377 , /* end */
378 }
379 }
380 ,
381
382 { /* Chile */
383 "CL",
384 CE,
385 {
386 {1, 13, 20, BOTH, FALSE}
387 , /* 2.4 G, ch 1~13 */
388 {36, 4, 20, BOTH, FALSE}
389 , /* 5G, ch 36~48 */
390 {52, 4, 20, BOTH, FALSE}
391 , /* 5G, ch 52~64 */
392 {149, 5, 20, BOTH, FALSE}
393 , /* 5G, ch 149~165 */
394 {0}
395 , /* end */
396 }
397 }
398 ,
399
400 { /* China */
401 "CN",
402 CE,
403 {
404 {1, 13, 20, BOTH, FALSE}
405 , /* 2.4 G, ch 1~13 */
406 {149, 4, 27, BOTH, FALSE}
407 , /* 5G, ch 149~161 */
408 {0}
409 , /* end */
410 }
411 }
412 ,
413
414 { /* Colombia */
415 "CO",
416 CE,
417 {
418 {1, 13, 20, BOTH, FALSE}
419 , /* 2.4 G, ch 1~13 */
420 {36, 4, 17, BOTH, FALSE}
421 , /* 5G, ch 36~48 */
422 {52, 4, 24, BOTH, FALSE}
423 , /* 5G, ch 52~64 */
424 {100, 11, 30, BOTH, FALSE}
425 , /* 5G, ch 100~140 */
426 {149, 5, 30, BOTH, FALSE}
427 , /* 5G, ch 149~165 */
428 {0}
429 , /* end */
430 }
431 }
432 ,
433
434 { /* Costa Rica */
435 "CR",
436 CE,
437 {
438 {1, 13, 20, BOTH, FALSE}
439 , /* 2.4 G, ch 1~13 */
440 {36, 4, 17, BOTH, FALSE}
441 , /* 5G, ch 36~48 */
442 {52, 4, 24, BOTH, FALSE}
443 , /* 5G, ch 52~64 */
444 {149, 4, 30, BOTH, FALSE}
445 , /* 5G, ch 149~161 */
446 {0}
447 , /* end */
448 }
449 }
450 ,
451
452 { /* Cyprus */
453 "CY",
454 CE,
455 {
456 {1, 13, 20, BOTH, FALSE}
457 , /* 2.4 G, ch 1~13 */
458 {36, 4, 23, IDOR, FALSE}
459 , /* 5G, ch 36~48 */
460 {52, 4, 24, IDOR, TRUE}
461 , /* 5G, ch 52~64 */
462 {100, 11, 30, BOTH, TRUE}
463 , /* 5G, ch 100~140 */
464 {0}
465 , /* end */
466 }
467 }
468 ,
469
470 { /* Czech_Republic */
471 "CZ",
472 CE,
473 {
474 {1, 13, 20, BOTH, FALSE}
475 , /* 2.4 G, ch 1~13 */
476 {36, 4, 23, IDOR, FALSE}
477 , /* 5G, ch 36~48 */
478 {52, 4, 23, IDOR, TRUE}
479 , /* 5G, ch 52~64 */
480 {0}
481 , /* end */
482 }
483 }
484 ,
485
486 { /* Denmark */
487 "DK",
488 CE,
489 {
490 {1, 13, 20, BOTH, FALSE}
491 , /* 2.4 G, ch 1~13 */
492 {36, 4, 23, IDOR, FALSE}
493 , /* 5G, ch 36~48 */
494 {52, 4, 23, IDOR, TRUE}
495 , /* 5G, ch 52~64 */
496 {100, 11, 30, BOTH, TRUE}
497 , /* 5G, ch 100~140 */
498 {0}
499 , /* end */
500 }
501 }
502 ,
503
504 { /* Dominican Republic */
505 "DO",
506 CE,
507 {
508 {1, 0, 20, BOTH, FALSE}
509 , /* 2.4 G, ch 0 */
510 {149, 4, 20, BOTH, FALSE}
511 , /* 5G, ch 149~161 */
512 {0}
513 , /* end */
514 }
515 }
516 ,
517
518 { /* Equador */
519 "EC",
520 CE,
521 {
522 {1, 13, 20, BOTH, FALSE}
523 , /* 2.4 G, ch 1~13 */
524 {100, 11, 27, BOTH, FALSE}
525 , /* 5G, ch 100~140 */
526 {0}
527 , /* end */
528 }
529 }
530 ,
531
532 { /* El Salvador */
533 "SV",
534 CE,
535 {
536 {1, 13, 20, BOTH, FALSE}
537 , /* 2.4 G, ch 1~13 */
538 {36, 4, 23, IDOR, FALSE}
539 , /* 5G, ch 36~48 */
540 {52, 4, 30, BOTH, TRUE}
541 , /* 5G, ch 52~64 */
542 {149, 4, 36, BOTH, TRUE}
543 , /* 5G, ch 149~165 */
544 {0}
545 , /* end */
546 }
547 }
548 ,
549
550 { /* Finland */
551 "FI",
552 CE,
553 {
554 {1, 13, 20, BOTH, FALSE}
555 , /* 2.4 G, ch 1~13 */
556 {36, 4, 23, IDOR, FALSE}
557 , /* 5G, ch 36~48 */
558 {52, 4, 23, IDOR, TRUE}
559 , /* 5G, ch 52~64 */
560 {100, 11, 30, BOTH, TRUE}
561 , /* 5G, ch 100~140 */
562 {0}
563 , /* end */
564 }
565 }
566 ,
567
568 { /* France */
569 "FR",
570 CE,
571 {
572 {1, 13, 20, BOTH, FALSE}
573 , /* 2.4 G, ch 1~13 */
574 {36, 4, 23, IDOR, FALSE}
575 , /* 5G, ch 36~48 */
576 {52, 4, 23, IDOR, TRUE}
577 , /* 5G, ch 52~64 */
578 {0}
579 , /* end */
580 }
581 }
582 ,
583
584 { /* Germany */
585 "DE",
586 CE,
587 {
588 {1, 13, 20, BOTH, FALSE}
589 , /* 2.4 G, ch 1~13 */
590 {36, 4, 23, IDOR, FALSE}
591 , /* 5G, ch 36~48 */
592 {52, 4, 23, IDOR, TRUE}
593 , /* 5G, ch 52~64 */
594 {100, 11, 30, BOTH, TRUE}
595 , /* 5G, ch 100~140 */
596 {0}
597 , /* end */
598 }
599 }
600 ,
601
602 { /* Greece */
603 "GR",
604 CE,
605 {
606 {1, 13, 20, BOTH, FALSE}
607 , /* 2.4 G, ch 1~13 */
608 {36, 4, 23, IDOR, FALSE}
609 , /* 5G, ch 36~48 */
610 {52, 4, 23, IDOR, TRUE}
611 , /* 5G, ch 52~64 */
612 {100, 11, 30, ODOR, TRUE}
613 , /* 5G, ch 100~140 */
614 {0}
615 , /* end */
616 }
617 }
618 ,
619
620 { /* Guam */
621 "GU",
622 CE,
623 {
624 {1, 11, 20, BOTH, FALSE}
625 , /* 2.4 G, ch 1~11 */
626 {36, 4, 17, BOTH, FALSE}
627 , /* 5G, ch 36~48 */
628 {52, 4, 24, BOTH, FALSE}
629 , /* 5G, ch 52~64 */
630 {100, 11, 30, BOTH, FALSE}
631 , /* 5G, ch 100~140 */
632 {149, 5, 30, BOTH, FALSE}
633 , /* 5G, ch 149~165 */
634 {0}
635 , /* end */
636 }
637 }
638 ,
639
640 { /* Guatemala */
641 "GT",
642 CE,
643 {
644 {1, 13, 20, BOTH, FALSE}
645 , /* 2.4 G, ch 1~13 */
646 {36, 4, 17, BOTH, FALSE}
647 , /* 5G, ch 36~48 */
648 {52, 4, 24, BOTH, FALSE}
649 , /* 5G, ch 52~64 */
650 {149, 4, 30, BOTH, FALSE}
651 , /* 5G, ch 149~161 */
652 {0}
653 , /* end */
654 }
655 }
656 ,
657
658 { /* Haiti */
659 "HT",
660 CE,
661 {
662 {1, 13, 20, BOTH, FALSE}
663 , /* 2.4 G, ch 1~13 */
664 {36, 4, 17, BOTH, FALSE}
665 , /* 5G, ch 36~48 */
666 {52, 4, 24, BOTH, FALSE}
667 , /* 5G, ch 52~64 */
668 {149, 4, 30, BOTH, FALSE}
669 , /* 5G, ch 149~161 */
670 {0}
671 , /* end */
672 }
673 }
674 ,
675
676 { /* Honduras */
677 "HN",
678 CE,
679 {
680 {1, 13, 20, BOTH, FALSE}
681 , /* 2.4 G, ch 1~13 */
682 {149, 4, 27, BOTH, FALSE}
683 , /* 5G, ch 149~161 */
684 {0}
685 , /* end */
686 }
687 }
688 ,
689
690 { /* Hong Kong */
691 "HK",
692 CE,
693 {
694 {1, 13, 20, BOTH, FALSE}
695 , /* 2.4 G, ch 1~13 */
696 {36, 4, 23, IDOR, FALSE}
697 , /* 5G, ch 36~48 */
698 {52, 4, 23, IDOR, FALSE}
699 , /* 5G, ch 52~64 */
700 {149, 4, 30, BOTH, FALSE}
701 , /* 5G, ch 149~161 */
702 {0}
703 , /* end */
704 }
705 }
706 ,
707
708 { /* Hungary */
709 "HU",
710 CE,
711 {
712 {1, 13, 20, BOTH, FALSE}
713 , /* 2.4 G, ch 1~13 */
714 {36, 4, 23, IDOR, FALSE}
715 , /* 5G, ch 36~48 */
716 {52, 4, 23, IDOR, TRUE}
717 , /* 5G, ch 52~64 */
718 {0}
719 , /* end */
720 }
721 }
722 ,
723
724 { /* Iceland */
725 "IS",
726 CE,
727 {
728 {1, 13, 20, BOTH, FALSE}
729 , /* 2.4 G, ch 1~13 */
730 {36, 4, 23, IDOR, FALSE}
731 , /* 5G, ch 36~48 */
732 {52, 4, 23, IDOR, TRUE}
733 , /* 5G, ch 52~64 */
734 {100, 11, 30, BOTH, TRUE}
735 , /* 5G, ch 100~140 */
736 {0}
737 , /* end */
738 }
739 }
740 ,
741
742 { /* India */
743 "IN",
744 CE,
745 {
746 {1, 13, 20, BOTH, FALSE}
747 , /* 2.4 G, ch 1~13 */
748 {149, 4, 24, IDOR, FALSE}
749 , /* 5G, ch 149~161 */
750 {0}
751 , /* end */
752 }
753 }
754 ,
755
756 { /* Indonesia */
757 "ID",
758 CE,
759 {
760 {1, 13, 20, BOTH, FALSE}
761 , /* 2.4 G, ch 1~13 */
762 {149, 4, 27, BOTH, FALSE}
763 , /* 5G, ch 149~161 */
764 {0}
765 , /* end */
766 }
767 }
768 ,
769
770 { /* Ireland */
771 "IE",
772 CE,
773 {
774 {1, 13, 20, BOTH, FALSE}
775 , /* 2.4 G, ch 1~13 */
776 {36, 4, 23, IDOR, FALSE}
777 , /* 5G, ch 36~48 */
778 {52, 4, 23, IDOR, TRUE}
779 , /* 5G, ch 52~64 */
780 {100, 11, 30, ODOR, TRUE}
781 , /* 5G, ch 100~140 */
782 {0}
783 , /* end */
784 }
785 }
786 ,
787
788 { /* Israel */
789 "IL",
790 CE,
791 {
792 {1, 3, 20, IDOR, FALSE}
793 , /* 2.4 G, ch 1~3 */
794 {4, 6, 20, BOTH, FALSE}
795 , /* 2.4 G, ch 4~9 */
796 {10, 4, 20, IDOR, FALSE}
797 , /* 2.4 G, ch 10~13 */
798 {0}
799 , /* end */
800 }
801 }
802 ,
803
804 { /* Italy */
805 "IT",
806 CE,
807 {
808 {1, 13, 20, BOTH, FALSE}
809 , /* 2.4 G, ch 1~13 */
810 {36, 4, 23, IDOR, FALSE}
811 , /* 5G, ch 36~48 */
812 {52, 4, 23, IDOR, TRUE}
813 , /* 5G, ch 52~64 */
814 {100, 11, 30, ODOR, TRUE}
815 , /* 5G, ch 100~140 */
816 {0}
817 , /* end */
818 }
819 }
820 ,
821
822 { /* Japan */
823 "JP",
824 JAP,
825 {
826 {1, 14, 20, BOTH, FALSE}
827 , /* 2.4 G, ch 1~14 */
828 {36, 4, 23, IDOR, FALSE}
829 , /* 5G, ch 36~48 */
830 {0}
831 , /* end */
832 }
833 }
834 ,
835
836 { /* Jordan */
837 "JO",
838 CE,
839 {
840 {1, 13, 20, IDOR, FALSE}
841 , /* 2.4 G, ch 1~13 */
842 {36, 4, 23, IDOR, FALSE}
843 , /* 5G, ch 36~48 */
844 {149, 4, 23, IDOR, FALSE}
845 , /* 5G, ch 149~161 */
846 {0}
847 , /* end */
848 }
849 }
850 ,
851
852 { /* Latvia */
853 "LV",
854 CE,
855 {
856 {1, 13, 20, BOTH, FALSE}
857 , /* 2.4 G, ch 1~13 */
858 {36, 4, 23, IDOR, FALSE}
859 , /* 5G, ch 36~48 */
860 {52, 4, 23, IDOR, TRUE}
861 , /* 5G, ch 52~64 */
862 {100, 11, 30, BOTH, TRUE}
863 , /* 5G, ch 100~140 */
864 {0}
865 , /* end */
866 }
867 }
868 ,
869
870 { /* Liechtenstein */
871 "LI",
872 CE,
873 {
874 {1, 13, 20, BOTH, FALSE}
875 , /* 2.4 G, ch 1~13 */
876 {52, 4, 23, IDOR, TRUE}
877 , /* 5G, ch 52~64 */
878 {100, 11, 30, BOTH, TRUE}
879 , /* 5G, ch 100~140 */
880 {0}
881 , /* end */
882 }
883 }
884 ,
885
886 { /* Lithuania */
887 "LT",
888 CE,
889 {
890 {1, 13, 20, BOTH, FALSE}
891 , /* 2.4 G, ch 1~13 */
892 {36, 4, 23, IDOR, FALSE}
893 , /* 5G, ch 36~48 */
894 {52, 4, 23, IDOR, TRUE}
895 , /* 5G, ch 52~64 */
896 {100, 11, 30, BOTH, TRUE}
897 , /* 5G, ch 100~140 */
898 {0}
899 , /* end */
900 }
901 }
902 ,
903
904 { /* Luxemburg */
905 "LU",
906 CE,
907 {
908 {1, 13, 20, BOTH, FALSE}
909 , /* 2.4 G, ch 1~13 */
910 {36, 4, 23, IDOR, FALSE}
911 , /* 5G, ch 36~48 */
912 {52, 4, 23, IDOR, TRUE}
913 , /* 5G, ch 52~64 */
914 {100, 11, 30, BOTH, TRUE}
915 , /* 5G, ch 100~140 */
916 {0}
917 , /* end */
918 }
919 }
920 ,
921
922 { /* Malaysia */
923 "MY",
924 CE,
925 {
926 {36, 4, 23, BOTH, FALSE}
927 , /* 5G, ch 36~48 */
928 {52, 4, 23, BOTH, FALSE}
929 , /* 5G, ch 52~64 */
930 {149, 5, 20, BOTH, FALSE}
931 , /* 5G, ch 149~165 */
932 {0}
933 , /* end */
934 }
935 }
936 ,
937
938 { /* Malta */
939 "MT",
940 CE,
941 {
942 {1, 13, 20, BOTH, FALSE}
943 , /* 2.4 G, ch 1~13 */
944 {36, 4, 23, IDOR, FALSE}
945 , /* 5G, ch 36~48 */
946 {52, 4, 23, IDOR, TRUE}
947 , /* 5G, ch 52~64 */
948 {100, 11, 30, BOTH, TRUE}
949 , /* 5G, ch 100~140 */
950 {0}
951 , /* end */
952 }
953 }
954 ,
955
956 { /* Marocco */
957 "MA",
958 CE,
959 {
960 {1, 13, 20, BOTH, FALSE}
961 , /* 2.4 G, ch 1~13 */
962 {36, 4, 24, IDOR, FALSE}
963 , /* 5G, ch 36~48 */
964 {0}
965 , /* end */
966 }
967 }
968 ,
969
970 { /* Mexico */
971 "MX",
972 CE,
973 {
974 {1, 13, 20, BOTH, FALSE}
975 , /* 2.4 G, ch 1~13 */
976 {36, 4, 23, BOTH, FALSE}
977 , /* 5G, ch 36~48 */
978 {52, 4, 24, BOTH, FALSE}
979 , /* 5G, ch 52~64 */
980 {149, 5, 30, IDOR, FALSE}
981 , /* 5G, ch 149~165 */
982 {0}
983 , /* end */
984 }
985 }
986 ,
987
988 { /* Netherlands */
989 "NL",
990 CE,
991 {
992 {1, 13, 20, BOTH, FALSE}
993 , /* 2.4 G, ch 1~13 */
994 {36, 4, 23, IDOR, FALSE}
995 , /* 5G, ch 36~48 */
996 {52, 4, 24, IDOR, TRUE}
997 , /* 5G, ch 52~64 */
998 {100, 11, 30, BOTH, TRUE}
999 , /* 5G, ch 100~140 */
1000 {0}
1001 , /* end */
1002 }
1003 }
1004 ,
1005
1006 { /* New Zealand */
1007 "NZ",
1008 CE,
1009 {
1010 {1, 13, 20, BOTH, FALSE}
1011 , /* 2.4 G, ch 1~13 */
1012 {36, 4, 24, BOTH, FALSE}
1013 , /* 5G, ch 36~48 */
1014 {52, 4, 24, BOTH, FALSE}
1015 , /* 5G, ch 52~64 */
1016 {149, 4, 30, BOTH, FALSE}
1017 , /* 5G, ch 149~161 */
1018 {0}
1019 , /* end */
1020 }
1021 }
1022 ,
1023
1024 { /* Norway */
1025 "NO",
1026 CE,
1027 {
1028 {1, 13, 20, BOTH, FALSE}
1029 , /* 2.4 G, ch 1~13 */
1030 {36, 4, 24, IDOR, FALSE}
1031 , /* 5G, ch 36~48 */
1032 {52, 4, 24, IDOR, TRUE}
1033 , /* 5G, ch 52~64 */
1034 {100, 11, 30, BOTH, TRUE}
1035 , /* 5G, ch 149~161 */
1036 {0}
1037 , /* end */
1038 }
1039 }
1040 ,
1041
1042 { /* Peru */
1043 "PE",
1044 CE,
1045 {
1046 {1, 13, 20, BOTH, FALSE}
1047 , /* 2.4 G, ch 1~13 */
1048 {149, 4, 27, BOTH, FALSE}
1049 , /* 5G, ch 149~161 */
1050 {0}
1051 , /* end */
1052 }
1053 }
1054 ,
1055
1056 { /* Portugal */
1057 "PT",
1058 CE,
1059 {
1060 {1, 13, 20, BOTH, FALSE}
1061 , /* 2.4 G, ch 1~13 */
1062 {36, 4, 23, IDOR, FALSE}
1063 , /* 5G, ch 36~48 */
1064 {52, 4, 23, IDOR, TRUE}
1065 , /* 5G, ch 52~64 */
1066 {100, 11, 30, BOTH, TRUE}
1067 , /* 5G, ch 100~140 */
1068 {0}
1069 , /* end */
1070 }
1071 }
1072 ,
1073
1074 { /* Poland */
1075 "PL",
1076 CE,
1077 {
1078 {1, 13, 20, BOTH, FALSE}
1079 , /* 2.4 G, ch 1~13 */
1080 {36, 4, 23, IDOR, FALSE}
1081 , /* 5G, ch 36~48 */
1082 {52, 4, 23, IDOR, TRUE}
1083 , /* 5G, ch 52~64 */
1084 {100, 11, 30, BOTH, TRUE}
1085 , /* 5G, ch 100~140 */
1086 {0}
1087 , /* end */
1088 }
1089 }
1090 ,
1091
1092 { /* Romania */
1093 "RO",
1094 CE,
1095 {
1096 {1, 13, 20, BOTH, FALSE}
1097 , /* 2.4 G, ch 1~13 */
1098 {36, 4, 23, IDOR, FALSE}
1099 , /* 5G, ch 36~48 */
1100 {52, 4, 23, IDOR, TRUE}
1101 , /* 5G, ch 52~64 */
1102 {100, 11, 30, BOTH, TRUE}
1103 , /* 5G, ch 100~140 */
1104 {0}
1105 , /* end */
1106 }
1107 }
1108 ,
1109
1110 { /* Russia */
1111 "RU",
1112 CE,
1113 {
1114 {1, 13, 20, BOTH, FALSE}
1115 , /* 2.4 G, ch 1~13 */
1116 {149, 4, 20, IDOR, FALSE}
1117 , /* 5G, ch 149~161 */
1118 {0}
1119 , /* end */
1120 }
1121 }
1122 ,
1123
1124 { /* Saudi Arabia */
1125 "SA",
1126 CE,
1127 {
1128 {1, 13, 20, BOTH, FALSE}
1129 , /* 2.4 G, ch 1~13 */
1130 {36, 4, 23, BOTH, FALSE}
1131 , /* 5G, ch 36~48 */
1132 {52, 4, 23, BOTH, FALSE}
1133 , /* 5G, ch 52~64 */
1134 {149, 4, 23, BOTH, FALSE}
1135 , /* 5G, ch 149~161 */
1136 {0}
1137 , /* end */
1138 }
1139 }
1140 ,
1141
1142 { /* Serbia_and_Montenegro */
1143 "CS",
1144 CE,
1145 {
1146 {1, 13, 20, BOTH, FALSE}
1147 , /* 2.4 G, ch 1~13 */
1148 {0}
1149 , /* end */
1150 }
1151 }
1152 ,
1153
1154 { /* Singapore */
1155 "SG",
1156 CE,
1157 {
1158 {1, 13, 20, BOTH, FALSE}
1159 , /* 2.4 G, ch 1~13 */
1160 {36, 4, 23, BOTH, FALSE}
1161 , /* 5G, ch 36~48 */
1162 {52, 4, 23, BOTH, FALSE}
1163 , /* 5G, ch 52~64 */
1164 {149, 4, 20, BOTH, FALSE}
1165 , /* 5G, ch 149~161 */
1166 {0}
1167 , /* end */
1168 }
1169 }
1170 ,
1171
1172 { /* Slovakia */
1173 "SK",
1174 CE,
1175 {
1176 {1, 13, 20, BOTH, FALSE}
1177 , /* 2.4 G, ch 1~13 */
1178 {36, 4, 23, IDOR, FALSE}
1179 , /* 5G, ch 36~48 */
1180 {52, 4, 23, IDOR, TRUE}
1181 , /* 5G, ch 52~64 */
1182 {100, 11, 30, BOTH, TRUE}
1183 , /* 5G, ch 100~140 */
1184 {0}
1185 , /* end */
1186 }
1187 }
1188 ,
1189
1190 { /* Slovenia */
1191 "SI",
1192 CE,
1193 {
1194 {1, 13, 20, BOTH, FALSE}
1195 , /* 2.4 G, ch 1~13 */
1196 {36, 4, 23, IDOR, FALSE}
1197 , /* 5G, ch 36~48 */
1198 {52, 4, 23, IDOR, TRUE}
1199 , /* 5G, ch 52~64 */
1200 {0}
1201 , /* end */
1202 }
1203 }
1204 ,
1205
1206 { /* South Africa */
1207 "ZA",
1208 CE,
1209 {
1210 {1, 13, 20, BOTH, FALSE}
1211 , /* 2.4 G, ch 1~13 */
1212 {36, 4, 23, BOTH, FALSE}
1213 , /* 5G, ch 36~48 */
1214 {52, 4, 23, IDOR, FALSE}
1215 , /* 5G, ch 52~64 */
1216 {100, 11, 30, BOTH, TRUE}
1217 , /* 5G, ch 100~140 */
1218 {149, 4, 30, BOTH, FALSE}
1219 , /* 5G, ch 149~161 */
1220 {0}
1221 , /* end */
1222 }
1223 }
1224 ,
1225
1226 { /* South Korea */
1227 "KR",
1228 CE,
1229 {
1230 {1, 13, 20, BOTH, FALSE}
1231 , /* 2.4 G, ch 1~13 */
1232 {36, 4, 20, BOTH, FALSE}
1233 , /* 5G, ch 36~48 */
1234 {52, 4, 20, BOTH, FALSE}
1235 , /* 5G, ch 52~64 */
1236 {100, 8, 20, BOTH, FALSE}
1237 , /* 5G, ch 100~128 */
1238 {149, 4, 20, BOTH, FALSE}
1239 , /* 5G, ch 149~161 */
1240 {0}
1241 , /* end */
1242 }
1243 }
1244 ,
1245
1246 { /* Spain */
1247 "ES",
1248 CE,
1249 {
1250 {1, 13, 20, BOTH, FALSE}
1251 , /* 2.4 G, ch 1~13 */
1252 {36, 4, 17, IDOR, FALSE}
1253 , /* 5G, ch 36~48 */
1254 {52, 4, 23, IDOR, TRUE}
1255 , /* 5G, ch 52~64 */
1256 {100, 11, 30, BOTH, TRUE}
1257 , /* 5G, ch 100~140 */
1258 {0}
1259 , /* end */
1260 }
1261 }
1262 ,
1263
1264 { /* Sweden */
1265 "SE",
1266 CE,
1267 {
1268 {1, 13, 20, BOTH, FALSE}
1269 , /* 2.4 G, ch 1~13 */
1270 {36, 4, 23, IDOR, FALSE}
1271 , /* 5G, ch 36~48 */
1272 {52, 4, 23, IDOR, TRUE}
1273 , /* 5G, ch 52~64 */
1274 {100, 11, 30, BOTH, TRUE}
1275 , /* 5G, ch 100~140 */
1276 {0}
1277 , /* end */
1278 }
1279 }
1280 ,
1281
1282 { /* Switzerland */
1283 "CH",
1284 CE,
1285 {
1286 {1, 13, 20, BOTH, FALSE}
1287 , /* 2.4 G, ch 1~13 */
1288 {36, 4, 23, IDOR, TRUE}
1289 , /* 5G, ch 36~48 */
1290 {52, 4, 23, IDOR, TRUE}
1291 , /* 5G, ch 52~64 */
1292 {0}
1293 , /* end */
1294 }
1295 }
1296 ,
1297
1298 { /* Taiwan */
1299 "TW",
1300 CE,
1301 {
1302 {1, 11, 30, BOTH, FALSE}
1303 , /* 2.4 G, ch 1~11 */
1304 {52, 4, 23, IDOR, FALSE}
1305 , /* 5G, ch 52~64 */
1306 {0}
1307 , /* end */
1308 }
1309 }
1310 ,
1311
1312 { /* Turkey */
1313 "TR",
1314 CE,
1315 {
1316 {1, 13, 20, BOTH, FALSE}
1317 , /* 2.4 G, ch 1~11 */
1318 {36, 4, 23, BOTH, FALSE}
1319 , /* 5G, ch 36~48 */
1320 {52, 4, 23, BOTH, FALSE}
1321 , /* 5G, ch 52~64 */
1322 {0}
1323 , /* end */
1324 }
1325 }
1326 ,
1327
1328 { /* UK */
1329 "GB",
1330 CE,
1331 {
1332 {1, 13, 20, BOTH, FALSE}
1333 , /* 2.4 G, ch 1~11 */
1334 {36, 4, 23, IDOR, FALSE}
1335 , /* 5G, ch 52~64 */
1336 {52, 4, 23, IDOR, TRUE}
1337 , /* 5G, ch 52~64 */
1338 {100, 11, 30, BOTH, TRUE}
1339 , /* 5G, ch 100~140 */
1340 {0}
1341 , /* end */
1342 }
1343 }
1344 ,
1345
1346 { /* Ukraine */
1347 "UA",
1348 CE,
1349 {
1350 {1, 13, 20, BOTH, FALSE}
1351 , /* 2.4 G, ch 1~11 */
1352 {0}
1353 , /* end */
1354 }
1355 }
1356 ,
1357
1358 { /* United_Arab_Emirates */
1359 "AE",
1360 CE,
1361 {
1362 {1, 13, 20, BOTH, FALSE}
1363 , /* 2.4 G, ch 1~11 */
1364 {0}
1365 , /* end */
1366 }
1367 }
1368 ,
1369
1370 { /* United_States */
1371 "US",
1372 CE,
1373 {
1374 {1, 11, 30, BOTH, FALSE}
1375 , /* 2.4 G, ch 1~11 */
1376 {36, 4, 17, IDOR, FALSE}
1377 , /* 5G, ch 52~64 */
1378 {52, 4, 24, BOTH, TRUE}
1379 , /* 5G, ch 52~64 */
1380 {100, 11, 30, BOTH, TRUE}
1381 , /* 5G, ch 100~140 */
1382 {149, 5, 30, BOTH, FALSE}
1383 , /* 5G, ch 149~165 */
1384 {0}
1385 , /* end */
1386 }
1387 }
1388 ,
1389
1390 { /* Venezuela */
1391 "VE",
1392 CE,
1393 {
1394 {1, 13, 20, BOTH, FALSE}
1395 , /* 2.4 G, ch 1~11 */
1396 {149, 4, 27, BOTH, FALSE}
1397 , /* 5G, ch 149~161 */
1398 {0}
1399 , /* end */
1400 }
1401 }
1402 ,
1403
1404 { /* Default */
1405 "",
1406 CE,
1407 {
1408 {1, 11, 20, BOTH, FALSE}
1409 , /* 2.4 G, ch 1~11 */
1410 {36, 4, 20, BOTH, FALSE}
1411 , /* 5G, ch 52~64 */
1412 {52, 4, 20, BOTH, FALSE}
1413 , /* 5G, ch 52~64 */
1414 {100, 11, 20, BOTH, FALSE}
1415 , /* 5G, ch 100~140 */
1416 {149, 5, 20, BOTH, FALSE}
1417 , /* 5G, ch 149~165 */
1418 {0}
1419 , /* end */
1420 }
1421 }
1422 ,
1423};
1424
1425static struct rt_ch_region *GetChRegion(u8 *CntryCode)
1426{
1427 int loop = 0;
1428 struct rt_ch_region *pChRegion = NULL;
1429
1430 while (strcmp((char *)ChRegion[loop].CountReg, "") != 0) {
1431 if (strncmp
1432 ((char *)ChRegion[loop].CountReg, (char *)CntryCode,
1433 2) == 0) {
1434 pChRegion = &ChRegion[loop];
1435 break;
1436 }
1437 loop++;
1438 }
1439
1440 if (pChRegion == NULL)
1441 pChRegion = &ChRegion[loop];
1442 return pChRegion;
1443}
1444
1445static void ChBandCheck(u8 PhyMode, u8 *pChType)
1446{
1447 switch (PhyMode) {
1448 case PHY_11A:
1449 case PHY_11AN_MIXED:
1450 *pChType = BAND_5G;
1451 break;
1452 case PHY_11ABG_MIXED:
1453 case PHY_11AGN_MIXED:
1454 case PHY_11ABGN_MIXED:
1455 *pChType = BAND_BOTH;
1456 break;
1457
1458 default:
1459 *pChType = BAND_24G;
1460 break;
1461 }
1462}
1463
1464static u8 FillChList(struct rt_rtmp_adapter *pAd,
1465 struct rt_ch_desp *pChDesp,
1466 u8 Offset, u8 increment)
1467{
1468 int i, j, l;
1469 u8 channel;
1470
1471 j = Offset;
1472 for (i = 0; i < pChDesp->NumOfCh; i++) {
1473 channel = pChDesp->FirstChannel + i * increment;
1474 for (l = 0; l < MAX_NUM_OF_CHANNELS; l++) {
1475 if (channel == pAd->TxPower[l].Channel) {
1476 pAd->ChannelList[j].Power =
1477 pAd->TxPower[l].Power;
1478 pAd->ChannelList[j].Power2 =
1479 pAd->TxPower[l].Power2;
1480 break;
1481 }
1482 }
1483 if (l == MAX_NUM_OF_CHANNELS)
1484 continue;
1485
1486 pAd->ChannelList[j].Channel =
1487 pChDesp->FirstChannel + i * increment;
1488 pAd->ChannelList[j].MaxTxPwr = pChDesp->MaxTxPwr;
1489 pAd->ChannelList[j].DfsReq = pChDesp->DfsReq;
1490 j++;
1491 }
1492 pAd->ChannelListNum = j;
1493
1494 return j;
1495}
1496
1497static inline void CreateChList(struct rt_rtmp_adapter *pAd,
1498 struct rt_ch_region *pChRegion, u8 Geography)
1499{
1500 int i;
1501 u8 offset = 0;
1502 struct rt_ch_desp *pChDesp;
1503 u8 ChType;
1504 u8 increment;
1505
1506 if (pChRegion == NULL)
1507 return;
1508
1509 ChBandCheck(pAd->CommonCfg.PhyMode, &ChType);
1510
1511 for (i = 0; i < 10; i++) {
1512 pChDesp = &pChRegion->ChDesp[i];
1513 if (pChDesp->FirstChannel == 0)
1514 break;
1515
1516 if (ChType == BAND_5G) {
1517 if (pChDesp->FirstChannel <= 14)
1518 continue;
1519 } else if (ChType == BAND_24G) {
1520 if (pChDesp->FirstChannel > 14)
1521 continue;
1522 }
1523
1524 if ((pChDesp->Geography == BOTH)
1525 || (pChDesp->Geography == Geography)) {
1526 if (pChDesp->FirstChannel > 14)
1527 increment = 4;
1528 else
1529 increment = 1;
1530 offset = FillChList(pAd, pChDesp, offset, increment);
1531 }
1532 }
1533}
1534
1535void BuildChannelListEx(struct rt_rtmp_adapter *pAd)
1536{
1537 struct rt_ch_region *pChReg;
1538
1539 pChReg = GetChRegion(pAd->CommonCfg.CountryCode);
1540 CreateChList(pAd, pChReg, pAd->CommonCfg.Geography);
1541}
1542
1543void BuildBeaconChList(struct rt_rtmp_adapter *pAd,
1544 u8 *pBuf, unsigned long *pBufLen)
1545{
1546 int i;
1547 unsigned long TmpLen;
1548 struct rt_ch_region *pChRegion;
1549 struct rt_ch_desp *pChDesp;
1550 u8 ChType;
1551
1552 pChRegion = GetChRegion(pAd->CommonCfg.CountryCode);
1553
1554 if (pChRegion == NULL)
1555 return;
1556
1557 ChBandCheck(pAd->CommonCfg.PhyMode, &ChType);
1558 *pBufLen = 0;
1559
1560 for (i = 0; i < 10; i++) {
1561 pChDesp = &pChRegion->ChDesp[i];
1562 if (pChDesp->FirstChannel == 0)
1563 break;
1564
1565 if (ChType == BAND_5G) {
1566 if (pChDesp->FirstChannel <= 14)
1567 continue;
1568 } else if (ChType == BAND_24G) {
1569 if (pChDesp->FirstChannel > 14)
1570 continue;
1571 }
1572
1573 if ((pChDesp->Geography == BOTH)
1574 || (pChDesp->Geography == pAd->CommonCfg.Geography)) {
1575 MakeOutgoingFrame(pBuf + *pBufLen, &TmpLen,
1576 1, &pChDesp->FirstChannel,
1577 1, &pChDesp->NumOfCh,
1578 1, &pChDesp->MaxTxPwr, END_OF_ARGS);
1579 *pBufLen += TmpLen;
1580 }
1581 }
1582}
1583
1584static BOOLEAN IsValidChannel(struct rt_rtmp_adapter *pAd, u8 channel)
1585{
1586 int i;
1587
1588 for (i = 0; i < pAd->ChannelListNum; i++) {
1589 if (pAd->ChannelList[i].Channel == channel)
1590 break;
1591 }
1592
1593 if (i == pAd->ChannelListNum)
1594 return FALSE;
1595 else
1596 return TRUE;
1597}
1598
1599static u8 GetExtCh(u8 Channel, u8 Direction)
1600{
1601 char ExtCh;
1602
1603 if (Direction == EXTCHA_ABOVE)
1604 ExtCh = Channel + 4;
1605 else
1606 ExtCh = (Channel - 4) > 0 ? (Channel - 4) : 0;
1607
1608 return ExtCh;
1609}
1610
1611void N_ChannelCheck(struct rt_rtmp_adapter *pAd)
1612{
1613 /*u8 ChannelNum = pAd->ChannelListNum; */
1614 u8 Channel = pAd->CommonCfg.Channel;
1615
1616 if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
1617 && (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40)) {
1618 if (Channel > 14) {
1619 if ((Channel == 36) || (Channel == 44)
1620 || (Channel == 52) || (Channel == 60)
1621 || (Channel == 100) || (Channel == 108)
1622 || (Channel == 116) || (Channel == 124)
1623 || (Channel == 132) || (Channel == 149)
1624 || (Channel == 157)) {
1625 pAd->CommonCfg.RegTransmitSetting.field.EXTCHA =
1626 EXTCHA_ABOVE;
1627 } else if ((Channel == 40) || (Channel == 48)
1628 || (Channel == 56) || (Channel == 64)
1629 || (Channel == 104) || (Channel == 112)
1630 || (Channel == 120) || (Channel == 128)
1631 || (Channel == 136) || (Channel == 153)
1632 || (Channel == 161)) {
1633 pAd->CommonCfg.RegTransmitSetting.field.EXTCHA =
1634 EXTCHA_BELOW;
1635 } else {
1636 pAd->CommonCfg.RegTransmitSetting.field.BW =
1637 BW_20;
1638 }
1639 } else {
1640 do {
1641 u8 ExtCh;
1642 u8 Dir =
1643 pAd->CommonCfg.RegTransmitSetting.field.
1644 EXTCHA;
1645 ExtCh = GetExtCh(Channel, Dir);
1646 if (IsValidChannel(pAd, ExtCh))
1647 break;
1648
1649 Dir =
1650 (Dir ==
1651 EXTCHA_ABOVE) ? EXTCHA_BELOW :
1652 EXTCHA_ABOVE;
1653 ExtCh = GetExtCh(Channel, Dir);
1654 if (IsValidChannel(pAd, ExtCh)) {
1655 pAd->CommonCfg.RegTransmitSetting.field.
1656 EXTCHA = Dir;
1657 break;
1658 }
1659 pAd->CommonCfg.RegTransmitSetting.field.BW =
1660 BW_20;
1661 } while (FALSE);
1662
1663 if (Channel == 14) {
1664 pAd->CommonCfg.RegTransmitSetting.field.BW =
1665 BW_20;
1666 /*pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_NONE; // We didn't set the ExtCh as NONE due to it'll set in RTMPSetHT() */
1667 }
1668 }
1669 }
1670
1671}
1672
1673void N_SetCenCh(struct rt_rtmp_adapter *pAd)
1674{
1675 if (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40) {
1676 if (pAd->CommonCfg.RegTransmitSetting.field.EXTCHA ==
1677 EXTCHA_ABOVE) {
1678 pAd->CommonCfg.CentralChannel =
1679 pAd->CommonCfg.Channel + 2;
1680 } else {
1681 if (pAd->CommonCfg.Channel == 14)
1682 pAd->CommonCfg.CentralChannel =
1683 pAd->CommonCfg.Channel - 1;
1684 else
1685 pAd->CommonCfg.CentralChannel =
1686 pAd->CommonCfg.Channel - 2;
1687 }
1688 } else {
1689 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
1690 }
1691}
1692
1693u8 GetCuntryMaxTxPwr(struct rt_rtmp_adapter *pAd, u8 channel)
1694{
1695 int i;
1696 for (i = 0; i < pAd->ChannelListNum; i++) {
1697 if (pAd->ChannelList[i].Channel == channel)
1698 break;
1699 }
1700
1701 if (i == pAd->ChannelListNum)
1702 return 0xff;
1703 else
1704 return pAd->ChannelList[i].MaxTxPwr;
1705}
diff --git a/drivers/staging/rt2860/common/rt_rf.c b/drivers/staging/rt2860/common/rt_rf.c
deleted file mode 100644
index 2895447ffc4..00000000000
--- a/drivers/staging/rt2860/common/rt_rf.c
+++ /dev/null
@@ -1,187 +0,0 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 rt_rf.c
29
30 Abstract:
31 Ralink Wireless driver RF related functions
32
33 Revision History:
34 Who When What
35 -------- ---------- ----------------------------------------------
36*/
37
38#include "../rt_config.h"
39
40#ifdef RTMP_RF_RW_SUPPORT
41/*
42 ========================================================================
43
44 Routine Description: Write RT30xx RF register through MAC
45
46 Arguments:
47
48 Return Value:
49
50 IRQL =
51
52 Note:
53
54 ========================================================================
55*/
56int RT30xxWriteRFRegister(struct rt_rtmp_adapter *pAd,
57 u8 regID, u8 value)
58{
59 RF_CSR_CFG_STRUC rfcsr;
60 u32 i = 0;
61
62 do {
63 RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word);
64
65 if (!rfcsr.field.RF_CSR_KICK)
66 break;
67 i++;
68 }
69 while ((i < RETRY_LIMIT)
70 && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
71
72 if ((i == RETRY_LIMIT)
73 || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) {
74 DBGPRINT_RAW(RT_DEBUG_ERROR,
75 ("Retry count exhausted or device removed!\n"));
76 return STATUS_UNSUCCESSFUL;
77 }
78
79 rfcsr.field.RF_CSR_WR = 1;
80 rfcsr.field.RF_CSR_KICK = 1;
81 rfcsr.field.TESTCSR_RFACC_REGNUM = regID;
82 rfcsr.field.RF_CSR_DATA = value;
83
84 RTMP_IO_WRITE32(pAd, RF_CSR_CFG, rfcsr.word);
85
86 return NDIS_STATUS_SUCCESS;
87}
88
89/*
90 ========================================================================
91
92 Routine Description: Read RT30xx RF register through MAC
93
94 Arguments:
95
96 Return Value:
97
98 IRQL =
99
100 Note:
101
102 ========================================================================
103*/
104int RT30xxReadRFRegister(struct rt_rtmp_adapter *pAd,
105 u8 regID, u8 *pValue)
106{
107 RF_CSR_CFG_STRUC rfcsr;
108 u32 i = 0, k = 0;
109
110 for (i = 0; i < MAX_BUSY_COUNT; i++) {
111 RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word);
112
113 if (rfcsr.field.RF_CSR_KICK == BUSY) {
114 continue;
115 }
116 rfcsr.word = 0;
117 rfcsr.field.RF_CSR_WR = 0;
118 rfcsr.field.RF_CSR_KICK = 1;
119 rfcsr.field.TESTCSR_RFACC_REGNUM = regID;
120 RTMP_IO_WRITE32(pAd, RF_CSR_CFG, rfcsr.word);
121 for (k = 0; k < MAX_BUSY_COUNT; k++) {
122 RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word);
123
124 if (rfcsr.field.RF_CSR_KICK == IDLE)
125 break;
126 }
127 if ((rfcsr.field.RF_CSR_KICK == IDLE) &&
128 (rfcsr.field.TESTCSR_RFACC_REGNUM == regID)) {
129 *pValue = (u8)rfcsr.field.RF_CSR_DATA;
130 break;
131 }
132 }
133 if (rfcsr.field.RF_CSR_KICK == BUSY) {
134 DBGPRINT_ERR("RF read R%d=0x%x fail, i[%d], k[%d]\n", regID, rfcsr.word, i, k);
135 return STATUS_UNSUCCESSFUL;
136 }
137
138 return STATUS_SUCCESS;
139}
140
141void NICInitRFRegisters(struct rt_rtmp_adapter *pAd)
142{
143 if (pAd->chipOps.AsicRfInit)
144 pAd->chipOps.AsicRfInit(pAd);
145}
146
147void RtmpChipOpsRFHook(struct rt_rtmp_adapter *pAd)
148{
149 struct rt_rtmp_chip_op *pChipOps = &pAd->chipOps;
150
151 pChipOps->pRFRegTable = NULL;
152 pChipOps->AsicRfInit = NULL;
153 pChipOps->AsicRfTurnOn = NULL;
154 pChipOps->AsicRfTurnOff = NULL;
155 pChipOps->AsicReverseRfFromSleepMode = NULL;
156 pChipOps->AsicHaltAction = NULL;
157 /* We depends on RfICType and MACVersion to assign the corresponding operation callbacks. */
158
159#ifdef RT30xx
160 if (IS_RT30xx(pAd)) {
161 pChipOps->pRFRegTable = RT30xx_RFRegTable;
162 pChipOps->AsicHaltAction = RT30xxHaltAction;
163#ifdef RT3070
164 if ((IS_RT3070(pAd) || IS_RT3071(pAd))
165 && (pAd->infType == RTMP_DEV_INF_USB)) {
166 pChipOps->AsicRfInit = NICInitRT3070RFRegisters;
167 if (IS_RT3071(pAd)) {
168 pChipOps->AsicRfTurnOff =
169 RT30xxLoadRFSleepModeSetup;
170 pChipOps->AsicReverseRfFromSleepMode =
171 RT30xxReverseRFSleepModeSetup;
172 }
173 }
174#endif /* RT3070 // */
175#ifdef RT3090
176 if (IS_RT3090(pAd) && (pAd->infType == RTMP_DEV_INF_PCI)) {
177 pChipOps->AsicRfTurnOff = RT30xxLoadRFSleepModeSetup;
178 pChipOps->AsicRfInit = NICInitRT3090RFRegisters;
179 pChipOps->AsicReverseRfFromSleepMode =
180 RT30xxReverseRFSleepModeSetup;
181 }
182#endif /* RT3090 // */
183 }
184#endif /* RT30xx // */
185}
186
187#endif /* RTMP_RF_RW_SUPPORT // */
diff --git a/drivers/staging/rt2860/common/rtmp_init.c b/drivers/staging/rt2860/common/rtmp_init.c
deleted file mode 100644
index 5fa193eac0d..00000000000
--- a/drivers/staging/rt2860/common/rtmp_init.c
+++ /dev/null
@@ -1,3536 +0,0 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 rtmp_init.c
29
30 Abstract:
31 Miniport generic portion header file
32
33 Revision History:
34 Who When What
35 -------- ---------- ----------------------------------------------
36*/
37#include "../rt_config.h"
38
39u8 BIT8[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
40char *CipherName[] =
41 { "none", "wep64", "wep128", "TKIP", "AES", "CKIP64", "CKIP128" };
42
43/* */
44/* BBP register initialization set */
45/* */
46struct rt_reg_pair BBPRegTable[] = {
47 {BBP_R65, 0x2C}, /* fix rssi issue */
48 {BBP_R66, 0x38}, /* Also set this default value to pAd->BbpTuning.R66CurrentValue at initial */
49 {BBP_R69, 0x12},
50 {BBP_R70, 0xa}, /* BBP_R70 will change to 0x8 in ApStartUp and LinkUp for rt2860C, otherwise value is 0xa */
51 {BBP_R73, 0x10},
52 {BBP_R81, 0x37},
53 {BBP_R82, 0x62},
54 {BBP_R83, 0x6A},
55 {BBP_R84, 0x99}, /* 0x19 is for rt2860E and after. This is for extension channel overlapping IOT. 0x99 is for rt2860D and before */
56 {BBP_R86, 0x00}, /* middle range issue, Rory @2008-01-28 */
57 {BBP_R91, 0x04}, /* middle range issue, Rory @2008-01-28 */
58 {BBP_R92, 0x00}, /* middle range issue, Rory @2008-01-28 */
59 {BBP_R103, 0x00}, /* near range high-power issue, requested from Gary @2008-0528 */
60 {BBP_R105, 0x05}, /* 0x05 is for rt2860E to turn on FEQ control. It is safe for rt2860D and before, because Bit 7:2 are reserved in rt2860D and before. */
61 {BBP_R106, 0x35}, /* for ShortGI throughput */
62};
63
64#define NUM_BBP_REG_PARMS (sizeof(BBPRegTable) / sizeof(struct rt_reg_pair))
65
66/* */
67/* ASIC register initialization sets */
68/* */
69
70struct rt_rtmp_reg_pair MACRegTable[] = {
71#if defined(HW_BEACON_OFFSET) && (HW_BEACON_OFFSET == 0x200)
72 {BCN_OFFSET0, 0xf8f0e8e0}, /* 0x3800(e0), 0x3A00(e8), 0x3C00(f0), 0x3E00(f8), 512B for each beacon */
73 {BCN_OFFSET1, 0x6f77d0c8}, /* 0x3200(c8), 0x3400(d0), 0x1DC0(77), 0x1BC0(6f), 512B for each beacon */
74#elif defined(HW_BEACON_OFFSET) && (HW_BEACON_OFFSET == 0x100)
75 {BCN_OFFSET0, 0xece8e4e0}, /* 0x3800, 0x3A00, 0x3C00, 0x3E00, 512B for each beacon */
76 {BCN_OFFSET1, 0xfcf8f4f0}, /* 0x3800, 0x3A00, 0x3C00, 0x3E00, 512B for each beacon */
77#else
78#error You must re-calculate new value for BCN_OFFSET0 & BCN_OFFSET1 in MACRegTable[]!
79#endif /* HW_BEACON_OFFSET // */
80
81 {LEGACY_BASIC_RATE, 0x0000013f}, /* Basic rate set bitmap */
82 {HT_BASIC_RATE, 0x00008003}, /* Basic HT rate set , 20M, MCS=3, MM. Format is the same as in TXWI. */
83 {MAC_SYS_CTRL, 0x00}, /* 0x1004, , default Disable RX */
84 {RX_FILTR_CFG, 0x17f97}, /*0x1400 , RX filter control, */
85 {BKOFF_SLOT_CFG, 0x209}, /* default set short slot time, CC_DELAY_TIME should be 2 */
86 /*{TX_SW_CFG0, 0x40a06}, // Gary,2006-08-23 */
87 {TX_SW_CFG0, 0x0}, /* Gary,2008-05-21 for CWC test */
88 {TX_SW_CFG1, 0x80606}, /* Gary,2006-08-23 */
89 {TX_LINK_CFG, 0x1020}, /* Gary,2006-08-23 */
90 /*{TX_TIMEOUT_CFG, 0x00182090}, // CCK has some problem. So increase timieout value. 2006-10-09// MArvek RT */
91 {TX_TIMEOUT_CFG, 0x000a2090}, /* CCK has some problem. So increase timieout value. 2006-10-09// MArvek RT , Modify for 2860E ,2007-08-01 */
92 {MAX_LEN_CFG, MAX_AGGREGATION_SIZE | 0x00001000}, /* 0x3018, MAX frame length. Max PSDU = 16kbytes. */
93 {LED_CFG, 0x7f031e46}, /* Gary, 2006-08-23 */
94
95 {PBF_MAX_PCNT, 0x1F3FBF9F}, /*0x1F3f7f9f}, //Jan, 2006/04/20 */
96
97 {TX_RTY_CFG, 0x47d01f0f}, /* Jan, 2006/11/16, Set TxWI->ACK =0 in Probe Rsp Modify for 2860E ,2007-08-03 */
98
99 {AUTO_RSP_CFG, 0x00000013}, /* Initial Auto_Responder, because QA will turn off Auto-Responder */
100 {CCK_PROT_CFG, 0x05740003 /*0x01740003 */ }, /* Initial Auto_Responder, because QA will turn off Auto-Responder. And RTS threshold is enabled. */
101 {OFDM_PROT_CFG, 0x05740003 /*0x01740003 */ }, /* Initial Auto_Responder, because QA will turn off Auto-Responder. And RTS threshold is enabled. */
102#ifdef RTMP_MAC_USB
103 {PBF_CFG, 0xf40006}, /* Only enable Queue 2 */
104 {MM40_PROT_CFG, 0x3F44084}, /* Initial Auto_Responder, because QA will turn off Auto-Responder */
105 {WPDMA_GLO_CFG, 0x00000030},
106#endif /* RTMP_MAC_USB // */
107 {GF20_PROT_CFG, 0x01744004}, /* set 19:18 --> Short NAV for MIMO PS */
108 {GF40_PROT_CFG, 0x03F44084},
109 {MM20_PROT_CFG, 0x01744004},
110#ifdef RTMP_MAC_PCI
111 {MM40_PROT_CFG, 0x03F54084},
112#endif /* RTMP_MAC_PCI // */
113 {TXOP_CTRL_CFG, 0x0000583f, /*0x0000243f *//*0x000024bf */ }, /*Extension channel backoff. */
114 {TX_RTS_CFG, 0x00092b20},
115 {EXP_ACK_TIME, 0x002400ca}, /* default value */
116
117 {TXOP_HLDR_ET, 0x00000002},
118
119 /* Jerry comments 2008/01/16: we use SIFS = 10us in CCK defaultly, but it seems that 10us
120 is too small for INTEL 2200bg card, so in MBSS mode, the delta time between beacon0
121 and beacon1 is SIFS (10us), so if INTEL 2200bg card connects to BSS0, the ping
122 will always lost. So we change the SIFS of CCK from 10us to 16us. */
123 {XIFS_TIME_CFG, 0x33a41010},
124 {PWR_PIN_CFG, 0x00000003}, /* patch for 2880-E */
125};
126
127struct rt_rtmp_reg_pair STAMACRegTable[] = {
128 {WMM_AIFSN_CFG, 0x00002273},
129 {WMM_CWMIN_CFG, 0x00002344},
130 {WMM_CWMAX_CFG, 0x000034aa},
131};
132
133#define NUM_MAC_REG_PARMS (sizeof(MACRegTable) / sizeof(struct rt_rtmp_reg_pair))
134#define NUM_STA_MAC_REG_PARMS (sizeof(STAMACRegTable) / sizeof(struct rt_rtmp_reg_pair))
135
136/*
137 ========================================================================
138
139 Routine Description:
140 Allocate struct rt_rtmp_adapter data block and do some initialization
141
142 Arguments:
143 Adapter Pointer to our adapter
144
145 Return Value:
146 NDIS_STATUS_SUCCESS
147 NDIS_STATUS_FAILURE
148
149 IRQL = PASSIVE_LEVEL
150
151 Note:
152
153 ========================================================================
154*/
155int RTMPAllocAdapterBlock(void *handle,
156 struct rt_rtmp_adapter * * ppAdapter)
157{
158 struct rt_rtmp_adapter *pAd;
159 int Status;
160 int index;
161 u8 *pBeaconBuf = NULL;
162
163 DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocAdapterBlock\n"));
164
165 *ppAdapter = NULL;
166
167 do {
168 /* Allocate struct rt_rtmp_adapter memory block */
169 pBeaconBuf = kmalloc(MAX_BEACON_SIZE, MEM_ALLOC_FLAG);
170 if (pBeaconBuf == NULL) {
171 Status = NDIS_STATUS_FAILURE;
172 DBGPRINT_ERR("Failed to allocate memory - BeaconBuf!\n");
173 break;
174 }
175 NdisZeroMemory(pBeaconBuf, MAX_BEACON_SIZE);
176
177 Status = AdapterBlockAllocateMemory(handle, (void **) & pAd);
178 if (Status != NDIS_STATUS_SUCCESS) {
179 DBGPRINT_ERR("Failed to allocate memory - ADAPTER\n");
180 break;
181 }
182 pAd->BeaconBuf = pBeaconBuf;
183 DBGPRINT(RT_DEBUG_OFF,
184 ("=== pAd = %p, size = %d ===\n", pAd,
185 (u32)sizeof(struct rt_rtmp_adapter)));
186
187 /* Init spin locks */
188 NdisAllocateSpinLock(&pAd->MgmtRingLock);
189#ifdef RTMP_MAC_PCI
190 NdisAllocateSpinLock(&pAd->RxRingLock);
191#ifdef RT3090
192 NdisAllocateSpinLock(&pAd->McuCmdLock);
193#endif /* RT3090 // */
194#endif /* RTMP_MAC_PCI // */
195
196 for (index = 0; index < NUM_OF_TX_RING; index++) {
197 NdisAllocateSpinLock(&pAd->TxSwQueueLock[index]);
198 NdisAllocateSpinLock(&pAd->DeQueueLock[index]);
199 pAd->DeQueueRunning[index] = FALSE;
200 }
201
202 NdisAllocateSpinLock(&pAd->irq_lock);
203
204 } while (FALSE);
205
206 if ((Status != NDIS_STATUS_SUCCESS) && (pBeaconBuf))
207 kfree(pBeaconBuf);
208
209 *ppAdapter = pAd;
210
211 DBGPRINT_S(Status, ("<-- RTMPAllocAdapterBlock, Status=%x\n", Status));
212 return Status;
213}
214
215/*
216 ========================================================================
217
218 Routine Description:
219 Read initial Tx power per MCS and BW from EEPROM
220
221 Arguments:
222 Adapter Pointer to our adapter
223
224 Return Value:
225 None
226
227 IRQL = PASSIVE_LEVEL
228
229 Note:
230
231 ========================================================================
232*/
233void RTMPReadTxPwrPerRate(struct rt_rtmp_adapter *pAd)
234{
235 unsigned long data, Adata, Gdata;
236 u16 i, value, value2;
237 int Apwrdelta, Gpwrdelta;
238 u8 t1, t2, t3, t4;
239 BOOLEAN bApwrdeltaMinus = TRUE, bGpwrdeltaMinus = TRUE;
240
241 /* */
242 /* Get power delta for 20MHz and 40MHz. */
243 /* */
244 DBGPRINT(RT_DEBUG_TRACE, ("Txpower per Rate\n"));
245 RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_DELTA, value2);
246 Apwrdelta = 0;
247 Gpwrdelta = 0;
248
249 if ((value2 & 0xff) != 0xff) {
250 if ((value2 & 0x80))
251 Gpwrdelta = (value2 & 0xf);
252
253 if ((value2 & 0x40))
254 bGpwrdeltaMinus = FALSE;
255 else
256 bGpwrdeltaMinus = TRUE;
257 }
258 if ((value2 & 0xff00) != 0xff00) {
259 if ((value2 & 0x8000))
260 Apwrdelta = ((value2 & 0xf00) >> 8);
261
262 if ((value2 & 0x4000))
263 bApwrdeltaMinus = FALSE;
264 else
265 bApwrdeltaMinus = TRUE;
266 }
267 DBGPRINT(RT_DEBUG_TRACE,
268 ("Gpwrdelta = %x, Apwrdelta = %x .\n", Gpwrdelta, Apwrdelta));
269
270 /* */
271 /* Get Txpower per MCS for 20MHz in 2.4G. */
272 /* */
273 for (i = 0; i < 5; i++) {
274 RT28xx_EEPROM_READ16(pAd,
275 EEPROM_TXPOWER_BYRATE_20MHZ_2_4G + i * 4,
276 value);
277 data = value;
278 if (bApwrdeltaMinus == FALSE) {
279 t1 = (value & 0xf) + (Apwrdelta);
280 if (t1 > 0xf)
281 t1 = 0xf;
282 t2 = ((value & 0xf0) >> 4) + (Apwrdelta);
283 if (t2 > 0xf)
284 t2 = 0xf;
285 t3 = ((value & 0xf00) >> 8) + (Apwrdelta);
286 if (t3 > 0xf)
287 t3 = 0xf;
288 t4 = ((value & 0xf000) >> 12) + (Apwrdelta);
289 if (t4 > 0xf)
290 t4 = 0xf;
291 } else {
292 if ((value & 0xf) > Apwrdelta)
293 t1 = (value & 0xf) - (Apwrdelta);
294 else
295 t1 = 0;
296 if (((value & 0xf0) >> 4) > Apwrdelta)
297 t2 = ((value & 0xf0) >> 4) - (Apwrdelta);
298 else
299 t2 = 0;
300 if (((value & 0xf00) >> 8) > Apwrdelta)
301 t3 = ((value & 0xf00) >> 8) - (Apwrdelta);
302 else
303 t3 = 0;
304 if (((value & 0xf000) >> 12) > Apwrdelta)
305 t4 = ((value & 0xf000) >> 12) - (Apwrdelta);
306 else
307 t4 = 0;
308 }
309 Adata = t1 + (t2 << 4) + (t3 << 8) + (t4 << 12);
310 if (bGpwrdeltaMinus == FALSE) {
311 t1 = (value & 0xf) + (Gpwrdelta);
312 if (t1 > 0xf)
313 t1 = 0xf;
314 t2 = ((value & 0xf0) >> 4) + (Gpwrdelta);
315 if (t2 > 0xf)
316 t2 = 0xf;
317 t3 = ((value & 0xf00) >> 8) + (Gpwrdelta);
318 if (t3 > 0xf)
319 t3 = 0xf;
320 t4 = ((value & 0xf000) >> 12) + (Gpwrdelta);
321 if (t4 > 0xf)
322 t4 = 0xf;
323 } else {
324 if ((value & 0xf) > Gpwrdelta)
325 t1 = (value & 0xf) - (Gpwrdelta);
326 else
327 t1 = 0;
328 if (((value & 0xf0) >> 4) > Gpwrdelta)
329 t2 = ((value & 0xf0) >> 4) - (Gpwrdelta);
330 else
331 t2 = 0;
332 if (((value & 0xf00) >> 8) > Gpwrdelta)
333 t3 = ((value & 0xf00) >> 8) - (Gpwrdelta);
334 else
335 t3 = 0;
336 if (((value & 0xf000) >> 12) > Gpwrdelta)
337 t4 = ((value & 0xf000) >> 12) - (Gpwrdelta);
338 else
339 t4 = 0;
340 }
341 Gdata = t1 + (t2 << 4) + (t3 << 8) + (t4 << 12);
342
343 RT28xx_EEPROM_READ16(pAd,
344 EEPROM_TXPOWER_BYRATE_20MHZ_2_4G + i * 4 +
345 2, value);
346 if (bApwrdeltaMinus == FALSE) {
347 t1 = (value & 0xf) + (Apwrdelta);
348 if (t1 > 0xf)
349 t1 = 0xf;
350 t2 = ((value & 0xf0) >> 4) + (Apwrdelta);
351 if (t2 > 0xf)
352 t2 = 0xf;
353 t3 = ((value & 0xf00) >> 8) + (Apwrdelta);
354 if (t3 > 0xf)
355 t3 = 0xf;
356 t4 = ((value & 0xf000) >> 12) + (Apwrdelta);
357 if (t4 > 0xf)
358 t4 = 0xf;
359 } else {
360 if ((value & 0xf) > Apwrdelta)
361 t1 = (value & 0xf) - (Apwrdelta);
362 else
363 t1 = 0;
364 if (((value & 0xf0) >> 4) > Apwrdelta)
365 t2 = ((value & 0xf0) >> 4) - (Apwrdelta);
366 else
367 t2 = 0;
368 if (((value & 0xf00) >> 8) > Apwrdelta)
369 t3 = ((value & 0xf00) >> 8) - (Apwrdelta);
370 else
371 t3 = 0;
372 if (((value & 0xf000) >> 12) > Apwrdelta)
373 t4 = ((value & 0xf000) >> 12) - (Apwrdelta);
374 else
375 t4 = 0;
376 }
377 Adata |= ((t1 << 16) + (t2 << 20) + (t3 << 24) + (t4 << 28));
378 if (bGpwrdeltaMinus == FALSE) {
379 t1 = (value & 0xf) + (Gpwrdelta);
380 if (t1 > 0xf)
381 t1 = 0xf;
382 t2 = ((value & 0xf0) >> 4) + (Gpwrdelta);
383 if (t2 > 0xf)
384 t2 = 0xf;
385 t3 = ((value & 0xf00) >> 8) + (Gpwrdelta);
386 if (t3 > 0xf)
387 t3 = 0xf;
388 t4 = ((value & 0xf000) >> 12) + (Gpwrdelta);
389 if (t4 > 0xf)
390 t4 = 0xf;
391 } else {
392 if ((value & 0xf) > Gpwrdelta)
393 t1 = (value & 0xf) - (Gpwrdelta);
394 else
395 t1 = 0;
396 if (((value & 0xf0) >> 4) > Gpwrdelta)
397 t2 = ((value & 0xf0) >> 4) - (Gpwrdelta);
398 else
399 t2 = 0;
400 if (((value & 0xf00) >> 8) > Gpwrdelta)
401 t3 = ((value & 0xf00) >> 8) - (Gpwrdelta);
402 else
403 t3 = 0;
404 if (((value & 0xf000) >> 12) > Gpwrdelta)
405 t4 = ((value & 0xf000) >> 12) - (Gpwrdelta);
406 else
407 t4 = 0;
408 }
409 Gdata |= ((t1 << 16) + (t2 << 20) + (t3 << 24) + (t4 << 28));
410 data |= (value << 16);
411
412 /* For 20M/40M Power Delta issue */
413 pAd->Tx20MPwrCfgABand[i] = data;
414 pAd->Tx20MPwrCfgGBand[i] = data;
415 pAd->Tx40MPwrCfgABand[i] = Adata;
416 pAd->Tx40MPwrCfgGBand[i] = Gdata;
417
418 if (data != 0xffffffff)
419 RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i * 4, data);
420 DBGPRINT_RAW(RT_DEBUG_TRACE,
421 ("20MHz BW, 2.4G band-%lx, Adata = %lx, Gdata = %lx \n",
422 data, Adata, Gdata));
423 }
424}
425
426/*
427 ========================================================================
428
429 Routine Description:
430 Read initial channel power parameters from EEPROM
431
432 Arguments:
433 Adapter Pointer to our adapter
434
435 Return Value:
436 None
437
438 IRQL = PASSIVE_LEVEL
439
440 Note:
441
442 ========================================================================
443*/
444void RTMPReadChannelPwr(struct rt_rtmp_adapter *pAd)
445{
446 u8 i, choffset;
447 EEPROM_TX_PWR_STRUC Power;
448 EEPROM_TX_PWR_STRUC Power2;
449
450 /* Read Tx power value for all channels */
451 /* Value from 1 - 0x7f. Default value is 24. */
452 /* Power value : 2.4G 0x00 (0) ~ 0x1F (31) */
453 /* : 5.5G 0xF9 (-7) ~ 0x0F (15) */
454
455 /* 0. 11b/g, ch1 - ch 14 */
456 for (i = 0; i < 7; i++) {
457 RT28xx_EEPROM_READ16(pAd, EEPROM_G_TX_PWR_OFFSET + i * 2,
458 Power.word);
459 RT28xx_EEPROM_READ16(pAd, EEPROM_G_TX2_PWR_OFFSET + i * 2,
460 Power2.word);
461 pAd->TxPower[i * 2].Channel = i * 2 + 1;
462 pAd->TxPower[i * 2 + 1].Channel = i * 2 + 2;
463
464 if ((Power.field.Byte0 > 31) || (Power.field.Byte0 < 0))
465 pAd->TxPower[i * 2].Power = DEFAULT_RF_TX_POWER;
466 else
467 pAd->TxPower[i * 2].Power = Power.field.Byte0;
468
469 if ((Power.field.Byte1 > 31) || (Power.field.Byte1 < 0))
470 pAd->TxPower[i * 2 + 1].Power = DEFAULT_RF_TX_POWER;
471 else
472 pAd->TxPower[i * 2 + 1].Power = Power.field.Byte1;
473
474 if ((Power2.field.Byte0 > 31) || (Power2.field.Byte0 < 0))
475 pAd->TxPower[i * 2].Power2 = DEFAULT_RF_TX_POWER;
476 else
477 pAd->TxPower[i * 2].Power2 = Power2.field.Byte0;
478
479 if ((Power2.field.Byte1 > 31) || (Power2.field.Byte1 < 0))
480 pAd->TxPower[i * 2 + 1].Power2 = DEFAULT_RF_TX_POWER;
481 else
482 pAd->TxPower[i * 2 + 1].Power2 = Power2.field.Byte1;
483 }
484
485 /* 1. U-NII lower/middle band: 36, 38, 40; 44, 46, 48; 52, 54, 56; 60, 62, 64 (including central frequency in BW 40MHz) */
486 /* 1.1 Fill up channel */
487 choffset = 14;
488 for (i = 0; i < 4; i++) {
489 pAd->TxPower[3 * i + choffset + 0].Channel = 36 + i * 8 + 0;
490 pAd->TxPower[3 * i + choffset + 0].Power = DEFAULT_RF_TX_POWER;
491 pAd->TxPower[3 * i + choffset + 0].Power2 = DEFAULT_RF_TX_POWER;
492
493 pAd->TxPower[3 * i + choffset + 1].Channel = 36 + i * 8 + 2;
494 pAd->TxPower[3 * i + choffset + 1].Power = DEFAULT_RF_TX_POWER;
495 pAd->TxPower[3 * i + choffset + 1].Power2 = DEFAULT_RF_TX_POWER;
496
497 pAd->TxPower[3 * i + choffset + 2].Channel = 36 + i * 8 + 4;
498 pAd->TxPower[3 * i + choffset + 2].Power = DEFAULT_RF_TX_POWER;
499 pAd->TxPower[3 * i + choffset + 2].Power2 = DEFAULT_RF_TX_POWER;
500 }
501
502 /* 1.2 Fill up power */
503 for (i = 0; i < 6; i++) {
504 RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX_PWR_OFFSET + i * 2,
505 Power.word);
506 RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX2_PWR_OFFSET + i * 2,
507 Power2.word);
508
509 if ((Power.field.Byte0 < 16) && (Power.field.Byte0 >= -7))
510 pAd->TxPower[i * 2 + choffset + 0].Power =
511 Power.field.Byte0;
512
513 if ((Power.field.Byte1 < 16) && (Power.field.Byte1 >= -7))
514 pAd->TxPower[i * 2 + choffset + 1].Power =
515 Power.field.Byte1;
516
517 if ((Power2.field.Byte0 < 16) && (Power2.field.Byte0 >= -7))
518 pAd->TxPower[i * 2 + choffset + 0].Power2 =
519 Power2.field.Byte0;
520
521 if ((Power2.field.Byte1 < 16) && (Power2.field.Byte1 >= -7))
522 pAd->TxPower[i * 2 + choffset + 1].Power2 =
523 Power2.field.Byte1;
524 }
525
526 /* 2. HipperLAN 2 100, 102 ,104; 108, 110, 112; 116, 118, 120; 124, 126, 128; 132, 134, 136; 140 (including central frequency in BW 40MHz) */
527 /* 2.1 Fill up channel */
528 choffset = 14 + 12;
529 for (i = 0; i < 5; i++) {
530 pAd->TxPower[3 * i + choffset + 0].Channel = 100 + i * 8 + 0;
531 pAd->TxPower[3 * i + choffset + 0].Power = DEFAULT_RF_TX_POWER;
532 pAd->TxPower[3 * i + choffset + 0].Power2 = DEFAULT_RF_TX_POWER;
533
534 pAd->TxPower[3 * i + choffset + 1].Channel = 100 + i * 8 + 2;
535 pAd->TxPower[3 * i + choffset + 1].Power = DEFAULT_RF_TX_POWER;
536 pAd->TxPower[3 * i + choffset + 1].Power2 = DEFAULT_RF_TX_POWER;
537
538 pAd->TxPower[3 * i + choffset + 2].Channel = 100 + i * 8 + 4;
539 pAd->TxPower[3 * i + choffset + 2].Power = DEFAULT_RF_TX_POWER;
540 pAd->TxPower[3 * i + choffset + 2].Power2 = DEFAULT_RF_TX_POWER;
541 }
542 pAd->TxPower[3 * 5 + choffset + 0].Channel = 140;
543 pAd->TxPower[3 * 5 + choffset + 0].Power = DEFAULT_RF_TX_POWER;
544 pAd->TxPower[3 * 5 + choffset + 0].Power2 = DEFAULT_RF_TX_POWER;
545
546 /* 2.2 Fill up power */
547 for (i = 0; i < 8; i++) {
548 RT28xx_EEPROM_READ16(pAd,
549 EEPROM_A_TX_PWR_OFFSET + (choffset - 14) +
550 i * 2, Power.word);
551 RT28xx_EEPROM_READ16(pAd,
552 EEPROM_A_TX2_PWR_OFFSET + (choffset - 14) +
553 i * 2, Power2.word);
554
555 if ((Power.field.Byte0 < 16) && (Power.field.Byte0 >= -7))
556 pAd->TxPower[i * 2 + choffset + 0].Power =
557 Power.field.Byte0;
558
559 if ((Power.field.Byte1 < 16) && (Power.field.Byte1 >= -7))
560 pAd->TxPower[i * 2 + choffset + 1].Power =
561 Power.field.Byte1;
562
563 if ((Power2.field.Byte0 < 16) && (Power2.field.Byte0 >= -7))
564 pAd->TxPower[i * 2 + choffset + 0].Power2 =
565 Power2.field.Byte0;
566
567 if ((Power2.field.Byte1 < 16) && (Power2.field.Byte1 >= -7))
568 pAd->TxPower[i * 2 + choffset + 1].Power2 =
569 Power2.field.Byte1;
570 }
571
572 /* 3. U-NII upper band: 149, 151, 153; 157, 159, 161; 165, 167, 169; 171, 173 (including central frequency in BW 40MHz) */
573 /* 3.1 Fill up channel */
574 choffset = 14 + 12 + 16;
575 /*for (i = 0; i < 2; i++) */
576 for (i = 0; i < 3; i++) {
577 pAd->TxPower[3 * i + choffset + 0].Channel = 149 + i * 8 + 0;
578 pAd->TxPower[3 * i + choffset + 0].Power = DEFAULT_RF_TX_POWER;
579 pAd->TxPower[3 * i + choffset + 0].Power2 = DEFAULT_RF_TX_POWER;
580
581 pAd->TxPower[3 * i + choffset + 1].Channel = 149 + i * 8 + 2;
582 pAd->TxPower[3 * i + choffset + 1].Power = DEFAULT_RF_TX_POWER;
583 pAd->TxPower[3 * i + choffset + 1].Power2 = DEFAULT_RF_TX_POWER;
584
585 pAd->TxPower[3 * i + choffset + 2].Channel = 149 + i * 8 + 4;
586 pAd->TxPower[3 * i + choffset + 2].Power = DEFAULT_RF_TX_POWER;
587 pAd->TxPower[3 * i + choffset + 2].Power2 = DEFAULT_RF_TX_POWER;
588 }
589 pAd->TxPower[3 * 3 + choffset + 0].Channel = 171;
590 pAd->TxPower[3 * 3 + choffset + 0].Power = DEFAULT_RF_TX_POWER;
591 pAd->TxPower[3 * 3 + choffset + 0].Power2 = DEFAULT_RF_TX_POWER;
592
593 pAd->TxPower[3 * 3 + choffset + 1].Channel = 173;
594 pAd->TxPower[3 * 3 + choffset + 1].Power = DEFAULT_RF_TX_POWER;
595 pAd->TxPower[3 * 3 + choffset + 1].Power2 = DEFAULT_RF_TX_POWER;
596
597 /* 3.2 Fill up power */
598 /*for (i = 0; i < 4; i++) */
599 for (i = 0; i < 6; i++) {
600 RT28xx_EEPROM_READ16(pAd,
601 EEPROM_A_TX_PWR_OFFSET + (choffset - 14) +
602 i * 2, Power.word);
603 RT28xx_EEPROM_READ16(pAd,
604 EEPROM_A_TX2_PWR_OFFSET + (choffset - 14) +
605 i * 2, Power2.word);
606
607 if ((Power.field.Byte0 < 16) && (Power.field.Byte0 >= -7))
608 pAd->TxPower[i * 2 + choffset + 0].Power =
609 Power.field.Byte0;
610
611 if ((Power.field.Byte1 < 16) && (Power.field.Byte1 >= -7))
612 pAd->TxPower[i * 2 + choffset + 1].Power =
613 Power.field.Byte1;
614
615 if ((Power2.field.Byte0 < 16) && (Power2.field.Byte0 >= -7))
616 pAd->TxPower[i * 2 + choffset + 0].Power2 =
617 Power2.field.Byte0;
618
619 if ((Power2.field.Byte1 < 16) && (Power2.field.Byte1 >= -7))
620 pAd->TxPower[i * 2 + choffset + 1].Power2 =
621 Power2.field.Byte1;
622 }
623
624 /* 4. Print and Debug */
625 /*choffset = 14 + 12 + 16 + 7; */
626 choffset = 14 + 12 + 16 + 11;
627
628}
629
630/*
631 ========================================================================
632
633 Routine Description:
634 Read the following from the registry
635 1. All the parameters
636 2. NetworkAddres
637
638 Arguments:
639 Adapter Pointer to our adapter
640 WrapperConfigurationContext For use by NdisOpenConfiguration
641
642 Return Value:
643 NDIS_STATUS_SUCCESS
644 NDIS_STATUS_FAILURE
645 NDIS_STATUS_RESOURCES
646
647 IRQL = PASSIVE_LEVEL
648
649 Note:
650
651 ========================================================================
652*/
653int NICReadRegParameters(struct rt_rtmp_adapter *pAd,
654 void *WrapperConfigurationContext)
655{
656 int Status = NDIS_STATUS_SUCCESS;
657 DBGPRINT_S(Status, ("<-- NICReadRegParameters, Status=%x\n", Status));
658 return Status;
659}
660
661/*
662 ========================================================================
663
664 Routine Description:
665 Read initial parameters from EEPROM
666
667 Arguments:
668 Adapter Pointer to our adapter
669
670 Return Value:
671 None
672
673 IRQL = PASSIVE_LEVEL
674
675 Note:
676
677 ========================================================================
678*/
679void NICReadEEPROMParameters(struct rt_rtmp_adapter *pAd, u8 *mac_addr)
680{
681 u32 data = 0;
682 u16 i, value, value2;
683 u8 TmpPhy;
684 EEPROM_TX_PWR_STRUC Power;
685 EEPROM_VERSION_STRUC Version;
686 EEPROM_ANTENNA_STRUC Antenna;
687 EEPROM_NIC_CONFIG2_STRUC NicConfig2;
688
689 DBGPRINT(RT_DEBUG_TRACE, ("--> NICReadEEPROMParameters\n"));
690
691 if (pAd->chipOps.eeinit)
692 pAd->chipOps.eeinit(pAd);
693
694 /* Init EEPROM Address Number, before access EEPROM; if 93c46, EEPROMAddressNum=6, else if 93c66, EEPROMAddressNum=8 */
695 RTMP_IO_READ32(pAd, E2PROM_CSR, &data);
696 DBGPRINT(RT_DEBUG_TRACE, ("--> E2PROM_CSR = 0x%x\n", data));
697
698 if ((data & 0x30) == 0)
699 pAd->EEPROMAddressNum = 6; /* 93C46 */
700 else if ((data & 0x30) == 0x10)
701 pAd->EEPROMAddressNum = 8; /* 93C66 */
702 else
703 pAd->EEPROMAddressNum = 8; /* 93C86 */
704 DBGPRINT(RT_DEBUG_TRACE,
705 ("--> EEPROMAddressNum = %d\n", pAd->EEPROMAddressNum));
706
707 /* RT2860 MAC no longer auto load MAC address from E2PROM. Driver has to initialize */
708 /* MAC address registers according to E2PROM setting */
709 if (mac_addr == NULL ||
710 strlen((char *)mac_addr) != 17 ||
711 mac_addr[2] != ':' || mac_addr[5] != ':' || mac_addr[8] != ':' ||
712 mac_addr[11] != ':' || mac_addr[14] != ':') {
713 u16 Addr01, Addr23, Addr45;
714
715 RT28xx_EEPROM_READ16(pAd, 0x04, Addr01);
716 RT28xx_EEPROM_READ16(pAd, 0x06, Addr23);
717 RT28xx_EEPROM_READ16(pAd, 0x08, Addr45);
718
719 pAd->PermanentAddress[0] = (u8)(Addr01 & 0xff);
720 pAd->PermanentAddress[1] = (u8)(Addr01 >> 8);
721 pAd->PermanentAddress[2] = (u8)(Addr23 & 0xff);
722 pAd->PermanentAddress[3] = (u8)(Addr23 >> 8);
723 pAd->PermanentAddress[4] = (u8)(Addr45 & 0xff);
724 pAd->PermanentAddress[5] = (u8)(Addr45 >> 8);
725
726 DBGPRINT(RT_DEBUG_TRACE,
727 ("Initialize MAC Address from E2PROM \n"));
728 } else {
729 int j;
730 char *macptr;
731
732 macptr = (char *)mac_addr;
733
734 for (j = 0; j < MAC_ADDR_LEN; j++) {
735 AtoH(macptr, &pAd->PermanentAddress[j], 1);
736 macptr = macptr + 3;
737 }
738
739 DBGPRINT(RT_DEBUG_TRACE,
740 ("Initialize MAC Address from module parameter \n"));
741 }
742
743 {
744 /*more conveninet to test mbssid, so ap's bssid &0xf1 */
745 if (pAd->PermanentAddress[0] == 0xff)
746 pAd->PermanentAddress[0] = RandomByte(pAd) & 0xf8;
747
748 /*if (pAd->PermanentAddress[5] == 0xff) */
749 /* pAd->PermanentAddress[5] = RandomByte(pAd)&0xf8; */
750
751 DBGPRINT_RAW(RT_DEBUG_TRACE,
752 ("E2PROM MAC: =%pM\n", pAd->PermanentAddress));
753 if (pAd->bLocalAdminMAC == FALSE) {
754 MAC_DW0_STRUC csr2;
755 MAC_DW1_STRUC csr3;
756 COPY_MAC_ADDR(pAd->CurrentAddress,
757 pAd->PermanentAddress);
758 csr2.field.Byte0 = pAd->CurrentAddress[0];
759 csr2.field.Byte1 = pAd->CurrentAddress[1];
760 csr2.field.Byte2 = pAd->CurrentAddress[2];
761 csr2.field.Byte3 = pAd->CurrentAddress[3];
762 RTMP_IO_WRITE32(pAd, MAC_ADDR_DW0, csr2.word);
763 csr3.word = 0;
764 csr3.field.Byte4 = pAd->CurrentAddress[4];
765 csr3.field.Byte5 = pAd->CurrentAddress[5];
766 csr3.field.U2MeMask = 0xff;
767 RTMP_IO_WRITE32(pAd, MAC_ADDR_DW1, csr3.word);
768 DBGPRINT_RAW(RT_DEBUG_TRACE,
769 ("E2PROM MAC: =%pM\n",
770 pAd->PermanentAddress));
771 }
772 }
773
774 /* if not return early. cause fail at emulation. */
775 /* Init the channel number for TX channel power */
776 RTMPReadChannelPwr(pAd);
777
778 /* if E2PROM version mismatch with driver's expectation, then skip */
779 /* all subsequent E2RPOM retieval and set a system error bit to notify GUI */
780 RT28xx_EEPROM_READ16(pAd, EEPROM_VERSION_OFFSET, Version.word);
781 pAd->EepromVersion =
782 Version.field.Version + Version.field.FaeReleaseNumber * 256;
783 DBGPRINT(RT_DEBUG_TRACE,
784 ("E2PROM: Version = %d, FAE release #%d\n",
785 Version.field.Version, Version.field.FaeReleaseNumber));
786
787 if (Version.field.Version > VALID_EEPROM_VERSION) {
788 DBGPRINT_ERR("E2PROM: WRONG VERSION 0x%x, should be %d\n", Version.field.Version, VALID_EEPROM_VERSION);
789 /*pAd->SystemErrorBitmap |= 0x00000001;
790
791 // hard-code default value when no proper E2PROM installed
792 pAd->bAutoTxAgcA = FALSE;
793 pAd->bAutoTxAgcG = FALSE;
794
795 // Default the channel power
796 for (i = 0; i < MAX_NUM_OF_CHANNELS; i++)
797 pAd->TxPower[i].Power = DEFAULT_RF_TX_POWER;
798
799 // Default the channel power
800 for (i = 0; i < MAX_NUM_OF_11JCHANNELS; i++)
801 pAd->TxPower11J[i].Power = DEFAULT_RF_TX_POWER;
802
803 for(i = 0; i < NUM_EEPROM_BBP_PARMS; i++)
804 pAd->EEPROMDefaultValue[i] = 0xffff;
805 return; */
806 }
807 /* Read BBP default value from EEPROM and store to array(EEPROMDefaultValue) in pAd */
808 RT28xx_EEPROM_READ16(pAd, EEPROM_NIC1_OFFSET, value);
809 pAd->EEPROMDefaultValue[0] = value;
810
811 RT28xx_EEPROM_READ16(pAd, EEPROM_NIC2_OFFSET, value);
812 pAd->EEPROMDefaultValue[1] = value;
813
814 RT28xx_EEPROM_READ16(pAd, 0x38, value); /* Country Region */
815 pAd->EEPROMDefaultValue[2] = value;
816
817 for (i = 0; i < 8; i++) {
818 RT28xx_EEPROM_READ16(pAd, EEPROM_BBP_BASE_OFFSET + i * 2,
819 value);
820 pAd->EEPROMDefaultValue[i + 3] = value;
821 }
822
823 /* We have to parse NIC configuration 0 at here. */
824 /* If TSSI did not have preloaded value, it should reset the TxAutoAgc to false */
825 /* Therefore, we have to read TxAutoAgc control beforehand. */
826 /* Read Tx AGC control bit */
827 Antenna.word = pAd->EEPROMDefaultValue[0];
828 if (Antenna.word == 0xFFFF) {
829#ifdef RT30xx
830 if (IS_RT3090(pAd) || IS_RT3390(pAd)) {
831 Antenna.word = 0;
832 Antenna.field.RfIcType = RFIC_3020;
833 Antenna.field.TxPath = 1;
834 Antenna.field.RxPath = 1;
835 } else
836#endif /* RT30xx // */
837 {
838
839 Antenna.word = 0;
840 Antenna.field.RfIcType = RFIC_2820;
841 Antenna.field.TxPath = 1;
842 Antenna.field.RxPath = 2;
843 DBGPRINT(RT_DEBUG_WARN,
844 ("E2PROM error, hard code as 0x%04x\n",
845 Antenna.word));
846 }
847 }
848 /* Choose the desired Tx&Rx stream. */
849 if ((pAd->CommonCfg.TxStream == 0)
850 || (pAd->CommonCfg.TxStream > Antenna.field.TxPath))
851 pAd->CommonCfg.TxStream = Antenna.field.TxPath;
852
853 if ((pAd->CommonCfg.RxStream == 0)
854 || (pAd->CommonCfg.RxStream > Antenna.field.RxPath)) {
855 pAd->CommonCfg.RxStream = Antenna.field.RxPath;
856
857 if ((pAd->MACVersion < RALINK_2883_VERSION) &&
858 (pAd->CommonCfg.RxStream > 2)) {
859 /* only 2 Rx streams for RT2860 series */
860 pAd->CommonCfg.RxStream = 2;
861 }
862 }
863 /* 3*3 */
864 /* read value from EEPROM and set them to CSR174 ~ 177 in chain0 ~ chain2 */
865 /* yet implement */
866 for (i = 0; i < 3; i++) {
867 }
868
869 NicConfig2.word = pAd->EEPROMDefaultValue[1];
870
871 {
872 if ((NicConfig2.word & 0x00ff) == 0xff) {
873 NicConfig2.word &= 0xff00;
874 }
875
876 if ((NicConfig2.word >> 8) == 0xff) {
877 NicConfig2.word &= 0x00ff;
878 }
879 }
880
881 if (NicConfig2.field.DynamicTxAgcControl == 1)
882 pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = TRUE;
883 else
884 pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = FALSE;
885
886 DBGPRINT_RAW(RT_DEBUG_TRACE,
887 ("NICReadEEPROMParameters: RxPath = %d, TxPath = %d\n",
888 Antenna.field.RxPath, Antenna.field.TxPath));
889
890 /* Save the antenna for future use */
891 pAd->Antenna.word = Antenna.word;
892
893 /* Set the RfICType here, then we can initialize RFIC related operation callbacks */
894 pAd->Mlme.RealRxPath = (u8)Antenna.field.RxPath;
895 pAd->RfIcType = (u8)Antenna.field.RfIcType;
896
897#ifdef RTMP_RF_RW_SUPPORT
898 RtmpChipOpsRFHook(pAd);
899#endif /* RTMP_RF_RW_SUPPORT // */
900
901#ifdef RTMP_MAC_PCI
902 sprintf((char *)pAd->nickname, "RT2860STA");
903#endif /* RTMP_MAC_PCI // */
904
905 /* */
906 /* Reset PhyMode if we don't support 802.11a */
907 /* Only RFIC_2850 & RFIC_2750 support 802.11a */
908 /* */
909 if ((Antenna.field.RfIcType != RFIC_2850)
910 && (Antenna.field.RfIcType != RFIC_2750)
911 && (Antenna.field.RfIcType != RFIC_3052)) {
912 if ((pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED) ||
913 (pAd->CommonCfg.PhyMode == PHY_11A))
914 pAd->CommonCfg.PhyMode = PHY_11BG_MIXED;
915 else if ((pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED) ||
916 (pAd->CommonCfg.PhyMode == PHY_11AN_MIXED) ||
917 (pAd->CommonCfg.PhyMode == PHY_11AGN_MIXED) ||
918 (pAd->CommonCfg.PhyMode == PHY_11N_5G))
919 pAd->CommonCfg.PhyMode = PHY_11BGN_MIXED;
920 }
921 /* Read TSSI reference and TSSI boundary for temperature compensation. This is ugly */
922 /* 0. 11b/g */
923 {
924 /* these are tempature reference value (0x00 ~ 0xFE)
925 ex: 0x00 0x15 0x25 0x45 0x88 0xA0 0xB5 0xD0 0xF0
926 TssiPlusBoundaryG [4] [3] [2] [1] [0] (smaller) +
927 TssiMinusBoundaryG[0] [1] [2] [3] [4] (larger) */
928 RT28xx_EEPROM_READ16(pAd, 0x6E, Power.word);
929 pAd->TssiMinusBoundaryG[4] = Power.field.Byte0;
930 pAd->TssiMinusBoundaryG[3] = Power.field.Byte1;
931 RT28xx_EEPROM_READ16(pAd, 0x70, Power.word);
932 pAd->TssiMinusBoundaryG[2] = Power.field.Byte0;
933 pAd->TssiMinusBoundaryG[1] = Power.field.Byte1;
934 RT28xx_EEPROM_READ16(pAd, 0x72, Power.word);
935 pAd->TssiRefG = Power.field.Byte0; /* reference value [0] */
936 pAd->TssiPlusBoundaryG[1] = Power.field.Byte1;
937 RT28xx_EEPROM_READ16(pAd, 0x74, Power.word);
938 pAd->TssiPlusBoundaryG[2] = Power.field.Byte0;
939 pAd->TssiPlusBoundaryG[3] = Power.field.Byte1;
940 RT28xx_EEPROM_READ16(pAd, 0x76, Power.word);
941 pAd->TssiPlusBoundaryG[4] = Power.field.Byte0;
942 pAd->TxAgcStepG = Power.field.Byte1;
943 pAd->TxAgcCompensateG = 0;
944 pAd->TssiMinusBoundaryG[0] = pAd->TssiRefG;
945 pAd->TssiPlusBoundaryG[0] = pAd->TssiRefG;
946
947 /* Disable TxAgc if the based value is not right */
948 if (pAd->TssiRefG == 0xff)
949 pAd->bAutoTxAgcG = FALSE;
950
951 DBGPRINT(RT_DEBUG_TRACE,
952 ("E2PROM: G Tssi[-4 .. +4] = %d %d %d %d - %d -%d %d %d %d, step=%d, tuning=%d\n",
953 pAd->TssiMinusBoundaryG[4],
954 pAd->TssiMinusBoundaryG[3],
955 pAd->TssiMinusBoundaryG[2],
956 pAd->TssiMinusBoundaryG[1], pAd->TssiRefG,
957 pAd->TssiPlusBoundaryG[1], pAd->TssiPlusBoundaryG[2],
958 pAd->TssiPlusBoundaryG[3], pAd->TssiPlusBoundaryG[4],
959 pAd->TxAgcStepG, pAd->bAutoTxAgcG));
960 }
961 /* 1. 11a */
962 {
963 RT28xx_EEPROM_READ16(pAd, 0xD4, Power.word);
964 pAd->TssiMinusBoundaryA[4] = Power.field.Byte0;
965 pAd->TssiMinusBoundaryA[3] = Power.field.Byte1;
966 RT28xx_EEPROM_READ16(pAd, 0xD6, Power.word);
967 pAd->TssiMinusBoundaryA[2] = Power.field.Byte0;
968 pAd->TssiMinusBoundaryA[1] = Power.field.Byte1;
969 RT28xx_EEPROM_READ16(pAd, 0xD8, Power.word);
970 pAd->TssiRefA = Power.field.Byte0;
971 pAd->TssiPlusBoundaryA[1] = Power.field.Byte1;
972 RT28xx_EEPROM_READ16(pAd, 0xDA, Power.word);
973 pAd->TssiPlusBoundaryA[2] = Power.field.Byte0;
974 pAd->TssiPlusBoundaryA[3] = Power.field.Byte1;
975 RT28xx_EEPROM_READ16(pAd, 0xDC, Power.word);
976 pAd->TssiPlusBoundaryA[4] = Power.field.Byte0;
977 pAd->TxAgcStepA = Power.field.Byte1;
978 pAd->TxAgcCompensateA = 0;
979 pAd->TssiMinusBoundaryA[0] = pAd->TssiRefA;
980 pAd->TssiPlusBoundaryA[0] = pAd->TssiRefA;
981
982 /* Disable TxAgc if the based value is not right */
983 if (pAd->TssiRefA == 0xff)
984 pAd->bAutoTxAgcA = FALSE;
985
986 DBGPRINT(RT_DEBUG_TRACE,
987 ("E2PROM: A Tssi[-4 .. +4] = %d %d %d %d - %d -%d %d %d %d, step=%d, tuning=%d\n",
988 pAd->TssiMinusBoundaryA[4],
989 pAd->TssiMinusBoundaryA[3],
990 pAd->TssiMinusBoundaryA[2],
991 pAd->TssiMinusBoundaryA[1], pAd->TssiRefA,
992 pAd->TssiPlusBoundaryA[1], pAd->TssiPlusBoundaryA[2],
993 pAd->TssiPlusBoundaryA[3], pAd->TssiPlusBoundaryA[4],
994 pAd->TxAgcStepA, pAd->bAutoTxAgcA));
995 }
996 pAd->BbpRssiToDbmDelta = 0x0;
997
998 /* Read frequency offset setting for RF */
999 RT28xx_EEPROM_READ16(pAd, EEPROM_FREQ_OFFSET, value);
1000 if ((value & 0x00FF) != 0x00FF)
1001 pAd->RfFreqOffset = (unsigned long)(value & 0x00FF);
1002 else
1003 pAd->RfFreqOffset = 0;
1004 DBGPRINT(RT_DEBUG_TRACE,
1005 ("E2PROM: RF FreqOffset=0x%lx \n", pAd->RfFreqOffset));
1006
1007 /*CountryRegion byte offset (38h) */
1008 value = pAd->EEPROMDefaultValue[2] >> 8; /* 2.4G band */
1009 value2 = pAd->EEPROMDefaultValue[2] & 0x00FF; /* 5G band */
1010
1011 if ((value <= REGION_MAXIMUM_BG_BAND)
1012 && (value2 <= REGION_MAXIMUM_A_BAND)) {
1013 pAd->CommonCfg.CountryRegion = ((u8)value) | 0x80;
1014 pAd->CommonCfg.CountryRegionForABand = ((u8)value2) | 0x80;
1015 TmpPhy = pAd->CommonCfg.PhyMode;
1016 pAd->CommonCfg.PhyMode = 0xff;
1017 RTMPSetPhyMode(pAd, TmpPhy);
1018 SetCommonHT(pAd);
1019 }
1020 /* */
1021 /* Get RSSI Offset on EEPROM 0x9Ah & 0x9Ch. */
1022 /* The valid value are (-10 ~ 10) */
1023 /* */
1024 RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_BG_OFFSET, value);
1025 pAd->BGRssiOffset0 = value & 0x00ff;
1026 pAd->BGRssiOffset1 = (value >> 8);
1027 RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_BG_OFFSET + 2, value);
1028 pAd->BGRssiOffset2 = value & 0x00ff;
1029 pAd->ALNAGain1 = (value >> 8);
1030 RT28xx_EEPROM_READ16(pAd, EEPROM_LNA_OFFSET, value);
1031 pAd->BLNAGain = value & 0x00ff;
1032 pAd->ALNAGain0 = (value >> 8);
1033
1034 /* Validate 11b/g RSSI_0 offset. */
1035 if ((pAd->BGRssiOffset0 < -10) || (pAd->BGRssiOffset0 > 10))
1036 pAd->BGRssiOffset0 = 0;
1037
1038 /* Validate 11b/g RSSI_1 offset. */
1039 if ((pAd->BGRssiOffset1 < -10) || (pAd->BGRssiOffset1 > 10))
1040 pAd->BGRssiOffset1 = 0;
1041
1042 /* Validate 11b/g RSSI_2 offset. */
1043 if ((pAd->BGRssiOffset2 < -10) || (pAd->BGRssiOffset2 > 10))
1044 pAd->BGRssiOffset2 = 0;
1045
1046 RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_A_OFFSET, value);
1047 pAd->ARssiOffset0 = value & 0x00ff;
1048 pAd->ARssiOffset1 = (value >> 8);
1049 RT28xx_EEPROM_READ16(pAd, (EEPROM_RSSI_A_OFFSET + 2), value);
1050 pAd->ARssiOffset2 = value & 0x00ff;
1051 pAd->ALNAGain2 = (value >> 8);
1052
1053 if (((u8)pAd->ALNAGain1 == 0xFF) || (pAd->ALNAGain1 == 0x00))
1054 pAd->ALNAGain1 = pAd->ALNAGain0;
1055 if (((u8)pAd->ALNAGain2 == 0xFF) || (pAd->ALNAGain2 == 0x00))
1056 pAd->ALNAGain2 = pAd->ALNAGain0;
1057
1058 /* Validate 11a RSSI_0 offset. */
1059 if ((pAd->ARssiOffset0 < -10) || (pAd->ARssiOffset0 > 10))
1060 pAd->ARssiOffset0 = 0;
1061
1062 /* Validate 11a RSSI_1 offset. */
1063 if ((pAd->ARssiOffset1 < -10) || (pAd->ARssiOffset1 > 10))
1064 pAd->ARssiOffset1 = 0;
1065
1066 /*Validate 11a RSSI_2 offset. */
1067 if ((pAd->ARssiOffset2 < -10) || (pAd->ARssiOffset2 > 10))
1068 pAd->ARssiOffset2 = 0;
1069
1070#ifdef RT30xx
1071 /* */
1072 /* Get TX mixer gain setting */
1073 /* 0xff are invalid value */
1074 /* Note: RT30xX default value is 0x00 and will program to RF_R17 only when this value is not zero. */
1075 /* RT359X default value is 0x02 */
1076 /* */
1077 if (IS_RT30xx(pAd) || IS_RT3572(pAd)) {
1078 RT28xx_EEPROM_READ16(pAd, EEPROM_TXMIXER_GAIN_2_4G, value);
1079 pAd->TxMixerGain24G = 0;
1080 value &= 0x00ff;
1081 if (value != 0xff) {
1082 value &= 0x07;
1083 pAd->TxMixerGain24G = (u8)value;
1084 }
1085 }
1086#endif /* RT30xx // */
1087
1088 /* */
1089 /* Get LED Setting. */
1090 /* */
1091 RT28xx_EEPROM_READ16(pAd, 0x3a, value);
1092 pAd->LedCntl.word = (value >> 8);
1093 RT28xx_EEPROM_READ16(pAd, EEPROM_LED1_OFFSET, value);
1094 pAd->Led1 = value;
1095 RT28xx_EEPROM_READ16(pAd, EEPROM_LED2_OFFSET, value);
1096 pAd->Led2 = value;
1097 RT28xx_EEPROM_READ16(pAd, EEPROM_LED3_OFFSET, value);
1098 pAd->Led3 = value;
1099
1100 RTMPReadTxPwrPerRate(pAd);
1101
1102#ifdef RT30xx
1103#ifdef RTMP_EFUSE_SUPPORT
1104 RtmpEfuseSupportCheck(pAd);
1105#endif /* RTMP_EFUSE_SUPPORT // */
1106#endif /* RT30xx // */
1107
1108 DBGPRINT(RT_DEBUG_TRACE, ("<-- NICReadEEPROMParameters\n"));
1109}
1110
1111/*
1112 ========================================================================
1113
1114 Routine Description:
1115 Set default value from EEPROM
1116
1117 Arguments:
1118 Adapter Pointer to our adapter
1119
1120 Return Value:
1121 None
1122
1123 IRQL = PASSIVE_LEVEL
1124
1125 Note:
1126
1127 ========================================================================
1128*/
1129void NICInitAsicFromEEPROM(struct rt_rtmp_adapter *pAd)
1130{
1131 u32 data = 0;
1132 u8 BBPR1 = 0;
1133 u16 i;
1134/* EEPROM_ANTENNA_STRUC Antenna; */
1135 EEPROM_NIC_CONFIG2_STRUC NicConfig2;
1136 u8 BBPR3 = 0;
1137
1138 DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitAsicFromEEPROM\n"));
1139 for (i = 3; i < NUM_EEPROM_BBP_PARMS; i++) {
1140 u8 BbpRegIdx, BbpValue;
1141
1142 if ((pAd->EEPROMDefaultValue[i] != 0xFFFF)
1143 && (pAd->EEPROMDefaultValue[i] != 0)) {
1144 BbpRegIdx = (u8)(pAd->EEPROMDefaultValue[i] >> 8);
1145 BbpValue = (u8)(pAd->EEPROMDefaultValue[i] & 0xff);
1146 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BbpRegIdx, BbpValue);
1147 }
1148 }
1149
1150 NicConfig2.word = pAd->EEPROMDefaultValue[1];
1151
1152 {
1153 if ((NicConfig2.word & 0x00ff) == 0xff) {
1154 NicConfig2.word &= 0xff00;
1155 }
1156
1157 if ((NicConfig2.word >> 8) == 0xff) {
1158 NicConfig2.word &= 0x00ff;
1159 }
1160 }
1161
1162 /* Save the antenna for future use */
1163 pAd->NicConfig2.word = NicConfig2.word;
1164
1165#ifdef RT30xx
1166 /* set default antenna as main */
1167 if (pAd->RfIcType == RFIC_3020)
1168 AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
1169#endif /* RT30xx // */
1170
1171 /* */
1172 /* Send LED Setting to MCU. */
1173 /* */
1174 if (pAd->LedCntl.word == 0xFF) {
1175 pAd->LedCntl.word = 0x01;
1176 pAd->Led1 = 0x5555;
1177 pAd->Led2 = 0x2221;
1178
1179#ifdef RTMP_MAC_PCI
1180 pAd->Led3 = 0xA9F8;
1181#endif /* RTMP_MAC_PCI // */
1182#ifdef RTMP_MAC_USB
1183 pAd->Led3 = 0x5627;
1184#endif /* RTMP_MAC_USB // */
1185 }
1186
1187 AsicSendCommandToMcu(pAd, 0x52, 0xff, (u8)pAd->Led1,
1188 (u8)(pAd->Led1 >> 8));
1189 AsicSendCommandToMcu(pAd, 0x53, 0xff, (u8)pAd->Led2,
1190 (u8)(pAd->Led2 >> 8));
1191 AsicSendCommandToMcu(pAd, 0x54, 0xff, (u8)pAd->Led3,
1192 (u8)(pAd->Led3 >> 8));
1193 AsicSendCommandToMcu(pAd, 0x51, 0xff, 0, pAd->LedCntl.field.Polarity);
1194
1195 pAd->LedIndicatorStrength = 0xFF;
1196 RTMPSetSignalLED(pAd, -100); /* Force signal strength Led to be turned off, before link up */
1197
1198 {
1199 /* Read Hardware controlled Radio state enable bit */
1200 if (NicConfig2.field.HardwareRadioControl == 1) {
1201 pAd->StaCfg.bHardwareRadio = TRUE;
1202
1203 /* Read GPIO pin2 as Hardware controlled radio state */
1204 RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &data);
1205 if ((data & 0x04) == 0) {
1206 pAd->StaCfg.bHwRadio = FALSE;
1207 pAd->StaCfg.bRadio = FALSE;
1208/* RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0x00001818); */
1209 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
1210 }
1211 } else
1212 pAd->StaCfg.bHardwareRadio = FALSE;
1213
1214 if (pAd->StaCfg.bRadio == FALSE) {
1215 RTMPSetLED(pAd, LED_RADIO_OFF);
1216 } else {
1217 RTMPSetLED(pAd, LED_RADIO_ON);
1218#ifdef RTMP_MAC_PCI
1219#ifdef RT3090
1220 AsicSendCommandToMcu(pAd, 0x30, PowerRadioOffCID, 0xff,
1221 0x02);
1222 AsicCheckCommanOk(pAd, PowerRadioOffCID);
1223#endif /* RT3090 // */
1224#ifndef RT3090
1225 AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02);
1226#endif /* RT3090 // */
1227 AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00,
1228 0x00);
1229 /* 2-1. wait command ok. */
1230 AsicCheckCommanOk(pAd, PowerWakeCID);
1231#endif /* RTMP_MAC_PCI // */
1232 }
1233 }
1234
1235#ifdef RTMP_MAC_PCI
1236#ifdef RT30xx
1237 if (IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) {
1238 struct rt_rtmp_chip_op *pChipOps = &pAd->chipOps;
1239 if (pChipOps->AsicReverseRfFromSleepMode)
1240 pChipOps->AsicReverseRfFromSleepMode(pAd);
1241 }
1242 /* 3090 MCU Wakeup command needs more time to be stable. */
1243 /* Before stable, don't issue other MCU command to prevent from firmware error. */
1244
1245 if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
1246 && IS_VERSION_AFTER_F(pAd)
1247 && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
1248 && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)) {
1249 DBGPRINT(RT_DEBUG_TRACE, ("%s, release Mcu Lock\n", __func__));
1250 RTMP_SEM_LOCK(&pAd->McuCmdLock);
1251 pAd->brt30xxBanMcuCmd = FALSE;
1252 RTMP_SEM_UNLOCK(&pAd->McuCmdLock);
1253 }
1254#endif /* RT30xx // */
1255#endif /* RTMP_MAC_PCI // */
1256
1257 /* Turn off patching for cardbus controller */
1258 if (NicConfig2.field.CardbusAcceleration == 1) {
1259/* pAd->bTest1 = TRUE; */
1260 }
1261
1262 if (NicConfig2.field.DynamicTxAgcControl == 1)
1263 pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = TRUE;
1264 else
1265 pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = FALSE;
1266 /* */
1267 /* Since BBP has been progamed, to make sure BBP setting will be */
1268 /* upate inside of AsicAntennaSelect, so reset to UNKNOWN_BAND! */
1269 /* */
1270 pAd->CommonCfg.BandState = UNKNOWN_BAND;
1271
1272 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPR3);
1273 BBPR3 &= (~0x18);
1274 if (pAd->Antenna.field.RxPath == 3) {
1275 BBPR3 |= (0x10);
1276 } else if (pAd->Antenna.field.RxPath == 2) {
1277 BBPR3 |= (0x8);
1278 } else if (pAd->Antenna.field.RxPath == 1) {
1279 BBPR3 |= (0x0);
1280 }
1281 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
1282
1283 {
1284 /* Handle the difference when 1T */
1285 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BBPR1);
1286 if (pAd->Antenna.field.TxPath == 1) {
1287 BBPR1 &= (~0x18);
1288 }
1289 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BBPR1);
1290
1291 DBGPRINT(RT_DEBUG_TRACE,
1292 ("Use Hw Radio Control Pin=%d; if used Pin=%d;\n",
1293 pAd->CommonCfg.bHardwareRadio,
1294 pAd->CommonCfg.bHardwareRadio));
1295 }
1296
1297#ifdef RTMP_MAC_USB
1298#ifdef RT30xx
1299 /* update registers from EEPROM for RT3071 or later(3572/3592). */
1300
1301 if (IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) {
1302 u8 RegIdx, RegValue;
1303 u16 value;
1304
1305 /* after RT3071, write BBP from EEPROM 0xF0 to 0x102 */
1306 for (i = 0xF0; i <= 0x102; i = i + 2) {
1307 value = 0xFFFF;
1308 RT28xx_EEPROM_READ16(pAd, i, value);
1309 if ((value != 0xFFFF) && (value != 0)) {
1310 RegIdx = (u8)(value >> 8);
1311 RegValue = (u8)(value & 0xff);
1312 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, RegIdx,
1313 RegValue);
1314 DBGPRINT(RT_DEBUG_TRACE,
1315 ("Update BBP Registers from EEPROM(0x%0x), BBP(0x%x) = 0x%x\n",
1316 i, RegIdx, RegValue));
1317 }
1318 }
1319
1320 /* after RT3071, write RF from EEPROM 0x104 to 0x116 */
1321 for (i = 0x104; i <= 0x116; i = i + 2) {
1322 value = 0xFFFF;
1323 RT28xx_EEPROM_READ16(pAd, i, value);
1324 if ((value != 0xFFFF) && (value != 0)) {
1325 RegIdx = (u8)(value >> 8);
1326 RegValue = (u8)(value & 0xff);
1327 RT30xxWriteRFRegister(pAd, RegIdx, RegValue);
1328 DBGPRINT(RT_DEBUG_TRACE,
1329 ("Update RF Registers from EEPROM0x%x), BBP(0x%x) = 0x%x\n",
1330 i, RegIdx, RegValue));
1331 }
1332 }
1333 }
1334#endif /* RT30xx // */
1335#endif /* RTMP_MAC_USB // */
1336
1337 DBGPRINT(RT_DEBUG_TRACE,
1338 ("TxPath = %d, RxPath = %d, RFIC=%d, Polar+LED mode=%x\n",
1339 pAd->Antenna.field.TxPath, pAd->Antenna.field.RxPath,
1340 pAd->RfIcType, pAd->LedCntl.word));
1341 DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitAsicFromEEPROM\n"));
1342}
1343
1344/*
1345 ========================================================================
1346
1347 Routine Description:
1348 Initialize NIC hardware
1349
1350 Arguments:
1351 Adapter Pointer to our adapter
1352
1353 Return Value:
1354 None
1355
1356 IRQL = PASSIVE_LEVEL
1357
1358 Note:
1359
1360 ========================================================================
1361*/
1362int NICInitializeAdapter(struct rt_rtmp_adapter *pAd, IN BOOLEAN bHardReset)
1363{
1364 int Status = NDIS_STATUS_SUCCESS;
1365 WPDMA_GLO_CFG_STRUC GloCfg;
1366#ifdef RTMP_MAC_PCI
1367 u32 Value;
1368 DELAY_INT_CFG_STRUC IntCfg;
1369#endif /* RTMP_MAC_PCI // */
1370/* INT_MASK_CSR_STRUC IntMask; */
1371 unsigned long i = 0, j = 0;
1372 AC_TXOP_CSR0_STRUC csr0;
1373
1374 DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitializeAdapter\n"));
1375
1376 /* 3. Set DMA global configuration except TX_DMA_EN and RX_DMA_EN bits: */
1377retry:
1378 i = 0;
1379 do {
1380 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
1381 if ((GloCfg.field.TxDMABusy == 0)
1382 && (GloCfg.field.RxDMABusy == 0))
1383 break;
1384
1385 RTMPusecDelay(1000);
1386 i++;
1387 } while (i < 100);
1388 DBGPRINT(RT_DEBUG_TRACE,
1389 ("<== DMA offset 0x208 = 0x%x\n", GloCfg.word));
1390 GloCfg.word &= 0xff0;
1391 GloCfg.field.EnTXWriteBackDDONE = 1;
1392 RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
1393
1394 /* Record HW Beacon offset */
1395 pAd->BeaconOffset[0] = HW_BEACON_BASE0;
1396 pAd->BeaconOffset[1] = HW_BEACON_BASE1;
1397 pAd->BeaconOffset[2] = HW_BEACON_BASE2;
1398 pAd->BeaconOffset[3] = HW_BEACON_BASE3;
1399 pAd->BeaconOffset[4] = HW_BEACON_BASE4;
1400 pAd->BeaconOffset[5] = HW_BEACON_BASE5;
1401 pAd->BeaconOffset[6] = HW_BEACON_BASE6;
1402 pAd->BeaconOffset[7] = HW_BEACON_BASE7;
1403
1404 /* */
1405 /* write all shared Ring's base address into ASIC */
1406 /* */
1407
1408 /* asic simulation sequence put this ahead before loading firmware. */
1409 /* pbf hardware reset */
1410#ifdef RTMP_MAC_PCI
1411 RTMP_IO_WRITE32(pAd, WPDMA_RST_IDX, 0x1003f); /* 0x10000 for reset rx, 0x3f resets all 6 tx rings. */
1412 RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0xe1f);
1413 RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0xe00);
1414#endif /* RTMP_MAC_PCI // */
1415
1416 /* Initialze ASIC for TX & Rx operation */
1417 if (NICInitializeAsic(pAd, bHardReset) != NDIS_STATUS_SUCCESS) {
1418 if (j++ == 0) {
1419 NICLoadFirmware(pAd);
1420 goto retry;
1421 }
1422 return NDIS_STATUS_FAILURE;
1423 }
1424
1425#ifdef RTMP_MAC_PCI
1426 /* Write AC_BK base address register */
1427 Value =
1428 RTMP_GetPhysicalAddressLow(pAd->TxRing[QID_AC_BK].Cell[0].AllocPa);
1429 RTMP_IO_WRITE32(pAd, TX_BASE_PTR1, Value);
1430 DBGPRINT(RT_DEBUG_TRACE, ("--> TX_BASE_PTR1 : 0x%x\n", Value));
1431
1432 /* Write AC_BE base address register */
1433 Value =
1434 RTMP_GetPhysicalAddressLow(pAd->TxRing[QID_AC_BE].Cell[0].AllocPa);
1435 RTMP_IO_WRITE32(pAd, TX_BASE_PTR0, Value);
1436 DBGPRINT(RT_DEBUG_TRACE, ("--> TX_BASE_PTR0 : 0x%x\n", Value));
1437
1438 /* Write AC_VI base address register */
1439 Value =
1440 RTMP_GetPhysicalAddressLow(pAd->TxRing[QID_AC_VI].Cell[0].AllocPa);
1441 RTMP_IO_WRITE32(pAd, TX_BASE_PTR2, Value);
1442 DBGPRINT(RT_DEBUG_TRACE, ("--> TX_BASE_PTR2 : 0x%x\n", Value));
1443
1444 /* Write AC_VO base address register */
1445 Value =
1446 RTMP_GetPhysicalAddressLow(pAd->TxRing[QID_AC_VO].Cell[0].AllocPa);
1447 RTMP_IO_WRITE32(pAd, TX_BASE_PTR3, Value);
1448 DBGPRINT(RT_DEBUG_TRACE, ("--> TX_BASE_PTR3 : 0x%x\n", Value));
1449
1450 /* Write MGMT_BASE_CSR register */
1451 Value = RTMP_GetPhysicalAddressLow(pAd->MgmtRing.Cell[0].AllocPa);
1452 RTMP_IO_WRITE32(pAd, TX_BASE_PTR5, Value);
1453 DBGPRINT(RT_DEBUG_TRACE, ("--> TX_BASE_PTR5 : 0x%x\n", Value));
1454
1455 /* Write RX_BASE_CSR register */
1456 Value = RTMP_GetPhysicalAddressLow(pAd->RxRing.Cell[0].AllocPa);
1457 RTMP_IO_WRITE32(pAd, RX_BASE_PTR, Value);
1458 DBGPRINT(RT_DEBUG_TRACE, ("--> RX_BASE_PTR : 0x%x\n", Value));
1459
1460 /* Init RX Ring index pointer */
1461 pAd->RxRing.RxSwReadIdx = 0;
1462 pAd->RxRing.RxCpuIdx = RX_RING_SIZE - 1;
1463 RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx);
1464
1465 /* Init TX rings index pointer */
1466 {
1467 for (i = 0; i < NUM_OF_TX_RING; i++) {
1468 pAd->TxRing[i].TxSwFreeIdx = 0;
1469 pAd->TxRing[i].TxCpuIdx = 0;
1470 RTMP_IO_WRITE32(pAd, (TX_CTX_IDX0 + i * 0x10),
1471 pAd->TxRing[i].TxCpuIdx);
1472 }
1473 }
1474
1475 /* init MGMT ring index pointer */
1476 pAd->MgmtRing.TxSwFreeIdx = 0;
1477 pAd->MgmtRing.TxCpuIdx = 0;
1478 RTMP_IO_WRITE32(pAd, TX_MGMTCTX_IDX, pAd->MgmtRing.TxCpuIdx);
1479
1480 /* */
1481 /* set each Ring's SIZE into ASIC. Descriptor Size is fixed by design. */
1482 /* */
1483
1484 /* Write TX_RING_CSR0 register */
1485 Value = TX_RING_SIZE;
1486 RTMP_IO_WRITE32(pAd, TX_MAX_CNT0, Value);
1487 RTMP_IO_WRITE32(pAd, TX_MAX_CNT1, Value);
1488 RTMP_IO_WRITE32(pAd, TX_MAX_CNT2, Value);
1489 RTMP_IO_WRITE32(pAd, TX_MAX_CNT3, Value);
1490 RTMP_IO_WRITE32(pAd, TX_MAX_CNT4, Value);
1491 Value = MGMT_RING_SIZE;
1492 RTMP_IO_WRITE32(pAd, TX_MGMTMAX_CNT, Value);
1493
1494 /* Write RX_RING_CSR register */
1495 Value = RX_RING_SIZE;
1496 RTMP_IO_WRITE32(pAd, RX_MAX_CNT, Value);
1497#endif /* RTMP_MAC_PCI // */
1498
1499 /* WMM parameter */
1500 csr0.word = 0;
1501 RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word);
1502 if (pAd->CommonCfg.PhyMode == PHY_11B) {
1503 csr0.field.Ac0Txop = 192; /* AC_VI: 192*32us ~= 6ms */
1504 csr0.field.Ac1Txop = 96; /* AC_VO: 96*32us ~= 3ms */
1505 } else {
1506 csr0.field.Ac0Txop = 96; /* AC_VI: 96*32us ~= 3ms */
1507 csr0.field.Ac1Txop = 48; /* AC_VO: 48*32us ~= 1.5ms */
1508 }
1509 RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr0.word);
1510
1511#ifdef RTMP_MAC_PCI
1512 /* 3. Set DMA global configuration except TX_DMA_EN and RX_DMA_EN bits: */
1513 i = 0;
1514 do {
1515 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
1516 if ((GloCfg.field.TxDMABusy == 0)
1517 && (GloCfg.field.RxDMABusy == 0))
1518 break;
1519
1520 RTMPusecDelay(1000);
1521 i++;
1522 } while (i < 100);
1523
1524 GloCfg.word &= 0xff0;
1525 GloCfg.field.EnTXWriteBackDDONE = 1;
1526 RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
1527
1528 IntCfg.word = 0;
1529 RTMP_IO_WRITE32(pAd, DELAY_INT_CFG, IntCfg.word);
1530#endif /* RTMP_MAC_PCI // */
1531
1532 /* reset action */
1533 /* Load firmware */
1534 /* Status = NICLoadFirmware(pAd); */
1535
1536 DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitializeAdapter\n"));
1537 return Status;
1538}
1539
1540/*
1541 ========================================================================
1542
1543 Routine Description:
1544 Initialize ASIC
1545
1546 Arguments:
1547 Adapter Pointer to our adapter
1548
1549 Return Value:
1550 None
1551
1552 IRQL = PASSIVE_LEVEL
1553
1554 Note:
1555
1556 ========================================================================
1557*/
1558int NICInitializeAsic(struct rt_rtmp_adapter *pAd, IN BOOLEAN bHardReset)
1559{
1560 unsigned long Index = 0;
1561 u8 R0 = 0xff;
1562 u32 MacCsr12 = 0, Counter = 0;
1563#ifdef RTMP_MAC_USB
1564 u32 MacCsr0 = 0;
1565 int Status;
1566 u8 Value = 0xff;
1567#endif /* RTMP_MAC_USB // */
1568#ifdef RT30xx
1569 u8 bbpreg = 0;
1570 u8 RFValue = 0;
1571#endif /* RT30xx // */
1572 u16 KeyIdx;
1573 int i, apidx;
1574
1575 DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitializeAsic\n"));
1576
1577#ifdef RTMP_MAC_PCI
1578 RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0x3); /* To fix driver disable/enable hang issue when radio off */
1579 if (bHardReset == TRUE) {
1580 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x3);
1581 } else
1582 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x1);
1583
1584 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x0);
1585 /* Initialize MAC register to default value */
1586 for (Index = 0; Index < NUM_MAC_REG_PARMS; Index++) {
1587 RTMP_IO_WRITE32(pAd, MACRegTable[Index].Register,
1588 MACRegTable[Index].Value);
1589 }
1590
1591 {
1592 for (Index = 0; Index < NUM_STA_MAC_REG_PARMS; Index++) {
1593 RTMP_IO_WRITE32(pAd, STAMACRegTable[Index].Register,
1594 STAMACRegTable[Index].Value);
1595 }
1596 }
1597#endif /* RTMP_MAC_PCI // */
1598#ifdef RTMP_MAC_USB
1599 /* */
1600 /* Make sure MAC gets ready after NICLoadFirmware(). */
1601 /* */
1602 Index = 0;
1603
1604 /*To avoid hang-on issue when interface up in kernel 2.4, */
1605 /*we use a local variable "MacCsr0" instead of using "pAd->MACVersion" directly. */
1606 do {
1607 RTMP_IO_READ32(pAd, MAC_CSR0, &MacCsr0);
1608
1609 if ((MacCsr0 != 0x00) && (MacCsr0 != 0xFFFFFFFF))
1610 break;
1611
1612 RTMPusecDelay(10);
1613 } while (Index++ < 100);
1614
1615 pAd->MACVersion = MacCsr0;
1616 DBGPRINT(RT_DEBUG_TRACE,
1617 ("MAC_CSR0 [ Ver:Rev=0x%08x]\n", pAd->MACVersion));
1618 /* turn on bit13 (set to zero) after rt2860D. This is to solve high-current issue. */
1619 RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &MacCsr12);
1620 MacCsr12 &= (~0x2000);
1621 RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, MacCsr12);
1622
1623 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x3);
1624 RTMP_IO_WRITE32(pAd, USB_DMA_CFG, 0x0);
1625 Status = RTUSBVenderReset(pAd);
1626
1627 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x0);
1628
1629 /* Initialize MAC register to default value */
1630 for (Index = 0; Index < NUM_MAC_REG_PARMS; Index++) {
1631#ifdef RT30xx
1632 if ((MACRegTable[Index].Register == TX_SW_CFG0)
1633 && (IS_RT3070(pAd) || IS_RT3071(pAd) || IS_RT3572(pAd)
1634 || IS_RT3090(pAd) || IS_RT3390(pAd))) {
1635 MACRegTable[Index].Value = 0x00000400;
1636 }
1637#endif /* RT30xx // */
1638 RTMP_IO_WRITE32(pAd, (u16)MACRegTable[Index].Register,
1639 MACRegTable[Index].Value);
1640 }
1641
1642 {
1643 for (Index = 0; Index < NUM_STA_MAC_REG_PARMS; Index++) {
1644 RTMP_IO_WRITE32(pAd,
1645 (u16)STAMACRegTable[Index].Register,
1646 STAMACRegTable[Index].Value);
1647 }
1648 }
1649#endif /* RTMP_MAC_USB // */
1650
1651#ifdef RT30xx
1652 /* Initialize RT3070 serial MAC registers which is different from RT2870 serial */
1653 if (IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) {
1654 RTMP_IO_WRITE32(pAd, TX_SW_CFG1, 0);
1655
1656 /* RT3071 version E has fixed this issue */
1657 if ((pAd->MACVersion & 0xffff) < 0x0211) {
1658 if (pAd->NicConfig2.field.DACTestBit == 1) {
1659 RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x2C); /* To fix throughput drop drastically */
1660 } else {
1661 RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x0F); /* To fix throughput drop drastically */
1662 }
1663 } else {
1664 RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x0);
1665 }
1666 } else if (IS_RT3070(pAd)) {
1667 if (((pAd->MACVersion & 0xffff) < 0x0201)) {
1668 RTMP_IO_WRITE32(pAd, TX_SW_CFG1, 0);
1669 RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x2C); /* To fix throughput drop drastically */
1670 } else {
1671 RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0);
1672 }
1673 }
1674#endif /* RT30xx // */
1675
1676 /* */
1677 /* Before program BBP, we need to wait BBP/RF get wake up. */
1678 /* */
1679 Index = 0;
1680 do {
1681 RTMP_IO_READ32(pAd, MAC_STATUS_CFG, &MacCsr12);
1682
1683 if ((MacCsr12 & 0x03) == 0) /* if BB.RF is stable */
1684 break;
1685
1686 DBGPRINT(RT_DEBUG_TRACE,
1687 ("Check MAC_STATUS_CFG = Busy = %x\n", MacCsr12));
1688 RTMPusecDelay(1000);
1689 } while (Index++ < 100);
1690
1691 /* The commands to firmware should be after these commands, these commands will init firmware */
1692 /* PCI and USB are not the same because PCI driver needs to wait for PCI bus ready */
1693 RTMP_IO_WRITE32(pAd, H2M_BBP_AGENT, 0); /* initialize BBP R/W access agent */
1694 RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CSR, 0);
1695#ifdef RT3090
1696 /*2008/11/28:KH add to fix the dead rf frequency offset bug<-- */
1697 AsicSendCommandToMcu(pAd, 0x72, 0, 0, 0);
1698 /*2008/11/28:KH add to fix the dead rf frequency offset bug--> */
1699#endif /* RT3090 // */
1700 RTMPusecDelay(1000);
1701
1702 /* Read BBP register, make sure BBP is up and running before write new data */
1703 Index = 0;
1704 do {
1705 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R0, &R0);
1706 DBGPRINT(RT_DEBUG_TRACE, ("BBP version = %x\n", R0));
1707 } while ((++Index < 20) && ((R0 == 0xff) || (R0 == 0x00)));
1708 /*ASSERT(Index < 20); //this will cause BSOD on Check-build driver */
1709
1710 if ((R0 == 0xff) || (R0 == 0x00))
1711 return NDIS_STATUS_FAILURE;
1712
1713 /* Initialize BBP register to default value */
1714 for (Index = 0; Index < NUM_BBP_REG_PARMS; Index++) {
1715 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBPRegTable[Index].Register,
1716 BBPRegTable[Index].Value);
1717 }
1718
1719#ifdef RTMP_MAC_PCI
1720 /* TODO: shiang, check MACVersion, currently, rbus-based chip use this. */
1721 if (pAd->MACVersion == 0x28720200) {
1722 /*u8 value; */
1723 unsigned long value2;
1724
1725 /*disable MLD by Bruce 20080704 */
1726 /*BBP_IO_READ8_BY_REG_ID(pAd, BBP_R105, &value); */
1727 /*BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R105, value | 4); */
1728
1729 /*Maximum PSDU length from 16K to 32K bytes */
1730 RTMP_IO_READ32(pAd, MAX_LEN_CFG, &value2);
1731 value2 &= ~(0x3 << 12);
1732 value2 |= (0x2 << 12);
1733 RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, value2);
1734 }
1735#endif /* RTMP_MAC_PCI // */
1736
1737 /* for rt2860E and after, init BBP_R84 with 0x19. This is for extension channel overlapping IOT. */
1738 /* RT3090 should not program BBP R84 to 0x19, otherwise TX will block. */
1739 /*3070/71/72,3090,3090A( are included in RT30xx),3572,3390 */
1740 if (((pAd->MACVersion & 0xffff) != 0x0101)
1741 && !(IS_RT30xx(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)))
1742 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R84, 0x19);
1743
1744#ifdef RT30xx
1745/* add by johnli, RF power sequence setup */
1746 if (IS_RT30xx(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) { /*update for RT3070/71/72/90/91/92,3572,3390. */
1747 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R79, 0x13);
1748 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R80, 0x05);
1749 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R81, 0x33);
1750 }
1751
1752 if (IS_RT3090(pAd) || IS_RT3390(pAd)) /* RT309x, RT3071/72 */
1753 {
1754 /* enable DC filter */
1755 if ((pAd->MACVersion & 0xffff) >= 0x0211) {
1756 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R103, 0xc0);
1757 }
1758 /* improve power consumption */
1759 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R138, &bbpreg);
1760 if (pAd->Antenna.field.TxPath == 1) {
1761 /* turn off tx DAC_1 */
1762 bbpreg = (bbpreg | 0x20);
1763 }
1764
1765 if (pAd->Antenna.field.RxPath == 1) {
1766 /* turn off tx ADC_1 */
1767 bbpreg &= (~0x2);
1768 }
1769 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R138, bbpreg);
1770
1771 /* improve power consumption in RT3071 Ver.E */
1772 if ((pAd->MACVersion & 0xffff) >= 0x0211) {
1773 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R31, &bbpreg);
1774 bbpreg &= (~0x3);
1775 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R31, bbpreg);
1776 }
1777 } else if (IS_RT3070(pAd)) {
1778 if ((pAd->MACVersion & 0xffff) >= 0x0201) {
1779 /* enable DC filter */
1780 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R103, 0xc0);
1781
1782 /* improve power consumption in RT3070 Ver.F */
1783 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R31, &bbpreg);
1784 bbpreg &= (~0x3);
1785 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R31, bbpreg);
1786 }
1787 /* TX_LO1_en, RF R17 register Bit 3 to 0 */
1788 RT30xxReadRFRegister(pAd, RF_R17, &RFValue);
1789 RFValue &= (~0x08);
1790 /* to fix rx long range issue */
1791 if (pAd->NicConfig2.field.ExternalLNAForG == 0) {
1792 RFValue |= 0x20;
1793 }
1794 /* set RF_R17_bit[2:0] equal to EEPROM setting at 0x48h */
1795 if (pAd->TxMixerGain24G >= 1) {
1796 RFValue &= (~0x7); /* clean bit [2:0] */
1797 RFValue |= pAd->TxMixerGain24G;
1798 }
1799 RT30xxWriteRFRegister(pAd, RF_R17, RFValue);
1800 }
1801/* end johnli */
1802#endif /* RT30xx // */
1803
1804 if (pAd->MACVersion == 0x28600100) {
1805 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
1806 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x12);
1807 }
1808
1809 if (pAd->MACVersion >= RALINK_2880E_VERSION && pAd->MACVersion < RALINK_3070_VERSION) /* 3*3 */
1810 {
1811 /* enlarge MAX_LEN_CFG */
1812 u32 csr;
1813 RTMP_IO_READ32(pAd, MAX_LEN_CFG, &csr);
1814 csr &= 0xFFF;
1815 csr |= 0x2000;
1816 RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, csr);
1817 }
1818#ifdef RTMP_MAC_USB
1819 {
1820 u8 MAC_Value[] =
1821 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0 };
1822
1823 /*Initialize WCID table */
1824 Value = 0xff;
1825 for (Index = 0; Index < 254; Index++) {
1826 RTUSBMultiWrite(pAd,
1827 (u16)(MAC_WCID_BASE + Index * 8),
1828 MAC_Value, 8);
1829 }
1830 }
1831#endif /* RTMP_MAC_USB // */
1832
1833 /* Add radio off control */
1834 {
1835 if (pAd->StaCfg.bRadio == FALSE) {
1836/* RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0x00001818); */
1837 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
1838 DBGPRINT(RT_DEBUG_TRACE, ("Set Radio Off\n"));
1839 }
1840 }
1841
1842 /* Clear raw counters */
1843 RTMP_IO_READ32(pAd, RX_STA_CNT0, &Counter);
1844 RTMP_IO_READ32(pAd, RX_STA_CNT1, &Counter);
1845 RTMP_IO_READ32(pAd, RX_STA_CNT2, &Counter);
1846 RTMP_IO_READ32(pAd, TX_STA_CNT0, &Counter);
1847 RTMP_IO_READ32(pAd, TX_STA_CNT1, &Counter);
1848 RTMP_IO_READ32(pAd, TX_STA_CNT2, &Counter);
1849
1850 /* ASIC will keep garbage value after boot */
1851 /* Clear all shared key table when initial */
1852 /* This routine can be ignored in radio-ON/OFF operation. */
1853 if (bHardReset) {
1854 for (KeyIdx = 0; KeyIdx < 4; KeyIdx++) {
1855 RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE + 4 * KeyIdx,
1856 0);
1857 }
1858
1859 /* Clear all pairwise key table when initial */
1860 for (KeyIdx = 0; KeyIdx < 256; KeyIdx++) {
1861 RTMP_IO_WRITE32(pAd,
1862 MAC_WCID_ATTRIBUTE_BASE +
1863 (KeyIdx * HW_WCID_ATTRI_SIZE), 1);
1864 }
1865 }
1866 /* assert HOST ready bit */
1867/* RTMP_IO_WRITE32(pAd, MAC_CSR1, 0x0); // 2004-09-14 asked by Mark */
1868/* RTMP_IO_WRITE32(pAd, MAC_CSR1, 0x4); */
1869
1870 /* It isn't necessary to clear this space when not hard reset. */
1871 if (bHardReset == TRUE) {
1872 /* clear all on-chip BEACON frame space */
1873 for (apidx = 0; apidx < HW_BEACON_MAX_COUNT; apidx++) {
1874 for (i = 0; i < HW_BEACON_OFFSET >> 2; i += 4)
1875 RTMP_IO_WRITE32(pAd,
1876 pAd->BeaconOffset[apidx] + i,
1877 0x00);
1878 }
1879 }
1880#ifdef RTMP_MAC_USB
1881 AsicDisableSync(pAd);
1882 /* Clear raw counters */
1883 RTMP_IO_READ32(pAd, RX_STA_CNT0, &Counter);
1884 RTMP_IO_READ32(pAd, RX_STA_CNT1, &Counter);
1885 RTMP_IO_READ32(pAd, RX_STA_CNT2, &Counter);
1886 RTMP_IO_READ32(pAd, TX_STA_CNT0, &Counter);
1887 RTMP_IO_READ32(pAd, TX_STA_CNT1, &Counter);
1888 RTMP_IO_READ32(pAd, TX_STA_CNT2, &Counter);
1889 /* Default PCI clock cycle per ms is different as default setting, which is based on PCI. */
1890 RTMP_IO_READ32(pAd, USB_CYC_CFG, &Counter);
1891 Counter &= 0xffffff00;
1892 Counter |= 0x000001e;
1893 RTMP_IO_WRITE32(pAd, USB_CYC_CFG, Counter);
1894#endif /* RTMP_MAC_USB // */
1895
1896 {
1897 /* for rt2860E and after, init TXOP_CTRL_CFG with 0x583f. This is for extension channel overlapping IOT. */
1898 if ((pAd->MACVersion & 0xffff) != 0x0101)
1899 RTMP_IO_WRITE32(pAd, TXOP_CTRL_CFG, 0x583f);
1900 }
1901
1902 DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitializeAsic\n"));
1903 return NDIS_STATUS_SUCCESS;
1904}
1905
1906/*
1907 ========================================================================
1908
1909 Routine Description:
1910 Reset NIC Asics
1911
1912 Arguments:
1913 Adapter Pointer to our adapter
1914
1915 Return Value:
1916 None
1917
1918 IRQL = PASSIVE_LEVEL
1919
1920 Note:
1921 Reset NIC to initial state AS IS system boot up time.
1922
1923 ========================================================================
1924*/
1925void NICIssueReset(struct rt_rtmp_adapter *pAd)
1926{
1927 u32 Value = 0;
1928 DBGPRINT(RT_DEBUG_TRACE, ("--> NICIssueReset\n"));
1929
1930 /* Abort Tx, prevent ASIC from writing to Host memory */
1931 /*RTMP_IO_WRITE32(pAd, TX_CNTL_CSR, 0x001f0000); */
1932
1933 /* Disable Rx, register value supposed will remain after reset */
1934 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
1935 Value &= (0xfffffff3);
1936 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
1937
1938 /* Issue reset and clear from reset state */
1939 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x03); /* 2004-09-17 change from 0x01 */
1940 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x00);
1941
1942 DBGPRINT(RT_DEBUG_TRACE, ("<-- NICIssueReset\n"));
1943}
1944
1945/*
1946 ========================================================================
1947
1948 Routine Description:
1949 Check ASIC registers and find any reason the system might hang
1950
1951 Arguments:
1952 Adapter Pointer to our adapter
1953
1954 Return Value:
1955 None
1956
1957 IRQL = DISPATCH_LEVEL
1958
1959 ========================================================================
1960*/
1961BOOLEAN NICCheckForHang(struct rt_rtmp_adapter *pAd)
1962{
1963 return (FALSE);
1964}
1965
1966void NICUpdateFifoStaCounters(struct rt_rtmp_adapter *pAd)
1967{
1968 TX_STA_FIFO_STRUC StaFifo;
1969 struct rt_mac_table_entry *pEntry;
1970 u8 i = 0;
1971 u8 pid = 0, wcid = 0;
1972 char reTry;
1973 u8 succMCS;
1974
1975 do {
1976 RTMP_IO_READ32(pAd, TX_STA_FIFO, &StaFifo.word);
1977
1978 if (StaFifo.field.bValid == 0)
1979 break;
1980
1981 wcid = (u8)StaFifo.field.wcid;
1982
1983 /* ignore NoACK and MGMT frame use 0xFF as WCID */
1984 if ((StaFifo.field.TxAckRequired == 0)
1985 || (wcid >= MAX_LEN_OF_MAC_TABLE)) {
1986 i++;
1987 continue;
1988 }
1989
1990 /* PID store Tx MCS Rate */
1991 pid = (u8)StaFifo.field.PidType;
1992
1993 pEntry = &pAd->MacTab.Content[wcid];
1994
1995 pEntry->DebugFIFOCount++;
1996
1997 if (StaFifo.field.TxBF) /* 3*3 */
1998 pEntry->TxBFCount++;
1999
2000 if (!StaFifo.field.TxSuccess) {
2001 pEntry->FIFOCount++;
2002 pEntry->OneSecTxFailCount++;
2003
2004 if (pEntry->FIFOCount >= 1) {
2005 DBGPRINT(RT_DEBUG_TRACE, ("#"));
2006 pEntry->NoBADataCountDown = 64;
2007
2008 if (pEntry->PsMode == PWR_ACTIVE) {
2009 int tid;
2010 for (tid = 0; tid < NUM_OF_TID; tid++) {
2011 BAOriSessionTearDown(pAd,
2012 pEntry->
2013 Aid, tid,
2014 FALSE,
2015 FALSE);
2016 }
2017
2018 /* Update the continuous transmission counter except PS mode */
2019 pEntry->ContinueTxFailCnt++;
2020 } else {
2021 /* Clear the FIFOCount when sta in Power Save mode. Basically we assume */
2022 /* this tx error happened due to sta just go to sleep. */
2023 pEntry->FIFOCount = 0;
2024 pEntry->ContinueTxFailCnt = 0;
2025 }
2026 /*pEntry->FIFOCount = 0; */
2027 }
2028 /*pEntry->bSendBAR = TRUE; */
2029 } else {
2030 if ((pEntry->PsMode != PWR_SAVE)
2031 && (pEntry->NoBADataCountDown > 0)) {
2032 pEntry->NoBADataCountDown--;
2033 if (pEntry->NoBADataCountDown == 0) {
2034 DBGPRINT(RT_DEBUG_TRACE, ("@\n"));
2035 }
2036 }
2037
2038 pEntry->FIFOCount = 0;
2039 pEntry->OneSecTxNoRetryOkCount++;
2040 /* update NoDataIdleCount when successful send packet to STA. */
2041 pEntry->NoDataIdleCount = 0;
2042 pEntry->ContinueTxFailCnt = 0;
2043 }
2044
2045 succMCS = StaFifo.field.SuccessRate & 0x7F;
2046
2047 reTry = pid - succMCS;
2048
2049 if (StaFifo.field.TxSuccess) {
2050 pEntry->TXMCSExpected[pid]++;
2051 if (pid == succMCS) {
2052 pEntry->TXMCSSuccessful[pid]++;
2053 } else {
2054 pEntry->TXMCSAutoFallBack[pid][succMCS]++;
2055 }
2056 } else {
2057 pEntry->TXMCSFailed[pid]++;
2058 }
2059
2060 if (reTry > 0) {
2061 if ((pid >= 12) && succMCS <= 7) {
2062 reTry -= 4;
2063 }
2064 pEntry->OneSecTxRetryOkCount += reTry;
2065 }
2066
2067 i++;
2068 /* ASIC store 16 stack */
2069 } while (i < (2 * TX_RING_SIZE));
2070
2071}
2072
2073/*
2074 ========================================================================
2075
2076 Routine Description:
2077 Read statistical counters from hardware registers and record them
2078 in software variables for later on query
2079
2080 Arguments:
2081 pAd Pointer to our adapter
2082
2083 Return Value:
2084 None
2085
2086 IRQL = DISPATCH_LEVEL
2087
2088 ========================================================================
2089*/
2090void NICUpdateRawCounters(struct rt_rtmp_adapter *pAd)
2091{
2092 u32 OldValue; /*, Value2; */
2093 /*unsigned long PageSum, OneSecTransmitCount; */
2094 /*unsigned long TxErrorRatio, Retry, Fail; */
2095 RX_STA_CNT0_STRUC RxStaCnt0;
2096 RX_STA_CNT1_STRUC RxStaCnt1;
2097 RX_STA_CNT2_STRUC RxStaCnt2;
2098 TX_STA_CNT0_STRUC TxStaCnt0;
2099 TX_STA_CNT1_STRUC StaTx1;
2100 TX_STA_CNT2_STRUC StaTx2;
2101 TX_AGG_CNT_STRUC TxAggCnt;
2102 TX_AGG_CNT0_STRUC TxAggCnt0;
2103 TX_AGG_CNT1_STRUC TxAggCnt1;
2104 TX_AGG_CNT2_STRUC TxAggCnt2;
2105 TX_AGG_CNT3_STRUC TxAggCnt3;
2106 TX_AGG_CNT4_STRUC TxAggCnt4;
2107 TX_AGG_CNT5_STRUC TxAggCnt5;
2108 TX_AGG_CNT6_STRUC TxAggCnt6;
2109 TX_AGG_CNT7_STRUC TxAggCnt7;
2110 struct rt_counter_ralink *pRalinkCounters;
2111
2112 pRalinkCounters = &pAd->RalinkCounters;
2113
2114 RTMP_IO_READ32(pAd, RX_STA_CNT0, &RxStaCnt0.word);
2115 RTMP_IO_READ32(pAd, RX_STA_CNT2, &RxStaCnt2.word);
2116
2117 {
2118 RTMP_IO_READ32(pAd, RX_STA_CNT1, &RxStaCnt1.word);
2119 /* Update RX PLCP error counter */
2120 pAd->PrivateInfo.PhyRxErrCnt += RxStaCnt1.field.PlcpErr;
2121 /* Update False CCA counter */
2122 pAd->RalinkCounters.OneSecFalseCCACnt +=
2123 RxStaCnt1.field.FalseCca;
2124 }
2125
2126 /* Update FCS counters */
2127 OldValue = pAd->WlanCounters.FCSErrorCount.u.LowPart;
2128 pAd->WlanCounters.FCSErrorCount.u.LowPart += (RxStaCnt0.field.CrcErr); /* >> 7); */
2129 if (pAd->WlanCounters.FCSErrorCount.u.LowPart < OldValue)
2130 pAd->WlanCounters.FCSErrorCount.u.HighPart++;
2131
2132 /* Add FCS error count to private counters */
2133 pRalinkCounters->OneSecRxFcsErrCnt += RxStaCnt0.field.CrcErr;
2134 OldValue = pRalinkCounters->RealFcsErrCount.u.LowPart;
2135 pRalinkCounters->RealFcsErrCount.u.LowPart += RxStaCnt0.field.CrcErr;
2136 if (pRalinkCounters->RealFcsErrCount.u.LowPart < OldValue)
2137 pRalinkCounters->RealFcsErrCount.u.HighPart++;
2138
2139 /* Update Duplicate Rcv check */
2140 pRalinkCounters->DuplicateRcv += RxStaCnt2.field.RxDupliCount;
2141 pAd->WlanCounters.FrameDuplicateCount.u.LowPart +=
2142 RxStaCnt2.field.RxDupliCount;
2143 /* Update RX Overflow counter */
2144 pAd->Counters8023.RxNoBuffer += (RxStaCnt2.field.RxFifoOverflowCount);
2145
2146 /*pAd->RalinkCounters.RxCount = 0; */
2147#ifdef RTMP_MAC_USB
2148 if (pRalinkCounters->RxCount != pAd->watchDogRxCnt) {
2149 pAd->watchDogRxCnt = pRalinkCounters->RxCount;
2150 pAd->watchDogRxOverFlowCnt = 0;
2151 } else {
2152 if (RxStaCnt2.field.RxFifoOverflowCount)
2153 pAd->watchDogRxOverFlowCnt++;
2154 else
2155 pAd->watchDogRxOverFlowCnt = 0;
2156 }
2157#endif /* RTMP_MAC_USB // */
2158
2159 /*if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED) || */
2160 /* (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED) && (pAd->MacTab.Size != 1))) */
2161 if (!pAd->bUpdateBcnCntDone) {
2162 /* Update BEACON sent count */
2163 RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word);
2164 RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word);
2165 RTMP_IO_READ32(pAd, TX_STA_CNT2, &StaTx2.word);
2166 pRalinkCounters->OneSecBeaconSentCnt +=
2167 TxStaCnt0.field.TxBeaconCount;
2168 pRalinkCounters->OneSecTxRetryOkCount +=
2169 StaTx1.field.TxRetransmit;
2170 pRalinkCounters->OneSecTxNoRetryOkCount +=
2171 StaTx1.field.TxSuccess;
2172 pRalinkCounters->OneSecTxFailCount +=
2173 TxStaCnt0.field.TxFailCount;
2174 pAd->WlanCounters.TransmittedFragmentCount.u.LowPart +=
2175 StaTx1.field.TxSuccess;
2176 pAd->WlanCounters.RetryCount.u.LowPart +=
2177 StaTx1.field.TxRetransmit;
2178 pAd->WlanCounters.FailedCount.u.LowPart +=
2179 TxStaCnt0.field.TxFailCount;
2180 }
2181
2182 /*if (pAd->bStaFifoTest == TRUE) */
2183 {
2184 RTMP_IO_READ32(pAd, TX_AGG_CNT, &TxAggCnt.word);
2185 RTMP_IO_READ32(pAd, TX_AGG_CNT0, &TxAggCnt0.word);
2186 RTMP_IO_READ32(pAd, TX_AGG_CNT1, &TxAggCnt1.word);
2187 RTMP_IO_READ32(pAd, TX_AGG_CNT2, &TxAggCnt2.word);
2188 RTMP_IO_READ32(pAd, TX_AGG_CNT3, &TxAggCnt3.word);
2189 RTMP_IO_READ32(pAd, TX_AGG_CNT4, &TxAggCnt4.word);
2190 RTMP_IO_READ32(pAd, TX_AGG_CNT5, &TxAggCnt5.word);
2191 RTMP_IO_READ32(pAd, TX_AGG_CNT6, &TxAggCnt6.word);
2192 RTMP_IO_READ32(pAd, TX_AGG_CNT7, &TxAggCnt7.word);
2193 pRalinkCounters->TxAggCount += TxAggCnt.field.AggTxCount;
2194 pRalinkCounters->TxNonAggCount += TxAggCnt.field.NonAggTxCount;
2195 pRalinkCounters->TxAgg1MPDUCount +=
2196 TxAggCnt0.field.AggSize1Count;
2197 pRalinkCounters->TxAgg2MPDUCount +=
2198 TxAggCnt0.field.AggSize2Count;
2199
2200 pRalinkCounters->TxAgg3MPDUCount +=
2201 TxAggCnt1.field.AggSize3Count;
2202 pRalinkCounters->TxAgg4MPDUCount +=
2203 TxAggCnt1.field.AggSize4Count;
2204 pRalinkCounters->TxAgg5MPDUCount +=
2205 TxAggCnt2.field.AggSize5Count;
2206 pRalinkCounters->TxAgg6MPDUCount +=
2207 TxAggCnt2.field.AggSize6Count;
2208
2209 pRalinkCounters->TxAgg7MPDUCount +=
2210 TxAggCnt3.field.AggSize7Count;
2211 pRalinkCounters->TxAgg8MPDUCount +=
2212 TxAggCnt3.field.AggSize8Count;
2213 pRalinkCounters->TxAgg9MPDUCount +=
2214 TxAggCnt4.field.AggSize9Count;
2215 pRalinkCounters->TxAgg10MPDUCount +=
2216 TxAggCnt4.field.AggSize10Count;
2217
2218 pRalinkCounters->TxAgg11MPDUCount +=
2219 TxAggCnt5.field.AggSize11Count;
2220 pRalinkCounters->TxAgg12MPDUCount +=
2221 TxAggCnt5.field.AggSize12Count;
2222 pRalinkCounters->TxAgg13MPDUCount +=
2223 TxAggCnt6.field.AggSize13Count;
2224 pRalinkCounters->TxAgg14MPDUCount +=
2225 TxAggCnt6.field.AggSize14Count;
2226
2227 pRalinkCounters->TxAgg15MPDUCount +=
2228 TxAggCnt7.field.AggSize15Count;
2229 pRalinkCounters->TxAgg16MPDUCount +=
2230 TxAggCnt7.field.AggSize16Count;
2231
2232 /* Calculate the transmitted A-MPDU count */
2233 pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
2234 TxAggCnt0.field.AggSize1Count;
2235 pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
2236 (TxAggCnt0.field.AggSize2Count / 2);
2237
2238 pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
2239 (TxAggCnt1.field.AggSize3Count / 3);
2240 pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
2241 (TxAggCnt1.field.AggSize4Count / 4);
2242
2243 pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
2244 (TxAggCnt2.field.AggSize5Count / 5);
2245 pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
2246 (TxAggCnt2.field.AggSize6Count / 6);
2247
2248 pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
2249 (TxAggCnt3.field.AggSize7Count / 7);
2250 pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
2251 (TxAggCnt3.field.AggSize8Count / 8);
2252
2253 pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
2254 (TxAggCnt4.field.AggSize9Count / 9);
2255 pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
2256 (TxAggCnt4.field.AggSize10Count / 10);
2257
2258 pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
2259 (TxAggCnt5.field.AggSize11Count / 11);
2260 pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
2261 (TxAggCnt5.field.AggSize12Count / 12);
2262
2263 pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
2264 (TxAggCnt6.field.AggSize13Count / 13);
2265 pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
2266 (TxAggCnt6.field.AggSize14Count / 14);
2267
2268 pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
2269 (TxAggCnt7.field.AggSize15Count / 15);
2270 pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
2271 (TxAggCnt7.field.AggSize16Count / 16);
2272 }
2273
2274}
2275
2276/*
2277 ========================================================================
2278
2279 Routine Description:
2280 Reset NIC from error
2281
2282 Arguments:
2283 Adapter Pointer to our adapter
2284
2285 Return Value:
2286 None
2287
2288 IRQL = PASSIVE_LEVEL
2289
2290 Note:
2291 Reset NIC from error state
2292
2293 ========================================================================
2294*/
2295void NICResetFromError(struct rt_rtmp_adapter *pAd)
2296{
2297 /* Reset BBP (according to alex, reset ASIC will force reset BBP */
2298 /* Therefore, skip the reset BBP */
2299 /* RTMP_IO_WRITE32(pAd, MAC_CSR1, 0x2); */
2300
2301 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x1);
2302 /* Remove ASIC from reset state */
2303 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x0);
2304
2305 NICInitializeAdapter(pAd, FALSE);
2306 NICInitAsicFromEEPROM(pAd);
2307
2308 /* Switch to current channel, since during reset process, the connection should remains on. */
2309 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
2310 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
2311}
2312
2313int NICLoadFirmware(struct rt_rtmp_adapter *pAd)
2314{
2315 int status = NDIS_STATUS_SUCCESS;
2316 if (pAd->chipOps.loadFirmware)
2317 status = pAd->chipOps.loadFirmware(pAd);
2318
2319 return status;
2320}
2321
2322/*
2323 ========================================================================
2324
2325 Routine Description:
2326 erase 8051 firmware image in MAC ASIC
2327
2328 Arguments:
2329 Adapter Pointer to our adapter
2330
2331 IRQL = PASSIVE_LEVEL
2332
2333 ========================================================================
2334*/
2335void NICEraseFirmware(struct rt_rtmp_adapter *pAd)
2336{
2337 if (pAd->chipOps.eraseFirmware)
2338 pAd->chipOps.eraseFirmware(pAd);
2339
2340} /* End of NICEraseFirmware */
2341
2342/*
2343 ========================================================================
2344
2345 Routine Description:
2346 Load Tx rate switching parameters
2347
2348 Arguments:
2349 Adapter Pointer to our adapter
2350
2351 Return Value:
2352 NDIS_STATUS_SUCCESS firmware image load ok
2353 NDIS_STATUS_FAILURE image not found
2354
2355 IRQL = PASSIVE_LEVEL
2356
2357 Rate Table Format:
2358 1. (B0: Valid Item number) (B1:Initial item from zero)
2359 2. Item Number(Dec) Mode(Hex) Current MCS(Dec) TrainUp(Dec) TrainDown(Dec)
2360
2361 ========================================================================
2362*/
2363int NICLoadRateSwitchingParams(struct rt_rtmp_adapter *pAd)
2364{
2365 return NDIS_STATUS_SUCCESS;
2366}
2367
2368/*
2369 ========================================================================
2370
2371 Routine Description:
2372 Compare two memory block
2373
2374 Arguments:
2375 pSrc1 Pointer to first memory address
2376 pSrc2 Pointer to second memory address
2377
2378 Return Value:
2379 0: memory is equal
2380 1: pSrc1 memory is larger
2381 2: pSrc2 memory is larger
2382
2383 IRQL = DISPATCH_LEVEL
2384
2385 Note:
2386
2387 ========================================================================
2388*/
2389unsigned long RTMPCompareMemory(void *pSrc1, void *pSrc2, unsigned long Length)
2390{
2391 u8 *pMem1;
2392 u8 *pMem2;
2393 unsigned long Index = 0;
2394
2395 pMem1 = (u8 *)pSrc1;
2396 pMem2 = (u8 *)pSrc2;
2397
2398 for (Index = 0; Index < Length; Index++) {
2399 if (pMem1[Index] > pMem2[Index])
2400 return (1);
2401 else if (pMem1[Index] < pMem2[Index])
2402 return (2);
2403 }
2404
2405 /* Equal */
2406 return (0);
2407}
2408
2409/*
2410 ========================================================================
2411
2412 Routine Description:
2413 Zero out memory block
2414
2415 Arguments:
2416 pSrc1 Pointer to memory address
2417 Length Size
2418
2419 Return Value:
2420 None
2421
2422 IRQL = PASSIVE_LEVEL
2423 IRQL = DISPATCH_LEVEL
2424
2425 Note:
2426
2427 ========================================================================
2428*/
2429void RTMPZeroMemory(void *pSrc, unsigned long Length)
2430{
2431 u8 *pMem;
2432 unsigned long Index = 0;
2433
2434 pMem = (u8 *)pSrc;
2435
2436 for (Index = 0; Index < Length; Index++) {
2437 pMem[Index] = 0x00;
2438 }
2439}
2440
2441/*
2442 ========================================================================
2443
2444 Routine Description:
2445 Copy data from memory block 1 to memory block 2
2446
2447 Arguments:
2448 pDest Pointer to destination memory address
2449 pSrc Pointer to source memory address
2450 Length Copy size
2451
2452 Return Value:
2453 None
2454
2455 IRQL = PASSIVE_LEVEL
2456 IRQL = DISPATCH_LEVEL
2457
2458 Note:
2459
2460 ========================================================================
2461*/
2462void RTMPMoveMemory(void *pDest, void *pSrc, unsigned long Length)
2463{
2464 u8 *pMem1;
2465 u8 *pMem2;
2466 u32 Index;
2467
2468 ASSERT((Length == 0) || (pDest && pSrc));
2469
2470 pMem1 = (u8 *)pDest;
2471 pMem2 = (u8 *)pSrc;
2472
2473 for (Index = 0; Index < Length; Index++) {
2474 pMem1[Index] = pMem2[Index];
2475 }
2476}
2477
2478/*
2479 ========================================================================
2480
2481 Routine Description:
2482 Initialize port configuration structure
2483
2484 Arguments:
2485 Adapter Pointer to our adapter
2486
2487 Return Value:
2488 None
2489
2490 IRQL = PASSIVE_LEVEL
2491
2492 Note:
2493
2494 ========================================================================
2495*/
2496void UserCfgInit(struct rt_rtmp_adapter *pAd)
2497{
2498 u32 key_index, bss_index;
2499
2500 DBGPRINT(RT_DEBUG_TRACE, ("--> UserCfgInit\n"));
2501
2502 /* */
2503 /* part I. initialize common configuration */
2504 /* */
2505#ifdef RTMP_MAC_USB
2506 pAd->BulkOutReq = 0;
2507
2508 pAd->BulkOutComplete = 0;
2509 pAd->BulkOutCompleteOther = 0;
2510 pAd->BulkOutCompleteCancel = 0;
2511 pAd->BulkInReq = 0;
2512 pAd->BulkInComplete = 0;
2513 pAd->BulkInCompleteFail = 0;
2514
2515 /*pAd->QuickTimerP = 100; */
2516 /*pAd->TurnAggrBulkInCount = 0; */
2517 pAd->bUsbTxBulkAggre = 0;
2518
2519 /* init as unused value to ensure driver will set to MCU once. */
2520 pAd->LedIndicatorStrength = 0xFF;
2521
2522 pAd->CommonCfg.MaxPktOneTxBulk = 2;
2523 pAd->CommonCfg.TxBulkFactor = 1;
2524 pAd->CommonCfg.RxBulkFactor = 1;
2525
2526 pAd->CommonCfg.TxPower = 100; /*mW */
2527
2528 NdisZeroMemory(&pAd->CommonCfg.IOTestParm,
2529 sizeof(pAd->CommonCfg.IOTestParm));
2530#endif /* RTMP_MAC_USB // */
2531
2532 for (key_index = 0; key_index < SHARE_KEY_NUM; key_index++) {
2533 for (bss_index = 0; bss_index < MAX_MBSSID_NUM; bss_index++) {
2534 pAd->SharedKey[bss_index][key_index].KeyLen = 0;
2535 pAd->SharedKey[bss_index][key_index].CipherAlg =
2536 CIPHER_NONE;
2537 }
2538 }
2539
2540 pAd->EepromAccess = FALSE;
2541
2542 pAd->Antenna.word = 0;
2543 pAd->CommonCfg.BBPCurrentBW = BW_20;
2544
2545 pAd->LedCntl.word = 0;
2546#ifdef RTMP_MAC_PCI
2547 pAd->LedIndicatorStrength = 0;
2548 pAd->RLnkCtrlOffset = 0;
2549 pAd->HostLnkCtrlOffset = 0;
2550 pAd->StaCfg.PSControl.field.EnableNewPS = TRUE;
2551 pAd->CheckDmaBusyCount = 0;
2552#endif /* RTMP_MAC_PCI // */
2553
2554 pAd->bAutoTxAgcA = FALSE; /* Default is OFF */
2555 pAd->bAutoTxAgcG = FALSE; /* Default is OFF */
2556 pAd->RfIcType = RFIC_2820;
2557
2558 /* Init timer for reset complete event */
2559 pAd->CommonCfg.CentralChannel = 1;
2560 pAd->bForcePrintTX = FALSE;
2561 pAd->bForcePrintRX = FALSE;
2562 pAd->bStaFifoTest = FALSE;
2563 pAd->bProtectionTest = FALSE;
2564 pAd->CommonCfg.Dsifs = 10; /* in units of usec */
2565 pAd->CommonCfg.TxPower = 100; /*mW */
2566 pAd->CommonCfg.TxPowerPercentage = 0xffffffff; /* AUTO */
2567 pAd->CommonCfg.TxPowerDefault = 0xffffffff; /* AUTO */
2568 pAd->CommonCfg.TxPreamble = Rt802_11PreambleAuto; /* use Long preamble on TX by defaut */
2569 pAd->CommonCfg.bUseZeroToDisableFragment = FALSE;
2570 pAd->CommonCfg.RtsThreshold = 2347;
2571 pAd->CommonCfg.FragmentThreshold = 2346;
2572 pAd->CommonCfg.UseBGProtection = 0; /* 0: AUTO */
2573 pAd->CommonCfg.bEnableTxBurst = TRUE; /*0; */
2574 pAd->CommonCfg.PhyMode = 0xff; /* unknown */
2575 pAd->CommonCfg.BandState = UNKNOWN_BAND;
2576 pAd->CommonCfg.RadarDetect.CSPeriod = 10;
2577 pAd->CommonCfg.RadarDetect.CSCount = 0;
2578 pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE;
2579
2580 pAd->CommonCfg.RadarDetect.ChMovingTime = 65;
2581 pAd->CommonCfg.RadarDetect.LongPulseRadarTh = 3;
2582 pAd->CommonCfg.bAPSDCapable = FALSE;
2583 pAd->CommonCfg.bNeedSendTriggerFrame = FALSE;
2584 pAd->CommonCfg.TriggerTimerCount = 0;
2585 pAd->CommonCfg.bAPSDForcePowerSave = FALSE;
2586 pAd->CommonCfg.bCountryFlag = FALSE;
2587 pAd->CommonCfg.TxStream = 0;
2588 pAd->CommonCfg.RxStream = 0;
2589
2590 NdisZeroMemory(&pAd->BeaconTxWI, sizeof(pAd->BeaconTxWI));
2591
2592 NdisZeroMemory(&pAd->CommonCfg.HtCapability,
2593 sizeof(pAd->CommonCfg.HtCapability));
2594 pAd->HTCEnable = FALSE;
2595 pAd->bBroadComHT = FALSE;
2596 pAd->CommonCfg.bRdg = FALSE;
2597
2598 NdisZeroMemory(&pAd->CommonCfg.AddHTInfo,
2599 sizeof(pAd->CommonCfg.AddHTInfo));
2600 pAd->CommonCfg.BACapability.field.MMPSmode = MMPS_ENABLE;
2601 pAd->CommonCfg.BACapability.field.MpduDensity = 0;
2602 pAd->CommonCfg.BACapability.field.Policy = IMMED_BA;
2603 pAd->CommonCfg.BACapability.field.RxBAWinLimit = 64; /*32; */
2604 pAd->CommonCfg.BACapability.field.TxBAWinLimit = 64; /*32; */
2605 DBGPRINT(RT_DEBUG_TRACE,
2606 ("--> UserCfgInit. BACapability = 0x%x\n",
2607 pAd->CommonCfg.BACapability.word));
2608
2609 pAd->CommonCfg.BACapability.field.AutoBA = FALSE;
2610 BATableInit(pAd, &pAd->BATable);
2611
2612 pAd->CommonCfg.bExtChannelSwitchAnnouncement = 1;
2613 pAd->CommonCfg.bHTProtect = 1;
2614 pAd->CommonCfg.bMIMOPSEnable = TRUE;
2615 /*2008/11/05:KH add to support Antenna power-saving of AP<-- */
2616 pAd->CommonCfg.bGreenAPEnable = FALSE;
2617 /*2008/11/05:KH add to support Antenna power-saving of AP--> */
2618 pAd->CommonCfg.bBADecline = FALSE;
2619 pAd->CommonCfg.bDisableReordering = FALSE;
2620
2621 if (pAd->MACVersion == 0x28720200) {
2622 pAd->CommonCfg.TxBASize = 13; /*by Jerry recommend */
2623 } else {
2624 pAd->CommonCfg.TxBASize = 7;
2625 }
2626
2627 pAd->CommonCfg.REGBACapability.word = pAd->CommonCfg.BACapability.word;
2628
2629 /*pAd->CommonCfg.HTPhyMode.field.BW = BW_20; */
2630 /*pAd->CommonCfg.HTPhyMode.field.MCS = MCS_AUTO; */
2631 /*pAd->CommonCfg.HTPhyMode.field.ShortGI = GI_800; */
2632 /*pAd->CommonCfg.HTPhyMode.field.STBC = STBC_NONE; */
2633 pAd->CommonCfg.TxRate = RATE_6;
2634
2635 pAd->CommonCfg.MlmeTransmit.field.MCS = MCS_RATE_6;
2636 pAd->CommonCfg.MlmeTransmit.field.BW = BW_20;
2637 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
2638
2639 pAd->CommonCfg.BeaconPeriod = 100; /* in mSec */
2640
2641 /* */
2642 /* part II. initialize STA specific configuration */
2643 /* */
2644 {
2645 RX_FILTER_SET_FLAG(pAd, fRX_FILTER_ACCEPT_DIRECT);
2646 RX_FILTER_CLEAR_FLAG(pAd, fRX_FILTER_ACCEPT_MULTICAST);
2647 RX_FILTER_SET_FLAG(pAd, fRX_FILTER_ACCEPT_BROADCAST);
2648 RX_FILTER_SET_FLAG(pAd, fRX_FILTER_ACCEPT_ALL_MULTICAST);
2649
2650 pAd->StaCfg.Psm = PWR_ACTIVE;
2651
2652 pAd->StaCfg.OrigWepStatus = Ndis802_11EncryptionDisabled;
2653 pAd->StaCfg.PairCipher = Ndis802_11EncryptionDisabled;
2654 pAd->StaCfg.GroupCipher = Ndis802_11EncryptionDisabled;
2655 pAd->StaCfg.bMixCipher = FALSE;
2656 pAd->StaCfg.DefaultKeyId = 0;
2657
2658 /* 802.1x port control */
2659 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
2660 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
2661 pAd->StaCfg.LastMicErrorTime = 0;
2662 pAd->StaCfg.MicErrCnt = 0;
2663 pAd->StaCfg.bBlockAssoc = FALSE;
2664 pAd->StaCfg.WpaState = SS_NOTUSE;
2665
2666 pAd->CommonCfg.NdisRadioStateOff = FALSE; /* New to support microsoft disable radio with OID command */
2667
2668 pAd->StaCfg.RssiTrigger = 0;
2669 NdisZeroMemory(&pAd->StaCfg.RssiSample, sizeof(struct rt_rssi_sample));
2670 pAd->StaCfg.RssiTriggerMode =
2671 RSSI_TRIGGERED_UPON_BELOW_THRESHOLD;
2672 pAd->StaCfg.AtimWin = 0;
2673 pAd->StaCfg.DefaultListenCount = 3; /*default listen count; */
2674 pAd->StaCfg.BssType = BSS_INFRA; /* BSS_INFRA or BSS_ADHOC or BSS_MONITOR */
2675 pAd->StaCfg.bScanReqIsFromWebUI = FALSE;
2676 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
2677 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_WAKEUP_NOW);
2678
2679 pAd->StaCfg.bAutoTxRateSwitch = TRUE;
2680 pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
2681 }
2682
2683#ifdef PCIE_PS_SUPPORT
2684 pAd->brt30xxBanMcuCmd = FALSE;
2685 pAd->b3090ESpecialChip = FALSE;
2686/*KH Debug:the following must be removed */
2687 pAd->StaCfg.PSControl.field.rt30xxPowerMode = 3;
2688 pAd->StaCfg.PSControl.field.rt30xxForceASPMTest = 0;
2689 pAd->StaCfg.PSControl.field.rt30xxFollowHostASPM = 1;
2690#endif /* PCIE_PS_SUPPORT // */
2691
2692 /* global variables mXXXX used in MAC protocol state machines */
2693 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
2694 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
2695 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
2696
2697 /* PHY specification */
2698 pAd->CommonCfg.PhyMode = PHY_11BG_MIXED; /* default PHY mode */
2699 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED); /* CCK use long preamble */
2700
2701 {
2702 /* user desired power mode */
2703 pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeCAM;
2704 pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeCAM;
2705 pAd->StaCfg.bWindowsACCAMEnable = FALSE;
2706
2707 RTMPInitTimer(pAd, &pAd->StaCfg.StaQuickResponeForRateUpTimer,
2708 GET_TIMER_FUNCTION(StaQuickResponeForRateUpExec),
2709 pAd, FALSE);
2710 pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = FALSE;
2711
2712 /* Patch for Ndtest */
2713 pAd->StaCfg.ScanCnt = 0;
2714
2715 pAd->StaCfg.bHwRadio = TRUE; /* Default Hardware Radio status is On */
2716 pAd->StaCfg.bSwRadio = TRUE; /* Default Software Radio status is On */
2717 pAd->StaCfg.bRadio = TRUE; /* bHwRadio && bSwRadio */
2718 pAd->StaCfg.bHardwareRadio = FALSE; /* Default is OFF */
2719 pAd->StaCfg.bShowHiddenSSID = FALSE; /* Default no show */
2720
2721 /* Nitro mode control */
2722 pAd->StaCfg.bAutoReconnect = TRUE;
2723
2724 /* Save the init time as last scan time, the system should do scan after 2 seconds. */
2725 /* This patch is for driver wake up from standby mode, system will do scan right away. */
2726 NdisGetSystemUpTime(&pAd->StaCfg.LastScanTime);
2727 if (pAd->StaCfg.LastScanTime > 10 * OS_HZ)
2728 pAd->StaCfg.LastScanTime -= (10 * OS_HZ);
2729
2730 NdisZeroMemory(pAd->nickname, IW_ESSID_MAX_SIZE + 1);
2731#ifdef RTMP_MAC_PCI
2732 sprintf((char *)pAd->nickname, "RT2860STA");
2733#endif /* RTMP_MAC_PCI // */
2734#ifdef RTMP_MAC_USB
2735 sprintf((char *)pAd->nickname, "RT2870STA");
2736#endif /* RTMP_MAC_USB // */
2737 RTMPInitTimer(pAd, &pAd->StaCfg.WpaDisassocAndBlockAssocTimer,
2738 GET_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc),
2739 pAd, FALSE);
2740 pAd->StaCfg.IEEE8021X = FALSE;
2741 pAd->StaCfg.IEEE8021x_required_keys = FALSE;
2742 pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_DISABLE;
2743 pAd->StaCfg.bRSN_IE_FromWpaSupplicant = FALSE;
2744 pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_ENABLE;
2745
2746 NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8);
2747
2748 pAd->StaCfg.bAutoConnectByBssid = FALSE;
2749 pAd->StaCfg.BeaconLostTime = BEACON_LOST_TIME;
2750 NdisZeroMemory(pAd->StaCfg.WpaPassPhrase, 64);
2751 pAd->StaCfg.WpaPassPhraseLen = 0;
2752 pAd->StaCfg.bAutoRoaming = FALSE;
2753 pAd->StaCfg.bForceTxBurst = FALSE;
2754 }
2755
2756 /* Default for extra information is not valid */
2757 pAd->ExtraInfo = EXTRA_INFO_CLEAR;
2758
2759 /* Default Config change flag */
2760 pAd->bConfigChanged = FALSE;
2761
2762 /* */
2763 /* part III. AP configurations */
2764 /* */
2765
2766 /* */
2767 /* part IV. others */
2768 /* */
2769 /* dynamic BBP R66:sensibity tuning to overcome background noise */
2770 pAd->BbpTuning.bEnable = TRUE;
2771 pAd->BbpTuning.FalseCcaLowerThreshold = 100;
2772 pAd->BbpTuning.FalseCcaUpperThreshold = 512;
2773 pAd->BbpTuning.R66Delta = 4;
2774 pAd->Mlme.bEnableAutoAntennaCheck = TRUE;
2775
2776 /* */
2777 /* Also initial R66CurrentValue, RTUSBResumeMsduTransmission might use this value. */
2778 /* if not initial this value, the default value will be 0. */
2779 /* */
2780 pAd->BbpTuning.R66CurrentValue = 0x38;
2781
2782 pAd->Bbp94 = BBPR94_DEFAULT;
2783 pAd->BbpForCCK = FALSE;
2784
2785 /* Default is FALSE for test bit 1 */
2786 /*pAd->bTest1 = FALSE; */
2787
2788 /* initialize MAC table and allocate spin lock */
2789 NdisZeroMemory(&pAd->MacTab, sizeof(struct rt_mac_table));
2790 InitializeQueueHeader(&pAd->MacTab.McastPsQueue);
2791 NdisAllocateSpinLock(&pAd->MacTabLock);
2792
2793 /*RTMPInitTimer(pAd, &pAd->RECBATimer, RECBATimerTimeout, pAd, TRUE); */
2794 /*RTMPSetTimer(&pAd->RECBATimer, REORDER_EXEC_INTV); */
2795
2796 pAd->CommonCfg.bWiFiTest = FALSE;
2797#ifdef RTMP_MAC_PCI
2798 pAd->bPCIclkOff = FALSE;
2799#endif /* RTMP_MAC_PCI // */
2800
2801 RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
2802 DBGPRINT(RT_DEBUG_TRACE, ("<-- UserCfgInit\n"));
2803}
2804
2805/* IRQL = PASSIVE_LEVEL */
2806/* */
2807/* FUNCTION: AtoH(char *, u8 *, int) */
2808/* */
2809/* PURPOSE: Converts ascii string to network order hex */
2810/* */
2811/* PARAMETERS: */
2812/* src - pointer to input ascii string */
2813/* dest - pointer to output hex */
2814/* destlen - size of dest */
2815/* */
2816/* COMMENTS: */
2817/* */
2818/* 2 ascii bytes make a hex byte so must put 1st ascii byte of pair */
2819/* into upper nibble and 2nd ascii byte of pair into lower nibble. */
2820/* */
2821/* IRQL = PASSIVE_LEVEL */
2822
2823void AtoH(char *src, u8 *dest, int destlen)
2824{
2825 char *srcptr;
2826 u8 *destTemp;
2827
2828 srcptr = src;
2829 destTemp = (u8 *)dest;
2830
2831 while (destlen--) {
2832 *destTemp = hex_to_bin(*srcptr++) << 4; /* Put 1st ascii byte in upper nibble. */
2833 *destTemp += hex_to_bin(*srcptr++); /* Add 2nd ascii byte to above. */
2834 destTemp++;
2835 }
2836}
2837
2838/*+++Mark by shiang, not use now, need to remove after confirm */
2839/*---Mark by shiang, not use now, need to remove after confirm */
2840
2841/*
2842 ========================================================================
2843
2844 Routine Description:
2845 Init timer objects
2846
2847 Arguments:
2848 pAd Pointer to our adapter
2849 pTimer Timer structure
2850 pTimerFunc Function to execute when timer expired
2851 Repeat Ture for period timer
2852
2853 Return Value:
2854 None
2855
2856 Note:
2857
2858 ========================================================================
2859*/
2860void RTMPInitTimer(struct rt_rtmp_adapter *pAd,
2861 struct rt_ralink_timer *pTimer,
2862 void *pTimerFunc, void *pData, IN BOOLEAN Repeat)
2863{
2864 /* */
2865 /* Set Valid to TRUE for later used. */
2866 /* It will crash if we cancel a timer or set a timer */
2867 /* that we haven't initialize before. */
2868 /* */
2869 pTimer->Valid = TRUE;
2870
2871 pTimer->PeriodicType = Repeat;
2872 pTimer->State = FALSE;
2873 pTimer->cookie = (unsigned long)pData;
2874
2875#ifdef RTMP_TIMER_TASK_SUPPORT
2876 pTimer->pAd = pAd;
2877#endif /* RTMP_TIMER_TASK_SUPPORT // */
2878
2879 RTMP_OS_Init_Timer(pAd, &pTimer->TimerObj, pTimerFunc, (void *)pTimer);
2880}
2881
2882/*
2883 ========================================================================
2884
2885 Routine Description:
2886 Init timer objects
2887
2888 Arguments:
2889 pTimer Timer structure
2890 Value Timer value in milliseconds
2891
2892 Return Value:
2893 None
2894
2895 Note:
2896 To use this routine, must call RTMPInitTimer before.
2897
2898 ========================================================================
2899*/
2900void RTMPSetTimer(struct rt_ralink_timer *pTimer, unsigned long Value)
2901{
2902 if (pTimer->Valid) {
2903 pTimer->TimerValue = Value;
2904 pTimer->State = FALSE;
2905 if (pTimer->PeriodicType == TRUE) {
2906 pTimer->Repeat = TRUE;
2907 RTMP_SetPeriodicTimer(&pTimer->TimerObj, Value);
2908 } else {
2909 pTimer->Repeat = FALSE;
2910 RTMP_OS_Add_Timer(&pTimer->TimerObj, Value);
2911 }
2912 } else {
2913 DBGPRINT_ERR("RTMPSetTimer failed, Timer hasn't been initialize!\n");
2914 }
2915}
2916
2917/*
2918 ========================================================================
2919
2920 Routine Description:
2921 Init timer objects
2922
2923 Arguments:
2924 pTimer Timer structure
2925 Value Timer value in milliseconds
2926
2927 Return Value:
2928 None
2929
2930 Note:
2931 To use this routine, must call RTMPInitTimer before.
2932
2933 ========================================================================
2934*/
2935void RTMPModTimer(struct rt_ralink_timer *pTimer, unsigned long Value)
2936{
2937 BOOLEAN Cancel;
2938
2939 if (pTimer->Valid) {
2940 pTimer->TimerValue = Value;
2941 pTimer->State = FALSE;
2942 if (pTimer->PeriodicType == TRUE) {
2943 RTMPCancelTimer(pTimer, &Cancel);
2944 RTMPSetTimer(pTimer, Value);
2945 } else {
2946 RTMP_OS_Mod_Timer(&pTimer->TimerObj, Value);
2947 }
2948 } else {
2949 DBGPRINT_ERR("RTMPModTimer failed, Timer hasn't been initialize!\n");
2950 }
2951}
2952
2953/*
2954 ========================================================================
2955
2956 Routine Description:
2957 Cancel timer objects
2958
2959 Arguments:
2960 Adapter Pointer to our adapter
2961
2962 Return Value:
2963 None
2964
2965 IRQL = PASSIVE_LEVEL
2966 IRQL = DISPATCH_LEVEL
2967
2968 Note:
2969 1.) To use this routine, must call RTMPInitTimer before.
2970 2.) Reset NIC to initial state AS IS system boot up time.
2971
2972 ========================================================================
2973*/
2974void RTMPCancelTimer(struct rt_ralink_timer *pTimer, OUT BOOLEAN * pCancelled)
2975{
2976 if (pTimer->Valid) {
2977 if (pTimer->State == FALSE)
2978 pTimer->Repeat = FALSE;
2979
2980 RTMP_OS_Del_Timer(&pTimer->TimerObj, pCancelled);
2981
2982 if (*pCancelled == TRUE)
2983 pTimer->State = TRUE;
2984
2985#ifdef RTMP_TIMER_TASK_SUPPORT
2986 /* We need to go-through the TimerQ to findout this timer handler and remove it if */
2987 /* it's still waiting for execution. */
2988 RtmpTimerQRemove(pTimer->pAd, pTimer);
2989#endif /* RTMP_TIMER_TASK_SUPPORT // */
2990 } else {
2991 DBGPRINT_ERR("RTMPCancelTimer failed, Timer hasn't been initialize!\n");
2992 }
2993}
2994
2995/*
2996 ========================================================================
2997
2998 Routine Description:
2999 Set LED Status
3000
3001 Arguments:
3002 pAd Pointer to our adapter
3003 Status LED Status
3004
3005 Return Value:
3006 None
3007
3008 IRQL = PASSIVE_LEVEL
3009 IRQL = DISPATCH_LEVEL
3010
3011 Note:
3012
3013 ========================================================================
3014*/
3015void RTMPSetLED(struct rt_rtmp_adapter *pAd, u8 Status)
3016{
3017 /*unsigned long data; */
3018 u8 HighByte = 0;
3019 u8 LowByte;
3020
3021 LowByte = pAd->LedCntl.field.LedMode & 0x7f;
3022 switch (Status) {
3023 case LED_LINK_DOWN:
3024 HighByte = 0x20;
3025 AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
3026 pAd->LedIndicatorStrength = 0;
3027 break;
3028 case LED_LINK_UP:
3029 if (pAd->CommonCfg.Channel > 14)
3030 HighByte = 0xa0;
3031 else
3032 HighByte = 0x60;
3033 AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
3034 break;
3035 case LED_RADIO_ON:
3036 HighByte = 0x20;
3037 AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
3038 break;
3039 case LED_HALT:
3040 LowByte = 0; /* Driver sets MAC register and MAC controls LED */
3041 case LED_RADIO_OFF:
3042 HighByte = 0;
3043 AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
3044 break;
3045 case LED_WPS:
3046 HighByte = 0x10;
3047 AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
3048 break;
3049 case LED_ON_SITE_SURVEY:
3050 HighByte = 0x08;
3051 AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
3052 break;
3053 case LED_POWER_UP:
3054 HighByte = 0x04;
3055 AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
3056 break;
3057 default:
3058 DBGPRINT(RT_DEBUG_WARN,
3059 ("RTMPSetLED::Unknown Status %d\n", Status));
3060 break;
3061 }
3062
3063 /* */
3064 /* Keep LED status for LED SiteSurvey mode. */
3065 /* After SiteSurvey, we will set the LED mode to previous status. */
3066 /* */
3067 if ((Status != LED_ON_SITE_SURVEY) && (Status != LED_POWER_UP))
3068 pAd->LedStatus = Status;
3069
3070 DBGPRINT(RT_DEBUG_TRACE,
3071 ("RTMPSetLED::Mode=%d,HighByte=0x%02x,LowByte=0x%02x\n",
3072 pAd->LedCntl.field.LedMode, HighByte, LowByte));
3073}
3074
3075/*
3076 ========================================================================
3077
3078 Routine Description:
3079 Set LED Signal Strength
3080
3081 Arguments:
3082 pAd Pointer to our adapter
3083 Dbm Signal Strength
3084
3085 Return Value:
3086 None
3087
3088 IRQL = PASSIVE_LEVEL
3089
3090 Note:
3091 Can be run on any IRQL level.
3092
3093 According to Microsoft Zero Config Wireless Signal Strength definition as belows.
3094 <= -90 No Signal
3095 <= -81 Very Low
3096 <= -71 Low
3097 <= -67 Good
3098 <= -57 Very Good
3099 > -57 Excellent
3100 ========================================================================
3101*/
3102void RTMPSetSignalLED(struct rt_rtmp_adapter *pAd, IN NDIS_802_11_RSSI Dbm)
3103{
3104 u8 nLed = 0;
3105
3106 if (pAd->LedCntl.field.LedMode == LED_MODE_SIGNAL_STREGTH) {
3107 if (Dbm <= -90)
3108 nLed = 0;
3109 else if (Dbm <= -81)
3110 nLed = 1;
3111 else if (Dbm <= -71)
3112 nLed = 3;
3113 else if (Dbm <= -67)
3114 nLed = 7;
3115 else if (Dbm <= -57)
3116 nLed = 15;
3117 else
3118 nLed = 31;
3119
3120 /* */
3121 /* Update Signal Strength to firmware if changed. */
3122 /* */
3123 if (pAd->LedIndicatorStrength != nLed) {
3124 AsicSendCommandToMcu(pAd, 0x51, 0xff, nLed,
3125 pAd->LedCntl.field.Polarity);
3126 pAd->LedIndicatorStrength = nLed;
3127 }
3128 }
3129}
3130
3131/*
3132 ========================================================================
3133
3134 Routine Description:
3135 Enable RX
3136
3137 Arguments:
3138 pAd Pointer to our adapter
3139
3140 Return Value:
3141 None
3142
3143 IRQL <= DISPATCH_LEVEL
3144
3145 Note:
3146 Before Enable RX, make sure you have enabled Interrupt.
3147 ========================================================================
3148*/
3149void RTMPEnableRxTx(struct rt_rtmp_adapter *pAd)
3150{
3151/* WPDMA_GLO_CFG_STRUC GloCfg; */
3152/* unsigned long i = 0; */
3153 u32 rx_filter_flag;
3154
3155 DBGPRINT(RT_DEBUG_TRACE, ("==> RTMPEnableRxTx\n"));
3156
3157 /* Enable Rx DMA. */
3158 RT28XXDMAEnable(pAd);
3159
3160 /* enable RX of MAC block */
3161 if (pAd->OpMode == OPMODE_AP) {
3162 rx_filter_flag = APNORMAL;
3163
3164 RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, rx_filter_flag); /* enable RX of DMA block */
3165 } else {
3166 if (pAd->CommonCfg.PSPXlink)
3167 rx_filter_flag = PSPXLINK;
3168 else
3169 rx_filter_flag = STANORMAL; /* Station not drop control frame will fail WiFi Certification. */
3170 RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, rx_filter_flag);
3171 }
3172
3173 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0xc);
3174 DBGPRINT(RT_DEBUG_TRACE, ("<== RTMPEnableRxTx\n"));
3175}
3176
3177/*+++Add by shiang, move from os/linux/rt_main_dev.c */
3178void CfgInitHook(struct rt_rtmp_adapter *pAd)
3179{
3180 pAd->bBroadComHT = TRUE;
3181}
3182
3183int rt28xx_init(struct rt_rtmp_adapter *pAd,
3184 char *pDefaultMac, char *pHostName)
3185{
3186 u32 index;
3187 u8 TmpPhy;
3188 int Status;
3189 u32 MacCsr0 = 0;
3190
3191#ifdef RTMP_MAC_PCI
3192 {
3193 /* If dirver doesn't wake up firmware here, */
3194 /* NICLoadFirmware will hang forever when interface is up again. */
3195 /* RT2860 PCI */
3196 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) &&
3197 OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) {
3198 AUTO_WAKEUP_STRUC AutoWakeupCfg;
3199 AsicForceWakeup(pAd, TRUE);
3200 AutoWakeupCfg.word = 0;
3201 RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG,
3202 AutoWakeupCfg.word);
3203 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
3204 }
3205 }
3206#endif /* RTMP_MAC_PCI // */
3207
3208 /* reset Adapter flags */
3209 RTMP_CLEAR_FLAGS(pAd);
3210
3211 /* Init BssTab & ChannelInfo tabbles for auto channel select. */
3212
3213 /* Allocate BA Reordering memory */
3214 ba_reordering_resource_init(pAd, MAX_REORDERING_MPDU_NUM);
3215
3216 /* Make sure MAC gets ready. */
3217 index = 0;
3218 do {
3219 RTMP_IO_READ32(pAd, MAC_CSR0, &MacCsr0);
3220 pAd->MACVersion = MacCsr0;
3221
3222 if ((pAd->MACVersion != 0x00)
3223 && (pAd->MACVersion != 0xFFFFFFFF))
3224 break;
3225
3226 RTMPusecDelay(10);
3227 } while (index++ < 100);
3228 DBGPRINT(RT_DEBUG_TRACE,
3229 ("MAC_CSR0 [ Ver:Rev=0x%08x]\n", pAd->MACVersion));
3230
3231#ifdef RTMP_MAC_PCI
3232#ifdef PCIE_PS_SUPPORT
3233 /*Iverson patch PCIE L1 issue to make sure that driver can be read,write ,BBP and RF register at pcie L.1 level */
3234 if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
3235 && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) {
3236 RTMP_IO_READ32(pAd, AUX_CTRL, &MacCsr0);
3237 MacCsr0 |= 0x402;
3238 RTMP_IO_WRITE32(pAd, AUX_CTRL, MacCsr0);
3239 DBGPRINT(RT_DEBUG_TRACE, ("AUX_CTRL = 0x%x\n", MacCsr0));
3240 }
3241#endif /* PCIE_PS_SUPPORT // */
3242
3243 /* To fix driver disable/enable hang issue when radio off */
3244 RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0x2);
3245#endif /* RTMP_MAC_PCI // */
3246
3247 /* Disable DMA */
3248 RT28XXDMADisable(pAd);
3249
3250 /* Load 8051 firmware */
3251 Status = NICLoadFirmware(pAd);
3252 if (Status != NDIS_STATUS_SUCCESS) {
3253 DBGPRINT_ERR("NICLoadFirmware failed, Status[=0x%08x]\n", Status);
3254 goto err1;
3255 }
3256
3257 NICLoadRateSwitchingParams(pAd);
3258
3259 /* Disable interrupts here which is as soon as possible */
3260 /* This statement should never be true. We might consider to remove it later */
3261#ifdef RTMP_MAC_PCI
3262 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE)) {
3263 RTMP_ASIC_INTERRUPT_DISABLE(pAd);
3264 }
3265#endif /* RTMP_MAC_PCI // */
3266
3267 Status = RTMPAllocTxRxRingMemory(pAd);
3268 if (Status != NDIS_STATUS_SUCCESS) {
3269 DBGPRINT_ERR("RTMPAllocDMAMemory failed, Status[=0x%08x]\n", Status);
3270 goto err1;
3271 }
3272
3273 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE);
3274
3275 /* initialize MLME */
3276 /* */
3277
3278 Status = RtmpMgmtTaskInit(pAd);
3279 if (Status != NDIS_STATUS_SUCCESS)
3280 goto err2;
3281
3282 Status = MlmeInit(pAd);
3283 if (Status != NDIS_STATUS_SUCCESS) {
3284 DBGPRINT_ERR("MlmeInit failed, Status[=0x%08x]\n", Status);
3285 goto err2;
3286 }
3287 /* Initialize pAd->StaCfg, pAd->ApCfg, pAd->CommonCfg to manufacture default */
3288 /* */
3289 UserCfgInit(pAd);
3290 Status = RtmpNetTaskInit(pAd);
3291 if (Status != NDIS_STATUS_SUCCESS)
3292 goto err3;
3293
3294/* COPY_MAC_ADDR(pAd->ApCfg.MBSSID[apidx].Bssid, netif->hwaddr); */
3295/* pAd->bForcePrintTX = TRUE; */
3296
3297 CfgInitHook(pAd);
3298
3299 NdisAllocateSpinLock(&pAd->MacTabLock);
3300
3301 MeasureReqTabInit(pAd);
3302 TpcReqTabInit(pAd);
3303
3304 /* */
3305 /* Init the hardware, we need to init asic before read registry, otherwise mac register will be reset */
3306 /* */
3307 Status = NICInitializeAdapter(pAd, TRUE);
3308 if (Status != NDIS_STATUS_SUCCESS) {
3309 DBGPRINT_ERR("NICInitializeAdapter failed, Status[=0x%08x]\n", Status);
3310 if (Status != NDIS_STATUS_SUCCESS)
3311 goto err3;
3312 }
3313
3314 DBGPRINT(RT_DEBUG_OFF, ("1. Phy Mode = %d\n", pAd->CommonCfg.PhyMode));
3315
3316#ifdef RTMP_MAC_USB
3317 pAd->CommonCfg.bMultipleIRP = FALSE;
3318
3319 if (pAd->CommonCfg.bMultipleIRP)
3320 pAd->CommonCfg.NumOfBulkInIRP = RX_RING_SIZE;
3321 else
3322 pAd->CommonCfg.NumOfBulkInIRP = 1;
3323#endif /* RTMP_MAC_USB // */
3324
3325 /*Init Ba Capability parameters. */
3326/* RT28XX_BA_INIT(pAd); */
3327 pAd->CommonCfg.DesiredHtPhy.MpduDensity =
3328 (u8)pAd->CommonCfg.BACapability.field.MpduDensity;
3329 pAd->CommonCfg.DesiredHtPhy.AmsduEnable =
3330 (u16)pAd->CommonCfg.BACapability.field.AmsduEnable;
3331 pAd->CommonCfg.DesiredHtPhy.AmsduSize =
3332 (u16)pAd->CommonCfg.BACapability.field.AmsduSize;
3333 pAd->CommonCfg.DesiredHtPhy.MimoPs =
3334 (u16)pAd->CommonCfg.BACapability.field.MMPSmode;
3335 /* UPdata to HT IE */
3336 pAd->CommonCfg.HtCapability.HtCapInfo.MimoPs =
3337 (u16)pAd->CommonCfg.BACapability.field.MMPSmode;
3338 pAd->CommonCfg.HtCapability.HtCapInfo.AMsduSize =
3339 (u16)pAd->CommonCfg.BACapability.field.AmsduSize;
3340 pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity =
3341 (u8)pAd->CommonCfg.BACapability.field.MpduDensity;
3342
3343 /* after reading Registry, we now know if in AP mode or STA mode */
3344
3345 /* Load 8051 firmware; crash when FW image not existent */
3346 /* Status = NICLoadFirmware(pAd); */
3347 /* if (Status != NDIS_STATUS_SUCCESS) */
3348 /* break; */
3349
3350 DBGPRINT(RT_DEBUG_OFF, ("2. Phy Mode = %d\n", pAd->CommonCfg.PhyMode));
3351
3352 /* We should read EEPROM for all cases. rt2860b */
3353 NICReadEEPROMParameters(pAd, (u8 *)pDefaultMac);
3354
3355 DBGPRINT(RT_DEBUG_OFF, ("3. Phy Mode = %d\n", pAd->CommonCfg.PhyMode));
3356
3357 NICInitAsicFromEEPROM(pAd); /*rt2860b */
3358
3359 /* Set PHY to appropriate mode */
3360 TmpPhy = pAd->CommonCfg.PhyMode;
3361 pAd->CommonCfg.PhyMode = 0xff;
3362 RTMPSetPhyMode(pAd, TmpPhy);
3363 SetCommonHT(pAd);
3364
3365 /* No valid channels. */
3366 if (pAd->ChannelListNum == 0) {
3367 DBGPRINT(RT_DEBUG_ERROR,
3368 ("Wrong configuration. No valid channel found. Check \"ContryCode\" and \"ChannelGeography\" setting.\n"));
3369 goto err4;
3370 }
3371
3372 DBGPRINT(RT_DEBUG_OFF,
3373 ("MCS Set = %02x %02x %02x %02x %02x\n",
3374 pAd->CommonCfg.HtCapability.MCSSet[0],
3375 pAd->CommonCfg.HtCapability.MCSSet[1],
3376 pAd->CommonCfg.HtCapability.MCSSet[2],
3377 pAd->CommonCfg.HtCapability.MCSSet[3],
3378 pAd->CommonCfg.HtCapability.MCSSet[4]));
3379
3380#ifdef RTMP_RF_RW_SUPPORT
3381 /*Init RT30xx RFRegisters after read RFIC type from EEPROM */
3382 NICInitRFRegisters(pAd);
3383#endif /* RTMP_RF_RW_SUPPORT // */
3384
3385/* APInitialize(pAd); */
3386
3387 /* */
3388 /* Initialize RF register to default value */
3389 /* */
3390 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
3391 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
3392
3393 /* 8051 firmware require the signal during booting time. */
3394 /*2008/11/28:KH marked the following codes to patch Frequency offset bug */
3395 /*AsicSendCommandToMcu(pAd, 0x72, 0xFF, 0x00, 0x00); */
3396
3397 if (pAd && (Status != NDIS_STATUS_SUCCESS)) {
3398 /* */
3399 /* Undo everything if it failed */
3400 /* */
3401 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
3402/* NdisMDeregisterInterrupt(&pAd->Interrupt); */
3403 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE);
3404 }
3405/* RTMPFreeAdapter(pAd); // we will free it in disconnect() */
3406 } else if (pAd) {
3407 /* Microsoft HCT require driver send a disconnect event after driver initialization. */
3408 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
3409/* pAd->IndicateMediaState = NdisMediaStateDisconnected; */
3410 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE);
3411
3412 DBGPRINT(RT_DEBUG_TRACE,
3413 ("NDIS_STATUS_MEDIA_DISCONNECT Event B!\n"));
3414
3415#ifdef RTMP_MAC_USB
3416 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS);
3417 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS);
3418
3419 /* */
3420 /* Support multiple BulkIn IRP, */
3421 /* the value on pAd->CommonCfg.NumOfBulkInIRP may be large than 1. */
3422 /* */
3423 for (index = 0; index < pAd->CommonCfg.NumOfBulkInIRP; index++) {
3424 RTUSBBulkReceive(pAd);
3425 DBGPRINT(RT_DEBUG_TRACE, ("RTUSBBulkReceive!\n"));
3426 }
3427#endif /* RTMP_MAC_USB // */
3428 } /* end of else */
3429
3430 /* Set up the Mac address */
3431 RtmpOSNetDevAddrSet(pAd->net_dev, &pAd->CurrentAddress[0]);
3432
3433 DBGPRINT_S(Status, ("<==== rt28xx_init, Status=%x\n", Status));
3434
3435 return TRUE;
3436
3437err4:
3438err3:
3439 MlmeHalt(pAd);
3440err2:
3441 RTMPFreeTxRxRingMemory(pAd);
3442err1:
3443
3444 os_free_mem(pAd, pAd->mpdu_blk_pool.mem); /* free BA pool */
3445
3446 /* shall not set priv to NULL here because the priv didn't been free yet. */
3447 /*net_dev->ml_priv = 0; */
3448#ifdef ST
3449err0:
3450#endif /* ST // */
3451
3452 DBGPRINT(RT_DEBUG_ERROR, ("rt28xx Initialized fail!\n"));
3453 return FALSE;
3454}
3455
3456/*---Add by shiang, move from os/linux/rt_main_dev.c */
3457
3458static int RtmpChipOpsRegister(struct rt_rtmp_adapter *pAd, int infType)
3459{
3460 struct rt_rtmp_chip_op *pChipOps = &pAd->chipOps;
3461 int status;
3462
3463 memset(pChipOps, 0, sizeof(struct rt_rtmp_chip_op));
3464
3465 /* set eeprom related hook functions */
3466 status = RtmpChipOpsEepromHook(pAd, infType);
3467
3468 /* set mcu related hook functions */
3469 switch (infType) {
3470#ifdef RTMP_PCI_SUPPORT
3471 case RTMP_DEV_INF_PCI:
3472 pChipOps->loadFirmware = RtmpAsicLoadFirmware;
3473 pChipOps->eraseFirmware = RtmpAsicEraseFirmware;
3474 pChipOps->sendCommandToMcu = RtmpAsicSendCommandToMcu;
3475 break;
3476#endif /* RTMP_PCI_SUPPORT // */
3477#ifdef RTMP_USB_SUPPORT
3478 case RTMP_DEV_INF_USB:
3479 pChipOps->loadFirmware = RtmpAsicLoadFirmware;
3480 pChipOps->sendCommandToMcu = RtmpAsicSendCommandToMcu;
3481 break;
3482#endif /* RTMP_USB_SUPPORT // */
3483 default:
3484 break;
3485 }
3486
3487 return status;
3488}
3489
3490int RtmpRaDevCtrlInit(struct rt_rtmp_adapter *pAd, IN RTMP_INF_TYPE infType)
3491{
3492 /*void *handle; */
3493
3494 /* Assign the interface type. We need use it when do register/EEPROM access. */
3495 pAd->infType = infType;
3496
3497 pAd->OpMode = OPMODE_STA;
3498 DBGPRINT(RT_DEBUG_TRACE,
3499 ("STA Driver version-%s\n", STA_DRIVER_VERSION));
3500
3501#ifdef RTMP_MAC_USB
3502 sema_init(&(pAd->UsbVendorReq_semaphore), 1);
3503 os_alloc_mem(pAd, (u8 **) & pAd->UsbVendorReqBuf,
3504 MAX_PARAM_BUFFER_SIZE - 1);
3505 if (pAd->UsbVendorReqBuf == NULL) {
3506 DBGPRINT(RT_DEBUG_ERROR,
3507 ("Allocate vendor request temp buffer failed!\n"));
3508 return FALSE;
3509 }
3510#endif /* RTMP_MAC_USB // */
3511
3512 RtmpChipOpsRegister(pAd, infType);
3513
3514 return 0;
3515}
3516
3517BOOLEAN RtmpRaDevCtrlExit(struct rt_rtmp_adapter *pAd)
3518{
3519
3520 RTMPFreeAdapter(pAd);
3521
3522 return TRUE;
3523}
3524
3525/* not yet support MBSS */
3526struct net_device *get_netdev_from_bssid(struct rt_rtmp_adapter *pAd, u8 FromWhichBSSID)
3527{
3528 struct net_device *dev_p = NULL;
3529
3530 {
3531 dev_p = pAd->net_dev;
3532 }
3533
3534 ASSERT(dev_p);
3535 return dev_p; /* return one of MBSS */
3536}
diff --git a/drivers/staging/rt2860/common/rtmp_mcu.c b/drivers/staging/rt2860/common/rtmp_mcu.c
deleted file mode 100644
index 80fa4160ed6..00000000000
--- a/drivers/staging/rt2860/common/rtmp_mcu.c
+++ /dev/null
@@ -1,336 +0,0 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 rtmp_mcu.c
29
30 Abstract:
31 Miniport generic portion header file
32
33 Revision History:
34 Who When What
35 -------- ---------- ----------------------------------------------
36*/
37
38#include "../rt_config.h"
39
40#include <linux/crc-ccitt.h>
41#include <linux/firmware.h>
42
43#ifdef RTMP_MAC_USB
44
45#define FIRMWAREIMAGE_LENGTH 0x1000
46
47#define FIRMWARE_2870_MIN_VERSION 12
48#define FIRMWARE_2870_FILENAME "rt2870.bin"
49MODULE_FIRMWARE(FIRMWARE_2870_FILENAME);
50
51#define FIRMWARE_3070_MIN_VERSION 17
52#define FIRMWARE_3070_FILENAME "rt3070.bin"
53MODULE_FIRMWARE(FIRMWARE_3070_FILENAME);
54
55#define FIRMWARE_3071_MIN_VERSION 17
56#define FIRMWARE_3071_FILENAME "rt3071.bin" /* for RT3071/RT3072 */
57MODULE_FIRMWARE(FIRMWARE_3071_FILENAME);
58
59#else /* RTMP_MAC_PCI */
60
61#define FIRMWAREIMAGE_LENGTH 0x2000
62
63#define FIRMWARE_2860_MIN_VERSION 11
64#define FIRMWARE_2860_FILENAME "rt2860.bin"
65MODULE_FIRMWARE(FIRMWARE_2860_FILENAME);
66
67#define FIRMWARE_3090_MIN_VERSION 19
68#define FIRMWARE_3090_FILENAME "rt3090.bin" /* for RT3090/RT3390 */
69MODULE_FIRMWARE(FIRMWARE_3090_FILENAME);
70
71#endif
72
73/*
74 ========================================================================
75
76 Routine Description:
77 erase 8051 firmware image in MAC ASIC
78
79 Arguments:
80 Adapter Pointer to our adapter
81
82 IRQL = PASSIVE_LEVEL
83
84 ========================================================================
85*/
86int RtmpAsicEraseFirmware(struct rt_rtmp_adapter *pAd)
87{
88 unsigned long i;
89
90 for (i = 0; i < MAX_FIRMWARE_IMAGE_SIZE; i += 4)
91 RTMP_IO_WRITE32(pAd, FIRMWARE_IMAGE_BASE + i, 0);
92
93 return 0;
94}
95
96static const struct firmware *rtmp_get_firmware(struct rt_rtmp_adapter *adapter)
97{
98 const char *name;
99 const struct firmware *fw = NULL;
100 u8 min_version;
101 struct device *dev;
102 int err;
103
104 if (adapter->firmware)
105 return adapter->firmware;
106
107#ifdef RTMP_MAC_USB
108 if (IS_RT3071(adapter)) {
109 name = FIRMWARE_3071_FILENAME;
110 min_version = FIRMWARE_3071_MIN_VERSION;
111 } else if (IS_RT3070(adapter)) {
112 name = FIRMWARE_3070_FILENAME;
113 min_version = FIRMWARE_3070_MIN_VERSION;
114 } else {
115 name = FIRMWARE_2870_FILENAME;
116 min_version = FIRMWARE_2870_MIN_VERSION;
117 }
118 dev = &((struct os_cookie *)adapter->OS_Cookie)->pUsb_Dev->dev;
119#else /* RTMP_MAC_PCI */
120 if (IS_RT3090(adapter) || IS_RT3390(adapter)) {
121 name = FIRMWARE_3090_FILENAME;
122 min_version = FIRMWARE_3090_MIN_VERSION;
123 } else {
124 name = FIRMWARE_2860_FILENAME;
125 min_version = FIRMWARE_2860_MIN_VERSION;
126 }
127 dev = &((struct os_cookie *)adapter->OS_Cookie)->pci_dev->dev;
128#endif
129
130 err = request_firmware(&fw, name, dev);
131 if (err) {
132 dev_err(dev, "firmware file %s request failed (%d)\n",
133 name, err);
134 return NULL;
135 }
136
137 if (fw->size < FIRMWAREIMAGE_LENGTH) {
138 dev_err(dev, "firmware file %s size is invalid\n", name);
139 goto invalid;
140 }
141
142 /* is it new enough? */
143 adapter->FirmwareVersion = fw->data[FIRMWAREIMAGE_LENGTH - 3];
144 if (adapter->FirmwareVersion < min_version) {
145 dev_err(dev,
146 "firmware file %s is too old;"
147 " driver requires v%d or later\n",
148 name, min_version);
149 goto invalid;
150 }
151
152 /* is the internal CRC correct? */
153 if (crc_ccitt(0xffff, fw->data, FIRMWAREIMAGE_LENGTH - 2) !=
154 (fw->data[FIRMWAREIMAGE_LENGTH - 2] |
155 (fw->data[FIRMWAREIMAGE_LENGTH - 1] << 8))) {
156 dev_err(dev, "firmware file %s failed internal CRC\n", name);
157 goto invalid;
158 }
159
160 adapter->firmware = fw;
161 return fw;
162
163invalid:
164 release_firmware(fw);
165 return NULL;
166}
167
168/*
169 ========================================================================
170
171 Routine Description:
172 Load 8051 firmware file into MAC ASIC
173
174 Arguments:
175 Adapter Pointer to our adapter
176
177 Return Value:
178 NDIS_STATUS_SUCCESS firmware image load ok
179 NDIS_STATUS_FAILURE image not found
180
181 IRQL = PASSIVE_LEVEL
182
183 ========================================================================
184*/
185int RtmpAsicLoadFirmware(struct rt_rtmp_adapter *pAd)
186{
187 const struct firmware *fw;
188 int Status = NDIS_STATUS_SUCCESS;
189 unsigned long Index;
190 u32 MacReg = 0;
191
192 fw = rtmp_get_firmware(pAd);
193 if (!fw)
194 return NDIS_STATUS_FAILURE;
195
196 RTMP_WRITE_FIRMWARE(pAd, fw->data, FIRMWAREIMAGE_LENGTH);
197
198 /* check if MCU is ready */
199 Index = 0;
200 do {
201 RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &MacReg);
202
203 if (MacReg & 0x80)
204 break;
205
206 RTMPusecDelay(1000);
207 } while (Index++ < 1000);
208
209 if (Index > 1000) {
210 DBGPRINT(RT_DEBUG_ERROR,
211 ("NICLoadFirmware: MCU is not ready\n"));
212 Status = NDIS_STATUS_FAILURE;
213 }
214
215 DBGPRINT(RT_DEBUG_TRACE, ("<=== %s (status=%d)\n", __func__, Status));
216
217 return Status;
218}
219
220int RtmpAsicSendCommandToMcu(struct rt_rtmp_adapter *pAd,
221 u8 Command,
222 u8 Token, u8 Arg0, u8 Arg1)
223{
224 HOST_CMD_CSR_STRUC H2MCmd;
225 H2M_MAILBOX_STRUC H2MMailbox;
226 unsigned long i = 0;
227
228#ifdef PCIE_PS_SUPPORT
229 /* 3090F power solution 3 has hw limitation that needs to ban all mcu command */
230 /* when firmware is in radio state. For other chip doesn't have this limitation. */
231 if (((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
232 && IS_VERSION_AFTER_F(pAd)) && IS_VERSION_AFTER_F(pAd)
233 && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
234 && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)) {
235 RTMP_SEM_LOCK(&pAd->McuCmdLock);
236 if ((pAd->brt30xxBanMcuCmd == TRUE)
237 && (Command != WAKE_MCU_CMD) && (Command != RFOFF_MCU_CMD)) {
238 RTMP_SEM_UNLOCK(&pAd->McuCmdLock);
239 DBGPRINT(RT_DEBUG_TRACE,
240 (" Ban Mcu Cmd %x in sleep mode\n", Command));
241 return FALSE;
242 } else if ((Command == SLEEP_MCU_CMD)
243 || (Command == RFOFF_MCU_CMD)) {
244 pAd->brt30xxBanMcuCmd = TRUE;
245 } else if (Command != WAKE_MCU_CMD) {
246 pAd->brt30xxBanMcuCmd = FALSE;
247 }
248
249 RTMP_SEM_UNLOCK(&pAd->McuCmdLock);
250
251 }
252 if (((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
253 && IS_VERSION_AFTER_F(pAd)) && IS_VERSION_AFTER_F(pAd)
254 && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
255 && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)
256 && (Command == WAKE_MCU_CMD)) {
257
258 do {
259 RTMP_IO_FORCE_READ32(pAd, H2M_MAILBOX_CSR,
260 &H2MMailbox.word);
261 if (H2MMailbox.field.Owner == 0)
262 break;
263
264 RTMPusecDelay(2);
265 DBGPRINT(RT_DEBUG_INFO,
266 ("AsicSendCommanToMcu::Mail box is busy\n"));
267 } while (i++ < 100);
268
269 if (i > 100) {
270 DBGPRINT_ERR("H2M_MAILBOX still hold by MCU. command fail\n");
271 return FALSE;
272 }
273
274 H2MMailbox.field.Owner = 1; /* pass ownership to MCU */
275 H2MMailbox.field.CmdToken = Token;
276 H2MMailbox.field.HighByte = Arg1;
277 H2MMailbox.field.LowByte = Arg0;
278 RTMP_IO_FORCE_WRITE32(pAd, H2M_MAILBOX_CSR, H2MMailbox.word);
279
280 H2MCmd.word = 0;
281 H2MCmd.field.HostCommand = Command;
282 RTMP_IO_FORCE_WRITE32(pAd, HOST_CMD_CSR, H2MCmd.word);
283
284 } else
285#endif /* PCIE_PS_SUPPORT // */
286 {
287 do {
288 RTMP_IO_READ32(pAd, H2M_MAILBOX_CSR, &H2MMailbox.word);
289 if (H2MMailbox.field.Owner == 0)
290 break;
291
292 RTMPusecDelay(2);
293 } while (i++ < 100);
294
295 if (i > 100) {
296#ifdef RTMP_MAC_PCI
297#endif /* RTMP_MAC_PCI // */
298 {
299 DBGPRINT_ERR("H2M_MAILBOX still hold by MCU. command fail\n");
300 }
301 return FALSE;
302 }
303#ifdef RTMP_MAC_PCI
304#endif /* RTMP_MAC_PCI // */
305
306 H2MMailbox.field.Owner = 1; /* pass ownership to MCU */
307 H2MMailbox.field.CmdToken = Token;
308 H2MMailbox.field.HighByte = Arg1;
309 H2MMailbox.field.LowByte = Arg0;
310 RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CSR, H2MMailbox.word);
311
312 H2MCmd.word = 0;
313 H2MCmd.field.HostCommand = Command;
314 RTMP_IO_WRITE32(pAd, HOST_CMD_CSR, H2MCmd.word);
315
316 if (Command != 0x80) {
317 }
318 }
319#ifdef PCIE_PS_SUPPORT
320 /* 3090 MCU Wakeup command needs more time to be stable. */
321 /* Before stable, don't issue other MCU command to prevent from firmware error. */
322 if (((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
323 && IS_VERSION_AFTER_F(pAd)) && IS_VERSION_AFTER_F(pAd)
324 && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
325 && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)
326 && (Command == WAKE_MCU_CMD)) {
327 RTMPusecDelay(2000);
328 /*Put this is after RF programming. */
329 /*NdisAcquireSpinLock(&pAd->McuCmdLock); */
330 /*pAd->brt30xxBanMcuCmd = FALSE; */
331 /*NdisReleaseSpinLock(&pAd->McuCmdLock); */
332 }
333#endif /* PCIE_PS_SUPPORT // */
334
335 return TRUE;
336}
diff --git a/drivers/staging/rt2860/common/rtmp_timer.c b/drivers/staging/rt2860/common/rtmp_timer.c
deleted file mode 100644
index ab520909490..00000000000
--- a/drivers/staging/rt2860/common/rtmp_timer.c
+++ /dev/null
@@ -1,302 +0,0 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 rtmp_timer.c
29
30 Abstract:
31 task for timer handling
32
33 Revision History:
34 Who When What
35 -------- ---------- ----------------------------------------------
36 Name Date Modification logs
37 Shiang Tu 08-28-2008 init version
38
39*/
40
41#include "../rt_config.h"
42
43BUILD_TIMER_FUNCTION(MlmePeriodicExec);
44/*BUILD_TIMER_FUNCTION(MlmeRssiReportExec); */
45BUILD_TIMER_FUNCTION(AsicRxAntEvalTimeout);
46BUILD_TIMER_FUNCTION(APSDPeriodicExec);
47BUILD_TIMER_FUNCTION(AsicRfTuningExec);
48#ifdef RTMP_MAC_USB
49BUILD_TIMER_FUNCTION(BeaconUpdateExec);
50#endif /* RTMP_MAC_USB // */
51
52BUILD_TIMER_FUNCTION(BeaconTimeout);
53BUILD_TIMER_FUNCTION(ScanTimeout);
54BUILD_TIMER_FUNCTION(AuthTimeout);
55BUILD_TIMER_FUNCTION(AssocTimeout);
56BUILD_TIMER_FUNCTION(ReassocTimeout);
57BUILD_TIMER_FUNCTION(DisassocTimeout);
58BUILD_TIMER_FUNCTION(LinkDownExec);
59BUILD_TIMER_FUNCTION(StaQuickResponeForRateUpExec);
60BUILD_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc);
61#ifdef RTMP_MAC_PCI
62BUILD_TIMER_FUNCTION(PsPollWakeExec);
63BUILD_TIMER_FUNCTION(RadioOnExec);
64#endif /* RTMP_MAC_PCI // */
65#ifdef RTMP_MAC_USB
66BUILD_TIMER_FUNCTION(RtmpUsbStaAsicForceWakeupTimeout);
67#endif /* RTMP_MAC_USB // */
68
69#if defined(AP_LED) || defined(STA_LED)
70extern void LedCtrlMain(void *SystemSpecific1,
71 void *FunctionContext,
72 void *SystemSpecific2, void *SystemSpecific3);
73BUILD_TIMER_FUNCTION(LedCtrlMain);
74#endif
75
76#ifdef RTMP_TIMER_TASK_SUPPORT
77static void RtmpTimerQHandle(struct rt_rtmp_adapter *pAd)
78{
79#ifndef KTHREAD_SUPPORT
80 int status;
81#endif
82 struct rt_ralink_timer *pTimer;
83 struct rt_rtmp_timer_task_entry *pEntry;
84 unsigned long irqFlag;
85 struct rt_rtmp_os_task *pTask;
86
87 pTask = &pAd->timerTask;
88 while (!pTask->task_killed) {
89 pTimer = NULL;
90
91#ifdef KTHREAD_SUPPORT
92 RTMP_WAIT_EVENT_INTERRUPTIBLE(pAd, pTask);
93#else
94 RTMP_SEM_EVENT_WAIT(&(pTask->taskSema), status);
95#endif
96
97 if (pAd->TimerQ.status == RTMP_TASK_STAT_STOPED)
98 break;
99
100 /* event happened. */
101 while (pAd->TimerQ.pQHead) {
102 RTMP_INT_LOCK(&pAd->TimerQLock, irqFlag);
103 pEntry = pAd->TimerQ.pQHead;
104 if (pEntry) {
105 pTimer = pEntry->pRaTimer;
106
107 /* update pQHead */
108 pAd->TimerQ.pQHead = pEntry->pNext;
109 if (pEntry == pAd->TimerQ.pQTail)
110 pAd->TimerQ.pQTail = NULL;
111
112 /* return this queue entry to timerQFreeList. */
113 pEntry->pNext = pAd->TimerQ.pQPollFreeList;
114 pAd->TimerQ.pQPollFreeList = pEntry;
115 }
116 RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlag);
117
118 if (pTimer) {
119 if ((pTimer->handle != NULL)
120 && (!pAd->PM_FlgSuspend))
121 pTimer->handle(NULL,
122 (void *)pTimer->cookie,
123 NULL, pTimer);
124 if ((pTimer->Repeat)
125 && (pTimer->State == FALSE))
126 RTMP_OS_Add_Timer(&pTimer->TimerObj,
127 pTimer->TimerValue);
128 }
129 }
130
131#ifndef KTHREAD_SUPPORT
132 if (status != 0) {
133 pAd->TimerQ.status = RTMP_TASK_STAT_STOPED;
134 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
135 break;
136 }
137#endif
138 }
139}
140
141int RtmpTimerQThread(IN void *Context)
142{
143 struct rt_rtmp_os_task *pTask;
144 struct rt_rtmp_adapter *pAd;
145
146 pTask = Context;
147 pAd = pTask->priv;
148
149 RtmpOSTaskCustomize(pTask);
150
151 RtmpTimerQHandle(pAd);
152
153 DBGPRINT(RT_DEBUG_TRACE, ("<---%s\n", __func__));
154#ifndef KTHREAD_SUPPORT
155 pTask->taskPID = THREAD_PID_INIT_VALUE;
156#endif
157 /* notify the exit routine that we're actually exiting now
158 *
159 * complete()/wait_for_completion() is similar to up()/down(),
160 * except that complete() is safe in the case where the structure
161 * is getting deleted in a parallel mode of execution (i.e. just
162 * after the down() -- that's necessary for the thread-shutdown
163 * case.
164 *
165 * complete_and_exit() goes even further than this -- it is safe in
166 * the case that the thread of the caller is going away (not just
167 * the structure) -- this is necessary for the module-remove case.
168 * This is important in preemption kernels, which transfer the flow
169 * of execution immediately upon a complete().
170 */
171 RtmpOSTaskNotifyToExit(pTask);
172
173 return 0;
174
175}
176
177struct rt_rtmp_timer_task_entry *RtmpTimerQInsert(struct rt_rtmp_adapter *pAd,
178 struct rt_ralink_timer *pTimer)
179{
180 struct rt_rtmp_timer_task_entry *pQNode = NULL, *pQTail;
181 unsigned long irqFlags;
182 struct rt_rtmp_os_task *pTask = &pAd->timerTask;
183
184 RTMP_INT_LOCK(&pAd->TimerQLock, irqFlags);
185 if (pAd->TimerQ.status & RTMP_TASK_CAN_DO_INSERT) {
186 if (pAd->TimerQ.pQPollFreeList) {
187 pQNode = pAd->TimerQ.pQPollFreeList;
188 pAd->TimerQ.pQPollFreeList = pQNode->pNext;
189
190 pQNode->pRaTimer = pTimer;
191 pQNode->pNext = NULL;
192
193 pQTail = pAd->TimerQ.pQTail;
194 if (pAd->TimerQ.pQTail != NULL)
195 pQTail->pNext = pQNode;
196 pAd->TimerQ.pQTail = pQNode;
197 if (pAd->TimerQ.pQHead == NULL)
198 pAd->TimerQ.pQHead = pQNode;
199 }
200 }
201 RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlags);
202
203 if (pQNode) {
204#ifdef KTHREAD_SUPPORT
205 WAKE_UP(pTask);
206#else
207 RTMP_SEM_EVENT_UP(&pTask->taskSema);
208#endif
209 }
210
211 return pQNode;
212}
213
214BOOLEAN RtmpTimerQRemove(struct rt_rtmp_adapter *pAd, struct rt_ralink_timer *pTimer)
215{
216 struct rt_rtmp_timer_task_entry *pNode, *pPrev = NULL;
217 unsigned long irqFlags;
218
219 RTMP_INT_LOCK(&pAd->TimerQLock, irqFlags);
220 if (pAd->TimerQ.status >= RTMP_TASK_STAT_INITED) {
221 pNode = pAd->TimerQ.pQHead;
222 while (pNode) {
223 if (pNode->pRaTimer == pTimer)
224 break;
225 pPrev = pNode;
226 pNode = pNode->pNext;
227 }
228
229 /* Now move it to freeList queue. */
230 if (pNode) {
231 if (pNode == pAd->TimerQ.pQHead)
232 pAd->TimerQ.pQHead = pNode->pNext;
233 if (pNode == pAd->TimerQ.pQTail)
234 pAd->TimerQ.pQTail = pPrev;
235 if (pPrev != NULL)
236 pPrev->pNext = pNode->pNext;
237
238 /* return this queue entry to timerQFreeList. */
239 pNode->pNext = pAd->TimerQ.pQPollFreeList;
240 pAd->TimerQ.pQPollFreeList = pNode;
241 }
242 }
243 RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlags);
244
245 return TRUE;
246}
247
248void RtmpTimerQExit(struct rt_rtmp_adapter *pAd)
249{
250 struct rt_rtmp_timer_task_entry *pTimerQ;
251 unsigned long irqFlags;
252
253 RTMP_INT_LOCK(&pAd->TimerQLock, irqFlags);
254 while (pAd->TimerQ.pQHead) {
255 pTimerQ = pAd->TimerQ.pQHead;
256 pAd->TimerQ.pQHead = pTimerQ->pNext;
257 /* remove the timeQ */
258 }
259 pAd->TimerQ.pQPollFreeList = NULL;
260 os_free_mem(pAd, pAd->TimerQ.pTimerQPoll);
261 pAd->TimerQ.pQTail = NULL;
262 pAd->TimerQ.pQHead = NULL;
263#ifndef KTHREAD_SUPPORT
264 pAd->TimerQ.status = RTMP_TASK_STAT_STOPED;
265#endif
266 RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlags);
267
268}
269
270void RtmpTimerQInit(struct rt_rtmp_adapter *pAd)
271{
272 int i;
273 struct rt_rtmp_timer_task_entry *pQNode, *pEntry;
274 unsigned long irqFlags;
275
276 NdisAllocateSpinLock(&pAd->TimerQLock);
277
278 NdisZeroMemory(&pAd->TimerQ, sizeof(pAd->TimerQ));
279
280 os_alloc_mem(pAd, &pAd->TimerQ.pTimerQPoll,
281 sizeof(struct rt_rtmp_timer_task_entry) * TIMER_QUEUE_SIZE_MAX);
282 if (pAd->TimerQ.pTimerQPoll) {
283 pEntry = NULL;
284 pQNode = (struct rt_rtmp_timer_task_entry *)pAd->TimerQ.pTimerQPoll;
285 NdisZeroMemory(pAd->TimerQ.pTimerQPoll,
286 sizeof(struct rt_rtmp_timer_task_entry) *
287 TIMER_QUEUE_SIZE_MAX);
288
289 RTMP_INT_LOCK(&pAd->TimerQLock, irqFlags);
290 for (i = 0; i < TIMER_QUEUE_SIZE_MAX; i++) {
291 pQNode->pNext = pEntry;
292 pEntry = pQNode;
293 pQNode++;
294 }
295 pAd->TimerQ.pQPollFreeList = pEntry;
296 pAd->TimerQ.pQHead = NULL;
297 pAd->TimerQ.pQTail = NULL;
298 pAd->TimerQ.status = RTMP_TASK_STAT_INITED;
299 RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlags);
300 }
301}
302#endif /* RTMP_TIMER_TASK_SUPPORT // */
diff --git a/drivers/staging/rt2860/common/spectrum.c b/drivers/staging/rt2860/common/spectrum.c
deleted file mode 100644
index ceb622df12d..00000000000
--- a/drivers/staging/rt2860/common/spectrum.c
+++ /dev/null
@@ -1,2205 +0,0 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 action.c
29
30 Abstract:
31 Handle association related requests either from WSTA or from local MLME
32
33 Revision History:
34 Who When What
35 --------- ---------- ----------------------------------------------
36 Fonchi Wu 2008 created for 802.11h
37 */
38
39#include "../rt_config.h"
40#include "action.h"
41
42/* The regulatory information in the USA (US) */
43struct rt_dot11_regulatory_information USARegulatoryInfo[] = {
44/* "regulatory class" "number of channels" "Max Tx Pwr" "channel list" */
45 {0, {0, 0, {0}
46 }
47 }
48 , /* Invlid entry */
49 {1, {4, 16, {36, 40, 44, 48}
50 }
51 }
52 ,
53 {2, {4, 23, {52, 56, 60, 64}
54 }
55 }
56 ,
57 {3, {4, 29, {149, 153, 157, 161}
58 }
59 }
60 ,
61 {4, {11, 23, {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}
62 }
63 }
64 ,
65 {5, {5, 30, {149, 153, 157, 161, 165}
66 }
67 }
68 ,
69 {6, {10, 14, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
70 }
71 }
72 ,
73 {7, {10, 27, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
74 }
75 }
76 ,
77 {8, {5, 17, {11, 13, 15, 17, 19}
78 }
79 }
80 ,
81 {9, {5, 30, {11, 13, 15, 17, 19}
82 }
83 }
84 ,
85 {10, {2, 20, {21, 25}
86 }
87 }
88 ,
89 {11, {2, 33, {21, 25}
90 }
91 }
92 ,
93 {12, {11, 30, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}
94 }
95 }
96};
97
98#define USA_REGULATORY_INFO_SIZE (sizeof(USARegulatoryInfo) / sizeof(struct rt_dot11_regulatory_information))
99
100/* The regulatory information in Europe */
101struct rt_dot11_regulatory_information EuropeRegulatoryInfo[] = {
102/* "regulatory class" "number of channels" "Max Tx Pwr" "channel list" */
103 {0, {0, 0, {0}
104 }
105 }
106 , /* Invalid entry */
107 {1, {4, 20, {36, 40, 44, 48}
108 }
109 }
110 ,
111 {2, {4, 20, {52, 56, 60, 64}
112 }
113 }
114 ,
115 {3, {11, 30, {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}
116 }
117 }
118 ,
119 {4, {13, 20, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}
120 }
121 }
122};
123
124#define EU_REGULATORY_INFO_SIZE (sizeof(EuropeRegulatoryInfo) / sizeof(struct rt_dot11_regulatory_information))
125
126/* The regulatory information in Japan */
127struct rt_dot11_regulatory_information JapanRegulatoryInfo[] = {
128/* "regulatory class" "number of channels" "Max Tx Pwr" "channel list" */
129 {0, {0, 0, {0}
130 }
131 }
132 , /* Invalid entry */
133 {1, {4, 22, {34, 38, 42, 46}
134 }
135 }
136 ,
137 {2, {3, 24, {8, 12, 16}
138 }
139 }
140 ,
141 {3, {3, 24, {8, 12, 16}
142 }
143 }
144 ,
145 {4, {3, 24, {8, 12, 16}
146 }
147 }
148 ,
149 {5, {3, 24, {8, 12, 16}
150 }
151 }
152 ,
153 {6, {3, 22, {8, 12, 16}
154 }
155 }
156 ,
157 {7, {4, 24, {184, 188, 192, 196}
158 }
159 }
160 ,
161 {8, {4, 24, {184, 188, 192, 196}
162 }
163 }
164 ,
165 {9, {4, 24, {184, 188, 192, 196}
166 }
167 }
168 ,
169 {10, {4, 24, {184, 188, 192, 196}
170 }
171 }
172 ,
173 {11, {4, 22, {184, 188, 192, 196}
174 }
175 }
176 ,
177 {12, {4, 24, {7, 8, 9, 11}
178 }
179 }
180 ,
181 {13, {4, 24, {7, 8, 9, 11}
182 }
183 }
184 ,
185 {14, {4, 24, {7, 8, 9, 11}
186 }
187 }
188 ,
189 {15, {4, 24, {7, 8, 9, 11}
190 }
191 }
192 ,
193 {16, {6, 24, {183, 184, 185, 187, 188, 189}
194 }
195 }
196 ,
197 {17, {6, 24, {183, 184, 185, 187, 188, 189}
198 }
199 }
200 ,
201 {18, {6, 24, {183, 184, 185, 187, 188, 189}
202 }
203 }
204 ,
205 {19, {6, 24, {183, 184, 185, 187, 188, 189}
206 }
207 }
208 ,
209 {20, {6, 17, {183, 184, 185, 187, 188, 189}
210 }
211 }
212 ,
213 {21, {6, 24, {6, 7, 8, 9, 10, 11}
214 }
215 }
216 ,
217 {22, {6, 24, {6, 7, 8, 9, 10, 11}
218 }
219 }
220 ,
221 {23, {6, 24, {6, 7, 8, 9, 10, 11}
222 }
223 }
224 ,
225 {24, {6, 24, {6, 7, 8, 9, 10, 11}
226 }
227 }
228 ,
229 {25, {8, 24, {182, 183, 184, 185, 186, 187, 188, 189}
230 }
231 }
232 ,
233 {26, {8, 24, {182, 183, 184, 185, 186, 187, 188, 189}
234 }
235 }
236 ,
237 {27, {8, 24, {182, 183, 184, 185, 186, 187, 188, 189}
238 }
239 }
240 ,
241 {28, {8, 24, {182, 183, 184, 185, 186, 187, 188, 189}
242 }
243 }
244 ,
245 {29, {8, 17, {182, 183, 184, 185, 186, 187, 188, 189}
246 }
247 }
248 ,
249 {30, {13, 23, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}
250 }
251 }
252 ,
253 {31, {1, 23, {14}
254 }
255 }
256 ,
257 {32, {4, 22, {52, 56, 60, 64}
258 }
259 }
260};
261
262#define JP_REGULATORY_INFO_SIZE (sizeof(JapanRegulatoryInfo) / sizeof(struct rt_dot11_regulatory_information))
263
264char RTMP_GetTxPwr(struct rt_rtmp_adapter *pAd, IN HTTRANSMIT_SETTING HTTxMode)
265{
266 struct tx_pwr_cfg {
267 u8 Mode;
268 u8 MCS;
269 u16 req;
270 u8 shift;
271 u32 BitMask;
272 };
273
274 u32 Value;
275 int Idx;
276 u8 PhyMode;
277 char CurTxPwr;
278 u8 TxPwrRef = 0;
279 char DaltaPwr;
280 unsigned long TxPwr[5];
281
282 struct tx_pwr_cfg TxPwrCfg[] = {
283 {MODE_CCK, 0, 0, 4, 0x000000f0},
284 {MODE_CCK, 1, 0, 0, 0x0000000f},
285 {MODE_CCK, 2, 0, 12, 0x0000f000},
286 {MODE_CCK, 3, 0, 8, 0x00000f00},
287
288 {MODE_OFDM, 0, 0, 20, 0x00f00000},
289 {MODE_OFDM, 1, 0, 16, 0x000f0000},
290 {MODE_OFDM, 2, 0, 28, 0xf0000000},
291 {MODE_OFDM, 3, 0, 24, 0x0f000000},
292 {MODE_OFDM, 4, 1, 4, 0x000000f0},
293 {MODE_OFDM, 5, 1, 0, 0x0000000f},
294 {MODE_OFDM, 6, 1, 12, 0x0000f000},
295 {MODE_OFDM, 7, 1, 8, 0x00000f00}
296 , {MODE_HTMIX, 0, 1, 20, 0x00f00000},
297 {MODE_HTMIX, 1, 1, 16, 0x000f0000},
298 {MODE_HTMIX, 2, 1, 28, 0xf0000000},
299 {MODE_HTMIX, 3, 1, 24, 0x0f000000},
300 {MODE_HTMIX, 4, 2, 4, 0x000000f0},
301 {MODE_HTMIX, 5, 2, 0, 0x0000000f},
302 {MODE_HTMIX, 6, 2, 12, 0x0000f000},
303 {MODE_HTMIX, 7, 2, 8, 0x00000f00},
304 {MODE_HTMIX, 8, 2, 20, 0x00f00000},
305 {MODE_HTMIX, 9, 2, 16, 0x000f0000},
306 {MODE_HTMIX, 10, 2, 28, 0xf0000000},
307 {MODE_HTMIX, 11, 2, 24, 0x0f000000},
308 {MODE_HTMIX, 12, 3, 4, 0x000000f0},
309 {MODE_HTMIX, 13, 3, 0, 0x0000000f},
310 {MODE_HTMIX, 14, 3, 12, 0x0000f000},
311 {MODE_HTMIX, 15, 3, 8, 0x00000f00}
312 };
313#define MAX_TXPWR_TAB_SIZE (sizeof(TxPwrCfg) / sizeof(struct tx_pwr_cfg))
314
315 CurTxPwr = 19;
316
317 /* check Tx Power setting from UI. */
318 if (pAd->CommonCfg.TxPowerPercentage > 90) ;
319 else if (pAd->CommonCfg.TxPowerPercentage > 60) /* reduce Pwr for 1 dB. */
320 CurTxPwr -= 1;
321 else if (pAd->CommonCfg.TxPowerPercentage > 30) /* reduce Pwr for 3 dB. */
322 CurTxPwr -= 3;
323 else if (pAd->CommonCfg.TxPowerPercentage > 15) /* reduce Pwr for 6 dB. */
324 CurTxPwr -= 6;
325 else if (pAd->CommonCfg.TxPowerPercentage > 9) /* reduce Pwr for 9 dB. */
326 CurTxPwr -= 9;
327 else /* reduce Pwr for 12 dB. */
328 CurTxPwr -= 12;
329
330 if (pAd->CommonCfg.BBPCurrentBW == BW_40) {
331 if (pAd->CommonCfg.CentralChannel > 14) {
332 TxPwr[0] = pAd->Tx40MPwrCfgABand[0];
333 TxPwr[1] = pAd->Tx40MPwrCfgABand[1];
334 TxPwr[2] = pAd->Tx40MPwrCfgABand[2];
335 TxPwr[3] = pAd->Tx40MPwrCfgABand[3];
336 TxPwr[4] = pAd->Tx40MPwrCfgABand[4];
337 } else {
338 TxPwr[0] = pAd->Tx40MPwrCfgGBand[0];
339 TxPwr[1] = pAd->Tx40MPwrCfgGBand[1];
340 TxPwr[2] = pAd->Tx40MPwrCfgGBand[2];
341 TxPwr[3] = pAd->Tx40MPwrCfgGBand[3];
342 TxPwr[4] = pAd->Tx40MPwrCfgGBand[4];
343 }
344 } else {
345 if (pAd->CommonCfg.Channel > 14) {
346 TxPwr[0] = pAd->Tx20MPwrCfgABand[0];
347 TxPwr[1] = pAd->Tx20MPwrCfgABand[1];
348 TxPwr[2] = pAd->Tx20MPwrCfgABand[2];
349 TxPwr[3] = pAd->Tx20MPwrCfgABand[3];
350 TxPwr[4] = pAd->Tx20MPwrCfgABand[4];
351 } else {
352 TxPwr[0] = pAd->Tx20MPwrCfgGBand[0];
353 TxPwr[1] = pAd->Tx20MPwrCfgGBand[1];
354 TxPwr[2] = pAd->Tx20MPwrCfgGBand[2];
355 TxPwr[3] = pAd->Tx20MPwrCfgGBand[3];
356 TxPwr[4] = pAd->Tx20MPwrCfgGBand[4];
357 }
358 }
359
360 switch (HTTxMode.field.MODE) {
361 case MODE_CCK:
362 case MODE_OFDM:
363 Value = TxPwr[1];
364 TxPwrRef = (Value & 0x00000f00) >> 8;
365
366 break;
367
368 case MODE_HTMIX:
369 case MODE_HTGREENFIELD:
370 if (pAd->CommonCfg.TxStream == 1) {
371 Value = TxPwr[2];
372 TxPwrRef = (Value & 0x00000f00) >> 8;
373 } else if (pAd->CommonCfg.TxStream == 2) {
374 Value = TxPwr[3];
375 TxPwrRef = (Value & 0x00000f00) >> 8;
376 }
377 break;
378 }
379
380 PhyMode = (HTTxMode.field.MODE == MODE_HTGREENFIELD)
381 ? MODE_HTMIX : HTTxMode.field.MODE;
382
383 for (Idx = 0; Idx < MAX_TXPWR_TAB_SIZE; Idx++) {
384 if ((TxPwrCfg[Idx].Mode == PhyMode)
385 && (TxPwrCfg[Idx].MCS == HTTxMode.field.MCS)) {
386 Value = TxPwr[TxPwrCfg[Idx].req];
387 DaltaPwr =
388 TxPwrRef - (char)((Value & TxPwrCfg[Idx].BitMask)
389 >> TxPwrCfg[Idx].shift);
390 CurTxPwr -= DaltaPwr;
391 break;
392 }
393 }
394
395 return CurTxPwr;
396}
397
398void MeasureReqTabInit(struct rt_rtmp_adapter *pAd)
399{
400 NdisAllocateSpinLock(&pAd->CommonCfg.MeasureReqTabLock);
401
402 pAd->CommonCfg.pMeasureReqTab =
403 kmalloc(sizeof(struct rt_measure_req_tab), GFP_ATOMIC);
404 if (pAd->CommonCfg.pMeasureReqTab)
405 NdisZeroMemory(pAd->CommonCfg.pMeasureReqTab,
406 sizeof(struct rt_measure_req_tab));
407 else
408 DBGPRINT(RT_DEBUG_ERROR,
409 ("%s Fail to alloc memory for pAd->CommonCfg.pMeasureReqTab.\n",
410 __func__));
411
412 return;
413}
414
415void MeasureReqTabExit(struct rt_rtmp_adapter *pAd)
416{
417 NdisFreeSpinLock(&pAd->CommonCfg.MeasureReqTabLock);
418
419 kfree(pAd->CommonCfg.pMeasureReqTab);
420 pAd->CommonCfg.pMeasureReqTab = NULL;
421
422 return;
423}
424
425struct rt_measure_req_entry *MeasureReqLookUp(struct rt_rtmp_adapter *pAd, u8 DialogToken)
426{
427 u32 HashIdx;
428 struct rt_measure_req_tab *pTab = pAd->CommonCfg.pMeasureReqTab;
429 struct rt_measure_req_entry *pEntry = NULL;
430 struct rt_measure_req_entry *pPrevEntry = NULL;
431
432 if (pTab == NULL) {
433 DBGPRINT(RT_DEBUG_ERROR,
434 ("%s: pMeasureReqTab doesn't exist.\n", __func__));
435 return NULL;
436 }
437
438 RTMP_SEM_LOCK(&pAd->CommonCfg.MeasureReqTabLock);
439
440 HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(DialogToken);
441 pEntry = pTab->Hash[HashIdx];
442
443 while (pEntry) {
444 if (pEntry->DialogToken == DialogToken)
445 break;
446 else {
447 pPrevEntry = pEntry;
448 pEntry = pEntry->pNext;
449 }
450 }
451
452 RTMP_SEM_UNLOCK(&pAd->CommonCfg.MeasureReqTabLock);
453
454 return pEntry;
455}
456
457struct rt_measure_req_entry *MeasureReqInsert(struct rt_rtmp_adapter *pAd, u8 DialogToken)
458{
459 int i;
460 unsigned long HashIdx;
461 struct rt_measure_req_tab *pTab = pAd->CommonCfg.pMeasureReqTab;
462 struct rt_measure_req_entry *pEntry = NULL, *pCurrEntry;
463 unsigned long Now;
464
465 if (pTab == NULL) {
466 DBGPRINT(RT_DEBUG_ERROR,
467 ("%s: pMeasureReqTab doesn't exist.\n", __func__));
468 return NULL;
469 }
470
471 pEntry = MeasureReqLookUp(pAd, DialogToken);
472 if (pEntry == NULL) {
473 RTMP_SEM_LOCK(&pAd->CommonCfg.MeasureReqTabLock);
474 for (i = 0; i < MAX_MEASURE_REQ_TAB_SIZE; i++) {
475 NdisGetSystemUpTime(&Now);
476 pEntry = &pTab->Content[i];
477
478 if ((pEntry->Valid == TRUE)
479 && RTMP_TIME_AFTER((unsigned long)Now,
480 (unsigned long)(pEntry->
481 lastTime +
482 MQ_REQ_AGE_OUT)))
483 {
484 struct rt_measure_req_entry *pPrevEntry = NULL;
485 unsigned long HashIdx =
486 MQ_DIALOGTOKEN_HASH_INDEX(pEntry->
487 DialogToken);
488 struct rt_measure_req_entry *pProbeEntry =
489 pTab->Hash[HashIdx];
490
491 /* update Hash list */
492 do {
493 if (pProbeEntry == pEntry) {
494 if (pPrevEntry == NULL) {
495 pTab->Hash[HashIdx] =
496 pEntry->pNext;
497 } else {
498 pPrevEntry->pNext =
499 pEntry->pNext;
500 }
501 break;
502 }
503
504 pPrevEntry = pProbeEntry;
505 pProbeEntry = pProbeEntry->pNext;
506 } while (pProbeEntry);
507
508 NdisZeroMemory(pEntry,
509 sizeof(struct rt_measure_req_entry));
510 pTab->Size--;
511
512 break;
513 }
514
515 if (pEntry->Valid == FALSE)
516 break;
517 }
518
519 if (i < MAX_MEASURE_REQ_TAB_SIZE) {
520 NdisGetSystemUpTime(&Now);
521 pEntry->lastTime = Now;
522 pEntry->Valid = TRUE;
523 pEntry->DialogToken = DialogToken;
524 pTab->Size++;
525 } else {
526 pEntry = NULL;
527 DBGPRINT(RT_DEBUG_ERROR,
528 ("%s: pMeasureReqTab tab full.\n", __func__));
529 }
530
531 /* add this Neighbor entry into HASH table */
532 if (pEntry) {
533 HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(DialogToken);
534 if (pTab->Hash[HashIdx] == NULL) {
535 pTab->Hash[HashIdx] = pEntry;
536 } else {
537 pCurrEntry = pTab->Hash[HashIdx];
538 while (pCurrEntry->pNext != NULL)
539 pCurrEntry = pCurrEntry->pNext;
540 pCurrEntry->pNext = pEntry;
541 }
542 }
543
544 RTMP_SEM_UNLOCK(&pAd->CommonCfg.MeasureReqTabLock);
545 }
546
547 return pEntry;
548}
549
550void MeasureReqDelete(struct rt_rtmp_adapter *pAd, u8 DialogToken)
551{
552 struct rt_measure_req_tab *pTab = pAd->CommonCfg.pMeasureReqTab;
553 struct rt_measure_req_entry *pEntry = NULL;
554
555 if (pTab == NULL) {
556 DBGPRINT(RT_DEBUG_ERROR,
557 ("%s: pMeasureReqTab doesn't exist.\n", __func__));
558 return;
559 }
560 /* if empty, return */
561 if (pTab->Size == 0) {
562 DBGPRINT(RT_DEBUG_ERROR, ("pMeasureReqTab empty.\n"));
563 return;
564 }
565
566 pEntry = MeasureReqLookUp(pAd, DialogToken);
567 if (pEntry != NULL) {
568 struct rt_measure_req_entry *pPrevEntry = NULL;
569 unsigned long HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken);
570 struct rt_measure_req_entry *pProbeEntry = pTab->Hash[HashIdx];
571
572 RTMP_SEM_LOCK(&pAd->CommonCfg.MeasureReqTabLock);
573 /* update Hash list */
574 do {
575 if (pProbeEntry == pEntry) {
576 if (pPrevEntry == NULL) {
577 pTab->Hash[HashIdx] = pEntry->pNext;
578 } else {
579 pPrevEntry->pNext = pEntry->pNext;
580 }
581 break;
582 }
583
584 pPrevEntry = pProbeEntry;
585 pProbeEntry = pProbeEntry->pNext;
586 } while (pProbeEntry);
587
588 NdisZeroMemory(pEntry, sizeof(struct rt_measure_req_entry));
589 pTab->Size--;
590
591 RTMP_SEM_UNLOCK(&pAd->CommonCfg.MeasureReqTabLock);
592 }
593
594 return;
595}
596
597void TpcReqTabInit(struct rt_rtmp_adapter *pAd)
598{
599 NdisAllocateSpinLock(&pAd->CommonCfg.TpcReqTabLock);
600
601 pAd->CommonCfg.pTpcReqTab = kmalloc(sizeof(struct rt_tpc_req_tab), GFP_ATOMIC);
602 if (pAd->CommonCfg.pTpcReqTab)
603 NdisZeroMemory(pAd->CommonCfg.pTpcReqTab, sizeof(struct rt_tpc_req_tab));
604 else
605 DBGPRINT(RT_DEBUG_ERROR,
606 ("%s Fail to alloc memory for pAd->CommonCfg.pTpcReqTab.\n",
607 __func__));
608
609 return;
610}
611
612void TpcReqTabExit(struct rt_rtmp_adapter *pAd)
613{
614 NdisFreeSpinLock(&pAd->CommonCfg.TpcReqTabLock);
615
616 kfree(pAd->CommonCfg.pTpcReqTab);
617 pAd->CommonCfg.pTpcReqTab = NULL;
618
619 return;
620}
621
622static struct rt_tpc_req_entry *TpcReqLookUp(struct rt_rtmp_adapter *pAd, u8 DialogToken)
623{
624 u32 HashIdx;
625 struct rt_tpc_req_tab *pTab = pAd->CommonCfg.pTpcReqTab;
626 struct rt_tpc_req_entry *pEntry = NULL;
627 struct rt_tpc_req_entry *pPrevEntry = NULL;
628
629 if (pTab == NULL) {
630 DBGPRINT(RT_DEBUG_ERROR,
631 ("%s: pTpcReqTab doesn't exist.\n", __func__));
632 return NULL;
633 }
634
635 RTMP_SEM_LOCK(&pAd->CommonCfg.TpcReqTabLock);
636
637 HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(DialogToken);
638 pEntry = pTab->Hash[HashIdx];
639
640 while (pEntry) {
641 if (pEntry->DialogToken == DialogToken)
642 break;
643 else {
644 pPrevEntry = pEntry;
645 pEntry = pEntry->pNext;
646 }
647 }
648
649 RTMP_SEM_UNLOCK(&pAd->CommonCfg.TpcReqTabLock);
650
651 return pEntry;
652}
653
654static struct rt_tpc_req_entry *TpcReqInsert(struct rt_rtmp_adapter *pAd, u8 DialogToken)
655{
656 int i;
657 unsigned long HashIdx;
658 struct rt_tpc_req_tab *pTab = pAd->CommonCfg.pTpcReqTab;
659 struct rt_tpc_req_entry *pEntry = NULL, *pCurrEntry;
660 unsigned long Now;
661
662 if (pTab == NULL) {
663 DBGPRINT(RT_DEBUG_ERROR,
664 ("%s: pTpcReqTab doesn't exist.\n", __func__));
665 return NULL;
666 }
667
668 pEntry = TpcReqLookUp(pAd, DialogToken);
669 if (pEntry == NULL) {
670 RTMP_SEM_LOCK(&pAd->CommonCfg.TpcReqTabLock);
671 for (i = 0; i < MAX_TPC_REQ_TAB_SIZE; i++) {
672 NdisGetSystemUpTime(&Now);
673 pEntry = &pTab->Content[i];
674
675 if ((pEntry->Valid == TRUE)
676 && RTMP_TIME_AFTER((unsigned long)Now,
677 (unsigned long)(pEntry->
678 lastTime +
679 TPC_REQ_AGE_OUT)))
680 {
681 struct rt_tpc_req_entry *pPrevEntry = NULL;
682 unsigned long HashIdx =
683 TPC_DIALOGTOKEN_HASH_INDEX(pEntry->
684 DialogToken);
685 struct rt_tpc_req_entry *pProbeEntry =
686 pTab->Hash[HashIdx];
687
688 /* update Hash list */
689 do {
690 if (pProbeEntry == pEntry) {
691 if (pPrevEntry == NULL) {
692 pTab->Hash[HashIdx] =
693 pEntry->pNext;
694 } else {
695 pPrevEntry->pNext =
696 pEntry->pNext;
697 }
698 break;
699 }
700
701 pPrevEntry = pProbeEntry;
702 pProbeEntry = pProbeEntry->pNext;
703 } while (pProbeEntry);
704
705 NdisZeroMemory(pEntry, sizeof(struct rt_tpc_req_entry));
706 pTab->Size--;
707
708 break;
709 }
710
711 if (pEntry->Valid == FALSE)
712 break;
713 }
714
715 if (i < MAX_TPC_REQ_TAB_SIZE) {
716 NdisGetSystemUpTime(&Now);
717 pEntry->lastTime = Now;
718 pEntry->Valid = TRUE;
719 pEntry->DialogToken = DialogToken;
720 pTab->Size++;
721 } else {
722 pEntry = NULL;
723 DBGPRINT(RT_DEBUG_ERROR,
724 ("%s: pTpcReqTab tab full.\n", __func__));
725 }
726
727 /* add this Neighbor entry into HASH table */
728 if (pEntry) {
729 HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(DialogToken);
730 if (pTab->Hash[HashIdx] == NULL) {
731 pTab->Hash[HashIdx] = pEntry;
732 } else {
733 pCurrEntry = pTab->Hash[HashIdx];
734 while (pCurrEntry->pNext != NULL)
735 pCurrEntry = pCurrEntry->pNext;
736 pCurrEntry->pNext = pEntry;
737 }
738 }
739
740 RTMP_SEM_UNLOCK(&pAd->CommonCfg.TpcReqTabLock);
741 }
742
743 return pEntry;
744}
745
746static void TpcReqDelete(struct rt_rtmp_adapter *pAd, u8 DialogToken)
747{
748 struct rt_tpc_req_tab *pTab = pAd->CommonCfg.pTpcReqTab;
749 struct rt_tpc_req_entry *pEntry = NULL;
750
751 if (pTab == NULL) {
752 DBGPRINT(RT_DEBUG_ERROR,
753 ("%s: pTpcReqTab doesn't exist.\n", __func__));
754 return;
755 }
756 /* if empty, return */
757 if (pTab->Size == 0) {
758 DBGPRINT(RT_DEBUG_ERROR, ("pTpcReqTab empty.\n"));
759 return;
760 }
761
762 pEntry = TpcReqLookUp(pAd, DialogToken);
763 if (pEntry != NULL) {
764 struct rt_tpc_req_entry *pPrevEntry = NULL;
765 unsigned long HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken);
766 struct rt_tpc_req_entry *pProbeEntry = pTab->Hash[HashIdx];
767
768 RTMP_SEM_LOCK(&pAd->CommonCfg.TpcReqTabLock);
769 /* update Hash list */
770 do {
771 if (pProbeEntry == pEntry) {
772 if (pPrevEntry == NULL) {
773 pTab->Hash[HashIdx] = pEntry->pNext;
774 } else {
775 pPrevEntry->pNext = pEntry->pNext;
776 }
777 break;
778 }
779
780 pPrevEntry = pProbeEntry;
781 pProbeEntry = pProbeEntry->pNext;
782 } while (pProbeEntry);
783
784 NdisZeroMemory(pEntry, sizeof(struct rt_tpc_req_entry));
785 pTab->Size--;
786
787 RTMP_SEM_UNLOCK(&pAd->CommonCfg.TpcReqTabLock);
788 }
789
790 return;
791}
792
793/*
794 ==========================================================================
795 Description:
796 Get Current TimeS tamp.
797
798 Parametrs:
799
800 Return : Current Time Stamp.
801 ==========================================================================
802 */
803static u64 GetCurrentTimeStamp(struct rt_rtmp_adapter *pAd)
804{
805 /* get current time stamp. */
806 return 0;
807}
808
809/*
810 ==========================================================================
811 Description:
812 Get Current Transmit Power.
813
814 Parametrs:
815
816 Return : Current Time Stamp.
817 ==========================================================================
818 */
819static u8 GetCurTxPwr(struct rt_rtmp_adapter *pAd, u8 Wcid)
820{
821 return 16; /* 16 dBm */
822}
823
824/*
825 ==========================================================================
826 Description:
827 Get Current Transmit Power.
828
829 Parametrs:
830
831 Return : Current Time Stamp.
832 ==========================================================================
833 */
834void InsertChannelRepIE(struct rt_rtmp_adapter *pAd,
835 u8 *pFrameBuf,
836 unsigned long *pFrameLen,
837 char *pCountry, u8 RegulatoryClass)
838{
839 unsigned long TempLen;
840 u8 Len;
841 u8 IEId = IE_AP_CHANNEL_REPORT;
842 u8 *pChListPtr = NULL;
843
844 Len = 1;
845 if (strncmp(pCountry, "US", 2) == 0) {
846 if (RegulatoryClass >= USA_REGULATORY_INFO_SIZE) {
847 DBGPRINT(RT_DEBUG_ERROR,
848 ("%s: USA Unknow Requlatory class (%d)\n",
849 __func__, RegulatoryClass));
850 return;
851 }
852
853 Len +=
854 USARegulatoryInfo[RegulatoryClass].ChannelSet.
855 NumberOfChannels;
856 pChListPtr =
857 USARegulatoryInfo[RegulatoryClass].ChannelSet.ChannelList;
858 } else if (strncmp(pCountry, "JP", 2) == 0) {
859 if (RegulatoryClass >= JP_REGULATORY_INFO_SIZE) {
860 DBGPRINT(RT_DEBUG_ERROR,
861 ("%s: JP Unknow Requlatory class (%d)\n",
862 __func__, RegulatoryClass));
863 return;
864 }
865
866 Len +=
867 JapanRegulatoryInfo[RegulatoryClass].ChannelSet.
868 NumberOfChannels;
869 pChListPtr =
870 JapanRegulatoryInfo[RegulatoryClass].ChannelSet.ChannelList;
871 } else {
872 DBGPRINT(RT_DEBUG_ERROR, ("%s: Unknow Country (%s)\n",
873 __func__, pCountry));
874 return;
875 }
876
877 MakeOutgoingFrame(pFrameBuf, &TempLen,
878 1, &IEId,
879 1, &Len,
880 1, &RegulatoryClass,
881 Len - 1, pChListPtr, END_OF_ARGS);
882
883 *pFrameLen = *pFrameLen + TempLen;
884
885 return;
886}
887
888/*
889 ==========================================================================
890 Description:
891 Insert Dialog Token into frame.
892
893 Parametrs:
894 1. frame buffer pointer.
895 2. frame length.
896 3. Dialog token.
897
898 Return : None.
899 ==========================================================================
900 */
901void InsertDialogToken(struct rt_rtmp_adapter *pAd,
902 u8 *pFrameBuf,
903 unsigned long *pFrameLen, u8 DialogToken)
904{
905 unsigned long TempLen;
906 MakeOutgoingFrame(pFrameBuf, &TempLen, 1, &DialogToken, END_OF_ARGS);
907
908 *pFrameLen = *pFrameLen + TempLen;
909
910 return;
911}
912
913/*
914 ==========================================================================
915 Description:
916 Insert TPC Request IE into frame.
917
918 Parametrs:
919 1. frame buffer pointer.
920 2. frame length.
921
922 Return : None.
923 ==========================================================================
924 */
925static void InsertTpcReqIE(struct rt_rtmp_adapter *pAd,
926 u8 *pFrameBuf, unsigned long *pFrameLen)
927{
928 unsigned long TempLen;
929 unsigned long Len = 0;
930 u8 ElementID = IE_TPC_REQUEST;
931
932 MakeOutgoingFrame(pFrameBuf, &TempLen,
933 1, &ElementID, 1, &Len, END_OF_ARGS);
934
935 *pFrameLen = *pFrameLen + TempLen;
936
937 return;
938}
939
940/*
941 ==========================================================================
942 Description:
943 Insert TPC Report IE into frame.
944
945 Parametrs:
946 1. frame buffer pointer.
947 2. frame length.
948 3. Transmit Power.
949 4. Link Margin.
950
951 Return : None.
952 ==========================================================================
953 */
954void InsertTpcReportIE(struct rt_rtmp_adapter *pAd,
955 u8 *pFrameBuf,
956 unsigned long *pFrameLen,
957 u8 TxPwr, u8 LinkMargin)
958{
959 unsigned long TempLen;
960 unsigned long Len = sizeof(struct rt_tpc_report_info);
961 u8 ElementID = IE_TPC_REPORT;
962 struct rt_tpc_report_info TpcReportIE;
963
964 TpcReportIE.TxPwr = TxPwr;
965 TpcReportIE.LinkMargin = LinkMargin;
966
967 MakeOutgoingFrame(pFrameBuf, &TempLen,
968 1, &ElementID,
969 1, &Len, Len, &TpcReportIE, END_OF_ARGS);
970
971 *pFrameLen = *pFrameLen + TempLen;
972
973 return;
974}
975
976/*
977 ==========================================================================
978 Description:
979 Insert Channel Switch Announcement IE into frame.
980
981 Parametrs:
982 1. frame buffer pointer.
983 2. frame length.
984 3. channel switch announcement mode.
985 4. new selected channel.
986 5. channel switch announcement count.
987
988 Return : None.
989 ==========================================================================
990 */
991static void InsertChSwAnnIE(struct rt_rtmp_adapter *pAd,
992 u8 *pFrameBuf,
993 unsigned long *pFrameLen,
994 u8 ChSwMode,
995 u8 NewChannel, u8 ChSwCnt)
996{
997 unsigned long TempLen;
998 unsigned long Len = sizeof(struct rt_ch_sw_ann_info);
999 u8 ElementID = IE_CHANNEL_SWITCH_ANNOUNCEMENT;
1000 struct rt_ch_sw_ann_info ChSwAnnIE;
1001
1002 ChSwAnnIE.ChSwMode = ChSwMode;
1003 ChSwAnnIE.Channel = NewChannel;
1004 ChSwAnnIE.ChSwCnt = ChSwCnt;
1005
1006 MakeOutgoingFrame(pFrameBuf, &TempLen,
1007 1, &ElementID, 1, &Len, Len, &ChSwAnnIE, END_OF_ARGS);
1008
1009 *pFrameLen = *pFrameLen + TempLen;
1010
1011 return;
1012}
1013
1014/*
1015 ==========================================================================
1016 Description:
1017 Insert Measure Request IE into frame.
1018
1019 Parametrs:
1020 1. frame buffer pointer.
1021 2. frame length.
1022 3. Measure Token.
1023 4. Measure Request Mode.
1024 5. Measure Request Type.
1025 6. Measure Channel.
1026 7. Measure Start time.
1027 8. Measure Duration.
1028
1029 Return : None.
1030 ==========================================================================
1031 */
1032static void InsertMeasureReqIE(struct rt_rtmp_adapter *pAd,
1033 u8 *pFrameBuf,
1034 unsigned long *pFrameLen,
1035 u8 Len, struct rt_measure_req_info * pMeasureReqIE)
1036{
1037 unsigned long TempLen;
1038 u8 ElementID = IE_MEASUREMENT_REQUEST;
1039
1040 MakeOutgoingFrame(pFrameBuf, &TempLen,
1041 1, &ElementID,
1042 1, &Len,
1043 sizeof(struct rt_measure_req_info), pMeasureReqIE, END_OF_ARGS);
1044
1045 *pFrameLen = *pFrameLen + TempLen;
1046
1047 return;
1048}
1049
1050/*
1051 ==========================================================================
1052 Description:
1053 Insert Measure Report IE into frame.
1054
1055 Parametrs:
1056 1. frame buffer pointer.
1057 2. frame length.
1058 3. Measure Token.
1059 4. Measure Request Mode.
1060 5. Measure Request Type.
1061 6. Length of Report Information
1062 7. Pointer of Report Information Buffer.
1063
1064 Return : None.
1065 ==========================================================================
1066 */
1067static void InsertMeasureReportIE(struct rt_rtmp_adapter *pAd,
1068 u8 *pFrameBuf,
1069 unsigned long *pFrameLen,
1070 struct rt_measure_report_info * pMeasureReportIE,
1071 u8 ReportLnfoLen, u8 *pReportInfo)
1072{
1073 unsigned long TempLen;
1074 unsigned long Len;
1075 u8 ElementID = IE_MEASUREMENT_REPORT;
1076
1077 Len = sizeof(struct rt_measure_report_info) + ReportLnfoLen;
1078
1079 MakeOutgoingFrame(pFrameBuf, &TempLen,
1080 1, &ElementID,
1081 1, &Len, Len, pMeasureReportIE, END_OF_ARGS);
1082
1083 *pFrameLen = *pFrameLen + TempLen;
1084
1085 if ((ReportLnfoLen > 0) && (pReportInfo != NULL)) {
1086 MakeOutgoingFrame(pFrameBuf + *pFrameLen, &TempLen,
1087 ReportLnfoLen, pReportInfo, END_OF_ARGS);
1088
1089 *pFrameLen = *pFrameLen + TempLen;
1090 }
1091 return;
1092}
1093
1094/*
1095 ==========================================================================
1096 Description:
1097 Prepare Measurement request action frame and enqueue it into
1098 management queue waiting for transmition.
1099
1100 Parametrs:
1101 1. the destination mac address of the frame.
1102
1103 Return : None.
1104 ==========================================================================
1105 */
1106void MakeMeasurementReqFrame(struct rt_rtmp_adapter *pAd,
1107 u8 *pOutBuffer,
1108 unsigned long *pFrameLen,
1109 u8 TotalLen,
1110 u8 Category,
1111 u8 Action,
1112 u8 MeasureToken,
1113 u8 MeasureReqMode,
1114 u8 MeasureReqType, u8 NumOfRepetitions)
1115{
1116 unsigned long TempLen;
1117 struct rt_measure_req_info MeasureReqIE;
1118
1119 InsertActField(pAd, (pOutBuffer + *pFrameLen), pFrameLen, Category,
1120 Action);
1121
1122 /* fill Dialog Token */
1123 InsertDialogToken(pAd, (pOutBuffer + *pFrameLen), pFrameLen,
1124 MeasureToken);
1125
1126 /* fill Number of repetitions. */
1127 if (Category == CATEGORY_RM) {
1128 MakeOutgoingFrame((pOutBuffer + *pFrameLen), &TempLen,
1129 2, &NumOfRepetitions, END_OF_ARGS);
1130
1131 *pFrameLen += TempLen;
1132 }
1133 /* prepare Measurement IE. */
1134 NdisZeroMemory(&MeasureReqIE, sizeof(struct rt_measure_req_info));
1135 MeasureReqIE.Token = MeasureToken;
1136 MeasureReqIE.ReqMode.word = MeasureReqMode;
1137 MeasureReqIE.ReqType = MeasureReqType;
1138 InsertMeasureReqIE(pAd, (pOutBuffer + *pFrameLen), pFrameLen,
1139 TotalLen, &MeasureReqIE);
1140
1141 return;
1142}
1143
1144/*
1145 ==========================================================================
1146 Description:
1147 Prepare Measurement report action frame and enqueue it into
1148 management queue waiting for transmition.
1149
1150 Parametrs:
1151 1. the destination mac address of the frame.
1152
1153 Return : None.
1154 ==========================================================================
1155 */
1156void EnqueueMeasurementRep(struct rt_rtmp_adapter *pAd,
1157 u8 *pDA,
1158 u8 DialogToken,
1159 u8 MeasureToken,
1160 u8 MeasureReqMode,
1161 u8 MeasureReqType,
1162 u8 ReportInfoLen, u8 *pReportInfo)
1163{
1164 u8 *pOutBuffer = NULL;
1165 int NStatus;
1166 unsigned long FrameLen;
1167 struct rt_header_802_11 ActHdr;
1168 struct rt_measure_report_info MeasureRepIE;
1169
1170 /* build action frame header. */
1171 MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
1172 pAd->CurrentAddress);
1173
1174 NStatus = MlmeAllocateMemory(pAd, (void *)& pOutBuffer); /*Get an unused nonpaged memory */
1175 if (NStatus != NDIS_STATUS_SUCCESS) {
1176 DBGPRINT(RT_DEBUG_TRACE,
1177 ("%s() allocate memory failed \n", __func__));
1178 return;
1179 }
1180 NdisMoveMemory(pOutBuffer, (char *)& ActHdr, sizeof(struct rt_header_802_11));
1181 FrameLen = sizeof(struct rt_header_802_11);
1182
1183 InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen,
1184 CATEGORY_SPECTRUM, SPEC_MRP);
1185
1186 /* fill Dialog Token */
1187 InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, DialogToken);
1188
1189 /* prepare Measurement IE. */
1190 NdisZeroMemory(&MeasureRepIE, sizeof(struct rt_measure_report_info));
1191 MeasureRepIE.Token = MeasureToken;
1192 MeasureRepIE.ReportMode = MeasureReqMode;
1193 MeasureRepIE.ReportType = MeasureReqType;
1194 InsertMeasureReportIE(pAd, (pOutBuffer + FrameLen), &FrameLen,
1195 &MeasureRepIE, ReportInfoLen, pReportInfo);
1196
1197 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
1198 MlmeFreeMemory(pAd, pOutBuffer);
1199
1200 return;
1201}
1202
1203/*
1204 ==========================================================================
1205 Description:
1206 Prepare TPC Request action frame and enqueue it into
1207 management queue waiting for transmition.
1208
1209 Parametrs:
1210 1. the destination mac address of the frame.
1211
1212 Return : None.
1213 ==========================================================================
1214 */
1215void EnqueueTPCReq(struct rt_rtmp_adapter *pAd, u8 *pDA, u8 DialogToken)
1216{
1217 u8 *pOutBuffer = NULL;
1218 int NStatus;
1219 unsigned long FrameLen;
1220
1221 struct rt_header_802_11 ActHdr;
1222
1223 /* build action frame header. */
1224 MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
1225 pAd->CurrentAddress);
1226
1227 NStatus = MlmeAllocateMemory(pAd, (void *)& pOutBuffer); /*Get an unused nonpaged memory */
1228 if (NStatus != NDIS_STATUS_SUCCESS) {
1229 DBGPRINT(RT_DEBUG_TRACE,
1230 ("%s() allocate memory failed \n", __func__));
1231 return;
1232 }
1233 NdisMoveMemory(pOutBuffer, (char *)& ActHdr, sizeof(struct rt_header_802_11));
1234 FrameLen = sizeof(struct rt_header_802_11);
1235
1236 InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen,
1237 CATEGORY_SPECTRUM, SPEC_TPCRQ);
1238
1239 /* fill Dialog Token */
1240 InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, DialogToken);
1241
1242 /* Insert TPC Request IE. */
1243 InsertTpcReqIE(pAd, (pOutBuffer + FrameLen), &FrameLen);
1244
1245 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
1246 MlmeFreeMemory(pAd, pOutBuffer);
1247
1248 return;
1249}
1250
1251/*
1252 ==========================================================================
1253 Description:
1254 Prepare TPC Report action frame and enqueue it into
1255 management queue waiting for transmition.
1256
1257 Parametrs:
1258 1. the destination mac address of the frame.
1259
1260 Return : None.
1261 ==========================================================================
1262 */
1263void EnqueueTPCRep(struct rt_rtmp_adapter *pAd,
1264 u8 *pDA,
1265 u8 DialogToken, u8 TxPwr, u8 LinkMargin)
1266{
1267 u8 *pOutBuffer = NULL;
1268 int NStatus;
1269 unsigned long FrameLen;
1270
1271 struct rt_header_802_11 ActHdr;
1272
1273 /* build action frame header. */
1274 MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
1275 pAd->CurrentAddress);
1276
1277 NStatus = MlmeAllocateMemory(pAd, (void *)& pOutBuffer); /*Get an unused nonpaged memory */
1278 if (NStatus != NDIS_STATUS_SUCCESS) {
1279 DBGPRINT(RT_DEBUG_TRACE,
1280 ("%s() allocate memory failed \n", __func__));
1281 return;
1282 }
1283 NdisMoveMemory(pOutBuffer, (char *)& ActHdr, sizeof(struct rt_header_802_11));
1284 FrameLen = sizeof(struct rt_header_802_11);
1285
1286 InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen,
1287 CATEGORY_SPECTRUM, SPEC_TPCRP);
1288
1289 /* fill Dialog Token */
1290 InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, DialogToken);
1291
1292 /* Insert TPC Request IE. */
1293 InsertTpcReportIE(pAd, (pOutBuffer + FrameLen), &FrameLen, TxPwr,
1294 LinkMargin);
1295
1296 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
1297 MlmeFreeMemory(pAd, pOutBuffer);
1298
1299 return;
1300}
1301
1302/*
1303 ==========================================================================
1304 Description:
1305 Prepare Channel Switch Announcement action frame and enqueue it into
1306 management queue waiting for transmition.
1307
1308 Parametrs:
1309 1. the destination mac address of the frame.
1310 2. Channel switch announcement mode.
1311 2. a New selected channel.
1312
1313 Return : None.
1314 ==========================================================================
1315 */
1316void EnqueueChSwAnn(struct rt_rtmp_adapter *pAd,
1317 u8 *pDA, u8 ChSwMode, u8 NewCh)
1318{
1319 u8 *pOutBuffer = NULL;
1320 int NStatus;
1321 unsigned long FrameLen;
1322
1323 struct rt_header_802_11 ActHdr;
1324
1325 /* build action frame header. */
1326 MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
1327 pAd->CurrentAddress);
1328
1329 NStatus = MlmeAllocateMemory(pAd, (void *)& pOutBuffer); /*Get an unused nonpaged memory */
1330 if (NStatus != NDIS_STATUS_SUCCESS) {
1331 DBGPRINT(RT_DEBUG_TRACE,
1332 ("%s() allocate memory failed \n", __func__));
1333 return;
1334 }
1335 NdisMoveMemory(pOutBuffer, (char *)& ActHdr, sizeof(struct rt_header_802_11));
1336 FrameLen = sizeof(struct rt_header_802_11);
1337
1338 InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen,
1339 CATEGORY_SPECTRUM, SPEC_CHANNEL_SWITCH);
1340
1341 InsertChSwAnnIE(pAd, (pOutBuffer + FrameLen), &FrameLen, ChSwMode,
1342 NewCh, 0);
1343
1344 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
1345 MlmeFreeMemory(pAd, pOutBuffer);
1346
1347 return;
1348}
1349
1350static BOOLEAN DfsRequirementCheck(struct rt_rtmp_adapter *pAd, u8 Channel)
1351{
1352 BOOLEAN Result = FALSE;
1353 int i;
1354
1355 do {
1356 /* check DFS procedure is running. */
1357 /* make sure DFS procedure won't start twice. */
1358 if (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE) {
1359 Result = FALSE;
1360 break;
1361 }
1362 /* check the new channel carried from Channel Switch Announcemnet is valid. */
1363 for (i = 0; i < pAd->ChannelListNum; i++) {
1364 if ((Channel == pAd->ChannelList[i].Channel)
1365 && (pAd->ChannelList[i].RemainingTimeForUse == 0)) {
1366 /* found radar signal in the channel. the channel can't use at least for 30 minutes. */
1367 pAd->ChannelList[i].RemainingTimeForUse = 1800; /*30 min = 1800 sec */
1368 Result = TRUE;
1369 break;
1370 }
1371 }
1372 } while (FALSE);
1373
1374 return Result;
1375}
1376
1377void NotifyChSwAnnToPeerAPs(struct rt_rtmp_adapter *pAd,
1378 u8 *pRA,
1379 u8 *pTA, u8 ChSwMode, u8 Channel)
1380{
1381}
1382
1383static void StartDFSProcedure(struct rt_rtmp_adapter *pAd,
1384 u8 Channel, u8 ChSwMode)
1385{
1386 /* start DFS procedure */
1387 pAd->CommonCfg.Channel = Channel;
1388
1389 N_ChannelCheck(pAd);
1390
1391 pAd->CommonCfg.RadarDetect.RDMode = RD_SWITCHING_MODE;
1392 pAd->CommonCfg.RadarDetect.CSCount = 0;
1393}
1394
1395/*
1396 ==========================================================================
1397 Description:
1398 Channel Switch Announcement action frame sanity check.
1399
1400 Parametrs:
1401 1. MLME message containing the received frame
1402 2. message length.
1403 3. Channel switch announcement information buffer.
1404
1405 Return : None.
1406 ==========================================================================
1407 */
1408
1409/*
1410 Channel Switch Announcement IE.
1411 +----+-----+-----------+------------+-----------+
1412 | ID | Len |Ch Sw Mode | New Ch Num | Ch Sw Cnt |
1413 +----+-----+-----------+------------+-----------+
1414 1 1 1 1 1
1415*/
1416static BOOLEAN PeerChSwAnnSanity(struct rt_rtmp_adapter *pAd,
1417 void * pMsg,
1418 unsigned long MsgLen,
1419 struct rt_ch_sw_ann_info * pChSwAnnInfo)
1420{
1421 struct rt_frame_802_11 * Fr = (struct rt_frame_802_11 *) pMsg;
1422 u8 *pFramePtr = Fr->Octet;
1423 BOOLEAN result = FALSE;
1424 struct rt_eid * eid_ptr;
1425
1426 /* skip 802.11 header. */
1427 MsgLen -= sizeof(struct rt_header_802_11);
1428
1429 /* skip category and action code. */
1430 pFramePtr += 2;
1431 MsgLen -= 2;
1432
1433 if (pChSwAnnInfo == NULL)
1434 return result;
1435
1436 eid_ptr = (struct rt_eid *) pFramePtr;
1437 while (((u8 *) eid_ptr + eid_ptr->Len + 1) <
1438 ((u8 *)pFramePtr + MsgLen)) {
1439 switch (eid_ptr->Eid) {
1440 case IE_CHANNEL_SWITCH_ANNOUNCEMENT:
1441 NdisMoveMemory(&pChSwAnnInfo->ChSwMode, eid_ptr->Octet,
1442 1);
1443 NdisMoveMemory(&pChSwAnnInfo->Channel,
1444 eid_ptr->Octet + 1, 1);
1445 NdisMoveMemory(&pChSwAnnInfo->ChSwCnt,
1446 eid_ptr->Octet + 2, 1);
1447
1448 result = TRUE;
1449 break;
1450
1451 default:
1452 break;
1453 }
1454 eid_ptr = (struct rt_eid *) ((u8 *) eid_ptr + 2 + eid_ptr->Len);
1455 }
1456
1457 return result;
1458}
1459
1460/*
1461 ==========================================================================
1462 Description:
1463 Measurement request action frame sanity check.
1464
1465 Parametrs:
1466 1. MLME message containing the received frame
1467 2. message length.
1468 3. Measurement request information buffer.
1469
1470 Return : None.
1471 ==========================================================================
1472 */
1473static BOOLEAN PeerMeasureReqSanity(struct rt_rtmp_adapter *pAd,
1474 void * pMsg,
1475 unsigned long MsgLen,
1476 u8 *pDialogToken,
1477 struct rt_measure_req_info * pMeasureReqInfo,
1478 struct rt_measure_req * pMeasureReq)
1479{
1480 struct rt_frame_802_11 * Fr = (struct rt_frame_802_11 *) pMsg;
1481 u8 *pFramePtr = Fr->Octet;
1482 BOOLEAN result = FALSE;
1483 struct rt_eid * eid_ptr;
1484 u8 *ptr;
1485 u64 MeasureStartTime;
1486 u16 MeasureDuration;
1487
1488 /* skip 802.11 header. */
1489 MsgLen -= sizeof(struct rt_header_802_11);
1490
1491 /* skip category and action code. */
1492 pFramePtr += 2;
1493 MsgLen -= 2;
1494
1495 if (pMeasureReqInfo == NULL)
1496 return result;
1497
1498 NdisMoveMemory(pDialogToken, pFramePtr, 1);
1499 pFramePtr += 1;
1500 MsgLen -= 1;
1501
1502 eid_ptr = (struct rt_eid *) pFramePtr;
1503 while (((u8 *) eid_ptr + eid_ptr->Len + 1) <
1504 ((u8 *)pFramePtr + MsgLen)) {
1505 switch (eid_ptr->Eid) {
1506 case IE_MEASUREMENT_REQUEST:
1507 NdisMoveMemory(&pMeasureReqInfo->Token, eid_ptr->Octet,
1508 1);
1509 NdisMoveMemory(&pMeasureReqInfo->ReqMode.word,
1510 eid_ptr->Octet + 1, 1);
1511 NdisMoveMemory(&pMeasureReqInfo->ReqType,
1512 eid_ptr->Octet + 2, 1);
1513 ptr = (u8 *)(eid_ptr->Octet + 3);
1514 NdisMoveMemory(&pMeasureReq->ChNum, ptr, 1);
1515 NdisMoveMemory(&MeasureStartTime, ptr + 1, 8);
1516 pMeasureReq->MeasureStartTime =
1517 SWAP64(MeasureStartTime);
1518 NdisMoveMemory(&MeasureDuration, ptr + 9, 2);
1519 pMeasureReq->MeasureDuration = SWAP16(MeasureDuration);
1520
1521 result = TRUE;
1522 break;
1523
1524 default:
1525 break;
1526 }
1527 eid_ptr = (struct rt_eid *) ((u8 *) eid_ptr + 2 + eid_ptr->Len);
1528 }
1529
1530 return result;
1531}
1532
1533/*
1534 ==========================================================================
1535 Description:
1536 Measurement report action frame sanity check.
1537
1538 Parametrs:
1539 1. MLME message containing the received frame
1540 2. message length.
1541 3. Measurement report information buffer.
1542 4. basic report information buffer.
1543
1544 Return : None.
1545 ==========================================================================
1546 */
1547
1548/*
1549 Measurement Report IE.
1550 +----+-----+-------+-------------+--------------+----------------+
1551 | ID | Len | Token | Report Mode | Measure Type | Measure Report |
1552 +----+-----+-------+-------------+--------------+----------------+
1553 1 1 1 1 1 variable
1554
1555 Basic Report.
1556 +--------+------------+----------+-----+
1557 | Ch Num | Start Time | Duration | Map |
1558 +--------+------------+----------+-----+
1559 1 8 2 1
1560
1561 Map Field Bit Format.
1562 +-----+---------------+---------------------+-------+------------+----------+
1563 | Bss | OFDM Preamble | Unidentified signal | Radar | Unmeasured | Reserved |
1564 +-----+---------------+---------------------+-------+------------+----------+
1565 0 1 2 3 4 5-7
1566*/
1567static BOOLEAN PeerMeasureReportSanity(struct rt_rtmp_adapter *pAd,
1568 void * pMsg,
1569 unsigned long MsgLen,
1570 u8 *pDialogToken,
1571 struct rt_measure_report_info *
1572 pMeasureReportInfo,
1573 u8 *pReportBuf)
1574{
1575 struct rt_frame_802_11 * Fr = (struct rt_frame_802_11 *) pMsg;
1576 u8 *pFramePtr = Fr->Octet;
1577 BOOLEAN result = FALSE;
1578 struct rt_eid * eid_ptr;
1579 u8 *ptr;
1580
1581 /* skip 802.11 header. */
1582 MsgLen -= sizeof(struct rt_header_802_11);
1583
1584 /* skip category and action code. */
1585 pFramePtr += 2;
1586 MsgLen -= 2;
1587
1588 if (pMeasureReportInfo == NULL)
1589 return result;
1590
1591 NdisMoveMemory(pDialogToken, pFramePtr, 1);
1592 pFramePtr += 1;
1593 MsgLen -= 1;
1594
1595 eid_ptr = (struct rt_eid *) pFramePtr;
1596 while (((u8 *) eid_ptr + eid_ptr->Len + 1) <
1597 ((u8 *)pFramePtr + MsgLen)) {
1598 switch (eid_ptr->Eid) {
1599 case IE_MEASUREMENT_REPORT:
1600 NdisMoveMemory(&pMeasureReportInfo->Token,
1601 eid_ptr->Octet, 1);
1602 NdisMoveMemory(&pMeasureReportInfo->ReportMode,
1603 eid_ptr->Octet + 1, 1);
1604 NdisMoveMemory(&pMeasureReportInfo->ReportType,
1605 eid_ptr->Octet + 2, 1);
1606 if (pMeasureReportInfo->ReportType == RM_BASIC) {
1607 struct rt_measure_basic_report * pReport =
1608 (struct rt_measure_basic_report *) pReportBuf;
1609 ptr = (u8 *)(eid_ptr->Octet + 3);
1610 NdisMoveMemory(&pReport->ChNum, ptr, 1);
1611 NdisMoveMemory(&pReport->MeasureStartTime,
1612 ptr + 1, 8);
1613 NdisMoveMemory(&pReport->MeasureDuration,
1614 ptr + 9, 2);
1615 NdisMoveMemory(&pReport->Map, ptr + 11, 1);
1616
1617 } else if (pMeasureReportInfo->ReportType == RM_CCA) {
1618 struct rt_measure_cca_report * pReport =
1619 (struct rt_measure_cca_report *) pReportBuf;
1620 ptr = (u8 *)(eid_ptr->Octet + 3);
1621 NdisMoveMemory(&pReport->ChNum, ptr, 1);
1622 NdisMoveMemory(&pReport->MeasureStartTime,
1623 ptr + 1, 8);
1624 NdisMoveMemory(&pReport->MeasureDuration,
1625 ptr + 9, 2);
1626 NdisMoveMemory(&pReport->CCA_Busy_Fraction,
1627 ptr + 11, 1);
1628
1629 } else if (pMeasureReportInfo->ReportType ==
1630 RM_RPI_HISTOGRAM) {
1631 struct rt_measure_rpi_report * pReport =
1632 (struct rt_measure_rpi_report *) pReportBuf;
1633 ptr = (u8 *)(eid_ptr->Octet + 3);
1634 NdisMoveMemory(&pReport->ChNum, ptr, 1);
1635 NdisMoveMemory(&pReport->MeasureStartTime,
1636 ptr + 1, 8);
1637 NdisMoveMemory(&pReport->MeasureDuration,
1638 ptr + 9, 2);
1639 NdisMoveMemory(&pReport->RPI_Density, ptr + 11,
1640 8);
1641 }
1642 result = TRUE;
1643 break;
1644
1645 default:
1646 break;
1647 }
1648 eid_ptr = (struct rt_eid *) ((u8 *) eid_ptr + 2 + eid_ptr->Len);
1649 }
1650
1651 return result;
1652}
1653
1654/*
1655 ==========================================================================
1656 Description:
1657 TPC Request action frame sanity check.
1658
1659 Parametrs:
1660 1. MLME message containing the received frame
1661 2. message length.
1662 3. Dialog Token.
1663
1664 Return : None.
1665 ==========================================================================
1666 */
1667static BOOLEAN PeerTpcReqSanity(struct rt_rtmp_adapter *pAd,
1668 void * pMsg,
1669 unsigned long MsgLen, u8 *pDialogToken)
1670{
1671 struct rt_frame_802_11 * Fr = (struct rt_frame_802_11 *) pMsg;
1672 u8 *pFramePtr = Fr->Octet;
1673 BOOLEAN result = FALSE;
1674 struct rt_eid * eid_ptr;
1675
1676 MsgLen -= sizeof(struct rt_header_802_11);
1677
1678 /* skip category and action code. */
1679 pFramePtr += 2;
1680 MsgLen -= 2;
1681
1682 if (pDialogToken == NULL)
1683 return result;
1684
1685 NdisMoveMemory(pDialogToken, pFramePtr, 1);
1686 pFramePtr += 1;
1687 MsgLen -= 1;
1688
1689 eid_ptr = (struct rt_eid *) pFramePtr;
1690 while (((u8 *) eid_ptr + eid_ptr->Len + 1) <
1691 ((u8 *)pFramePtr + MsgLen)) {
1692 switch (eid_ptr->Eid) {
1693 case IE_TPC_REQUEST:
1694 result = TRUE;
1695 break;
1696
1697 default:
1698 break;
1699 }
1700 eid_ptr = (struct rt_eid *) ((u8 *) eid_ptr + 2 + eid_ptr->Len);
1701 }
1702
1703 return result;
1704}
1705
1706/*
1707 ==========================================================================
1708 Description:
1709 TPC Report action frame sanity check.
1710
1711 Parametrs:
1712 1. MLME message containing the received frame
1713 2. message length.
1714 3. Dialog Token.
1715 4. TPC Report IE.
1716
1717 Return : None.
1718 ==========================================================================
1719 */
1720static BOOLEAN PeerTpcRepSanity(struct rt_rtmp_adapter *pAd,
1721 void * pMsg,
1722 unsigned long MsgLen,
1723 u8 *pDialogToken,
1724 struct rt_tpc_report_info * pTpcRepInfo)
1725{
1726 struct rt_frame_802_11 * Fr = (struct rt_frame_802_11 *) pMsg;
1727 u8 *pFramePtr = Fr->Octet;
1728 BOOLEAN result = FALSE;
1729 struct rt_eid * eid_ptr;
1730
1731 MsgLen -= sizeof(struct rt_header_802_11);
1732
1733 /* skip category and action code. */
1734 pFramePtr += 2;
1735 MsgLen -= 2;
1736
1737 if (pDialogToken == NULL)
1738 return result;
1739
1740 NdisMoveMemory(pDialogToken, pFramePtr, 1);
1741 pFramePtr += 1;
1742 MsgLen -= 1;
1743
1744 eid_ptr = (struct rt_eid *) pFramePtr;
1745 while (((u8 *) eid_ptr + eid_ptr->Len + 1) <
1746 ((u8 *)pFramePtr + MsgLen)) {
1747 switch (eid_ptr->Eid) {
1748 case IE_TPC_REPORT:
1749 NdisMoveMemory(&pTpcRepInfo->TxPwr, eid_ptr->Octet, 1);
1750 NdisMoveMemory(&pTpcRepInfo->LinkMargin,
1751 eid_ptr->Octet + 1, 1);
1752 result = TRUE;
1753 break;
1754
1755 default:
1756 break;
1757 }
1758 eid_ptr = (struct rt_eid *) ((u8 *) eid_ptr + 2 + eid_ptr->Len);
1759 }
1760
1761 return result;
1762}
1763
1764/*
1765 ==========================================================================
1766 Description:
1767 Channel Switch Announcement action frame handler.
1768
1769 Parametrs:
1770 Elme - MLME message containing the received frame
1771
1772 Return : None.
1773 ==========================================================================
1774 */
1775static void PeerChSwAnnAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
1776{
1777 struct rt_ch_sw_ann_info ChSwAnnInfo;
1778 struct rt_frame_802_11 * pFr = (struct rt_frame_802_11 *) Elem->Msg;
1779 u8 index = 0, Channel = 0, NewChannel = 0;
1780 unsigned long Bssidx = 0;
1781
1782 NdisZeroMemory(&ChSwAnnInfo, sizeof(struct rt_ch_sw_ann_info));
1783 if (!PeerChSwAnnSanity(pAd, Elem->Msg, Elem->MsgLen, &ChSwAnnInfo)) {
1784 DBGPRINT(RT_DEBUG_TRACE,
1785 ("Invalid Channel Switch Action Frame.\n"));
1786 return;
1787 }
1788
1789 if (pAd->OpMode == OPMODE_STA) {
1790 Bssidx =
1791 BssTableSearch(&pAd->ScanTab, pFr->Hdr.Addr3,
1792 pAd->CommonCfg.Channel);
1793 if (Bssidx == BSS_NOT_FOUND) {
1794 DBGPRINT(RT_DEBUG_TRACE,
1795 ("PeerChSwAnnAction - Bssidx is not found\n"));
1796 return;
1797 }
1798
1799 DBGPRINT(RT_DEBUG_TRACE,
1800 ("\n****Bssidx is %d, Channel = %d\n", index,
1801 pAd->ScanTab.BssEntry[Bssidx].Channel));
1802 hex_dump("SSID", pAd->ScanTab.BssEntry[Bssidx].Bssid, 6);
1803
1804 Channel = pAd->CommonCfg.Channel;
1805 NewChannel = ChSwAnnInfo.Channel;
1806
1807 if ((pAd->CommonCfg.bIEEE80211H == 1) && (NewChannel != 0)
1808 && (Channel != NewChannel)) {
1809 /* Switching to channel 1 can prevent from rescanning the current channel immediately (by auto reconnection). */
1810 /* In addition, clear the MLME queue and the scan table to discard the RX packets and previous scanning results. */
1811 AsicSwitchChannel(pAd, 1, FALSE);
1812 AsicLockChannel(pAd, 1);
1813 LinkDown(pAd, FALSE);
1814 MlmeQueueInit(&pAd->Mlme.Queue);
1815 BssTableInit(&pAd->ScanTab);
1816 RTMPusecDelay(1000000); /* use delay to prevent STA do reassoc */
1817
1818 /* channel sanity check */
1819 for (index = 0; index < pAd->ChannelListNum; index++) {
1820 if (pAd->ChannelList[index].Channel ==
1821 NewChannel) {
1822 pAd->ScanTab.BssEntry[Bssidx].Channel =
1823 NewChannel;
1824 pAd->CommonCfg.Channel = NewChannel;
1825 AsicSwitchChannel(pAd,
1826 pAd->CommonCfg.
1827 Channel, FALSE);
1828 AsicLockChannel(pAd,
1829 pAd->CommonCfg.Channel);
1830 DBGPRINT(RT_DEBUG_TRACE,
1831 ("&&&&&&&&&&&&&&&&PeerChSwAnnAction - STA receive channel switch announcement IE (New Channel =%d)\n",
1832 NewChannel));
1833 break;
1834 }
1835 }
1836
1837 if (index >= pAd->ChannelListNum) {
1838 DBGPRINT_ERR("&&&&&&&&&&&&&&&&&&&&&&&&&&PeerChSwAnnAction(can not find New Channel=%d in ChannelList[%d]\n", pAd->CommonCfg.Channel, pAd->ChannelListNum);
1839 }
1840 }
1841 }
1842
1843 return;
1844}
1845
1846/*
1847 ==========================================================================
1848 Description:
1849 Measurement Request action frame handler.
1850
1851 Parametrs:
1852 Elme - MLME message containing the received frame
1853
1854 Return : None.
1855 ==========================================================================
1856 */
1857static void PeerMeasureReqAction(struct rt_rtmp_adapter *pAd,
1858 struct rt_mlme_queue_elem *Elem)
1859{
1860 struct rt_frame_802_11 * pFr = (struct rt_frame_802_11 *) Elem->Msg;
1861 u8 DialogToken;
1862 struct rt_measure_req_info MeasureReqInfo;
1863 struct rt_measure_req MeasureReq;
1864 MEASURE_REPORT_MODE ReportMode;
1865
1866 if (PeerMeasureReqSanity
1867 (pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &MeasureReqInfo,
1868 &MeasureReq)) {
1869 ReportMode.word = 0;
1870 ReportMode.field.Incapable = 1;
1871 EnqueueMeasurementRep(pAd, pFr->Hdr.Addr2, DialogToken,
1872 MeasureReqInfo.Token, ReportMode.word,
1873 MeasureReqInfo.ReqType, 0, NULL);
1874 }
1875
1876 return;
1877}
1878
1879/*
1880 ==========================================================================
1881 Description:
1882 Measurement Report action frame handler.
1883
1884 Parametrs:
1885 Elme - MLME message containing the received frame
1886
1887 Return : None.
1888 ==========================================================================
1889 */
1890static void PeerMeasureReportAction(struct rt_rtmp_adapter *pAd,
1891 struct rt_mlme_queue_elem *Elem)
1892{
1893 struct rt_measure_report_info MeasureReportInfo;
1894 struct rt_frame_802_11 * pFr = (struct rt_frame_802_11 *) Elem->Msg;
1895 u8 DialogToken;
1896 u8 *pMeasureReportInfo;
1897
1898/* if (pAd->CommonCfg.bIEEE80211H != TRUE) */
1899/* return; */
1900
1901 pMeasureReportInfo = kmalloc(sizeof(struct rt_measure_rpi_report), GFP_ATOMIC);
1902 if (pMeasureReportInfo == NULL) {
1903 DBGPRINT(RT_DEBUG_ERROR,
1904 ("%s unable to alloc memory for measure report buffer (size=%zu).\n",
1905 __func__, sizeof(struct rt_measure_rpi_report)));
1906 return;
1907 }
1908
1909 NdisZeroMemory(&MeasureReportInfo, sizeof(struct rt_measure_report_info));
1910 NdisZeroMemory(pMeasureReportInfo, sizeof(struct rt_measure_rpi_report));
1911 if (PeerMeasureReportSanity
1912 (pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &MeasureReportInfo,
1913 pMeasureReportInfo)) {
1914 do {
1915 struct rt_measure_req_entry *pEntry = NULL;
1916
1917 /* Not a autonomous measure report. */
1918 /* check the dialog token field. drop it if the dialog token doesn't match. */
1919 if ((DialogToken != 0)
1920 && ((pEntry = MeasureReqLookUp(pAd, DialogToken)) ==
1921 NULL))
1922 break;
1923
1924 if (pEntry != NULL)
1925 MeasureReqDelete(pAd, pEntry->DialogToken);
1926
1927 if (MeasureReportInfo.ReportType == RM_BASIC) {
1928 struct rt_measure_basic_report * pBasicReport =
1929 (struct rt_measure_basic_report *) pMeasureReportInfo;
1930 if ((pBasicReport->Map.field.Radar)
1931 &&
1932 (DfsRequirementCheck
1933 (pAd, pBasicReport->ChNum) == TRUE)) {
1934 NotifyChSwAnnToPeerAPs(pAd,
1935 pFr->Hdr.Addr1,
1936 pFr->Hdr.Addr2,
1937 1,
1938 pBasicReport->
1939 ChNum);
1940 StartDFSProcedure(pAd,
1941 pBasicReport->ChNum,
1942 1);
1943 }
1944 }
1945 } while (FALSE);
1946 } else
1947 DBGPRINT(RT_DEBUG_TRACE,
1948 ("Invalid Measurement Report Frame.\n"));
1949
1950 kfree(pMeasureReportInfo);
1951
1952 return;
1953}
1954
1955/*
1956 ==========================================================================
1957 Description:
1958 TPC Request action frame handler.
1959
1960 Parametrs:
1961 Elme - MLME message containing the received frame
1962
1963 Return : None.
1964 ==========================================================================
1965 */
1966static void PeerTpcReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
1967{
1968 struct rt_frame_802_11 * pFr = (struct rt_frame_802_11 *) Elem->Msg;
1969 u8 *pFramePtr = pFr->Octet;
1970 u8 DialogToken;
1971 u8 TxPwr = GetCurTxPwr(pAd, Elem->Wcid);
1972 u8 LinkMargin = 0;
1973 char RealRssi;
1974
1975 /* link margin: Ratio of the received signal power to the minimum desired by the station (STA). The */
1976 /* STA may incorporate rate information and channel conditions, including interference, into its computation */
1977 /* of link margin. */
1978
1979 RealRssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0),
1980 ConvertToRssi(pAd, Elem->Rssi1, RSSI_1),
1981 ConvertToRssi(pAd, Elem->Rssi2, RSSI_2));
1982
1983 /* skip Category and action code. */
1984 pFramePtr += 2;
1985
1986 /* Dialog token. */
1987 NdisMoveMemory(&DialogToken, pFramePtr, 1);
1988
1989 LinkMargin = (RealRssi / MIN_RCV_PWR);
1990 if (PeerTpcReqSanity(pAd, Elem->Msg, Elem->MsgLen, &DialogToken))
1991 EnqueueTPCRep(pAd, pFr->Hdr.Addr2, DialogToken, TxPwr,
1992 LinkMargin);
1993
1994 return;
1995}
1996
1997/*
1998 ==========================================================================
1999 Description:
2000 TPC Report action frame handler.
2001
2002 Parametrs:
2003 Elme - MLME message containing the received frame
2004
2005 Return : None.
2006 ==========================================================================
2007 */
2008static void PeerTpcRepAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
2009{
2010 u8 DialogToken;
2011 struct rt_tpc_report_info TpcRepInfo;
2012 struct rt_tpc_req_entry *pEntry = NULL;
2013
2014 NdisZeroMemory(&TpcRepInfo, sizeof(struct rt_tpc_report_info));
2015 if (PeerTpcRepSanity
2016 (pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &TpcRepInfo)) {
2017 pEntry = TpcReqLookUp(pAd, DialogToken);
2018 if (pEntry != NULL) {
2019 TpcReqDelete(pAd, pEntry->DialogToken);
2020 DBGPRINT(RT_DEBUG_TRACE,
2021 ("%s: DialogToken=%x, TxPwr=%d, LinkMargin=%d\n",
2022 __func__, DialogToken, TpcRepInfo.TxPwr,
2023 TpcRepInfo.LinkMargin));
2024 }
2025 }
2026
2027 return;
2028}
2029
2030/*
2031 ==========================================================================
2032 Description:
2033 Spectrun action frames Handler such as channel switch annoucement,
2034 measurement report, measurement request actions frames.
2035
2036 Parametrs:
2037 Elme - MLME message containing the received frame
2038
2039 Return : None.
2040 ==========================================================================
2041 */
2042void PeerSpectrumAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
2043{
2044
2045 u8 Action = Elem->Msg[LENGTH_802_11 + 1];
2046
2047 if (pAd->CommonCfg.bIEEE80211H != TRUE)
2048 return;
2049
2050 switch (Action) {
2051 case SPEC_MRQ:
2052 /* current rt2860 unable do such measure specified in Measurement Request. */
2053 /* reject all measurement request. */
2054 PeerMeasureReqAction(pAd, Elem);
2055 break;
2056
2057 case SPEC_MRP:
2058 PeerMeasureReportAction(pAd, Elem);
2059 break;
2060
2061 case SPEC_TPCRQ:
2062 PeerTpcReqAction(pAd, Elem);
2063 break;
2064
2065 case SPEC_TPCRP:
2066 PeerTpcRepAction(pAd, Elem);
2067 break;
2068
2069 case SPEC_CHANNEL_SWITCH:
2070
2071 PeerChSwAnnAction(pAd, Elem);
2072 break;
2073 }
2074
2075 return;
2076}
2077
2078/*
2079 ==========================================================================
2080 Description:
2081
2082 Parametrs:
2083
2084 Return : None.
2085 ==========================================================================
2086 */
2087int Set_MeasureReq_Proc(struct rt_rtmp_adapter *pAd, char *arg)
2088{
2089 u32 Aid = 1;
2090 u32 ArgIdx;
2091 char *thisChar;
2092
2093 MEASURE_REQ_MODE MeasureReqMode;
2094 u8 MeasureReqToken = RandomByte(pAd);
2095 u8 MeasureReqType = RM_BASIC;
2096 u8 MeasureCh = 1;
2097 u64 MeasureStartTime = GetCurrentTimeStamp(pAd);
2098 struct rt_measure_req MeasureReq;
2099 u8 TotalLen;
2100
2101 struct rt_header_802_11 ActHdr;
2102 u8 *pOutBuffer = NULL;
2103 int NStatus;
2104 unsigned long FrameLen;
2105
2106 NStatus = MlmeAllocateMemory(pAd, (void *)& pOutBuffer); /*Get an unused nonpaged memory */
2107 if (NStatus != NDIS_STATUS_SUCCESS) {
2108 DBGPRINT(RT_DEBUG_TRACE,
2109 ("%s() allocate memory failed \n", __func__));
2110 goto END_OF_MEASURE_REQ;
2111 }
2112
2113 ArgIdx = 1;
2114 while ((thisChar = strsep((char **)&arg, "-")) != NULL) {
2115 switch (ArgIdx) {
2116 case 1: /* Aid. */
2117 Aid = (u8)simple_strtol(thisChar, 0, 16);
2118 break;
2119
2120 case 2: /* Measurement Request Type. */
2121 MeasureReqType = simple_strtol(thisChar, 0, 16);
2122 if (MeasureReqType > 3) {
2123 DBGPRINT(RT_DEBUG_ERROR,
2124 ("%s: unknow MeasureReqType(%d)\n",
2125 __func__, MeasureReqType));
2126 goto END_OF_MEASURE_REQ;
2127 }
2128 break;
2129
2130 case 3: /* Measurement channel. */
2131 MeasureCh = (u8)simple_strtol(thisChar, 0, 16);
2132 break;
2133 }
2134 ArgIdx++;
2135 }
2136
2137 DBGPRINT(RT_DEBUG_TRACE,
2138 ("%s::Aid = %d, MeasureReqType=%d MeasureCh=%d\n", __func__,
2139 Aid, MeasureReqType, MeasureCh));
2140 if (!VALID_WCID(Aid)) {
2141 DBGPRINT(RT_DEBUG_ERROR,
2142 ("%s: unknow sta of Aid(%d)\n", __func__, Aid));
2143 goto END_OF_MEASURE_REQ;
2144 }
2145
2146 MeasureReqMode.word = 0;
2147 MeasureReqMode.field.Enable = 1;
2148
2149 MeasureReqInsert(pAd, MeasureReqToken);
2150
2151 /* build action frame header. */
2152 MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0,
2153 pAd->MacTab.Content[Aid].Addr, pAd->CurrentAddress);
2154
2155 NdisMoveMemory(pOutBuffer, (char *)& ActHdr, sizeof(struct rt_header_802_11));
2156 FrameLen = sizeof(struct rt_header_802_11);
2157
2158 TotalLen = sizeof(struct rt_measure_req_info) + sizeof(struct rt_measure_req);
2159
2160 MakeMeasurementReqFrame(pAd, pOutBuffer, &FrameLen,
2161 sizeof(struct rt_measure_req_info), CATEGORY_RM, RM_BASIC,
2162 MeasureReqToken, MeasureReqMode.word,
2163 MeasureReqType, 0);
2164
2165 MeasureReq.ChNum = MeasureCh;
2166 MeasureReq.MeasureStartTime = cpu2le64(MeasureStartTime);
2167 MeasureReq.MeasureDuration = cpu2le16(2000);
2168
2169 {
2170 unsigned long TempLen;
2171 MakeOutgoingFrame(pOutBuffer + FrameLen, &TempLen,
2172 sizeof(struct rt_measure_req), &MeasureReq,
2173 END_OF_ARGS);
2174 FrameLen += TempLen;
2175 }
2176
2177 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, (u32)FrameLen);
2178
2179END_OF_MEASURE_REQ:
2180 MlmeFreeMemory(pAd, pOutBuffer);
2181
2182 return TRUE;
2183}
2184
2185int Set_TpcReq_Proc(struct rt_rtmp_adapter *pAd, char *arg)
2186{
2187 u32 Aid;
2188
2189 u8 TpcReqToken = RandomByte(pAd);
2190
2191 Aid = (u32)simple_strtol(arg, 0, 16);
2192
2193 DBGPRINT(RT_DEBUG_TRACE, ("%s::Aid = %d\n", __func__, Aid));
2194 if (!VALID_WCID(Aid)) {
2195 DBGPRINT(RT_DEBUG_ERROR,
2196 ("%s: unknow sta of Aid(%d)\n", __func__, Aid));
2197 return TRUE;
2198 }
2199
2200 TpcReqInsert(pAd, TpcReqToken);
2201
2202 EnqueueTPCReq(pAd, pAd->MacTab.Content[Aid].Addr, TpcReqToken);
2203
2204 return TRUE;
2205}