aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/rt2860/common
diff options
context:
space:
mode:
authorBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2009-09-22 14:44:07 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-12-11 15:21:44 -0500
commitca97b8388838ee9ea4b4bad04948f8f7f8a607a3 (patch)
tree2f45db84158e603cbde3871fb9f5137448ef6773 /drivers/staging/rt2860/common
parent3441d25f03a078d493777f165194f8623ec2750f (diff)
Staging: rt28x0: updates from vendor's V2.1.0.0 drivers
Port changes from: * 2009_0420_RT2860_Linux_STA_V2.1.0.0 * 2009_0302_RT2870_Linux_STA_v2.1.0.0 * 2009_0525_RT3070_Linux_STA_v2.1.1.0 to in-kernel drivers. From the RT2860 driver release note: [2.1.0.0] 1. New generation schema for multiple OS porting 2. Fixed Ad-hoc ping failed in noisy environment. (Probe Response has too many retry packet then cause "not enough space in MgmtRing") 3. Fixed WPA(2)PSK issue when group cipher of AP is WEP40 or WEP104. 4. Modified iwpriv ra0 get_site_survey: In scan list result: Security shows "NONE" when AP is OPEN/NONE, shows "WEP" when AP is OPEN/WEP or SHARED/WEP, shows "WPAPSK(WPA2PSK)/TKIP(AES)" when AP is WPAPSK(WPA2PSK)/TKIP(AES) shows "WPA(WPA2)/TKIP(AES)" when AP is WPA(WPA2)/TKIP(AES) 5. Support kthread. 6. Add New A band channel list region 15 contains the whole channels in the A band region 4 and the new CE channel 167,169,171,173 7. Add New IEEE802.11r functionality. 8. Fixed WPA2-Enterprise failed when AP reboot or turn off then turn on. 9. Fixed STA cannot connect to 11B only AP when the setting of is PHY_11GN. From the RT2870 driver release note: [V2.1.0.0] 1. New generation schema for multiple OS porting. 2. Fixed Ad-hoc ping failed in noisy environment. (Probe Response has too many retry packet then cause "not enough space in MgmtRing"). 3. Fixed WPS failed with D-Link DIR-628 in 5GHz. 4. Change FastRoaming in DAT file to AutoRoaming. 5. Support kthread. 6. Add New A band channel list region 15 contains the whole channels in the A band region and the new CE channel 167,169,171,173. 7. New IEEE802.11r functionality. From the RT3070 driver release note: Version V2.1.1.0 1. Linux kernel 2.6.29 support. 2. Fix eFuse write from BIN file bug. Version 2.1.0.0 1. New generation schema for multiple OS porting 2. Fixed Ad-hoc ping failed in noisy environment. 3. Modified iwpriv ra0 get_site_survey: 4. Change FastRoaming in DAT file to AutoRoaming. 5. Support kthread. 6. New IEEE802.11r functionality. Tested with RT2860 and RT3070 chipsets. Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/staging/rt2860/common')
-rw-r--r--drivers/staging/rt2860/common/2860_rtmp_init.c897
-rw-r--r--drivers/staging/rt2860/common/action.c12
-rw-r--r--drivers/staging/rt2860/common/ba_action.c147
-rw-r--r--drivers/staging/rt2860/common/cmm_aes.c (renamed from drivers/staging/rt2860/common/md5.c)1327
-rw-r--r--drivers/staging/rt2860/common/cmm_asic.c2531
-rw-r--r--drivers/staging/rt2860/common/cmm_cfg.c290
-rw-r--r--drivers/staging/rt2860/common/cmm_data.c906
-rw-r--r--drivers/staging/rt2860/common/cmm_data_pci.c1153
-rw-r--r--drivers/staging/rt2860/common/cmm_data_usb.c968
-rw-r--r--drivers/staging/rt2860/common/cmm_info.c820
-rw-r--r--drivers/staging/rt2860/common/cmm_mac_pci.c1504
-rw-r--r--drivers/staging/rt2860/common/cmm_mac_usb.c1216
-rw-r--r--drivers/staging/rt2860/common/cmm_profile.c1736
-rw-r--r--drivers/staging/rt2860/common/cmm_sanity.c233
-rw-r--r--drivers/staging/rt2860/common/cmm_sync.c70
-rw-r--r--drivers/staging/rt2860/common/cmm_tkip.c (renamed from drivers/staging/rt2860/common/rtmp_tkip.c)720
-rw-r--r--drivers/staging/rt2860/common/cmm_wep.c (renamed from drivers/staging/rt2860/common/rtmp_wep.c)22
-rw-r--r--drivers/staging/rt2860/common/cmm_wpa.c2428
-rw-r--r--drivers/staging/rt2860/common/crypt_hmac.c194
-rw-r--r--drivers/staging/rt2860/common/crypt_md5.c352
-rw-r--r--drivers/staging/rt2860/common/crypt_sha2.c535
-rw-r--r--drivers/staging/rt2860/common/dfs.c66
-rw-r--r--drivers/staging/rt2860/common/ee_efuse.c1525
-rw-r--r--drivers/staging/rt2860/common/ee_prom.c270
-rw-r--r--drivers/staging/rt2860/common/eeprom.c1460
-rw-r--r--drivers/staging/rt2860/common/firmware.h2
-rw-r--r--drivers/staging/rt2860/common/firmware_3070.h517
-rw-r--r--drivers/staging/rt2860/common/mlme.c5122
-rw-r--r--drivers/staging/rt2860/common/rt_channel.c1280
-rw-r--r--drivers/staging/rt2860/common/rt_rf.c194
-rw-r--r--drivers/staging/rt2860/common/rtmp_init.c1963
-rw-r--r--drivers/staging/rt2860/common/rtmp_mcu.c233
-rw-r--r--drivers/staging/rt2860/common/rtmp_timer.c323
-rw-r--r--drivers/staging/rt2860/common/spectrum.c460
34 files changed, 21368 insertions, 10108 deletions
diff --git a/drivers/staging/rt2860/common/2860_rtmp_init.c b/drivers/staging/rt2860/common/2860_rtmp_init.c
deleted file mode 100644
index 0bc0fb99d2e..00000000000
--- a/drivers/staging/rt2860/common/2860_rtmp_init.c
+++ /dev/null
@@ -1,897 +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 2860_rtmp_init.c
29
30 Abstract:
31 Miniport generic portion header file
32
33 Revision History:
34 Who When What
35 -------- ---------- ----------------------------------------------
36 Paul Lin 2002-08-01 created
37 John Chang 2004-08-20 RT2561/2661 use scatter-gather scheme
38 Jan Lee 2006-09-15 RT2860. Change for 802.11n , EEPROM, Led, BA, HT.
39*/
40#include "../rt_config.h"
41
42
43
44
45/*
46 ========================================================================
47
48 Routine Description:
49 Allocate DMA memory blocks for send, receive
50
51 Arguments:
52 Adapter Pointer to our adapter
53
54 Return Value:
55 NDIS_STATUS_SUCCESS
56 NDIS_STATUS_FAILURE
57 NDIS_STATUS_RESOURCES
58
59 IRQL = PASSIVE_LEVEL
60
61 Note:
62
63 ========================================================================
64*/
65NDIS_STATUS RTMPAllocTxRxRingMemory(
66 IN PRTMP_ADAPTER pAd)
67{
68 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
69 ULONG RingBasePaHigh;
70 ULONG RingBasePaLow;
71 PVOID RingBaseVa;
72 INT index, num;
73 PTXD_STRUC pTxD;
74 PRXD_STRUC pRxD;
75 ULONG ErrorValue = 0;
76 PRTMP_TX_RING pTxRing;
77 PRTMP_DMABUF pDmaBuf;
78 PNDIS_PACKET pPacket;
79
80 DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocTxRxRingMemory\n"));
81 do
82 {
83 //
84 // Allocate all ring descriptors, include TxD, RxD, MgmtD.
85 // Although each size is different, to prevent cacheline and alignment
86 // issue, I intentional set them all to 64 bytes.
87 //
88 for (num=0; num<NUM_OF_TX_RING; num++)
89 {
90 ULONG BufBasePaHigh;
91 ULONG BufBasePaLow;
92 PVOID BufBaseVa;
93
94 //
95 // Allocate Tx ring descriptor's memory (5 TX rings = 4 ACs + 1 HCCA)
96 //
97 pAd->TxDescRing[num].AllocSize = TX_RING_SIZE * TXD_SIZE;
98 RTMP_AllocateTxDescMemory(
99 pAd,
100 num,
101 pAd->TxDescRing[num].AllocSize,
102 FALSE,
103 &pAd->TxDescRing[num].AllocVa,
104 &pAd->TxDescRing[num].AllocPa);
105
106 if (pAd->TxDescRing[num].AllocVa == NULL)
107 {
108 ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
109 DBGPRINT_ERR(("Failed to allocate a big buffer\n"));
110 Status = NDIS_STATUS_RESOURCES;
111 break;
112 }
113
114 // Zero init this memory block
115 NdisZeroMemory(pAd->TxDescRing[num].AllocVa, pAd->TxDescRing[num].AllocSize);
116
117 // Save PA & VA for further operation
118 RingBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->TxDescRing[num].AllocPa);
119 RingBasePaLow = RTMP_GetPhysicalAddressLow (pAd->TxDescRing[num].AllocPa);
120 RingBaseVa = pAd->TxDescRing[num].AllocVa;
121
122 //
123 // Allocate all 1st TXBuf's memory for this TxRing
124 //
125 pAd->TxBufSpace[num].AllocSize = TX_RING_SIZE * TX_DMA_1ST_BUFFER_SIZE;
126 RTMP_AllocateFirstTxBuffer(
127 pAd,
128 num,
129 pAd->TxBufSpace[num].AllocSize,
130 FALSE,
131 &pAd->TxBufSpace[num].AllocVa,
132 &pAd->TxBufSpace[num].AllocPa);
133
134 if (pAd->TxBufSpace[num].AllocVa == NULL)
135 {
136 ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
137 DBGPRINT_ERR(("Failed to allocate a big buffer\n"));
138 Status = NDIS_STATUS_RESOURCES;
139 break;
140 }
141
142 // Zero init this memory block
143 NdisZeroMemory(pAd->TxBufSpace[num].AllocVa, pAd->TxBufSpace[num].AllocSize);
144
145 // Save PA & VA for further operation
146 BufBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->TxBufSpace[num].AllocPa);
147 BufBasePaLow = RTMP_GetPhysicalAddressLow (pAd->TxBufSpace[num].AllocPa);
148 BufBaseVa = pAd->TxBufSpace[num].AllocVa;
149
150 //
151 // Initialize Tx Ring Descriptor and associated buffer memory
152 //
153 pTxRing = &pAd->TxRing[num];
154 for (index = 0; index < TX_RING_SIZE; index++)
155 {
156 pTxRing->Cell[index].pNdisPacket = NULL;
157 pTxRing->Cell[index].pNextNdisPacket = NULL;
158 // Init Tx Ring Size, Va, Pa variables
159 pTxRing->Cell[index].AllocSize = TXD_SIZE;
160 pTxRing->Cell[index].AllocVa = RingBaseVa;
161 RTMP_SetPhysicalAddressHigh(pTxRing->Cell[index].AllocPa, RingBasePaHigh);
162 RTMP_SetPhysicalAddressLow (pTxRing->Cell[index].AllocPa, RingBasePaLow);
163
164 // Setup Tx Buffer size & address. only 802.11 header will store in this space
165 pDmaBuf = &pTxRing->Cell[index].DmaBuf;
166 pDmaBuf->AllocSize = TX_DMA_1ST_BUFFER_SIZE;
167 pDmaBuf->AllocVa = BufBaseVa;
168 RTMP_SetPhysicalAddressHigh(pDmaBuf->AllocPa, BufBasePaHigh);
169 RTMP_SetPhysicalAddressLow(pDmaBuf->AllocPa, BufBasePaLow);
170
171 // link the pre-allocated TxBuf to TXD
172 pTxD = (PTXD_STRUC) pTxRing->Cell[index].AllocVa;
173 pTxD->SDPtr0 = BufBasePaLow;
174 // advance to next ring descriptor address
175 pTxD->DMADONE = 1;
176 RingBasePaLow += TXD_SIZE;
177 RingBaseVa = (PUCHAR) RingBaseVa + TXD_SIZE;
178
179 // advance to next TxBuf address
180 BufBasePaLow += TX_DMA_1ST_BUFFER_SIZE;
181 BufBaseVa = (PUCHAR) BufBaseVa + TX_DMA_1ST_BUFFER_SIZE;
182 }
183 DBGPRINT(RT_DEBUG_TRACE, ("TxRing[%d]: total %d entry allocated\n", num, 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(
193 pAd,
194 pAd->MgmtDescRing.AllocSize,
195 FALSE,
196 &pAd->MgmtDescRing.AllocVa,
197 &pAd->MgmtDescRing.AllocPa);
198
199 if (pAd->MgmtDescRing.AllocVa == NULL)
200 {
201 ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
202 DBGPRINT_ERR(("Failed to allocate a big buffer\n"));
203 Status = NDIS_STATUS_RESOURCES;
204 break;
205 }
206
207 // Zero init this memory block
208 NdisZeroMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize);
209
210 // Save PA & VA for further operation
211 RingBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->MgmtDescRing.AllocPa);
212 RingBasePaLow = 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 {
220 pAd->MgmtRing.Cell[index].pNdisPacket = NULL;
221 pAd->MgmtRing.Cell[index].pNextNdisPacket = NULL;
222 // Init MGMT Ring Size, Va, Pa variables
223 pAd->MgmtRing.Cell[index].AllocSize = TXD_SIZE;
224 pAd->MgmtRing.Cell[index].AllocVa = RingBaseVa;
225 RTMP_SetPhysicalAddressHigh(pAd->MgmtRing.Cell[index].AllocPa, RingBasePaHigh);
226 RTMP_SetPhysicalAddressLow (pAd->MgmtRing.Cell[index].AllocPa, RingBasePaLow);
227
228 // Offset to next ring descriptor address
229 RingBasePaLow += TXD_SIZE;
230 RingBaseVa = (PUCHAR) RingBaseVa + TXD_SIZE;
231
232 // link the pre-allocated TxBuf to TXD
233 pTxD = (PTXD_STRUC) pAd->MgmtRing.Cell[index].AllocVa;
234 pTxD->DMADONE = 1;
235
236 // no pre-allocated buffer required in MgmtRing for scatter-gather case
237 }
238 DBGPRINT(RT_DEBUG_TRACE, ("MGMT Ring: total %d entry allocated\n", index));
239
240 //
241 // Allocate RX ring descriptor's memory except Tx ring which allocated eariler
242 //
243 pAd->RxDescRing.AllocSize = RX_RING_SIZE * RXD_SIZE;
244 RTMP_AllocateRxDescMemory(
245 pAd,
246 pAd->RxDescRing.AllocSize,
247 FALSE,
248 &pAd->RxDescRing.AllocVa,
249 &pAd->RxDescRing.AllocPa);
250
251 if (pAd->RxDescRing.AllocVa == NULL)
252 {
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
259 // Zero init this memory block
260 NdisZeroMemory(pAd->RxDescRing.AllocVa, pAd->RxDescRing.AllocSize);
261
262
263 printk("RX DESC %p size = %ld\n", pAd->RxDescRing.AllocVa,
264 pAd->RxDescRing.AllocSize);
265
266 // Save PA & VA for further operation
267 RingBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->RxDescRing.AllocPa);
268 RingBasePaLow = RTMP_GetPhysicalAddressLow (pAd->RxDescRing.AllocPa);
269 RingBaseVa = pAd->RxDescRing.AllocVa;
270
271 //
272 // Initialize Rx Ring and associated buffer memory
273 //
274 for (index = 0; index < RX_RING_SIZE; index++)
275 {
276 // Init RX Ring Size, Va, Pa variables
277 pAd->RxRing.Cell[index].AllocSize = RXD_SIZE;
278 pAd->RxRing.Cell[index].AllocVa = RingBaseVa;
279 RTMP_SetPhysicalAddressHigh(pAd->RxRing.Cell[index].AllocPa, RingBasePaHigh);
280 RTMP_SetPhysicalAddressLow (pAd->RxRing.Cell[index].AllocPa, RingBasePaLow);
281
282 // Offset to next ring descriptor address
283 RingBasePaLow += RXD_SIZE;
284 RingBaseVa = (PUCHAR) RingBaseVa + RXD_SIZE;
285
286 // Setup Rx associated Buffer size & allocate share memory
287 pDmaBuf = &pAd->RxRing.Cell[index].DmaBuf;
288 pDmaBuf->AllocSize = RX_BUFFER_AGGRESIZE;
289 pPacket = RTMP_AllocateRxPacketBuffer(
290 pAd,
291 pDmaBuf->AllocSize,
292 FALSE,
293 &pDmaBuf->AllocVa,
294 &pDmaBuf->AllocPa);
295
296 /* keep allocated rx packet */
297 pAd->RxRing.Cell[index].pNdisPacket = pPacket;
298
299 // Error handling
300 if (pDmaBuf->AllocVa == NULL)
301 {
302 ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
303 DBGPRINT_ERR(("Failed to allocate RxRing's 1st buffer\n"));
304 Status = NDIS_STATUS_RESOURCES;
305 break;
306 }
307
308 // Zero init this memory block
309 NdisZeroMemory(pDmaBuf->AllocVa, pDmaBuf->AllocSize);
310
311 // Write RxD buffer address & allocated buffer length
312 pRxD = (PRXD_STRUC) pAd->RxRing.Cell[index].AllocVa;
313 pRxD->SDP0 = RTMP_GetPhysicalAddressLow(pDmaBuf->AllocPa);
314 pRxD->DDONE = 0;
315 }
316
317 DBGPRINT(RT_DEBUG_TRACE, ("Rx Ring: total %d entry allocated\n", index));
318
319 } while (FALSE);
320
321
322 NdisZeroMemory(&pAd->FragFrame, sizeof(FRAGMENT_FRAME));
323 pAd->FragFrame.pFragPacket = RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE);
324
325 if (pAd->FragFrame.pFragPacket == NULL)
326 {
327 Status = NDIS_STATUS_RESOURCES;
328 }
329
330 if (Status != NDIS_STATUS_SUCCESS)
331 {
332 // Log error inforamtion
333 NdisWriteErrorLogEntry(
334 pAd->AdapterHandle,
335 NDIS_ERROR_CODE_OUT_OF_RESOURCES,
336 1,
337 ErrorValue);
338 }
339
340 DBGPRINT_S(Status, ("<-- RTMPAllocTxRxRingMemory, Status=%x\n", Status));
341 return Status;
342}
343
344
345/*
346 ========================================================================
347
348 Routine Description:
349 Initialize transmit data structures
350
351 Arguments:
352 Adapter Pointer to our adapter
353
354 Return Value:
355 None
356
357 IRQL = PASSIVE_LEVEL
358
359 Note:
360 Initialize all transmit releated private buffer, include those define
361 in RTMP_ADAPTER structure and all private data structures.
362
363 ========================================================================
364*/
365VOID NICInitTxRxRingAndBacklogQueue(
366 IN PRTMP_ADAPTER pAd)
367{
368 //WPDMA_GLO_CFG_STRUC GloCfg;
369 int i;
370
371 DBGPRINT(RT_DEBUG_TRACE, ("<--> NICInitTxRxRingAndBacklogQueue\n"));
372
373 // Initialize all transmit related software queues
374 InitializeQueueHeader(&pAd->TxSwQueue[QID_AC_BE]);
375 InitializeQueueHeader(&pAd->TxSwQueue[QID_AC_BK]);
376 InitializeQueueHeader(&pAd->TxSwQueue[QID_AC_VI]);
377 InitializeQueueHeader(&pAd->TxSwQueue[QID_AC_VO]);
378 InitializeQueueHeader(&pAd->TxSwQueue[QID_HCCA]);
379
380 // Init RX Ring index pointer
381 pAd->RxRing.RxSwReadIdx = 0;
382 pAd->RxRing.RxCpuIdx = RX_RING_SIZE - 1;
383
384 // Init TX rings index pointer
385 for (i=0; i<NUM_OF_TX_RING; i++)
386 {
387 pAd->TxRing[i].TxSwFreeIdx = 0;
388 pAd->TxRing[i].TxCpuIdx = 0;
389 }
390
391 // init MGMT ring index pointer
392 pAd->MgmtRing.TxSwFreeIdx = 0;
393 pAd->MgmtRing.TxCpuIdx = 0;
394
395 pAd->PrivateInfo.TxRingFullCnt = 0;
396}
397
398
399/*
400 ========================================================================
401
402 Routine Description:
403 Reset NIC Asics. Call after rest DMA. So reset TX_CTX_IDX to zero.
404
405 Arguments:
406 Adapter Pointer to our adapter
407
408 Return Value:
409 None
410
411 IRQL = PASSIVE_LEVEL
412 IRQL = DISPATCH_LEVEL
413
414 Note:
415 Reset NIC to initial state AS IS system boot up time.
416
417 ========================================================================
418*/
419VOID RTMPRingCleanUp(
420 IN PRTMP_ADAPTER pAd,
421 IN UCHAR RingType)
422{
423 PTXD_STRUC pTxD;
424 PRXD_STRUC pRxD;
425 PQUEUE_ENTRY pEntry;
426 PNDIS_PACKET pPacket;
427 int i;
428 PRTMP_TX_RING pTxRing;
429 unsigned long IrqFlags;
430
431 DBGPRINT(RT_DEBUG_TRACE,("RTMPRingCleanUp(RingIdx=%d, Pending-NDIS=%ld)\n", RingType, pAd->RalinkCounters.PendingNdisPacketCount));
432 switch (RingType)
433 {
434 case QID_AC_BK:
435 case QID_AC_BE:
436 case QID_AC_VI:
437 case QID_AC_VO:
438 case QID_HCCA:
439 RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
440 pTxRing = &pAd->TxRing[RingType];
441
442 // We have to clean all descriptors in case some error happened with reset
443 for (i=0; i<TX_RING_SIZE; i++) // We have to scan all TX ring
444 {
445 pTxD = (PTXD_STRUC) pTxRing->Cell[i].AllocVa;
446
447 pPacket = (PNDIS_PACKET) pTxRing->Cell[i].pNdisPacket;
448 // release scatter-and-gather NDIS_PACKET
449 if (pPacket)
450 {
451 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
452 pTxRing->Cell[i].pNdisPacket = NULL;
453 }
454
455 pPacket = (PNDIS_PACKET) pTxRing->Cell[i].pNextNdisPacket;
456 // release scatter-and-gather NDIS_PACKET
457 if (pPacket)
458 {
459 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
460 pTxRing->Cell[i].pNextNdisPacket = NULL;
461 }
462 }
463
464 RTMP_IO_READ32(pAd, TX_DTX_IDX0 + RingType * 0x10, &pTxRing->TxDmaIdx);
465 pTxRing->TxSwFreeIdx = pTxRing->TxDmaIdx;
466 pTxRing->TxCpuIdx = pTxRing->TxDmaIdx;
467 RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + RingType * 0x10, pTxRing->TxCpuIdx);
468
469 RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
470 RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
471 while (pAd->TxSwQueue[RingType].Head != NULL)
472 {
473 pEntry = RemoveHeadQueue(&pAd->TxSwQueue[RingType]);
474 pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
475 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
476 DBGPRINT(RT_DEBUG_TRACE,("Release 1 NDIS packet from s/w backlog queue\n"));
477 }
478 RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
479 break;
480
481 case QID_MGMT:
482 // We have to clean all descriptors in case some error happened with reset
483 NdisAcquireSpinLock(&pAd->MgmtRingLock);
484
485 for (i=0; i<MGMT_RING_SIZE; i++)
486 {
487 pTxD = (PTXD_STRUC) pAd->MgmtRing.Cell[i].AllocVa;
488
489 pPacket = (PNDIS_PACKET) pAd->MgmtRing.Cell[i].pNdisPacket;
490 // rlease scatter-and-gather NDIS_PACKET
491 if (pPacket)
492 {
493 PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, PCI_DMA_TODEVICE);
494 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
495 }
496 pAd->MgmtRing.Cell[i].pNdisPacket = NULL;
497
498 pPacket = (PNDIS_PACKET) pAd->MgmtRing.Cell[i].pNextNdisPacket;
499 // release scatter-and-gather NDIS_PACKET
500 if (pPacket)
501 {
502 PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
503 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
504 }
505 pAd->MgmtRing.Cell[i].pNextNdisPacket = NULL;
506
507 }
508
509 RTMP_IO_READ32(pAd, TX_MGMTDTX_IDX, &pAd->MgmtRing.TxDmaIdx);
510 pAd->MgmtRing.TxSwFreeIdx = pAd->MgmtRing.TxDmaIdx;
511 pAd->MgmtRing.TxCpuIdx = pAd->MgmtRing.TxDmaIdx;
512 RTMP_IO_WRITE32(pAd, TX_MGMTCTX_IDX, pAd->MgmtRing.TxCpuIdx);
513
514 NdisReleaseSpinLock(&pAd->MgmtRingLock);
515 pAd->RalinkCounters.MgmtRingFullCount = 0;
516 break;
517
518 case QID_RX:
519 // We have to clean all descriptors in case some error happened with reset
520 NdisAcquireSpinLock(&pAd->RxRingLock);
521
522 for (i=0; i<RX_RING_SIZE; i++)
523 {
524 pRxD = (PRXD_STRUC) pAd->RxRing.Cell[i].AllocVa;
525 pRxD->DDONE = 0 ;
526 }
527
528 RTMP_IO_READ32(pAd, RX_DRX_IDX, &pAd->RxRing.RxDmaIdx);
529 pAd->RxRing.RxSwReadIdx = pAd->RxRing.RxDmaIdx;
530 pAd->RxRing.RxCpuIdx = ((pAd->RxRing.RxDmaIdx == 0) ? (RX_RING_SIZE-1) : (pAd->RxRing.RxDmaIdx-1));
531 RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx);
532
533 NdisReleaseSpinLock(&pAd->RxRingLock);
534 break;
535
536 default:
537 break;
538 }
539}
540
541
542NDIS_STATUS AdapterBlockAllocateMemory(
543 IN PVOID handle,
544 OUT PVOID *ppAd)
545{
546 PPCI_DEV pci_dev;
547 dma_addr_t *phy_addr;
548 POS_COOKIE pObj = (POS_COOKIE) handle;
549
550 pci_dev = pObj->pci_dev;
551 phy_addr = &pObj->pAd_pa;
552
553 *ppAd = (PVOID)vmalloc(sizeof(RTMP_ADAPTER)); //pci_alloc_consistent(pci_dev, sizeof(RTMP_ADAPTER), phy_addr);
554
555 if (*ppAd)
556 {
557 NdisZeroMemory(*ppAd, sizeof(RTMP_ADAPTER));
558 ((PRTMP_ADAPTER)*ppAd)->OS_Cookie = handle;
559 return (NDIS_STATUS_SUCCESS);
560 } else {
561 return (NDIS_STATUS_FAILURE);
562 }
563}
564
565
566void RTMP_AllocateTxDescMemory(
567 IN PRTMP_ADAPTER pAd,
568 IN UINT Index,
569 IN ULONG Length,
570 IN BOOLEAN Cached,
571 OUT PVOID *VirtualAddress,
572 OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
573{
574 POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
575
576 *VirtualAddress = (PVOID)PCI_ALLOC_CONSISTENT(pObj->pci_dev,sizeof(char)*Length, PhysicalAddress);
577
578}
579
580void RTMP_AllocateMgmtDescMemory(
581 IN PRTMP_ADAPTER pAd,
582 IN ULONG Length,
583 IN BOOLEAN Cached,
584 OUT PVOID *VirtualAddress,
585 OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
586{
587 POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
588
589 *VirtualAddress = (PVOID)PCI_ALLOC_CONSISTENT(pObj->pci_dev,sizeof(char)*Length, PhysicalAddress);
590
591}
592
593void RTMP_AllocateRxDescMemory(
594 IN PRTMP_ADAPTER pAd,
595 IN ULONG Length,
596 IN BOOLEAN Cached,
597 OUT PVOID *VirtualAddress,
598 OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
599{
600 POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
601
602 *VirtualAddress = (PVOID)PCI_ALLOC_CONSISTENT(pObj->pci_dev,sizeof(char)*Length, PhysicalAddress);
603
604}
605
606void RTMP_FreeRxDescMemory(
607 IN PRTMP_ADAPTER pAd,
608 IN ULONG Length,
609 IN PVOID VirtualAddress,
610 IN NDIS_PHYSICAL_ADDRESS PhysicalAddress)
611{
612 POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
613
614 PCI_FREE_CONSISTENT(pObj->pci_dev, Length, VirtualAddress, PhysicalAddress);
615}
616
617
618void RTMP_AllocateFirstTxBuffer(
619 IN PRTMP_ADAPTER pAd,
620 IN UINT Index,
621 IN ULONG Length,
622 IN BOOLEAN Cached,
623 OUT PVOID *VirtualAddress,
624 OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
625{
626 POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
627
628 *VirtualAddress = (PVOID)PCI_ALLOC_CONSISTENT(pObj->pci_dev,sizeof(char)*Length, PhysicalAddress);
629}
630
631/*
632 * FUNCTION: Allocate a common buffer for DMA
633 * ARGUMENTS:
634 * AdapterHandle: AdapterHandle
635 * Length: Number of bytes to allocate
636 * Cached: Whether or not the memory can be cached
637 * VirtualAddress: Pointer to memory is returned here
638 * PhysicalAddress: Physical address corresponding to virtual address
639 */
640
641void RTMP_AllocateSharedMemory(
642 IN PRTMP_ADAPTER pAd,
643 IN ULONG Length,
644 IN BOOLEAN Cached,
645 OUT PVOID *VirtualAddress,
646 OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
647{
648 POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
649
650 *VirtualAddress = (PVOID)PCI_ALLOC_CONSISTENT(pObj->pci_dev,sizeof(char)*Length, PhysicalAddress);
651}
652
653VOID RTMPFreeTxRxRingMemory(
654 IN PRTMP_ADAPTER pAd)
655{
656 int index, num , j;
657 PRTMP_TX_RING pTxRing;
658 PTXD_STRUC pTxD;
659 PNDIS_PACKET pPacket;
660 unsigned int IrqFlags;
661
662 POS_COOKIE pObj =(POS_COOKIE) pAd->OS_Cookie;
663
664 DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPFreeTxRxRingMemory\n"));
665
666 // Free TxSwQueue Packet
667 for (index=0; index <NUM_OF_TX_RING; index++)
668 {
669 PQUEUE_ENTRY pEntry;
670 PNDIS_PACKET pPacket;
671 PQUEUE_HEADER pQueue;
672
673 RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
674 pQueue = &pAd->TxSwQueue[index];
675 while (pQueue->Head)
676 {
677 pEntry = RemoveHeadQueue(pQueue);
678 pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
679 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
680 }
681 RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
682 }
683
684 // Free Tx Ring Packet
685 for (index=0;index< NUM_OF_TX_RING;index++)
686 {
687 pTxRing = &pAd->TxRing[index];
688
689 for (j=0; j< TX_RING_SIZE; j++)
690 {
691 pTxD = (PTXD_STRUC) (pTxRing->Cell[j].AllocVa);
692 pPacket = pTxRing->Cell[j].pNdisPacket;
693
694 if (pPacket)
695 {
696 PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, PCI_DMA_TODEVICE);
697 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
698 }
699 //Always assign pNdisPacket as NULL after clear
700 pTxRing->Cell[j].pNdisPacket = NULL;
701
702 pPacket = pTxRing->Cell[j].pNextNdisPacket;
703
704 if (pPacket)
705 {
706 PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
707 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
708 }
709 //Always assign pNextNdisPacket as NULL after clear
710 pTxRing->Cell[pTxRing->TxSwFreeIdx].pNextNdisPacket = NULL;
711
712 }
713 }
714
715 for (index = RX_RING_SIZE - 1 ; index >= 0; index--)
716 {
717 if ((pAd->RxRing.Cell[index].DmaBuf.AllocVa) && (pAd->RxRing.Cell[index].pNdisPacket))
718 {
719 PCI_UNMAP_SINGLE(pObj->pci_dev, pAd->RxRing.Cell[index].DmaBuf.AllocPa, pAd->RxRing.Cell[index].DmaBuf.AllocSize, PCI_DMA_FROMDEVICE);
720 RELEASE_NDIS_PACKET(pAd, pAd->RxRing.Cell[index].pNdisPacket, NDIS_STATUS_SUCCESS);
721 }
722 }
723 NdisZeroMemory(pAd->RxRing.Cell, RX_RING_SIZE * sizeof(RTMP_DMACB));
724
725 if (pAd->RxDescRing.AllocVa)
726 {
727 PCI_FREE_CONSISTENT(pObj->pci_dev, pAd->RxDescRing.AllocSize, pAd->RxDescRing.AllocVa, pAd->RxDescRing.AllocPa);
728 }
729 NdisZeroMemory(&pAd->RxDescRing, sizeof(RTMP_DMABUF));
730
731 if (pAd->MgmtDescRing.AllocVa)
732 {
733 PCI_FREE_CONSISTENT(pObj->pci_dev, pAd->MgmtDescRing.AllocSize, pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocPa);
734 }
735 NdisZeroMemory(&pAd->MgmtDescRing, sizeof(RTMP_DMABUF));
736
737 for (num = 0; num < NUM_OF_TX_RING; num++)
738 {
739 if (pAd->TxBufSpace[num].AllocVa)
740 {
741 PCI_FREE_CONSISTENT(pObj->pci_dev, pAd->TxBufSpace[num].AllocSize, pAd->TxBufSpace[num].AllocVa, pAd->TxBufSpace[num].AllocPa);
742 }
743 NdisZeroMemory(&pAd->TxBufSpace[num], sizeof(RTMP_DMABUF));
744
745 if (pAd->TxDescRing[num].AllocVa)
746 {
747 PCI_FREE_CONSISTENT(pObj->pci_dev, pAd->TxDescRing[num].AllocSize, pAd->TxDescRing[num].AllocVa, pAd->TxDescRing[num].AllocPa);
748 }
749 NdisZeroMemory(&pAd->TxDescRing[num], sizeof(RTMP_DMABUF));
750 }
751
752 if (pAd->FragFrame.pFragPacket)
753 RELEASE_NDIS_PACKET(pAd, pAd->FragFrame.pFragPacket, NDIS_STATUS_SUCCESS);
754
755 DBGPRINT(RT_DEBUG_TRACE, ("<-- RTMPFreeTxRxRingMemory\n"));
756}
757
758
759/*
760 * FUNCTION: Allocate a packet buffer for DMA
761 * ARGUMENTS:
762 * AdapterHandle: AdapterHandle
763 * Length: Number of bytes to allocate
764 * Cached: Whether or not the memory can be cached
765 * VirtualAddress: Pointer to memory is returned here
766 * PhysicalAddress: Physical address corresponding to virtual address
767 * Notes:
768 * Cached is ignored: always cached memory
769 */
770PNDIS_PACKET RTMP_AllocateRxPacketBuffer(
771 IN PRTMP_ADAPTER pAd,
772 IN ULONG Length,
773 IN BOOLEAN Cached,
774 OUT PVOID *VirtualAddress,
775 OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
776{
777 PNDIS_PACKET pkt;
778
779 pkt = RTPKT_TO_OSPKT(DEV_ALLOC_SKB(Length));
780
781 if (pkt == NULL) {
782 DBGPRINT(RT_DEBUG_ERROR, ("can't allocate rx %ld size packet\n",Length));
783 }
784
785 if (pkt) {
786 RTMP_SET_PACKET_SOURCE(pkt, PKTSRC_NDIS);
787 *VirtualAddress = (PVOID) RTPKT_TO_OSPKT(pkt)->data;
788 *PhysicalAddress = PCI_MAP_SINGLE(pAd, *VirtualAddress, Length, -1, PCI_DMA_FROMDEVICE);
789 } else {
790 *VirtualAddress = (PVOID) NULL;
791 *PhysicalAddress = (NDIS_PHYSICAL_ADDRESS) NULL;
792 }
793
794 return (PNDIS_PACKET) pkt;
795}
796
797
798VOID Invalid_Remaining_Packet(
799 IN PRTMP_ADAPTER pAd,
800 IN ULONG VirtualAddress)
801{
802 NDIS_PHYSICAL_ADDRESS PhysicalAddress;
803
804 PhysicalAddress = PCI_MAP_SINGLE(pAd, (void *)(VirtualAddress+1600), RX_BUFFER_NORMSIZE-1600, -1, PCI_DMA_FROMDEVICE);
805}
806
807PNDIS_PACKET GetPacketFromRxRing(
808 IN PRTMP_ADAPTER pAd,
809 OUT PRT28XX_RXD_STRUC pSaveRxD,
810 OUT BOOLEAN *pbReschedule,
811 IN OUT UINT32 *pRxPending)
812{
813 PRXD_STRUC pRxD;
814 PNDIS_PACKET pRxPacket = NULL;
815 PNDIS_PACKET pNewPacket;
816 PVOID AllocVa;
817 NDIS_PHYSICAL_ADDRESS AllocPa;
818 BOOLEAN bReschedule = FALSE;
819
820 RTMP_SEM_LOCK(&pAd->RxRingLock);
821
822 if (*pRxPending == 0)
823 {
824 // Get how may packets had been received
825 RTMP_IO_READ32(pAd, RX_DRX_IDX , &pAd->RxRing.RxDmaIdx);
826
827 if (pAd->RxRing.RxSwReadIdx == pAd->RxRing.RxDmaIdx)
828 {
829 // no more rx packets
830 bReschedule = FALSE;
831 goto done;
832 }
833
834 // get rx pending count
835 if (pAd->RxRing.RxDmaIdx > pAd->RxRing.RxSwReadIdx)
836 *pRxPending = pAd->RxRing.RxDmaIdx - pAd->RxRing.RxSwReadIdx;
837 else
838 *pRxPending = pAd->RxRing.RxDmaIdx + RX_RING_SIZE - pAd->RxRing.RxSwReadIdx;
839
840 }
841
842 // Point to Rx indexed rx ring descriptor
843 pRxD = (PRXD_STRUC) pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].AllocVa;
844
845 if (pRxD->DDONE == 0)
846 {
847 *pRxPending = 0;
848 // DMAIndx had done but DDONE bit not ready
849 bReschedule = TRUE;
850 goto done;
851 }
852
853
854 // return rx descriptor
855 NdisMoveMemory(pSaveRxD, pRxD, RXD_SIZE);
856
857 pNewPacket = RTMP_AllocateRxPacketBuffer(pAd, RX_BUFFER_AGGRESIZE, FALSE, &AllocVa, &AllocPa);
858
859 if (pNewPacket)
860 {
861 // unmap the rx buffer
862 PCI_UNMAP_SINGLE(pAd, pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].DmaBuf.AllocPa,
863 pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].DmaBuf.AllocSize, PCI_DMA_FROMDEVICE);
864 pRxPacket = pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].pNdisPacket;
865
866 pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].DmaBuf.AllocSize = RX_BUFFER_AGGRESIZE;
867 pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].pNdisPacket = (PNDIS_PACKET) pNewPacket;
868 pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].DmaBuf.AllocVa = AllocVa;
869 pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].DmaBuf.AllocPa = AllocPa;
870 /* update SDP0 to new buffer of rx packet */
871 pRxD->SDP0 = AllocPa;
872 }
873 else
874 {
875 //printk("No Rx Buffer\n");
876 pRxPacket = NULL;
877 bReschedule = TRUE;
878 }
879
880 pRxD->DDONE = 0;
881
882 // had handled one rx packet
883 *pRxPending = *pRxPending - 1;
884
885 // update rx descriptor and kick rx
886 INC_RING_INDEX(pAd->RxRing.RxSwReadIdx, RX_RING_SIZE);
887
888 pAd->RxRing.RxCpuIdx = (pAd->RxRing.RxSwReadIdx == 0) ? (RX_RING_SIZE-1) : (pAd->RxRing.RxSwReadIdx-1);
889 RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx);
890
891done:
892 RTMP_SEM_UNLOCK(&pAd->RxRingLock);
893 *pbReschedule = bReschedule;
894 return pRxPacket;
895}
896/* End of 2860_rtmp_init.c */
897
diff --git a/drivers/staging/rt2860/common/action.c b/drivers/staging/rt2860/common/action.c
index 256cb67e059..5593966f0a9 100644
--- a/drivers/staging/rt2860/common/action.c
+++ b/drivers/staging/rt2860/common/action.c
@@ -150,7 +150,9 @@ VOID MlmeADDBAAction(
150 MakeOutgoingFrame(pOutBuffer, &FrameLen, 150 MakeOutgoingFrame(pOutBuffer, &FrameLen,
151 sizeof(FRAME_ADDBA_REQ), &Frame, 151 sizeof(FRAME_ADDBA_REQ), &Frame,
152 END_OF_ARGS); 152 END_OF_ARGS);
153 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); 153
154 MiniportMMRequest(pAd, (MGMT_USE_QUEUE_FLAG | MapUserPriorityToAccessCategory[pInfo->TID]), pOutBuffer, FrameLen);
155
154 MlmeFreeMemory(pAd, pOutBuffer); 156 MlmeFreeMemory(pAd, pOutBuffer);
155 157
156 DBGPRINT(RT_DEBUG_TRACE, ("BA - Send ADDBA request. StartSeq = %x, FrameLen = %ld. BufSize = %d\n", Frame.BaStartSeq.field.StartSeq, FrameLen, Frame.BaParm.BufSize)); 158 DBGPRINT(RT_DEBUG_TRACE, ("BA - Send ADDBA request. StartSeq = %x, FrameLen = %ld. BufSize = %d\n", Frame.BaStartSeq.field.StartSeq, FrameLen, Frame.BaParm.BufSize));
@@ -527,9 +529,13 @@ VOID SendRefreshBAR(
527 MakeOutgoingFrame(pOutBuffer, &FrameLen, 529 MakeOutgoingFrame(pOutBuffer, &FrameLen,
528 sizeof(FRAME_BAR), &FrameBar, 530 sizeof(FRAME_BAR), &FrameBar,
529 END_OF_ARGS); 531 END_OF_ARGS);
532 //if (!(CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_RALINK_CHIPSET)))
533 if (1) // Now we always send BAR.
534 {
535 //MiniportMMRequestUnlock(pAd, 0, pOutBuffer, FrameLen);
536 MiniportMMRequest(pAd, (MGMT_USE_QUEUE_FLAG | MapUserPriorityToAccessCategory[TID]), pOutBuffer, FrameLen);
530 537
531 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); 538 }
532
533 MlmeFreeMemory(pAd, pOutBuffer); 539 MlmeFreeMemory(pAd, pOutBuffer);
534 } 540 }
535 } 541 }
diff --git a/drivers/staging/rt2860/common/ba_action.c b/drivers/staging/rt2860/common/ba_action.c
index b7bbe99d4d5..ff4dce6786f 100644
--- a/drivers/staging/rt2860/common/ba_action.c
+++ b/drivers/staging/rt2860/common/ba_action.c
@@ -35,8 +35,8 @@
35#define ORI_BA_SESSION_TIMEOUT (2000) // ms 35#define ORI_BA_SESSION_TIMEOUT (2000) // ms
36#define REC_BA_SESSION_IDLE_TIMEOUT (1000) // ms 36#define REC_BA_SESSION_IDLE_TIMEOUT (1000) // ms
37 37
38#define REORDERING_PACKET_TIMEOUT ((100 * HZ)/1000) // system ticks -- 100 ms 38#define REORDERING_PACKET_TIMEOUT ((100 * OS_HZ)/1000) // system ticks -- 100 ms
39#define MAX_REORDERING_PACKET_TIMEOUT ((3000 * HZ)/1000) // system ticks -- 100 ms 39#define MAX_REORDERING_PACKET_TIMEOUT ((3000 * OS_HZ)/1000) // system ticks -- 100 ms
40 40
41#define RESET_RCV_SEQ (0xFFFF) 41#define RESET_RCV_SEQ (0xFFFF)
42 42
@@ -460,6 +460,8 @@ void ba_flush_reordering_timeout_mpdus(
460 pBAEntry->LastIndSeq = Sequence; 460 pBAEntry->LastIndSeq = Sequence;
461 } 461 }
462 462
463 DBGPRINT(RT_DEBUG_OFF, ("%x, flush one!\n", pBAEntry->LastIndSeq));
464
463 } 465 }
464} 466}
465 467
@@ -493,7 +495,7 @@ VOID BAOriSessionSetUp(
493 { 495 {
494 // try again after 3 secs 496 // try again after 3 secs
495 DelayTime = 3000; 497 DelayTime = 3000;
496// printk("DeCline BA from Peer\n"); 498// DBGPRINT(RT_DEBUG_TRACE, ("DeCline BA from Peer\n"));
497// return; 499// return;
498 } 500 }
499 501
@@ -531,11 +533,6 @@ VOID BAOriSessionSetUp(
531 pBAEntry->TimeOutValue = TimeOut; 533 pBAEntry->TimeOutValue = TimeOut;
532 pBAEntry->pAdapter = pAd; 534 pBAEntry->pAdapter = pAd;
533 535
534 DBGPRINT(RT_DEBUG_TRACE,("Send AddBA to %02x:%02x:%02x:%02x:%02x:%02x Tid:%d isForced:%d Wcid:%d\n"
535 ,pEntry->Addr[0],pEntry->Addr[1],pEntry->Addr[2]
536 ,pEntry->Addr[3],pEntry->Addr[4],pEntry->Addr[5]
537 ,TID,isForced,pEntry->Aid));
538
539 if (!(pEntry->TXBAbitmap & (1<<TID))) 536 if (!(pEntry->TXBAbitmap & (1<<TID)))
540 { 537 {
541 RTMPInitTimer(pAd, &pBAEntry->ORIBATimer, GET_TIMER_FUNCTION(BAOriSessionSetupTimeout), pBAEntry, FALSE); 538 RTMPInitTimer(pAd, &pBAEntry->ORIBATimer, GET_TIMER_FUNCTION(BAOriSessionSetupTimeout), pBAEntry, FALSE);
@@ -573,6 +570,8 @@ VOID BAOriSessionAdd(
573 570
574 pBAEntry->TimeOutValue = pFrame->TimeOutValue; 571 pBAEntry->TimeOutValue = pFrame->TimeOutValue;
575 pBAEntry->ORI_BA_Status = Originator_Done; 572 pBAEntry->ORI_BA_Status = Originator_Done;
573 pAd->BATable.numDoneOriginator ++;
574
576 // reset sequence number 575 // reset sequence number
577 pBAEntry->Sequence = BA_ORI_INIT_SEQ; 576 pBAEntry->Sequence = BA_ORI_INIT_SEQ;
578 // Set Bitmap flag. 577 // Set Bitmap flag.
@@ -668,7 +667,7 @@ BOOLEAN BARecSessionAdd(
668 // initial sequence number 667 // initial sequence number
669 pBAEntry->LastIndSeq = RESET_RCV_SEQ; //pFrame->BaStartSeq.field.StartSeq; 668 pBAEntry->LastIndSeq = RESET_RCV_SEQ; //pFrame->BaStartSeq.field.StartSeq;
670 669
671 printk("Start Seq = %08x\n", pFrame->BaStartSeq.field.StartSeq); 670 DBGPRINT(RT_DEBUG_OFF, ("Start Seq = %08x\n", pFrame->BaStartSeq.field.StartSeq));
672 671
673 if (pEntry->RXBAbitmap & (1<<TID)) 672 if (pEntry->RXBAbitmap & (1<<TID))
674 { 673 {
@@ -686,7 +685,7 @@ BOOLEAN BARecSessionAdd(
686 pEntry->BADeclineBitmap &= ~(1<<TID); 685 pEntry->BADeclineBitmap &= ~(1<<TID);
687 686
688 // Set BA session mask in WCID table. 687 // Set BA session mask in WCID table.
689 RT28XX_ADD_BA_SESSION_TO_ASIC(pAd, pEntry->Aid, TID); 688 RTMP_ADD_BA_SESSION_TO_ASIC(pAd, pEntry->Aid, TID);
690 689
691 DBGPRINT(RT_DEBUG_TRACE,("MACEntry[%d]RXBAbitmap = 0x%x. BARecWcidArray=%d\n", 690 DBGPRINT(RT_DEBUG_TRACE,("MACEntry[%d]RXBAbitmap = 0x%x. BARecWcidArray=%d\n",
692 pEntry->Aid, pEntry->RXBAbitmap, pEntry->BARecWcidArray[TID])); 691 pEntry->Aid, pEntry->RXBAbitmap, pEntry->BARecWcidArray[TID]));
@@ -713,8 +712,8 @@ BA_REC_ENTRY *BATableAllocRecEntry(
713 712
714 if (pAd->BATable.numAsRecipient >= MAX_BARECI_SESSION) 713 if (pAd->BATable.numAsRecipient >= MAX_BARECI_SESSION)
715 { 714 {
716 printk("BA Recipeint Session (%ld) > %d\n", pAd->BATable.numAsRecipient, 715 DBGPRINT(RT_DEBUG_OFF, ("BA Recipeint Session (%ld) > %d\n",
717 MAX_BARECI_SESSION); 716 pAd->BATable.numAsRecipient, MAX_BARECI_SESSION));
718 goto done; 717 goto done;
719 } 718 }
720 719
@@ -794,6 +793,7 @@ VOID BATableFreeOriEntry(
794 NdisAcquireSpinLock(&pAd->BATabLock); 793 NdisAcquireSpinLock(&pAd->BATabLock);
795 if (pBAEntry->ORI_BA_Status == Originator_Done) 794 if (pBAEntry->ORI_BA_Status == Originator_Done)
796 { 795 {
796 pAd->BATable.numDoneOriginator -= 1;
797 pEntry->TXBAbitmap &= (~(1<<(pBAEntry->TID) )); 797 pEntry->TXBAbitmap &= (~(1<<(pBAEntry->TID) ));
798 DBGPRINT(RT_DEBUG_TRACE, ("BATableFreeOriEntry numAsOriginator= %ld\n", pAd->BATable.numAsRecipient)); 798 DBGPRINT(RT_DEBUG_TRACE, ("BATableFreeOriEntry numAsOriginator= %ld\n", pAd->BATable.numAsRecipient));
799 // Erase Bitmap flag. 799 // Erase Bitmap flag.
@@ -867,9 +867,8 @@ VOID BAOriSessionTearDown(
867 // force send specified TID DelBA 867 // force send specified TID DelBA
868 MLME_DELBA_REQ_STRUCT DelbaReq; 868 MLME_DELBA_REQ_STRUCT DelbaReq;
869 MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG); 869 MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
870 if (Elem == NULL) 870 if (Elem != NULL)
871 return; 871 {
872
873 NdisZeroMemory(&DelbaReq, sizeof(DelbaReq)); 872 NdisZeroMemory(&DelbaReq, sizeof(DelbaReq));
874 NdisZeroMemory(Elem, sizeof(MLME_QUEUE_ELEM)); 873 NdisZeroMemory(Elem, sizeof(MLME_QUEUE_ELEM));
875 874
@@ -877,15 +876,15 @@ VOID BAOriSessionTearDown(
877 DelbaReq.Wcid = Wcid; 876 DelbaReq.Wcid = Wcid;
878 DelbaReq.TID = TID; 877 DelbaReq.TID = TID;
879 DelbaReq.Initiator = ORIGINATOR; 878 DelbaReq.Initiator = ORIGINATOR;
880#if 1
881 Elem->MsgLen = sizeof(DelbaReq); 879 Elem->MsgLen = sizeof(DelbaReq);
882 NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq)); 880 NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq));
883 MlmeDELBAAction(pAd, Elem); 881 MlmeDELBAAction(pAd, Elem);
884 kfree(Elem); 882 kfree(Elem);
885#else 883 }
886 MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ORI_DELBA_CATE, sizeof(MLME_DELBA_REQ_STRUCT), (PVOID)&DelbaReq); 884 else
887 RT28XX_MLME_HANDLER(pAd); 885 {
888#endif 886 DBGPRINT(RT_DEBUG_ERROR, ("%s(bForceSend):alloc memory failed!\n", __func__));
887 }
889 } 888 }
890 889
891 return; 890 return;
@@ -902,9 +901,8 @@ VOID BAOriSessionTearDown(
902 { 901 {
903 MLME_DELBA_REQ_STRUCT DelbaReq; 902 MLME_DELBA_REQ_STRUCT DelbaReq;
904 MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG); 903 MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
905 if (Elem == NULL) 904 if (Elem != NULL)
906 return; 905 {
907
908 NdisZeroMemory(&DelbaReq, sizeof(DelbaReq)); 906 NdisZeroMemory(&DelbaReq, sizeof(DelbaReq));
909 NdisZeroMemory(Elem, sizeof(MLME_QUEUE_ELEM)); 907 NdisZeroMemory(Elem, sizeof(MLME_QUEUE_ELEM));
910 908
@@ -912,15 +910,16 @@ VOID BAOriSessionTearDown(
912 DelbaReq.Wcid = Wcid; 910 DelbaReq.Wcid = Wcid;
913 DelbaReq.TID = pBAEntry->TID; 911 DelbaReq.TID = pBAEntry->TID;
914 DelbaReq.Initiator = ORIGINATOR; 912 DelbaReq.Initiator = ORIGINATOR;
915#if 1
916 Elem->MsgLen = sizeof(DelbaReq); 913 Elem->MsgLen = sizeof(DelbaReq);
917 NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq)); 914 NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq));
918 MlmeDELBAAction(pAd, Elem); 915 MlmeDELBAAction(pAd, Elem);
919 kfree(Elem); 916 kfree(Elem);
920#else 917 }
921 MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ORI_DELBA_CATE, sizeof(MLME_DELBA_REQ_STRUCT), (PVOID)&DelbaReq); 918 else
922 RT28XX_MLME_HANDLER(pAd); 919 {
923#endif 920 DBGPRINT(RT_DEBUG_ERROR, ("%s():alloc memory failed!\n", __func__));
921 return;
922 }
924 } 923 }
925 RTMPCancelTimer(&pBAEntry->ORIBATimer, &Cancelled); 924 RTMPCancelTimer(&pBAEntry->ORIBATimer, &Cancelled);
926 BATableFreeOriEntry(pAd, Idx); 925 BATableFreeOriEntry(pAd, Idx);
@@ -964,7 +963,6 @@ VOID BARecSessionTearDown(
964 { 963 {
965 MLME_DELBA_REQ_STRUCT DelbaReq; 964 MLME_DELBA_REQ_STRUCT DelbaReq;
966 BOOLEAN Cancelled; 965 BOOLEAN Cancelled;
967 MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
968 //ULONG offset; 966 //ULONG offset;
969 //UINT32 VALUE; 967 //UINT32 VALUE;
970 968
@@ -975,6 +973,9 @@ VOID BARecSessionTearDown(
975 // 973 //
976 if (bPassive == FALSE) 974 if (bPassive == FALSE)
977 { 975 {
976 MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
977 if (Elem != NULL)
978 {
978 NdisZeroMemory(&DelbaReq, sizeof(DelbaReq)); 979 NdisZeroMemory(&DelbaReq, sizeof(DelbaReq));
979 NdisZeroMemory(Elem, sizeof(MLME_QUEUE_ELEM)); 980 NdisZeroMemory(Elem, sizeof(MLME_QUEUE_ELEM));
980 981
@@ -982,15 +983,16 @@ VOID BARecSessionTearDown(
982 DelbaReq.Wcid = Wcid; 983 DelbaReq.Wcid = Wcid;
983 DelbaReq.TID = TID; 984 DelbaReq.TID = TID;
984 DelbaReq.Initiator = RECIPIENT; 985 DelbaReq.Initiator = RECIPIENT;
985#if 1
986 Elem->MsgLen = sizeof(DelbaReq); 986 Elem->MsgLen = sizeof(DelbaReq);
987 NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq)); 987 NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq));
988 MlmeDELBAAction(pAd, Elem); 988 MlmeDELBAAction(pAd, Elem);
989 kfree(Elem); 989 kfree(Elem);
990#else 990 }
991 MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ORI_DELBA_CATE, sizeof(MLME_DELBA_REQ_STRUCT), (PVOID)&DelbaReq); 991 else
992 RT28XX_MLME_HANDLER(pAd); 992 {
993#endif 993 DBGPRINT(RT_DEBUG_ERROR, ("%s():alloc memory failed!\n", __func__));
994 return;
995 }
994 } 996 }
995 997
996 998
@@ -1009,7 +1011,7 @@ VOID BARecSessionTearDown(
1009 pAd->MacTab.Content[Wcid].RXBAbitmap &= (~(1<<(pBAEntry->TID))); 1011 pAd->MacTab.Content[Wcid].RXBAbitmap &= (~(1<<(pBAEntry->TID)));
1010 pAd->MacTab.Content[Wcid].BARecWcidArray[TID] = 0; 1012 pAd->MacTab.Content[Wcid].BARecWcidArray[TID] = 0;
1011 1013
1012 RT28XX_DEL_BA_SESSION_FROM_ASIC(pAd, Wcid, TID); 1014 RTMP_DEL_BA_SESSION_FROM_ASIC(pAd, Wcid, TID);
1013 1015
1014 NdisReleaseSpinLock(&pAd->BATabLock); 1016 NdisReleaseSpinLock(&pAd->BATabLock);
1015 1017
@@ -1061,9 +1063,12 @@ VOID BAOriSessionSetupTimeout(
1061 1063
1062 pAd = pBAEntry->pAdapter; 1064 pAd = pBAEntry->pAdapter;
1063 1065
1066 {
1064 // Do nothing if monitor mode is on 1067 // Do nothing if monitor mode is on
1065 if (MONITOR_ON(pAd)) 1068 if (MONITOR_ON(pAd))
1066 return; 1069 return;
1070 }
1071
1067 1072
1068 pEntry = &pAd->MacTab.Content[pBAEntry->Wcid]; 1073 pEntry = &pAd->MacTab.Content[pBAEntry->Wcid];
1069 1074
@@ -1079,12 +1084,9 @@ VOID BAOriSessionSetupTimeout(
1079 AddbaReq.TimeOutValue = 0; 1084 AddbaReq.TimeOutValue = 0;
1080 AddbaReq.Token = pBAEntry->Token; 1085 AddbaReq.Token = pBAEntry->Token;
1081 MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ADD_BA_CATE, sizeof(MLME_ADDBA_REQ_STRUCT), (PVOID)&AddbaReq); 1086 MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ADD_BA_CATE, sizeof(MLME_ADDBA_REQ_STRUCT), (PVOID)&AddbaReq);
1082 RT28XX_MLME_HANDLER(pAd); 1087 RTMP_MLME_HANDLER(pAd);
1083 DBGPRINT(RT_DEBUG_TRACE,("BA Ori Session Timeout(%d) to %02x:%02x:%02x:%02x:%02x:%02x Tid:%d Wcid:%d\n" 1088 DBGPRINT(RT_DEBUG_TRACE,("BA Ori Session Timeout(%d) : Send ADD BA again\n", pBAEntry->Token));
1084 ,pBAEntry->Token 1089
1085 ,pEntry->Addr[0],pEntry->Addr[1],pEntry->Addr[2]
1086 ,pEntry->Addr[3],pEntry->Addr[4],pEntry->Addr[5]
1087 ,pBAEntry->TID,pEntry->Aid));
1088 pBAEntry->Token++; 1090 pBAEntry->Token++;
1089 RTMPSetTimer(&pBAEntry->ORIBATimer, ORI_BA_SESSION_TIMEOUT); 1091 RTMPSetTimer(&pBAEntry->ORIBATimer, ORI_BA_SESSION_TIMEOUT);
1090 } 1092 }
@@ -1131,7 +1133,7 @@ VOID BARecSessionIdleTimeout(
1131 pAd = pBAEntry->pAdapter; 1133 pAd = pBAEntry->pAdapter;
1132 // flush all pending reordering mpdus 1134 // flush all pending reordering mpdus
1133 ba_refresh_reordering_mpdus(pAd, pBAEntry); 1135 ba_refresh_reordering_mpdus(pAd, pBAEntry);
1134 printk("%ld: REC BA session Timeout\n", Now32); 1136 DBGPRINT(RT_DEBUG_OFF, ("%ld: REC BA session Timeout\n", Now32));
1135 } 1137 }
1136 } 1138 }
1137} 1139}
@@ -1174,7 +1176,7 @@ VOID PeerAddBAReqAction(
1174 if ((pAd->CommonCfg.bBADecline == FALSE) && IS_HT_STA(pMacEntry)) 1176 if ((pAd->CommonCfg.bBADecline == FALSE) && IS_HT_STA(pMacEntry))
1175 { 1177 {
1176 pAddreqFrame = (PFRAME_ADDBA_REQ)(&Elem->Msg[0]); 1178 pAddreqFrame = (PFRAME_ADDBA_REQ)(&Elem->Msg[0]);
1177 printk("Rcv Wcid(%d) AddBAReq\n", Elem->Wcid); 1179 DBGPRINT(RT_DEBUG_OFF, ("Rcv Wcid(%d) AddBAReq\n", Elem->Wcid));
1178 if (BARecSessionAdd(pAd, &pAd->MacTab.Content[Elem->Wcid], pAddreqFrame)) 1180 if (BARecSessionAdd(pAd, &pAd->MacTab.Content[Elem->Wcid], pAddreqFrame))
1179 Status = 0; 1181 Status = 0;
1180 else 1182 else
@@ -1367,7 +1369,7 @@ BOOLEAN CntlEnqueueForRecv(
1367 1369
1368 if (SEQ_SMALLER(pBAEntry->LastIndSeq, pFrame->BAStartingSeq.field.StartSeq, MAXSEQ)) 1370 if (SEQ_SMALLER(pBAEntry->LastIndSeq, pFrame->BAStartingSeq.field.StartSeq, MAXSEQ))
1369 { 1371 {
1370 //printk("BAR Seq = %x, LastIndSeq = %x\n", pFrame->BAStartingSeq.field.StartSeq, pBAEntry->LastIndSeq); 1372 //DBGPRINT(RT_DEBUG_TRACE, ("BAR Seq = %x, LastIndSeq = %x\n", pFrame->BAStartingSeq.field.StartSeq, pBAEntry->LastIndSeq));
1371 ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, pFrame->BAStartingSeq.field.StartSeq); 1373 ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, pFrame->BAStartingSeq.field.StartSeq);
1372 pBAEntry->LastIndSeq = (pFrame->BAStartingSeq.field.StartSeq == 0) ? MAXSEQ :(pFrame->BAStartingSeq.field.StartSeq -1); 1374 pBAEntry->LastIndSeq = (pFrame->BAStartingSeq.field.StartSeq == 0) ? MAXSEQ :(pFrame->BAStartingSeq.field.StartSeq -1);
1373 } 1375 }
@@ -1388,8 +1390,6 @@ VOID SendPSMPAction(
1388 //ULONG Idx; 1390 //ULONG Idx;
1389 FRAME_PSMP_ACTION Frame; 1391 FRAME_PSMP_ACTION Frame;
1390 ULONG FrameLen; 1392 ULONG FrameLen;
1391 UCHAR bbpdata=0;
1392 UINT32 macdata;
1393 1393
1394 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory 1394 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
1395 if (NStatus != NDIS_STATUS_SUCCESS) 1395 if (NStatus != NDIS_STATUS_SUCCESS)
@@ -1405,48 +1405,26 @@ VOID SendPSMPAction(
1405 switch (Psmp) 1405 switch (Psmp)
1406 { 1406 {
1407 case MMPS_ENABLE: 1407 case MMPS_ENABLE:
1408 if (IS_RT3090(pAd)) 1408#ifdef RT30xx
1409 if (IS_RT30xx(pAd)
1410 &&(pAd->Antenna.field.RxPath>1||pAd->Antenna.field.TxPath>1))
1409 { 1411 {
1410 // disable MMPS BBP control register 1412 RTMP_ASIC_MMPS_DISABLE(pAd);
1411 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &bbpdata);
1412 bbpdata &= ~(0x04); //bit 2
1413 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, bbpdata);
1414
1415 // disable MMPS MAC control register
1416 RTMP_IO_READ32(pAd, 0x1210, &macdata);
1417 macdata &= ~(0x09); //bit 0, 3
1418 RTMP_IO_WRITE32(pAd, 0x1210, macdata);
1419 } 1413 }
1414#endif // RT30xx //
1420 Frame.Psmp = 0; 1415 Frame.Psmp = 0;
1421 break; 1416 break;
1422 case MMPS_DYNAMIC: 1417 case MMPS_DYNAMIC:
1423 if (IS_RT3090(pAd))
1424 {
1425 // enable MMPS BBP control register
1426 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &bbpdata);
1427 bbpdata |= 0x04; //bit 2
1428 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, bbpdata);
1429
1430 // enable MMPS MAC control register
1431 RTMP_IO_READ32(pAd, 0x1210, &macdata);
1432 macdata |= 0x09; //bit 0, 3
1433 RTMP_IO_WRITE32(pAd, 0x1210, macdata);
1434 }
1435 Frame.Psmp = 3; 1418 Frame.Psmp = 3;
1436 break; 1419 break;
1437 case MMPS_STATIC: 1420 case MMPS_STATIC:
1438 if (IS_RT3090(pAd)) 1421#ifdef RT30xx
1422 if (IS_RT30xx(pAd)
1423 &&(pAd->Antenna.field.RxPath>1||pAd->Antenna.field.TxPath>1))
1439 { 1424 {
1440 // enable MMPS BBP control register 1425 RTMP_ASIC_MMPS_ENABLE(pAd);
1441 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &bbpdata);
1442 bbpdata |= 0x04; //bit 2
1443 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, bbpdata);
1444
1445 // enable MMPS MAC control register
1446 RTMP_IO_READ32(pAd, 0x1210, &macdata);
1447 macdata |= 0x09; //bit 0, 3
1448 RTMP_IO_WRITE32(pAd, 0x1210, macdata);
1449 } 1426 }
1427#endif // RT30xx //
1450 Frame.Psmp = 1; 1428 Frame.Psmp = 1;
1451 break; 1429 break;
1452 } 1430 }
@@ -1504,20 +1482,22 @@ void convert_reordering_packet_to_preAMSDU_or_802_3_packet(
1504 ASSERT(pRxBlk->pRxPacket); 1482 ASSERT(pRxBlk->pRxPacket);
1505 pRxPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket); 1483 pRxPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
1506 1484
1507 RTPKT_TO_OSPKT(pRxPkt)->dev = get_netdev_from_bssid(pAd, FromWhichBSSID); 1485 SET_OS_PKT_NETDEV(pRxPkt, get_netdev_from_bssid(pAd, FromWhichBSSID));
1508 RTPKT_TO_OSPKT(pRxPkt)->data = pRxBlk->pData; 1486 SET_OS_PKT_DATAPTR(pRxPkt, pRxBlk->pData);
1509 RTPKT_TO_OSPKT(pRxPkt)->len = pRxBlk->DataSize; 1487 SET_OS_PKT_LEN(pRxPkt, pRxBlk->DataSize);
1510 RTPKT_TO_OSPKT(pRxPkt)->tail = RTPKT_TO_OSPKT(pRxPkt)->data + RTPKT_TO_OSPKT(pRxPkt)->len; 1488 SET_OS_PKT_DATATAIL(pRxPkt, pRxBlk->pData, pRxBlk->DataSize);
1511 1489
1512 // 1490 //
1513 // copy 802.3 header, if necessary 1491 // copy 802.3 header, if necessary
1514 // 1492 //
1515 if (!RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU)) 1493 if (!RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU))
1516 { 1494 {
1495 {
1517#ifdef LINUX 1496#ifdef LINUX
1518 NdisMoveMemory(skb_push(pRxPkt, LENGTH_802_3), Header802_3, LENGTH_802_3); 1497 NdisMoveMemory(skb_push(pRxPkt, LENGTH_802_3), Header802_3, LENGTH_802_3);
1519#endif 1498#endif
1520 } 1499 }
1500 }
1521} 1501}
1522 1502
1523 1503
@@ -1550,7 +1530,8 @@ static VOID ba_enqueue_reordering_packet(
1550 UINT16 Sequence = (UINT16) pRxBlk->pHeader->Sequence; 1530 UINT16 Sequence = (UINT16) pRxBlk->pHeader->Sequence;
1551 1531
1552 mpdu_blk = ba_mpdu_blk_alloc(pAd); 1532 mpdu_blk = ba_mpdu_blk_alloc(pAd);
1553 if (mpdu_blk != NULL) 1533 if ((mpdu_blk != NULL) &&
1534 (!RX_BLK_TEST_FLAG(pRxBlk, fRX_EAP)))
1554 { 1535 {
1555 // Write RxD buffer address & allocated buffer length 1536 // Write RxD buffer address & allocated buffer length
1556 NdisAcquireSpinLock(&pBAEntry->RxReRingLock); 1537 NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
diff --git a/drivers/staging/rt2860/common/md5.c b/drivers/staging/rt2860/common/cmm_aes.c
index ad883ca2ffc..2c311b16678 100644
--- a/drivers/staging/rt2860/common/md5.c
+++ b/drivers/staging/rt2860/common/cmm_aes.c
@@ -24,673 +24,644 @@
24 * * 24 * *
25 ************************************************************************* 25 *************************************************************************
26 26
27 Module Name: 27 Module Name:
28 md5.c 28 cmm_aes.c
29 29
30 Abstract: 30 Abstract:
31 31
32 Revision History: 32 Revision History:
33 Who When What 33 Who When What
34 -------- ---------- ---------------------------------------------- 34 -------- ---------- ----------------------------------------------
35 Name Date Modification logs 35 Paul Wu 02-25-02 Initial
36 jan 10-28-03 Initial 36*/
37 Rita 11-23-04 Modify MD5 and SHA-1
38 Rita 10-14-05 Modify SHA-1 in big-endian platform
39 */
40#include "../rt_config.h"
41
42/**
43 * md5_mac:
44 * @key: pointer to the key used for MAC generation
45 * @key_len: length of the key in bytes
46 * @data: pointer to the data area for which the MAC is generated
47 * @data_len: length of the data in bytes
48 * @mac: pointer to the buffer holding space for the MAC; the buffer should
49 * have space for 128-bit (16 bytes) MD5 hash value
50 *
51 * md5_mac() determines the message authentication code by using secure hash
52 * MD5(key | data | key).
53 */
54void md5_mac(u8 *key, size_t key_len, u8 *data, size_t data_len, u8 *mac)
55{
56 MD5_CTX context;
57 37
58 MD5Init(&context); 38#include "../rt_config.h"
59 MD5Update(&context, key, key_len);
60 MD5Update(&context, data, data_len);
61 MD5Update(&context, key, key_len);
62 MD5Final(mac, &context);
63}
64 39
65/** 40
66 * hmac_md5: 41typedef struct
67 * @key: pointer to the key used for MAC generation
68 * @key_len: length of the key in bytes
69 * @data: pointer to the data area for which the MAC is generated
70 * @data_len: length of the data in bytes
71 * @mac: pointer to the buffer holding space for the MAC; the buffer should
72 * have space for 128-bit (16 bytes) MD5 hash value
73 *
74 * hmac_md5() determines the message authentication code using HMAC-MD5.
75 * This implementation is based on the sample code presented in RFC 2104.
76 */
77void hmac_md5(u8 *key, size_t key_len, u8 *data, size_t data_len, u8 *mac)
78{ 42{
79 MD5_CTX context; 43 UINT32 erk[64]; /* encryption round keys */
80 u8 k_ipad[65]; /* inner padding - key XORd with ipad */ 44 UINT32 drk[64]; /* decryption round keys */
81 u8 k_opad[65]; /* outer padding - key XORd with opad */ 45 int nr; /* number of rounds */
82 u8 tk[16]; 46}
83 int i; 47aes_context;
84 48
85 //assert(key != NULL && data != NULL && mac != NULL); 49/*****************************/
50/******** SBOX Table *********/
51/*****************************/
86 52
87 /* if key is longer than 64 bytes reset it to key = MD5(key) */ 53UCHAR SboxTable[256] =
88 if (key_len > 64) { 54{
89 MD5_CTX ttcontext; 55 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
56 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
57 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
58 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
59 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
60 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
61 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
62 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
63 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
64 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
65 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
66 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
67 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
68 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
69 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
70 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
71 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
72 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
73 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
74 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
75 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
76 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
77 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
78 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
79 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
80 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
81 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
82 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
83 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
84 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
85 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
86 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
87};
90 88
91 MD5Init(&ttcontext); 89VOID xor_32(
92 MD5Update(&ttcontext, key, key_len); 90 IN PUCHAR a,
93 MD5Final(tk, &ttcontext); 91 IN PUCHAR b,
94 //key=(PUCHAR)ttcontext.buf; 92 OUT PUCHAR out)
95 key = tk; 93{
96 key_len = 16; 94 INT i;
97 }
98 95
99 /* the HMAC_MD5 transform looks like: 96 for (i=0;i<4; i++)
100 * 97 {
101 * MD5(K XOR opad, MD5(K XOR ipad, text)) 98 out[i] = a[i] ^ b[i];
102 *
103 * where K is an n byte key
104 * ipad is the byte 0x36 repeated 64 times
105 * opad is the byte 0x5c repeated 64 times
106 * and text is the data being protected */
107
108 /* start out by storing key in pads */
109 NdisZeroMemory(k_ipad, sizeof(k_ipad));
110 NdisZeroMemory(k_opad, sizeof(k_opad));
111 //assert(key_len < sizeof(k_ipad));
112 NdisMoveMemory(k_ipad, key, key_len);
113 NdisMoveMemory(k_opad, key, key_len);
114
115 /* XOR key with ipad and opad values */
116 for (i = 0; i < 64; i++) {
117 k_ipad[i] ^= 0x36;
118 k_opad[i] ^= 0x5c;
119 } 99 }
120
121 /* perform inner MD5 */
122 MD5Init(&context); /* init context for 1st pass */
123 MD5Update(&context, k_ipad, 64); /* start with inner pad */
124 MD5Update(&context, data, data_len); /* then text of datagram */
125 MD5Final(mac, &context); /* finish up 1st pass */
126
127 /* perform outer MD5 */
128 MD5Init(&context); /* init context for 2nd pass */
129 MD5Update(&context, k_opad, 64); /* start with outer pad */
130 MD5Update(&context, mac, 16); /* then results of 1st hash */
131 MD5Final(mac, &context); /* finish up 2nd pass */
132} 100}
133 101
134#define byteReverse(buf, len) /* Nothing */ 102VOID xor_128(
135 103 IN PUCHAR a,
136/* ========================== MD5 implementation =========================== */ 104 IN PUCHAR b,
137// four base functions for MD5 105 OUT PUCHAR out)
138#define MD5_F1(x, y, z) (((x) & (y)) | ((~x) & (z)))
139#define MD5_F2(x, y, z) (((x) & (z)) | ((y) & (~z)))
140#define MD5_F3(x, y, z) ((x) ^ (y) ^ (z))
141#define MD5_F4(x, y, z) ((y) ^ ((x) | (~z)))
142#define CYCLIC_LEFT_SHIFT(w, s) (((w) << (s)) | ((w) >> (32-(s))))
143
144#define MD5Step(f, w, x, y, z, data, t, s) \
145 ( w += f(x, y, z) + data + t, w = (CYCLIC_LEFT_SHIFT(w, s)) & 0xffffffff, w += x )
146
147
148/*
149 * Function Description:
150 * Initiate MD5 Context satisfied in RFC 1321
151 *
152 * Arguments:
153 * pCtx Pointer to MD5 context
154 *
155 * Return Value:
156 * None
157 */
158VOID MD5Init(MD5_CTX *pCtx)
159{ 106{
160 pCtx->Buf[0]=0x67452301; 107 INT i;
161 pCtx->Buf[1]=0xefcdab89;
162 pCtx->Buf[2]=0x98badcfe;
163 pCtx->Buf[3]=0x10325476;
164 108
165 pCtx->LenInBitCount[0]=0; 109 for (i=0;i<16; i++)
166 pCtx->LenInBitCount[1]=0; 110 {
111 out[i] = a[i] ^ b[i];
112 }
167} 113}
168 114
169 115UCHAR RTMPCkipSbox(
170/* 116 IN UCHAR a)
171 * Function Description:
172 * Update MD5 Context, allow of an arrary of octets as the next portion
173 * of the message
174 *
175 * Arguments:
176 * pCtx Pointer to MD5 context
177 * pData Pointer to input data
178 * LenInBytes The length of input data (unit: byte)
179 *
180 * Return Value:
181 * None
182 *
183 * Note:
184 * Called after MD5Init or MD5Update(itself)
185 */
186VOID MD5Update(MD5_CTX *pCtx, UCHAR *pData, UINT32 LenInBytes)
187{ 117{
188 118 return SboxTable[(int)a];
189 UINT32 TfTimes;
190 UINT32 temp;
191 unsigned int i;
192
193 temp = pCtx->LenInBitCount[0];
194
195 pCtx->LenInBitCount[0] = (UINT32) (pCtx->LenInBitCount[0] + (LenInBytes << 3));
196
197 if (pCtx->LenInBitCount[0] < temp)
198 pCtx->LenInBitCount[1]++; //carry in
199
200 pCtx->LenInBitCount[1] += LenInBytes >> 29;
201
202 // mod 64 bytes
203 temp = (temp >> 3) & 0x3f;
204
205 // process lacks of 64-byte data
206 if (temp)
207 {
208 UCHAR *pAds = (UCHAR *) pCtx->Input + temp;
209
210 if ((temp+LenInBytes) < 64)
211 {
212 NdisMoveMemory(pAds, (UCHAR *)pData, LenInBytes);
213 return;
214 }
215
216 NdisMoveMemory(pAds, (UCHAR *)pData, 64-temp);
217 byteReverse(pCtx->Input, 16);
218 MD5Transform(pCtx->Buf, (UINT32 *)pCtx->Input);
219
220 pData += 64-temp;
221 LenInBytes -= 64-temp;
222 } // end of if (temp)
223
224
225 TfTimes = (LenInBytes >> 6);
226
227 for (i=TfTimes; i>0; i--)
228 {
229 NdisMoveMemory(pCtx->Input, (UCHAR *)pData, 64);
230 byteReverse(pCtx->Input, 16);
231 MD5Transform(pCtx->Buf, (UINT32 *)pCtx->Input);
232 pData += 64;
233 LenInBytes -= 64;
234 } // end of for
235
236 // buffering lacks of 64-byte data
237 if(LenInBytes)
238 NdisMoveMemory(pCtx->Input, (UCHAR *)pData, LenInBytes);
239
240} 119}
241 120
242 121VOID next_key(
243/* 122 IN PUCHAR key,
244 * Function Description: 123 IN INT round)
245 * Append padding bits and length of original message in the tail
246 * The message digest has to be completed in the end
247 *
248 * Arguments:
249 * Digest Output of Digest-Message for MD5
250 * pCtx Pointer to MD5 context
251 *
252 * Return Value:
253 * None
254 *
255 * Note:
256 * Called after MD5Update
257 */
258VOID MD5Final(UCHAR Digest[16], MD5_CTX *pCtx)
259{ 124{
260 UCHAR Remainder; 125 UCHAR rcon;
261 UCHAR PadLenInBytes; 126 UCHAR sbox_key[4];
262 UCHAR *pAppend=0; 127 UCHAR rcon_table[12] =
263 unsigned int i; 128 {
264 129 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
265 Remainder = (UCHAR)((pCtx->LenInBitCount[0] >> 3) & 0x3f); 130 0x1b, 0x36, 0x36, 0x36
266 131 };
267 PadLenInBytes = (Remainder < 56) ? (56-Remainder) : (120-Remainder);
268
269 pAppend = (UCHAR *)pCtx->Input + Remainder;
270
271 // padding bits without crossing block(64-byte based) boundary
272 if (Remainder < 56)
273 {
274 *pAppend = 0x80;
275 PadLenInBytes --;
276
277 NdisZeroMemory((UCHAR *)pCtx->Input + Remainder+1, PadLenInBytes);
278
279 // add data-length field, from low to high
280 for (i=0; i<4; i++)
281 {
282 pCtx->Input[56+i] = (UCHAR)((pCtx->LenInBitCount[0] >> (i << 3)) & 0xff);
283 pCtx->Input[60+i] = (UCHAR)((pCtx->LenInBitCount[1] >> (i << 3)) & 0xff);
284 }
285
286 byteReverse(pCtx->Input, 16);
287 MD5Transform(pCtx->Buf, (UINT32 *)pCtx->Input);
288 } // end of if
289
290 // padding bits with crossing block(64-byte based) boundary
291 else
292 {
293 // the first block ===
294 *pAppend = 0x80;
295 PadLenInBytes --;
296
297 NdisZeroMemory((UCHAR *)pCtx->Input + Remainder+1, (64-Remainder-1));
298 PadLenInBytes -= (64 - Remainder - 1);
299
300 byteReverse(pCtx->Input, 16);
301 MD5Transform(pCtx->Buf, (UINT32 *)pCtx->Input);
302
303
304 // the second block ===
305 NdisZeroMemory((UCHAR *)pCtx->Input, PadLenInBytes);
306 132
307 // add data-length field 133 sbox_key[0] = RTMPCkipSbox(key[13]);
308 for (i=0; i<4; i++) 134 sbox_key[1] = RTMPCkipSbox(key[14]);
309 { 135 sbox_key[2] = RTMPCkipSbox(key[15]);
310 pCtx->Input[56+i] = (UCHAR)((pCtx->LenInBitCount[0] >> (i << 3)) & 0xff); 136 sbox_key[3] = RTMPCkipSbox(key[12]);
311 pCtx->Input[60+i] = (UCHAR)((pCtx->LenInBitCount[1] >> (i << 3)) & 0xff);
312 }
313 137
314 byteReverse(pCtx->Input, 16); 138 rcon = rcon_table[round];
315 MD5Transform(pCtx->Buf, (UINT32 *)pCtx->Input);
316 } // end of else
317 139
140 xor_32(&key[0], sbox_key, &key[0]);
141 key[0] = key[0] ^ rcon;
318 142
319 NdisMoveMemory((UCHAR *)Digest, (UINT32 *)pCtx->Buf, 16); // output 143 xor_32(&key[4], &key[0], &key[4]);
320 byteReverse((UCHAR *)Digest, 4); 144 xor_32(&key[8], &key[4], &key[8]);
321 NdisZeroMemory(pCtx, sizeof(pCtx)); // memory free 145 xor_32(&key[12], &key[8], &key[12]);
322} 146}
323 147
324 148VOID byte_sub(
325/* 149 IN PUCHAR in,
326 * Function Description: 150 OUT PUCHAR out)
327 * The central algorithm of MD5, consists of four rounds and sixteen
328 * steps per round
329 *
330 * Arguments:
331 * Buf Buffers of four states (output: 16 bytes)
332 * Mes Input data (input: 64 bytes)
333 *
334 * Return Value:
335 * None
336 *
337 * Note:
338 * Called by MD5Update or MD5Final
339 */
340VOID MD5Transform(UINT32 Buf[4], UINT32 Mes[16])
341{ 151{
342 UINT32 Reg[4], Temp; 152 INT i;
343 unsigned int i;
344 153
345 static UCHAR LShiftVal[16] = 154 for (i=0; i< 16; i++)
346 { 155 {
347 7, 12, 17, 22, 156 out[i] = RTMPCkipSbox(in[i]);
348 5, 9 , 14, 20, 157 }
349 4, 11, 16, 23, 158}
350 6, 10, 15, 21,
351 };
352 159
160/************************************/
161/* bitwise_xor() */
162/* A 128 bit, bitwise exclusive or */
163/************************************/
353 164
354 // [equal to 4294967296*abs(sin(index))] 165void bitwise_xor(unsigned char *ina, unsigned char *inb, unsigned char *out)
355 static UINT32 MD5Table[64] = 166{
167 int i;
168 for (i=0; i<16; i++)
356 { 169 {
357 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 170 out[i] = ina[i] ^ inb[i];
358 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, 171 }
359 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 172}
360 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
361
362 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
363 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
364 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
365 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
366
367 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
368 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
369 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
370 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
371
372 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
373 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
374 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
375 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391
376 };
377 173
174VOID shift_row(
175 IN PUCHAR in,
176 OUT PUCHAR out)
177{
178 out[0] = in[0];
179 out[1] = in[5];
180 out[2] = in[10];
181 out[3] = in[15];
182 out[4] = in[4];
183 out[5] = in[9];
184 out[6] = in[14];
185 out[7] = in[3];
186 out[8] = in[8];
187 out[9] = in[13];
188 out[10] = in[2];
189 out[11] = in[7];
190 out[12] = in[12];
191 out[13] = in[1];
192 out[14] = in[6];
193 out[15] = in[11];
194}
378 195
379 for (i=0; i<4; i++) 196VOID mix_column(
380 Reg[i]=Buf[i]; 197 IN PUCHAR in,
198 OUT PUCHAR out)
199{
200 INT i;
201 UCHAR add1b[4];
202 UCHAR add1bf7[4];
203 UCHAR rotl[4];
204 UCHAR swap_halfs[4];
205 UCHAR andf7[4];
206 UCHAR rotr[4];
207 UCHAR temp[4];
208 UCHAR tempb[4];
209
210 for (i=0 ; i<4; i++)
211 {
212 if ((in[i] & 0x80)== 0x80)
213 add1b[i] = 0x1b;
214 else
215 add1b[i] = 0x00;
216 }
381 217
218 swap_halfs[0] = in[2]; /* Swap halfs */
219 swap_halfs[1] = in[3];
220 swap_halfs[2] = in[0];
221 swap_halfs[3] = in[1];
382 222
383 // 64 steps in MD5 algorithm 223 rotl[0] = in[3]; /* Rotate left 8 bits */
384 for (i=0; i<16; i++) 224 rotl[1] = in[0];
385 { 225 rotl[2] = in[1];
386 MD5Step(MD5_F1, Reg[0], Reg[1], Reg[2], Reg[3], Mes[i], 226 rotl[3] = in[2];
387 MD5Table[i], LShiftVal[i & 0x3]);
388
389 // one-word right shift
390 Temp = Reg[3];
391 Reg[3] = Reg[2];
392 Reg[2] = Reg[1];
393 Reg[1] = Reg[0];
394 Reg[0] = Temp;
395 }
396 for (i=16; i<32; i++)
397 {
398 MD5Step(MD5_F2, Reg[0], Reg[1], Reg[2], Reg[3], Mes[(5*(i & 0xf)+1) & 0xf],
399 MD5Table[i], LShiftVal[(0x1 << 2)+(i & 0x3)]);
400
401 // one-word right shift
402 Temp = Reg[3];
403 Reg[3] = Reg[2];
404 Reg[2] = Reg[1];
405 Reg[1] = Reg[0];
406 Reg[0] = Temp;
407 }
408 for (i=32; i<48; i++)
409 {
410 MD5Step(MD5_F3, Reg[0], Reg[1], Reg[2], Reg[3], Mes[(3*(i & 0xf)+5) & 0xf],
411 MD5Table[i], LShiftVal[(0x1 << 3)+(i & 0x3)]);
412
413 // one-word right shift
414 Temp = Reg[3];
415 Reg[3] = Reg[2];
416 Reg[2] = Reg[1];
417 Reg[1] = Reg[0];
418 Reg[0] = Temp;
419 }
420 for (i=48; i<64; i++)
421 {
422 MD5Step(MD5_F4, Reg[0], Reg[1], Reg[2], Reg[3], Mes[(7*(i & 0xf)) & 0xf],
423 MD5Table[i], LShiftVal[(0x3 << 2)+(i & 0x3)]);
424
425 // one-word right shift
426 Temp = Reg[3];
427 Reg[3] = Reg[2];
428 Reg[2] = Reg[1];
429 Reg[1] = Reg[0];
430 Reg[0] = Temp;
431 }
432 227
228 andf7[0] = in[0] & 0x7f;
229 andf7[1] = in[1] & 0x7f;
230 andf7[2] = in[2] & 0x7f;
231 andf7[3] = in[3] & 0x7f;
433 232
434 // (temporary)output 233 for (i = 3; i>0; i--) /* logical shift left 1 bit */
435 for (i=0; i<4; i++) 234 {
436 Buf[i] += Reg[i]; 235 andf7[i] = andf7[i] << 1;
236 if ((andf7[i-1] & 0x80) == 0x80)
237 {
238 andf7[i] = (andf7[i] | 0x01);
239 }
240 }
241 andf7[0] = andf7[0] << 1;
242 andf7[0] = andf7[0] & 0xfe;
437 243
438} 244 xor_32(add1b, andf7, add1bf7);
439 245
246 xor_32(in, add1bf7, rotr);
440 247
248 temp[0] = rotr[0]; /* Rotate right 8 bits */
249 rotr[0] = rotr[1];
250 rotr[1] = rotr[2];
251 rotr[2] = rotr[3];
252 rotr[3] = temp[0];
441 253
442/* ========================= SHA-1 implementation ========================== */ 254 xor_32(add1bf7, rotr, temp);
443// four base functions for SHA-1 255 xor_32(swap_halfs, rotl,tempb);
444#define SHA1_F1(b, c, d) (((b) & (c)) | ((~b) & (d))) 256 xor_32(temp, tempb, out);
445#define SHA1_F2(b, c, d) ((b) ^ (c) ^ (d)) 257}
446#define SHA1_F3(b, c, d) (((b) & (c)) | ((b) & (d)) | ((c) & (d)))
447 258
448 259
449#define SHA1Step(f, a, b, c, d, e, w, k) \ 260/************************************************/
450 ( e += ( f(b, c, d) + w + k + CYCLIC_LEFT_SHIFT(a, 5)) & 0xffffffff, \ 261/* construct_mic_header1() */
451 b = CYCLIC_LEFT_SHIFT(b, 30) ) 262/* Builds the first MIC header block from */
263/* header fields. */
264/************************************************/
452 265
453//Initiate SHA-1 Context satisfied in RFC 3174 266void construct_mic_header1(
454VOID SHAInit(SHA_CTX *pCtx) 267 unsigned char *mic_header1,
268 int header_length,
269 unsigned char *mpdu)
455{ 270{
456 pCtx->Buf[0]=0x67452301; 271 mic_header1[0] = (unsigned char)((header_length - 2) / 256);
457 pCtx->Buf[1]=0xefcdab89; 272 mic_header1[1] = (unsigned char)((header_length - 2) % 256);
458 pCtx->Buf[2]=0x98badcfe; 273 mic_header1[2] = mpdu[0] & 0xcf; /* Mute CF poll & CF ack bits */
459 pCtx->Buf[3]=0x10325476; 274 mic_header1[3] = mpdu[1] & 0xc7; /* Mute retry, more data and pwr mgt bits */
460 pCtx->Buf[4]=0xc3d2e1f0; 275 mic_header1[4] = mpdu[4]; /* A1 */
461 276 mic_header1[5] = mpdu[5];
462 pCtx->LenInBitCount[0]=0; 277 mic_header1[6] = mpdu[6];
463 pCtx->LenInBitCount[1]=0; 278 mic_header1[7] = mpdu[7];
279 mic_header1[8] = mpdu[8];
280 mic_header1[9] = mpdu[9];
281 mic_header1[10] = mpdu[10]; /* A2 */
282 mic_header1[11] = mpdu[11];
283 mic_header1[12] = mpdu[12];
284 mic_header1[13] = mpdu[13];
285 mic_header1[14] = mpdu[14];
286 mic_header1[15] = mpdu[15];
464} 287}
465 288
466/* 289/************************************************/
467 * Function Description: 290/* construct_mic_header2() */
468 * Update SHA-1 Context, allow of an arrary of octets as the next 291/* Builds the last MIC header block from */
469 * portion of the message 292/* header fields. */
470 * 293/************************************************/
471 * Arguments: 294
472 * pCtx Pointer to SHA-1 context 295void construct_mic_header2(
473 * pData Pointer to input data 296 unsigned char *mic_header2,
474 * LenInBytes The length of input data (unit: byte) 297 unsigned char *mpdu,
475 * 298 int a4_exists,
476 * Return Value: 299 int qc_exists)
477 * error indicate more than pow(2,64) bits of data
478 *
479 * Note:
480 * Called after SHAInit or SHAUpdate(itself)
481 */
482UCHAR SHAUpdate(SHA_CTX *pCtx, UCHAR *pData, UINT32 LenInBytes)
483{ 300{
484 UINT32 TfTimes; 301 int i;
485 UINT32 temp1,temp2;
486 unsigned int i;
487 UCHAR err=1;
488
489 temp1 = pCtx->LenInBitCount[0];
490 temp2 = pCtx->LenInBitCount[1];
491 302
492 pCtx->LenInBitCount[0] = (UINT32) (pCtx->LenInBitCount[0] + (LenInBytes << 3)); 303 for (i = 0; i<16; i++) mic_header2[i]=0x00;
493 if (pCtx->LenInBitCount[0] < temp1)
494 pCtx->LenInBitCount[1]++; //carry in
495 304
305 mic_header2[0] = mpdu[16]; /* A3 */
306 mic_header2[1] = mpdu[17];
307 mic_header2[2] = mpdu[18];
308 mic_header2[3] = mpdu[19];
309 mic_header2[4] = mpdu[20];
310 mic_header2[5] = mpdu[21];
496 311
497 pCtx->LenInBitCount[1] = (UINT32) (pCtx->LenInBitCount[1] +(LenInBytes >> 29)); 312 // In Sequence Control field, mute sequence numer bits (12-bit)
498 if (pCtx->LenInBitCount[1] < temp2) 313 mic_header2[6] = mpdu[22] & 0x0f; /* SC */
499 return (err); //check total length of original data 314 mic_header2[7] = 0x00; /* mpdu[23]; */
500 315
316 if ((!qc_exists) & a4_exists)
317 {
318 for (i=0;i<6;i++) mic_header2[8+i] = mpdu[24+i]; /* A4 */
501 319
502 // mod 64 bytes 320 }
503 temp1 = (temp1 >> 3) & 0x3f;
504
505 // process lacks of 64-byte data
506 if (temp1)
507 {
508 UCHAR *pAds = (UCHAR *) pCtx->Input + temp1;
509
510 if ((temp1+LenInBytes) < 64)
511 {
512 NdisMoveMemory(pAds, (UCHAR *)pData, LenInBytes);
513 return (0);
514 }
515
516 NdisMoveMemory(pAds, (UCHAR *)pData, 64-temp1);
517 byteReverse((UCHAR *)pCtx->Input, 16);
518
519 NdisZeroMemory((UCHAR *)pCtx->Input + 64, 16);
520 SHATransform(pCtx->Buf, (UINT32 *)pCtx->Input);
521
522 pData += 64-temp1;
523 LenInBytes -= 64-temp1;
524 } // end of if (temp1)
525 321
322 if (qc_exists && (!a4_exists))
323 {
324 mic_header2[8] = mpdu[24] & 0x0f; /* mute bits 15 - 4 */
325 mic_header2[9] = mpdu[25] & 0x00;
326 }
526 327
527 TfTimes = (LenInBytes >> 6); 328 if (qc_exists && a4_exists)
329 {
330 for (i=0;i<6;i++) mic_header2[8+i] = mpdu[24+i]; /* A4 */
528 331
529 for (i=TfTimes; i>0; i--) 332 mic_header2[14] = mpdu[30] & 0x0f;
530 { 333 mic_header2[15] = mpdu[31] & 0x00;
531 NdisMoveMemory(pCtx->Input, (UCHAR *)pData, 64); 334 }
532 byteReverse((UCHAR *)pCtx->Input, 16); 335}
533 336
534 NdisZeroMemory((UCHAR *)pCtx->Input + 64, 16);
535 SHATransform(pCtx->Buf, (UINT32 *)pCtx->Input);
536 pData += 64;
537 LenInBytes -= 64;
538 } // end of for
539 337
540 // buffering lacks of 64-byte data 338/************************************************/
541 if(LenInBytes) 339/* construct_mic_iv() */
542 NdisMoveMemory(pCtx->Input, (UCHAR *)pData, LenInBytes); 340/* Builds the MIC IV from header fields and PN */
341/************************************************/
543 342
544 return (0); 343void construct_mic_iv(
344 unsigned char *mic_iv,
345 int qc_exists,
346 int a4_exists,
347 unsigned char *mpdu,
348 unsigned int payload_length,
349 unsigned char *pn_vector)
350{
351 int i;
352
353 mic_iv[0] = 0x59;
354 if (qc_exists && a4_exists)
355 mic_iv[1] = mpdu[30] & 0x0f; /* QoS_TC */
356 if (qc_exists && !a4_exists)
357 mic_iv[1] = mpdu[24] & 0x0f; /* mute bits 7-4 */
358 if (!qc_exists)
359 mic_iv[1] = 0x00;
360 for (i = 2; i < 8; i++)
361 mic_iv[i] = mpdu[i + 8]; /* mic_iv[2:7] = A2[0:5] = mpdu[10:15] */
362#ifdef CONSISTENT_PN_ORDER
363 for (i = 8; i < 14; i++)
364 mic_iv[i] = pn_vector[i - 8]; /* mic_iv[8:13] = PN[0:5] */
365#else
366 for (i = 8; i < 14; i++)
367 mic_iv[i] = pn_vector[13 - i]; /* mic_iv[8:13] = PN[5:0] */
368#endif
369 i = (payload_length / 256);
370 i = (payload_length % 256);
371 mic_iv[14] = (unsigned char) (payload_length / 256);
372 mic_iv[15] = (unsigned char) (payload_length % 256);
545 373
546} 374}
547 375
548// Append padding bits and length of original message in the tail 376/****************************************/
549// The message digest has to be completed in the end 377/* aes128k128d() */
550VOID SHAFinal(SHA_CTX *pCtx, UCHAR Digest[20]) 378/* Performs a 128 bit AES encrypt with */
379/* 128 bit data. */
380/****************************************/
381void aes128k128d(unsigned char *key, unsigned char *data, unsigned char *ciphertext)
551{ 382{
552 UCHAR Remainder; 383 int round;
553 UCHAR PadLenInBytes; 384 int i;
554 UCHAR *pAppend=0; 385 unsigned char intermediatea[16];
555 unsigned int i; 386 unsigned char intermediateb[16];
556 387 unsigned char round_key[16];
557 Remainder = (UCHAR)((pCtx->LenInBitCount[0] >> 3) & 0x3f);
558
559 pAppend = (UCHAR *)pCtx->Input + Remainder;
560
561 PadLenInBytes = (Remainder < 56) ? (56-Remainder) : (120-Remainder);
562
563 // padding bits without crossing block(64-byte based) boundary
564 if (Remainder < 56)
565 {
566 *pAppend = 0x80;
567 PadLenInBytes --;
568
569 NdisZeroMemory((UCHAR *)pCtx->Input + Remainder+1, PadLenInBytes);
570
571 // add data-length field, from high to low
572 for (i=0; i<4; i++)
573 {
574 pCtx->Input[56+i] = (UCHAR)((pCtx->LenInBitCount[1] >> ((3-i) << 3)) & 0xff);
575 pCtx->Input[60+i] = (UCHAR)((pCtx->LenInBitCount[0] >> ((3-i) << 3)) & 0xff);
576 }
577
578 byteReverse((UCHAR *)pCtx->Input, 16);
579 NdisZeroMemory((UCHAR *)pCtx->Input + 64, 14);
580 SHATransform(pCtx->Buf, (UINT32 *)pCtx->Input);
581 } // end of if
582
583 // padding bits with crossing block(64-byte based) boundary
584 else
585 {
586 // the first block ===
587 *pAppend = 0x80;
588 PadLenInBytes --;
589
590 NdisZeroMemory((UCHAR *)pCtx->Input + Remainder+1, (64-Remainder-1));
591 PadLenInBytes -= (64 - Remainder - 1);
592
593 byteReverse((UCHAR *)pCtx->Input, 16);
594 NdisZeroMemory((UCHAR *)pCtx->Input + 64, 16);
595 SHATransform(pCtx->Buf, (UINT32 *)pCtx->Input);
596
597 388
598 // the second block === 389 for(i=0; i<16; i++) round_key[i] = key[i];
599 NdisZeroMemory((UCHAR *)pCtx->Input, PadLenInBytes);
600 390
601 // add data-length field 391 for (round = 0; round < 11; round++)
602 for (i=0; i<4; i++) 392 {
603 { 393 if (round == 0)
604 pCtx->Input[56+i] = (UCHAR)((pCtx->LenInBitCount[1] >> ((3-i) << 3)) & 0xff); 394 {
605 pCtx->Input[60+i] = (UCHAR)((pCtx->LenInBitCount[0] >> ((3-i) << 3)) & 0xff); 395 xor_128(round_key, data, ciphertext);
606 } 396 next_key(round_key, round);
397 }
398 else if (round == 10)
399 {
400 byte_sub(ciphertext, intermediatea);
401 shift_row(intermediatea, intermediateb);
402 xor_128(intermediateb, round_key, ciphertext);
403 }
404 else /* 1 - 9 */
405 {
406 byte_sub(ciphertext, intermediatea);
407 shift_row(intermediatea, intermediateb);
408 mix_column(&intermediateb[0], &intermediatea[0]);
409 mix_column(&intermediateb[4], &intermediatea[4]);
410 mix_column(&intermediateb[8], &intermediatea[8]);
411 mix_column(&intermediateb[12], &intermediatea[12]);
412 xor_128(intermediatea, round_key, ciphertext);
413 next_key(round_key, round);
414 }
415 }
607 416
608 byteReverse((UCHAR *)pCtx->Input, 16); 417}
609 NdisZeroMemory((UCHAR *)pCtx->Input + 64, 16);
610 SHATransform(pCtx->Buf, (UINT32 *)pCtx->Input);
611 } // end of else
612 418
419void construct_ctr_preload(
420 unsigned char *ctr_preload,
421 int a4_exists,
422 int qc_exists,
423 unsigned char *mpdu,
424 unsigned char *pn_vector,
425 int c)
426{
613 427
614 //Output, bytereverse 428 int i = 0;
615 for (i=0; i<20; i++) 429 for (i=0; i<16; i++) ctr_preload[i] = 0x00;
616 { 430 i = 0;
617 Digest [i] = (UCHAR)(pCtx->Buf[i>>2] >> 8*(3-(i & 0x3))); 431
618 } 432 ctr_preload[0] = 0x01; /* flag */
433 if (qc_exists && a4_exists) ctr_preload[1] = mpdu[30] & 0x0f; /* QoC_Control */
434 if (qc_exists && !a4_exists) ctr_preload[1] = mpdu[24] & 0x0f;
435
436 for (i = 2; i < 8; i++)
437 ctr_preload[i] = mpdu[i + 8]; /* ctr_preload[2:7] = A2[0:5] = mpdu[10:15] */
438#ifdef CONSISTENT_PN_ORDER
439 for (i = 8; i < 14; i++)
440 ctr_preload[i] = pn_vector[i - 8]; /* ctr_preload[8:13] = PN[0:5] */
441#else
442 for (i = 8; i < 14; i++)
443 ctr_preload[i] = pn_vector[13 - i]; /* ctr_preload[8:13] = PN[5:0] */
444#endif
445 ctr_preload[14] = (unsigned char) (c / 256); // Ctr
446 ctr_preload[15] = (unsigned char) (c % 256);
619 447
620 NdisZeroMemory(pCtx, sizeof(pCtx)); // memory free
621} 448}
622 449
623 450BOOLEAN RTMPSoftDecryptAES(
624// The central algorithm of SHA-1, consists of four rounds and 451 IN PRTMP_ADAPTER pAd,
625// twenty steps per round 452 IN PUCHAR pData,
626VOID SHATransform(UINT32 Buf[5], UINT32 Mes[20]) 453 IN ULONG DataByteCnt,
454 IN PCIPHER_KEY pWpaKey)
627{ 455{
628 UINT32 Reg[5],Temp; 456 UCHAR KeyID;
629 unsigned int i; 457 UINT HeaderLen;
630 UINT32 W[80]; 458 UCHAR PN[6];
459 UINT payload_len;
460 UINT num_blocks;
461 UINT payload_remainder;
462 USHORT fc;
463 UCHAR fc0;
464 UCHAR fc1;
465 UINT frame_type;
466 UINT frame_subtype;
467 UINT from_ds;
468 UINT to_ds;
469 INT a4_exists;
470 INT qc_exists;
471 UCHAR aes_out[16];
472 int payload_index;
473 UINT i;
474 UCHAR ctr_preload[16];
475 UCHAR chain_buffer[16];
476 UCHAR padded_buffer[16];
477 UCHAR mic_iv[16];
478 UCHAR mic_header1[16];
479 UCHAR mic_header2[16];
480 UCHAR MIC[8];
481 UCHAR TrailMIC[8];
482
483
484 fc0 = *pData;
485 fc1 = *(pData + 1);
486
487 fc = *((PUSHORT)pData);
488
489 frame_type = ((fc0 >> 2) & 0x03);
490 frame_subtype = ((fc0 >> 4) & 0x0f);
491
492 from_ds = (fc1 & 0x2) >> 1;
493 to_ds = (fc1 & 0x1);
494
495 a4_exists = (from_ds & to_ds);
496 qc_exists = ((frame_subtype == 0x08) || /* Assumed QoS subtypes */
497 (frame_subtype == 0x09) || /* Likely to change. */
498 (frame_subtype == 0x0a) ||
499 (frame_subtype == 0x0b)
500 );
501
502 HeaderLen = 24;
503 if (a4_exists)
504 HeaderLen += 6;
505
506 KeyID = *((PUCHAR)(pData+ HeaderLen + 3));
507 KeyID = KeyID >> 6;
508
509 if (pWpaKey[KeyID].KeyLen == 0)
510 {
511 DBGPRINT(RT_DEBUG_TRACE, ("RTMPSoftDecryptAES failed!(KeyID[%d] Length can not be 0)\n", KeyID));
512 return FALSE;
513 }
631 514
632 static UINT32 SHA1Table[4] = { 0x5a827999, 0x6ed9eba1, 515 PN[0] = *(pData+ HeaderLen);
633 0x8f1bbcdc, 0xca62c1d6 }; 516 PN[1] = *(pData+ HeaderLen + 1);
517 PN[2] = *(pData+ HeaderLen + 4);
518 PN[3] = *(pData+ HeaderLen + 5);
519 PN[4] = *(pData+ HeaderLen + 6);
520 PN[5] = *(pData+ HeaderLen + 7);
634 521
635 Reg[0]=Buf[0]; 522 payload_len = DataByteCnt - HeaderLen - 8 - 8; // 8 bytes for CCMP header , 8 bytes for MIC
636 Reg[1]=Buf[1]; 523 payload_remainder = (payload_len) % 16;
637 Reg[2]=Buf[2]; 524 num_blocks = (payload_len) / 16;
638 Reg[3]=Buf[3];
639 Reg[4]=Buf[4];
640 525
641 //the first octet of a word is stored in the 0th element, bytereverse
642 for(i = 0; i < 16; i++)
643 {
644 W[i] = (Mes[i] >> 24) & 0xff;
645 W[i] |= (Mes[i] >> 8 ) & 0xff00;
646 W[i] |= (Mes[i] << 8 ) & 0xff0000;
647 W[i] |= (Mes[i] << 24) & 0xff000000;
648 }
649 526
650 527
651 for (i = 0; i < 64; i++) 528 // Find start of payload
652 W[16+i] = CYCLIC_LEFT_SHIFT(W[i] ^ W[2+i] ^ W[8+i] ^ W[13+i], 1); 529 payload_index = HeaderLen + 8; //IV+EIV
653 530
531 for (i=0; i< num_blocks; i++)
532 {
533 construct_ctr_preload(ctr_preload,
534 a4_exists,
535 qc_exists,
536 pData,
537 PN,
538 i+1 );
539
540 aes128k128d(pWpaKey[KeyID].Key, ctr_preload, aes_out);
541
542 bitwise_xor(aes_out, pData + payload_index, chain_buffer);
543 NdisMoveMemory(pData + payload_index - 8, chain_buffer, 16);
544 payload_index += 16;
545 }
654 546
655 // 80 steps in SHA-1 algorithm 547 //
656 for (i=0; i<80; i++) 548 // If there is a short final block, then pad it
657 { 549 // encrypt it and copy the unpadded part back
658 if (i<20) 550 //
659 SHA1Step(SHA1_F1, Reg[0], Reg[1], Reg[2], Reg[3], Reg[4], 551 if (payload_remainder > 0)
660 W[i], SHA1Table[0]); 552 {
553 construct_ctr_preload(ctr_preload,
554 a4_exists,
555 qc_exists,
556 pData,
557 PN,
558 num_blocks + 1);
661 559
662 else if (i>=20 && i<40) 560 NdisZeroMemory(padded_buffer, 16);
663 SHA1Step(SHA1_F2, Reg[0], Reg[1], Reg[2], Reg[3], Reg[4], 561 NdisMoveMemory(padded_buffer, pData + payload_index, payload_remainder);
664 W[i], SHA1Table[1]);
665 562
666 else if (i>=40 && i<60) 563 aes128k128d(pWpaKey[KeyID].Key, ctr_preload, aes_out);
667 SHA1Step(SHA1_F3, Reg[0], Reg[1], Reg[2], Reg[3], Reg[4],
668 W[i], SHA1Table[2]);
669 564
670 else 565 bitwise_xor(aes_out, padded_buffer, chain_buffer);
671 SHA1Step(SHA1_F2, Reg[0], Reg[1], Reg[2], Reg[3], Reg[4], 566 NdisMoveMemory(pData + payload_index - 8, chain_buffer, payload_remainder);
672 W[i], SHA1Table[3]); 567 payload_index += payload_remainder;
568 }
673 569
570 //
571 // Descrypt the MIC
572 //
573 construct_ctr_preload(ctr_preload,
574 a4_exists,
575 qc_exists,
576 pData,
577 PN,
578 0);
579 NdisZeroMemory(padded_buffer, 16);
580 NdisMoveMemory(padded_buffer, pData + payload_index, 8);
581
582 aes128k128d(pWpaKey[KeyID].Key, ctr_preload, aes_out);
583
584 bitwise_xor(aes_out, padded_buffer, chain_buffer);
585
586 NdisMoveMemory(TrailMIC, chain_buffer, 8);
587
588
589 //
590 // Calculate MIC
591 //
592
593 //Force the protected frame bit on
594 *(pData + 1) = *(pData + 1) | 0x40;
595
596 // Find start of payload
597 // Because the CCMP header has been removed
598 payload_index = HeaderLen;
599
600 construct_mic_iv(
601 mic_iv,
602 qc_exists,
603 a4_exists,
604 pData,
605 payload_len,
606 PN);
607
608 construct_mic_header1(
609 mic_header1,
610 HeaderLen,
611 pData);
612
613 construct_mic_header2(
614 mic_header2,
615 pData,
616 a4_exists,
617 qc_exists);
618
619 aes128k128d(pWpaKey[KeyID].Key, mic_iv, aes_out);
620 bitwise_xor(aes_out, mic_header1, chain_buffer);
621 aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
622 bitwise_xor(aes_out, mic_header2, chain_buffer);
623 aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
624
625 // iterate through each 16 byte payload block
626 for (i = 0; i < num_blocks; i++)
627 {
628 bitwise_xor(aes_out, pData + payload_index, chain_buffer);
629 payload_index += 16;
630 aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
631 }
674 632
675 // one-word right shift 633 // Add on the final payload block if it needs padding
676 Temp = Reg[4]; 634 if (payload_remainder > 0)
677 Reg[4] = Reg[3]; 635 {
678 Reg[3] = Reg[2]; 636 NdisZeroMemory(padded_buffer, 16);
679 Reg[2] = Reg[1]; 637 NdisMoveMemory(padded_buffer, pData + payload_index, payload_remainder);
680 Reg[1] = Reg[0];
681 Reg[0] = Temp;
682 638
683 } // end of for-loop 639 bitwise_xor(aes_out, padded_buffer, chain_buffer);
640 aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
641 }
684 642
643 // aes_out contains padded mic, discard most significant
644 // 8 bytes to generate 64 bit MIC
645 for (i = 0 ; i < 8; i++) MIC[i] = aes_out[i];
685 646
686 // (temporary)output 647 if (!NdisEqualMemory(MIC, TrailMIC, 8))
687 for (i=0; i<5; i++) 648 {
688 Buf[i] += Reg[i]; 649 DBGPRINT(RT_DEBUG_ERROR, ("RTMPSoftDecryptAES, MIC Error !\n")); //MIC error.
650 return FALSE;
651 }
689 652
690}
691 653
654 return TRUE;
655}
692 656
693/* ========================= AES En/Decryption ========================== */ 657/* ========================= AES En/Decryption ========================== */
658#ifndef uint8
659#define uint8 unsigned char
660#endif
661
662#ifndef uint32
663#define uint32 unsigned int
664#endif
694 665
695/* forward S-box */ 666/* forward S-box */
696static uint32 FSb[256] = 667static uint32 FSb[256] =
@@ -976,9 +947,8 @@ static uint32 KT3[256];
976 (b)[(i) + 3] = (uint8) ( (n) ); \ 947 (b)[(i) + 3] = (uint8) ( (n) ); \
977} 948}
978 949
979/* AES key scheduling routine */
980 950
981int rtmp_aes_set_key( aes_context *ctx, uint8 *key, int nbits ) 951int rt_aes_set_key( aes_context *ctx, uint8 *key, int nbits )
982{ 952{
983 int i; 953 int i;
984 uint32 *RK, *SK; 954 uint32 *RK, *SK;
@@ -991,7 +961,7 @@ int rtmp_aes_set_key( aes_context *ctx, uint8 *key, int nbits )
991 default : return( 1 ); 961 default : return( 1 );
992 } 962 }
993 963
994 RK = ctx->erk; 964 RK = (uint32 *) ctx->erk;
995 965
996 for( i = 0; i < (nbits >> 5); i++ ) 966 for( i = 0; i < (nbits >> 5); i++ )
997 { 967 {
@@ -1078,7 +1048,7 @@ int rtmp_aes_set_key( aes_context *ctx, uint8 *key, int nbits )
1078 KT_init = 0; 1048 KT_init = 0;
1079 } 1049 }
1080 1050
1081 SK = ctx->drk; 1051 SK = (uint32 *) ctx->drk;
1082 1052
1083 *SK++ = *RK++; 1053 *SK++ = *RK++;
1084 *SK++ = *RK++; 1054 *SK++ = *RK++;
@@ -1122,11 +1092,11 @@ int rtmp_aes_set_key( aes_context *ctx, uint8 *key, int nbits )
1122 1092
1123/* AES 128-bit block encryption routine */ 1093/* AES 128-bit block encryption routine */
1124 1094
1125void rtmp_aes_encrypt(aes_context *ctx, uint8 input[16], uint8 output[16] ) 1095void rt_aes_encrypt(aes_context *ctx, uint8 input[16], uint8 output[16] )
1126{ 1096{
1127 uint32 *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3; 1097 uint32 *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
1128 1098
1129 RK = ctx->erk; 1099 RK = (uint32 *) ctx->erk;
1130 GET_UINT32( X0, input, 0 ); X0 ^= RK[0]; 1100 GET_UINT32( X0, input, 0 ); X0 ^= RK[0];
1131 GET_UINT32( X1, input, 4 ); X1 ^= RK[1]; 1101 GET_UINT32( X1, input, 4 ); X1 ^= RK[1];
1132 GET_UINT32( X2, input, 8 ); X2 ^= RK[2]; 1102 GET_UINT32( X2, input, 8 ); X2 ^= RK[2];
@@ -1211,11 +1181,11 @@ void rtmp_aes_encrypt(aes_context *ctx, uint8 input[16], uint8 output[16] )
1211 1181
1212/* AES 128-bit block decryption routine */ 1182/* AES 128-bit block decryption routine */
1213 1183
1214void rtmp_aes_decrypt( aes_context *ctx, uint8 input[16], uint8 output[16] ) 1184void rt_aes_decrypt( aes_context *ctx, uint8 input[16], uint8 output[16] )
1215{ 1185{
1216 uint32 *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3; 1186 uint32 *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
1217 1187
1218 RK = ctx->drk; 1188 RK = (uint32 *) ctx->drk;
1219 1189
1220 GET_UINT32( X0, input, 0 ); X0 ^= RK[0]; 1190 GET_UINT32( X0, input, 0 ); X0 ^= RK[0];
1221 GET_UINT32( X1, input, 4 ); X1 ^= RK[1]; 1191 GET_UINT32( X1, input, 4 ); X1 ^= RK[1];
@@ -1300,116 +1270,135 @@ void rtmp_aes_decrypt( aes_context *ctx, uint8 input[16], uint8 output[16] )
1300} 1270}
1301 1271
1302/* 1272/*
1273 ==========================================================================
1274 Description:
1275 ENCRYPT AES GTK before sending in EAPOL frame.
1276 AES GTK length = 128 bit, so fix blocks for aes-key-wrap as 2 in this function.
1277 This function references to RFC 3394 for aes key wrap algorithm.
1278 Return:
1279 ==========================================================================
1280*/
1281VOID AES_GTK_KEY_WRAP(
1282 IN UCHAR *key,
1283 IN UCHAR *plaintext,
1284 IN UINT32 p_len,
1285 OUT UCHAR *ciphertext)
1286{
1287 UCHAR A[8], BIN[16], BOUT[16];
1288 UCHAR R[512];
1289 INT num_blocks = p_len/8; // unit:64bits
1290 INT i, j;
1291 aes_context aesctx;
1292 UCHAR xor;
1293
1294 rt_aes_set_key(&aesctx, key, 128);
1295
1296 // Init IA
1297 for (i = 0; i < 8; i++)
1298 A[i] = 0xa6;
1299
1300 //Input plaintext
1301 for (i = 0; i < num_blocks; i++)
1302 {
1303 for (j = 0 ; j < 8; j++)
1304 R[8 * (i + 1) + j] = plaintext[8 * i + j];
1305 }
1306
1307 // Key Mix
1308 for (j = 0; j < 6; j++)
1309 {
1310 for(i = 1; i <= num_blocks; i++)
1311 {
1312 //phase 1
1313 NdisMoveMemory(BIN, A, 8);
1314 NdisMoveMemory(&BIN[8], &R[8 * i], 8);
1315 rt_aes_encrypt(&aesctx, BIN, BOUT);
1316
1317 NdisMoveMemory(A, &BOUT[0], 8);
1318 xor = num_blocks * j + i;
1319 A[7] = BOUT[7] ^ xor;
1320 NdisMoveMemory(&R[8 * i], &BOUT[8], 8);
1321 }
1322 }
1323
1324 // Output ciphertext
1325 NdisMoveMemory(ciphertext, A, 8);
1326
1327 for (i = 1; i <= num_blocks; i++)
1328 {
1329 for (j = 0 ; j < 8; j++)
1330 ciphertext[8 * i + j] = R[8 * i + j];
1331 }
1332}
1333
1334/*
1303 ======================================================================== 1335 ========================================================================
1304 1336
1305 Routine Description: 1337 Routine Description:
1306 SHA1 function 1338 Misc function to decrypt AES body
1307 1339
1308 Arguments: 1340 Arguments:
1309 1341
1310 Return Value: 1342 Return Value:
1311 1343
1312 Note: 1344 Note:
1345 This function references to RFC 3394 for aes key unwrap algorithm.
1313 1346
1314 ======================================================================== 1347 ========================================================================
1315*/ 1348*/
1316VOID HMAC_SHA1( 1349VOID AES_GTK_KEY_UNWRAP(
1317 IN UCHAR *text,
1318 IN UINT text_len,
1319 IN UCHAR *key, 1350 IN UCHAR *key,
1320 IN UINT key_len, 1351 OUT UCHAR *plaintext,
1321 IN UCHAR *digest) 1352 IN UINT32 c_len,
1353 IN UCHAR *ciphertext)
1354
1322{ 1355{
1323 SHA_CTX context; 1356 UCHAR A[8], BIN[16], BOUT[16];
1324 UCHAR k_ipad[65]; /* inner padding - key XORd with ipad */ 1357 UCHAR xor;
1325 UCHAR k_opad[65]; /* outer padding - key XORd with opad */ 1358 INT i, j;
1326 INT i; 1359 aes_context aesctx;
1360 UCHAR *R;
1361 INT num_blocks = c_len/8; // unit:64bits
1327 1362
1328 // if key is longer than 64 bytes reset it to key=SHA1(key)
1329 if (key_len > 64)
1330 {
1331 SHA_CTX tctx;
1332 SHAInit(&tctx);
1333 SHAUpdate(&tctx, key, key_len);
1334 SHAFinal(&tctx, key);
1335 key_len = 20;
1336 }
1337 NdisZeroMemory(k_ipad, sizeof(k_ipad));
1338 NdisZeroMemory(k_opad, sizeof(k_opad));
1339 NdisMoveMemory(k_ipad, key, key_len);
1340 NdisMoveMemory(k_opad, key, key_len);
1341 1363
1342 // XOR key with ipad and opad values 1364 os_alloc_mem(NULL, (PUCHAR *)&R, 512);
1343 for (i = 0; i < 64; i++) 1365
1366 if (R == NULL)
1367 {
1368 DBGPRINT(RT_DEBUG_ERROR, ("!!!AES_GTK_KEY_UNWRAP: no memory!!!\n"));
1369 return;
1370 } /* End of if */
1371
1372 // Initialize
1373 NdisMoveMemory(A, ciphertext, 8);
1374 //Input plaintext
1375 for(i = 0; i < (c_len-8); i++)
1344 { 1376 {
1345 k_ipad[i] ^= 0x36; 1377 R[ i] = ciphertext[i + 8];
1346 k_opad[i] ^= 0x5c;
1347 } 1378 }
1348 1379
1349 // perform inner SHA1 1380 rt_aes_set_key(&aesctx, key, 128);
1350 SHAInit(&context); /* init context for 1st pass */
1351 SHAUpdate(&context, k_ipad, 64); /* start with inner pad */
1352 SHAUpdate(&context, text, text_len); /* then text of datagram */
1353 SHAFinal(&context, digest); /* finish up 1st pass */
1354
1355 //perform outer SHA1
1356 SHAInit(&context); /* init context for 2nd pass */
1357 SHAUpdate(&context, k_opad, 64); /* start with outer pad */
1358 SHAUpdate(&context, digest, 20); /* then results of 1st hash */
1359 SHAFinal(&context, digest); /* finish up 2nd pass */
1360
1361}
1362
1363/*
1364* F(P, S, c, i) = U1 xor U2 xor ... Uc
1365* U1 = PRF(P, S || Int(i))
1366* U2 = PRF(P, U1)
1367* Uc = PRF(P, Uc-1)
1368*/
1369
1370void F(char *password, unsigned char *ssid, int ssidlength, int iterations, int count, unsigned char *output)
1371{
1372 unsigned char digest[36], digest1[SHA_DIGEST_LEN];
1373 int i, j;
1374
1375 /* U1 = PRF(P, S || int(i)) */
1376 memcpy(digest, ssid, ssidlength);
1377 digest[ssidlength] = (unsigned char)((count>>24) & 0xff);
1378 digest[ssidlength+1] = (unsigned char)((count>>16) & 0xff);
1379 digest[ssidlength+2] = (unsigned char)((count>>8) & 0xff);
1380 digest[ssidlength+3] = (unsigned char)(count & 0xff);
1381 HMAC_SHA1(digest, ssidlength+4, (unsigned char*) password, (int) strlen(password), digest1); // for WPA update
1382 1381
1383 /* output = U1 */ 1382 for(j = 5; j >= 0; j--)
1384 memcpy(output, digest1, SHA_DIGEST_LEN); 1383 {
1384 for(i = (num_blocks-1); i > 0; i--)
1385 {
1386 xor = (num_blocks -1 )* j + i;
1387 NdisMoveMemory(BIN, A, 8);
1388 BIN[7] = A[7] ^ xor;
1389 NdisMoveMemory(&BIN[8], &R[(i-1)*8], 8);
1390 rt_aes_decrypt(&aesctx, BIN, BOUT);
1391 NdisMoveMemory(A, &BOUT[0], 8);
1392 NdisMoveMemory(&R[(i-1)*8], &BOUT[8], 8);
1393 }
1394 }
1385 1395
1386 for (i = 1; i < iterations; i++) 1396 // OUTPUT
1387 { 1397 for(i = 0; i < c_len; i++)
1388 /* Un = PRF(P, Un-1) */ 1398 {
1389 HMAC_SHA1(digest1, SHA_DIGEST_LEN, (unsigned char*) password, (int) strlen(password), digest); // for WPA update 1399 plaintext[i] = R[i];
1390 memcpy(digest1, digest, SHA_DIGEST_LEN); 1400 }
1391 1401
1392 /* output = output xor Un */
1393 for (j = 0; j < SHA_DIGEST_LEN; j++)
1394 {
1395 output[j] ^= digest[j];
1396 }
1397 }
1398}
1399/*
1400* password - ascii string up to 63 characters in length
1401* ssid - octet string up to 32 octets
1402* ssidlength - length of ssid in octets
1403* output must be 40 octets in length and outputs 256 bits of key
1404*/
1405int PasswordHash(char *password, unsigned char *ssid, int ssidlength, unsigned char *output)
1406{
1407 if ((strlen(password) > 63) || (ssidlength > 32))
1408 return 0;
1409 1402
1410 F(password, ssid, ssidlength, 4096, 1, output); 1403 os_free_mem(NULL, R);
1411 F(password, ssid, ssidlength, 4096, 2, &output[SHA_DIGEST_LEN]);
1412 return 1;
1413} 1404}
1414
1415
diff --git a/drivers/staging/rt2860/common/cmm_asic.c b/drivers/staging/rt2860/common/cmm_asic.c
new file mode 100644
index 00000000000..83ed07b45bd
--- /dev/null
+++ b/drivers/staging/rt2860/common/cmm_asic.c
@@ -0,0 +1,2531 @@
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
41// Reset the RFIC setting to new series
42RTMP_RF_REGS RF2850RegTable[] = {
43// ch R1 R2 R3(TX0~4=0) R4
44 {1, 0x98402ecc, 0x984c0786, 0x9816b455, 0x9800510b},
45 {2, 0x98402ecc, 0x984c0786, 0x98168a55, 0x9800519f},
46 {3, 0x98402ecc, 0x984c078a, 0x98168a55, 0x9800518b},
47 {4, 0x98402ecc, 0x984c078a, 0x98168a55, 0x9800519f},
48 {5, 0x98402ecc, 0x984c078e, 0x98168a55, 0x9800518b},
49 {6, 0x98402ecc, 0x984c078e, 0x98168a55, 0x9800519f},
50 {7, 0x98402ecc, 0x984c0792, 0x98168a55, 0x9800518b},
51 {8, 0x98402ecc, 0x984c0792, 0x98168a55, 0x9800519f},
52 {9, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800518b},
53 {10, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800519f},
54 {11, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800518b},
55 {12, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800519f},
56 {13, 0x98402ecc, 0x984c079e, 0x98168a55, 0x9800518b},
57 {14, 0x98402ecc, 0x984c07a2, 0x98168a55, 0x98005193},
58
59 // 802.11 UNI / HyperLan 2
60 {36, 0x98402ecc, 0x984c099a, 0x98158a55, 0x980ed1a3},
61 {38, 0x98402ecc, 0x984c099e, 0x98158a55, 0x980ed193},
62 {40, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed183},
63 {44, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed1a3},
64 {46, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed18b},
65 {48, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed19b},
66 {52, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed193},
67 {54, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed1a3},
68 {56, 0x98402ec8, 0x984c068e, 0x98158a55, 0x980ed18b},
69 {60, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed183},
70 {62, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed193},
71 {64, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed1a3}, // Plugfest#4, Day4, change RFR3 left4th 9->5.
72
73 // 802.11 HyperLan 2
74 {100, 0x98402ec8, 0x984c06b2, 0x98178a55, 0x980ed783},
75
76 // 2008.04.30 modified
77 // The system team has AN to improve the EVM value
78 // for channel 102 to 108 for the RT2850/RT2750 dual band solution.
79 {102, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed793},
80 {104, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed1a3},
81 {108, 0x98402ecc, 0x985c0a32, 0x98578a55, 0x980ed193},
82
83 {110, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed183},
84 {112, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed19b},
85 {116, 0x98402ecc, 0x984c0a3a, 0x98178a55, 0x980ed1a3},
86 {118, 0x98402ecc, 0x984c0a3e, 0x98178a55, 0x980ed193},
87 {120, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed183},
88 {124, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed193},
89 {126, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed15b}, // 0x980ed1bb->0x980ed15b required by Rory 20070927
90 {128, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed1a3},
91 {132, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed18b},
92 {134, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed193},
93 {136, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed19b},
94 {140, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed183},
95
96 // 802.11 UNII
97 {149, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed1a7},
98 {151, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed187},
99 {153, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed18f},
100 {157, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed19f},
101 {159, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed1a7},
102 {161, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed187},
103 {165, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed197},
104 {167, 0x98402ec4, 0x984c03d2, 0x98179855, 0x9815531f},
105 {169, 0x98402ec4, 0x984c03d2, 0x98179855, 0x98155327},
106 {171, 0x98402ec4, 0x984c03d6, 0x98179855, 0x98155307},
107 {173, 0x98402ec4, 0x984c03d6, 0x98179855, 0x9815530f},
108
109 // Japan
110 {184, 0x95002ccc, 0x9500491e, 0x9509be55, 0x950c0a0b},
111 {188, 0x95002ccc, 0x95004922, 0x9509be55, 0x950c0a13},
112 {192, 0x95002ccc, 0x95004926, 0x9509be55, 0x950c0a1b},
113 {196, 0x95002ccc, 0x9500492a, 0x9509be55, 0x950c0a23},
114 {208, 0x95002ccc, 0x9500493a, 0x9509be55, 0x950c0a13},
115 {212, 0x95002ccc, 0x9500493e, 0x9509be55, 0x950c0a1b},
116 {216, 0x95002ccc, 0x95004982, 0x9509be55, 0x950c0a23},
117
118 // still lack of MMAC(Japan) ch 34,38,42,46
119};
120UCHAR NUM_OF_2850_CHNL = (sizeof(RF2850RegTable) / sizeof(RTMP_RF_REGS));
121
122FREQUENCY_ITEM FreqItems3020[] =
123{
124 /**************************************************/
125 // ISM : 2.4 to 2.483 GHz //
126 /**************************************************/
127 // 11g
128 /**************************************************/
129 //-CH---N-------R---K-----------
130 {1, 241, 2, 2},
131 {2, 241, 2, 7},
132 {3, 242, 2, 2},
133 {4, 242, 2, 7},
134 {5, 243, 2, 2},
135 {6, 243, 2, 7},
136 {7, 244, 2, 2},
137 {8, 244, 2, 7},
138 {9, 245, 2, 2},
139 {10, 245, 2, 7},
140 {11, 246, 2, 2},
141 {12, 246, 2, 7},
142 {13, 247, 2, 2},
143 {14, 248, 2, 4},
144};
145UCHAR NUM_OF_3020_CHNL = (sizeof(FreqItems3020) / sizeof(FREQUENCY_ITEM));
146
147
148VOID AsicUpdateAutoFallBackTable(
149 IN PRTMP_ADAPTER pAd,
150 IN PUCHAR pRateTable)
151{
152 UCHAR i;
153 HT_FBK_CFG0_STRUC HtCfg0;
154 HT_FBK_CFG1_STRUC HtCfg1;
155 LG_FBK_CFG0_STRUC LgCfg0;
156 LG_FBK_CFG1_STRUC LgCfg1;
157 PRTMP_TX_RATE_SWITCH pCurrTxRate, pNextTxRate;
158
159 // set to initial value
160 HtCfg0.word = 0x65432100;
161 HtCfg1.word = 0xedcba988;
162 LgCfg0.word = 0xedcba988;
163 LgCfg1.word = 0x00002100;
164
165 pNextTxRate = (PRTMP_TX_RATE_SWITCH)pRateTable+1;
166 for (i = 1; i < *((PUCHAR) pRateTable); i++)
167 {
168 pCurrTxRate = (PRTMP_TX_RATE_SWITCH)pRateTable+1+i;
169 switch (pCurrTxRate->Mode)
170 {
171 case 0: //CCK
172 break;
173 case 1: //OFDM
174 {
175 switch(pCurrTxRate->CurrMCS)
176 {
177 case 0:
178 LgCfg0.field.OFDMMCS0FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
179 break;
180 case 1:
181 LgCfg0.field.OFDMMCS1FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
182 break;
183 case 2:
184 LgCfg0.field.OFDMMCS2FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
185 break;
186 case 3:
187 LgCfg0.field.OFDMMCS3FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
188 break;
189 case 4:
190 LgCfg0.field.OFDMMCS4FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
191 break;
192 case 5:
193 LgCfg0.field.OFDMMCS5FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
194 break;
195 case 6:
196 LgCfg0.field.OFDMMCS6FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
197 break;
198 case 7:
199 LgCfg0.field.OFDMMCS7FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
200 break;
201 }
202 }
203 break;
204 case 2: //HT-MIX
205 case 3: //HT-GF
206 {
207 if ((pNextTxRate->Mode >= MODE_HTMIX) && (pCurrTxRate->CurrMCS != pNextTxRate->CurrMCS))
208 {
209 switch(pCurrTxRate->CurrMCS)
210 {
211 case 0:
212 HtCfg0.field.HTMCS0FBK = pNextTxRate->CurrMCS;
213 break;
214 case 1:
215 HtCfg0.field.HTMCS1FBK = pNextTxRate->CurrMCS;
216 break;
217 case 2:
218 HtCfg0.field.HTMCS2FBK = pNextTxRate->CurrMCS;
219 break;
220 case 3:
221 HtCfg0.field.HTMCS3FBK = pNextTxRate->CurrMCS;
222 break;
223 case 4:
224 HtCfg0.field.HTMCS4FBK = pNextTxRate->CurrMCS;
225 break;
226 case 5:
227 HtCfg0.field.HTMCS5FBK = pNextTxRate->CurrMCS;
228 break;
229 case 6:
230 HtCfg0.field.HTMCS6FBK = pNextTxRate->CurrMCS;
231 break;
232 case 7:
233 HtCfg0.field.HTMCS7FBK = pNextTxRate->CurrMCS;
234 break;
235 case 8:
236 HtCfg1.field.HTMCS8FBK = pNextTxRate->CurrMCS;
237 break;
238 case 9:
239 HtCfg1.field.HTMCS9FBK = pNextTxRate->CurrMCS;
240 break;
241 case 10:
242 HtCfg1.field.HTMCS10FBK = pNextTxRate->CurrMCS;
243 break;
244 case 11:
245 HtCfg1.field.HTMCS11FBK = pNextTxRate->CurrMCS;
246 break;
247 case 12:
248 HtCfg1.field.HTMCS12FBK = pNextTxRate->CurrMCS;
249 break;
250 case 13:
251 HtCfg1.field.HTMCS13FBK = pNextTxRate->CurrMCS;
252 break;
253 case 14:
254 HtCfg1.field.HTMCS14FBK = pNextTxRate->CurrMCS;
255 break;
256 case 15:
257 HtCfg1.field.HTMCS15FBK = pNextTxRate->CurrMCS;
258 break;
259 default:
260 DBGPRINT(RT_DEBUG_ERROR, ("AsicUpdateAutoFallBackTable: not support CurrMCS=%d\n", pCurrTxRate->CurrMCS));
261 }
262 }
263 }
264 break;
265 }
266
267 pNextTxRate = pCurrTxRate;
268 }
269
270 RTMP_IO_WRITE32(pAd, HT_FBK_CFG0, HtCfg0.word);
271 RTMP_IO_WRITE32(pAd, HT_FBK_CFG1, HtCfg1.word);
272 RTMP_IO_WRITE32(pAd, LG_FBK_CFG0, LgCfg0.word);
273 RTMP_IO_WRITE32(pAd, LG_FBK_CFG1, LgCfg1.word);
274}
275
276/*
277 ========================================================================
278
279 Routine Description:
280 Set MAC register value according operation mode.
281 OperationMode AND bNonGFExist are for MM and GF Proteciton.
282 If MM or GF mask is not set, those passing argument doesn't not take effect.
283
284 Operation mode meaning:
285 = 0 : Pure HT, no preotection.
286 = 0x01; there may be non-HT devices in both the control and extension channel, protection is optional in BSS.
287 = 0x10: No Transmission in 40M is protected.
288 = 0x11: Transmission in both 40M and 20M shall be protected
289 if (bNonGFExist)
290 we should choose not to use GF. But still set correct ASIC registers.
291 ========================================================================
292*/
293VOID AsicUpdateProtect(
294 IN PRTMP_ADAPTER pAd,
295 IN USHORT OperationMode,
296 IN UCHAR SetMask,
297 IN BOOLEAN bDisableBGProtect,
298 IN BOOLEAN bNonGFExist)
299{
300 PROT_CFG_STRUC ProtCfg, ProtCfg4;
301 UINT32 Protect[6];
302 USHORT offset;
303 UCHAR i;
304 UINT32 MacReg = 0;
305
306
307 if (!(pAd->CommonCfg.bHTProtect) && (OperationMode != 8))
308 {
309 return;
310 }
311
312 if (pAd->BATable.numDoneOriginator)
313 {
314 //
315 // enable the RTS/CTS to avoid channel collision
316 //
317 SetMask = ALLN_SETPROTECT;
318 OperationMode = 8;
319 }
320
321 // Config ASIC RTS threshold register
322 RTMP_IO_READ32(pAd, TX_RTS_CFG, &MacReg);
323 MacReg &= 0xFF0000FF;
324 // If the user want disable RtsThreshold and enable Amsdu/Ralink-Aggregation, set the RtsThreshold as 4096
325 if ((
326 (pAd->CommonCfg.BACapability.field.AmsduEnable) ||
327 (pAd->CommonCfg.bAggregationCapable == TRUE))
328 && pAd->CommonCfg.RtsThreshold == MAX_RTS_THRESHOLD)
329 {
330 MacReg |= (0x1000 << 8);
331 }
332 else
333 {
334 MacReg |= (pAd->CommonCfg.RtsThreshold << 8);
335 }
336
337 RTMP_IO_WRITE32(pAd, TX_RTS_CFG, MacReg);
338
339 // Initial common protection settings
340 RTMPZeroMemory(Protect, sizeof(Protect));
341 ProtCfg4.word = 0;
342 ProtCfg.word = 0;
343 ProtCfg.field.TxopAllowGF40 = 1;
344 ProtCfg.field.TxopAllowGF20 = 1;
345 ProtCfg.field.TxopAllowMM40 = 1;
346 ProtCfg.field.TxopAllowMM20 = 1;
347 ProtCfg.field.TxopAllowOfdm = 1;
348 ProtCfg.field.TxopAllowCck = 1;
349 ProtCfg.field.RTSThEn = 1;
350 ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
351
352 // update PHY mode and rate
353 if (pAd->CommonCfg.Channel > 14)
354 ProtCfg.field.ProtectRate = 0x4000;
355 ProtCfg.field.ProtectRate |= pAd->CommonCfg.RtsRate;
356
357 // Handle legacy(B/G) protection
358 if (bDisableBGProtect)
359 {
360 //ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate;
361 ProtCfg.field.ProtectCtrl = 0;
362 Protect[0] = ProtCfg.word;
363 Protect[1] = ProtCfg.word;
364 pAd->FlgCtsEnabled = 0; /* CTS-self is not used */
365 }
366 else
367 {
368 //ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate;
369 ProtCfg.field.ProtectCtrl = 0; // CCK do not need to be protected
370 Protect[0] = ProtCfg.word;
371 ProtCfg.field.ProtectCtrl = ASIC_CTS; // OFDM needs using CCK to protect
372 Protect[1] = ProtCfg.word;
373 pAd->FlgCtsEnabled = 1; /* CTS-self is used */
374 }
375
376 // Decide HT frame protection.
377 if ((SetMask & ALLN_SETPROTECT) != 0)
378 {
379 switch(OperationMode)
380 {
381 case 0x0:
382 // NO PROTECT
383 // 1.All STAs in the BSS are 20/40 MHz HT
384 // 2. in ai 20/40MHz BSS
385 // 3. all STAs are 20MHz in a 20MHz BSS
386 // Pure HT. no protection.
387
388 // MM20_PROT_CFG
389 // Reserved (31:27)
390 // PROT_TXOP(25:20) -- 010111
391 // PROT_NAV(19:18) -- 01 (Short NAV protection)
392 // PROT_CTRL(17:16) -- 00 (None)
393 // PROT_RATE(15:0) -- 0x4004 (OFDM 24M)
394 Protect[2] = 0x01744004;
395
396 // MM40_PROT_CFG
397 // Reserved (31:27)
398 // PROT_TXOP(25:20) -- 111111
399 // PROT_NAV(19:18) -- 01 (Short NAV protection)
400 // PROT_CTRL(17:16) -- 00 (None)
401 // PROT_RATE(15:0) -- 0x4084 (duplicate OFDM 24M)
402 Protect[3] = 0x03f44084;
403
404 // CF20_PROT_CFG
405 // Reserved (31:27)
406 // PROT_TXOP(25:20) -- 010111
407 // PROT_NAV(19:18) -- 01 (Short NAV protection)
408 // PROT_CTRL(17:16) -- 00 (None)
409 // PROT_RATE(15:0) -- 0x4004 (OFDM 24M)
410 Protect[4] = 0x01744004;
411
412 // CF40_PROT_CFG
413 // Reserved (31:27)
414 // PROT_TXOP(25:20) -- 111111
415 // PROT_NAV(19:18) -- 01 (Short NAV protection)
416 // PROT_CTRL(17:16) -- 00 (None)
417 // PROT_RATE(15:0) -- 0x4084 (duplicate OFDM 24M)
418 Protect[5] = 0x03f44084;
419
420 if (bNonGFExist)
421 {
422 // PROT_NAV(19:18) -- 01 (Short NAV protectiion)
423 // PROT_CTRL(17:16) -- 01 (RTS/CTS)
424 Protect[4] = 0x01754004;
425 Protect[5] = 0x03f54084;
426 }
427 pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE;
428 break;
429
430 case 1:
431 // This is "HT non-member protection mode."
432 // If there may be non-HT STAs my BSS
433 ProtCfg.word = 0x01744004; // PROT_CTRL(17:16) : 0 (None)
434 ProtCfg4.word = 0x03f44084; // duplicaet legacy 24M. BW set 1.
435 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED))
436 {
437 ProtCfg.word = 0x01740003; //ERP use Protection bit is set, use protection rate at Clause 18..
438 ProtCfg4.word = 0x03f40003; // Don't duplicate RTS/CTS in CCK mode. 0x03f40083;
439 }
440 //Assign Protection method for 20&40 MHz packets
441 ProtCfg.field.ProtectCtrl = ASIC_RTS;
442 ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
443 ProtCfg4.field.ProtectCtrl = ASIC_RTS;
444 ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
445 Protect[2] = ProtCfg.word;
446 Protect[3] = ProtCfg4.word;
447 Protect[4] = ProtCfg.word;
448 Protect[5] = ProtCfg4.word;
449 pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
450 break;
451
452 case 2:
453 // If only HT STAs are in BSS. at least one is 20MHz. Only protect 40MHz packets
454 ProtCfg.word = 0x01744004; // PROT_CTRL(17:16) : 0 (None)
455 ProtCfg4.word = 0x03f44084; // duplicaet legacy 24M. BW set 1.
456
457 //Assign Protection method for 40MHz packets
458 ProtCfg4.field.ProtectCtrl = ASIC_RTS;
459 ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
460 Protect[2] = ProtCfg.word;
461 Protect[3] = ProtCfg4.word;
462 if (bNonGFExist)
463 {
464 ProtCfg.field.ProtectCtrl = ASIC_RTS;
465 ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
466 }
467 Protect[4] = ProtCfg.word;
468 Protect[5] = ProtCfg4.word;
469
470 pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE;
471 break;
472
473 case 3:
474 // HT mixed mode. PROTECT ALL!
475 // Assign Rate
476 ProtCfg.word = 0x01744004; //duplicaet legacy 24M. BW set 1.
477 ProtCfg4.word = 0x03f44084;
478 // both 20MHz and 40MHz are protected. Whether use RTS or CTS-to-self depends on the
479 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED))
480 {
481 ProtCfg.word = 0x01740003; //ERP use Protection bit is set, use protection rate at Clause 18..
482 ProtCfg4.word = 0x03f40003; // Don't duplicate RTS/CTS in CCK mode. 0x03f40083
483 }
484 //Assign Protection method for 20&40 MHz packets
485 ProtCfg.field.ProtectCtrl = ASIC_RTS;
486 ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
487 ProtCfg4.field.ProtectCtrl = ASIC_RTS;
488 ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
489 Protect[2] = ProtCfg.word;
490 Protect[3] = ProtCfg4.word;
491 Protect[4] = ProtCfg.word;
492 Protect[5] = ProtCfg4.word;
493 pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
494 break;
495
496 case 8:
497 // Special on for Atheros problem n chip.
498 Protect[2] = 0x01754004;
499 Protect[3] = 0x03f54084;
500 Protect[4] = 0x01754004;
501 Protect[5] = 0x03f54084;
502 pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
503 break;
504 }
505 }
506
507 offset = CCK_PROT_CFG;
508 for (i = 0;i < 6;i++)
509 {
510 if ((SetMask & (1<< i)))
511 {
512 RTMP_IO_WRITE32(pAd, offset + i*4, Protect[i]);
513 }
514}
515}
516
517
518/*
519 ==========================================================================
520 Description:
521
522 IRQL = PASSIVE_LEVEL
523 IRQL = DISPATCH_LEVEL
524
525 ==========================================================================
526 */
527VOID AsicSwitchChannel(
528 IN PRTMP_ADAPTER pAd,
529 IN UCHAR Channel,
530 IN BOOLEAN bScan)
531{
532 ULONG R2 = 0, R3 = DEFAULT_RF_TX_POWER, R4 = 0;
533 CHAR TxPwer = 0, TxPwer2 = DEFAULT_RF_TX_POWER; //Bbp94 = BBPR94_DEFAULT, TxPwer2 = DEFAULT_RF_TX_POWER;
534 UCHAR index;
535 UINT32 Value = 0; //BbpReg, Value;
536 RTMP_RF_REGS *RFRegTable;
537 UCHAR RFValue;
538
539 RFValue = 0;
540 // Search Tx power value
541 // We can't use ChannelList to search channel, since some central channl's txpowr doesn't list
542 // in ChannelList, so use TxPower array instead.
543 //
544 for (index = 0; index < MAX_NUM_OF_CHANNELS; index++)
545 {
546 if (Channel == pAd->TxPower[index].Channel)
547 {
548 TxPwer = pAd->TxPower[index].Power;
549 TxPwer2 = pAd->TxPower[index].Power2;
550 break;
551 }
552 }
553
554 if (index == MAX_NUM_OF_CHANNELS)
555 {
556 DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: Can't find the Channel#%d \n", Channel));
557 }
558
559#ifdef RT30xx
560 // The RF programming sequence is difference between 3xxx and 2xxx
561 if ((IS_RT3070(pAd) || IS_RT3090(pAd)||IS_RT3390(pAd)) && ((pAd->RfIcType == RFIC_3020) || (pAd->RfIcType == RFIC_2020) ||
562 (pAd->RfIcType == RFIC_3021) || (pAd->RfIcType == RFIC_3022)))
563 {
564 /* modify by WY for Read RF Reg. error */
565
566 for (index = 0; index < NUM_OF_3020_CHNL; index++)
567 {
568 if (Channel == FreqItems3020[index].Channel)
569 {
570 // Programming channel parameters
571 RT30xxWriteRFRegister(pAd, RF_R02, FreqItems3020[index].N);
572 RT30xxWriteRFRegister(pAd, RF_R03, FreqItems3020[index].K);
573 RT30xxReadRFRegister(pAd, RF_R06, &RFValue);
574 RFValue = (RFValue & 0xFC) | FreqItems3020[index].R;
575 RT30xxWriteRFRegister(pAd, RF_R06, RFValue);
576
577 // Set Tx0 Power
578 RT30xxReadRFRegister(pAd, RF_R12, &RFValue);
579 RFValue = (RFValue & 0xE0) | TxPwer;
580 RT30xxWriteRFRegister(pAd, RF_R12, RFValue);
581
582 // Set Tx1 Power
583 RT30xxReadRFRegister(pAd, RF_R13, &RFValue);
584 RFValue = (RFValue & 0xE0) | TxPwer2;
585 RT30xxWriteRFRegister(pAd, RF_R13, RFValue);
586
587 // Tx/Rx Stream setting
588 RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
589 //if (IS_RT3090(pAd))
590 // RFValue |= 0x01; // Enable RF block.
591 RFValue &= 0x03; //clear bit[7~2]
592 if (pAd->Antenna.field.TxPath == 1)
593 RFValue |= 0xA0;
594 else if (pAd->Antenna.field.TxPath == 2)
595 RFValue |= 0x80;
596 if (pAd->Antenna.field.RxPath == 1)
597 RFValue |= 0x50;
598 else if (pAd->Antenna.field.RxPath == 2)
599 RFValue |= 0x40;
600 RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
601
602 // Set RF offset
603 RT30xxReadRFRegister(pAd, RF_R23, &RFValue);
604 RFValue = (RFValue & 0x80) | pAd->RfFreqOffset;
605 RT30xxWriteRFRegister(pAd, RF_R23, RFValue);
606
607 // Set BW
608 if (!bScan && (pAd->CommonCfg.BBPCurrentBW == BW_40))
609 {
610 RFValue = pAd->Mlme.CaliBW40RfR24;
611 //DISABLE_11N_CHECK(pAd);
612 }
613 else
614 {
615 RFValue = pAd->Mlme.CaliBW20RfR24;
616 }
617 RT30xxWriteRFRegister(pAd, RF_R24, RFValue);
618 RT30xxWriteRFRegister(pAd, RF_R31, RFValue);
619
620 // Enable RF tuning
621 RT30xxReadRFRegister(pAd, RF_R07, &RFValue);
622 RFValue = RFValue | 0x1;
623 RT30xxWriteRFRegister(pAd, RF_R07, RFValue);
624
625 // latch channel for future usage.
626 pAd->LatchRfRegs.Channel = Channel;
627
628 DBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, Pwr0=%d, Pwr1=%d, %dT), N=0x%02X, K=0x%02X, R=0x%02X\n",
629 Channel,
630 pAd->RfIcType,
631 TxPwer,
632 TxPwer2,
633 pAd->Antenna.field.TxPath,
634 FreqItems3020[index].N,
635 FreqItems3020[index].K,
636 FreqItems3020[index].R));
637
638 break;
639 }
640 }
641 }
642 else
643#endif // RT30xx //
644 {
645 RFRegTable = RF2850RegTable;
646 switch (pAd->RfIcType)
647 {
648 case RFIC_2820:
649 case RFIC_2850:
650 case RFIC_2720:
651 case RFIC_2750:
652
653 for (index = 0; index < NUM_OF_2850_CHNL; index++)
654 {
655 if (Channel == RFRegTable[index].Channel)
656 {
657 R2 = RFRegTable[index].R2;
658 if (pAd->Antenna.field.TxPath == 1)
659 {
660 R2 |= 0x4000; // If TXpath is 1, bit 14 = 1;
661 }
662
663 if (pAd->Antenna.field.RxPath == 2)
664 {
665 R2 |= 0x40; // write 1 to off Rxpath.
666 }
667 else if (pAd->Antenna.field.RxPath == 1)
668 {
669 R2 |= 0x20040; // write 1 to off RxPath
670 }
671
672 if (Channel > 14)
673 {
674 // initialize R3, R4
675 R3 = (RFRegTable[index].R3 & 0xffffc1ff);
676 R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->RfFreqOffset << 15);
677
678 // 5G band power range: 0xF9~0X0F, TX0 Reg3 bit9/TX1 Reg4 bit6="0" means the TX power reduce 7dB
679 // R3
680 if ((TxPwer >= -7) && (TxPwer < 0))
681 {
682 TxPwer = (7+TxPwer);
683 TxPwer = (TxPwer > 0xF) ? (0xF) : (TxPwer);
684 R3 |= (TxPwer << 10);
685 DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: TxPwer=%d \n", TxPwer));
686 }
687 else
688 {
689 TxPwer = (TxPwer > 0xF) ? (0xF) : (TxPwer);
690 R3 |= (TxPwer << 10) | (1 << 9);
691 }
692
693 // R4
694 if ((TxPwer2 >= -7) && (TxPwer2 < 0))
695 {
696 TxPwer2 = (7+TxPwer2);
697 TxPwer2 = (TxPwer2 > 0xF) ? (0xF) : (TxPwer2);
698 R4 |= (TxPwer2 << 7);
699 DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: TxPwer2=%d \n", TxPwer2));
700 }
701 else
702 {
703 TxPwer2 = (TxPwer2 > 0xF) ? (0xF) : (TxPwer2);
704 R4 |= (TxPwer2 << 7) | (1 << 6);
705 }
706 }
707 else
708 {
709 R3 = (RFRegTable[index].R3 & 0xffffc1ff) | (TxPwer << 9); // set TX power0
710 R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->RfFreqOffset << 15) | (TxPwer2 <<6);// Set freq Offset & TxPwr1
711 }
712
713 // Based on BBP current mode before changing RF channel.
714 if (!bScan && (pAd->CommonCfg.BBPCurrentBW == BW_40))
715 {
716 R4 |=0x200000;
717 }
718
719 // Update variables
720 pAd->LatchRfRegs.Channel = Channel;
721 pAd->LatchRfRegs.R1 = RFRegTable[index].R1;
722 pAd->LatchRfRegs.R2 = R2;
723 pAd->LatchRfRegs.R3 = R3;
724 pAd->LatchRfRegs.R4 = R4;
725
726 // Set RF value 1's set R3[bit2] = [0]
727 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
728 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
729 RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 & (~0x04)));
730 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
731
732 RTMPusecDelay(200);
733
734 // Set RF value 2's set R3[bit2] = [1]
735 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
736 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
737 RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 | 0x04));
738 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
739
740 RTMPusecDelay(200);
741
742 // Set RF value 3's set R3[bit2] = [0]
743 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
744 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
745 RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 & (~0x04)));
746 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
747
748 break;
749 }
750 }
751 break;
752
753 default:
754 break;
755 }
756
757 DBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, Pwr0=%lu, Pwr1=%lu, %dT) to , R1=0x%08lx, R2=0x%08lx, R3=0x%08lx, R4=0x%08lx\n",
758 Channel,
759 pAd->RfIcType,
760 (R3 & 0x00003e00) >> 9,
761 (R4 & 0x000007c0) >> 6,
762 pAd->Antenna.field.TxPath,
763 pAd->LatchRfRegs.R1,
764 pAd->LatchRfRegs.R2,
765 pAd->LatchRfRegs.R3,
766 pAd->LatchRfRegs.R4));
767 }
768
769 // Change BBP setting during siwtch from a->g, g->a
770 if (Channel <= 14)
771 {
772 ULONG TxPinCfg = 0x00050F0A;//Gary 2007/08/09 0x050A0A
773
774 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd)));
775 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd)));
776 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd)));
777 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.
778 //RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62);
779
780 // Rx High power VGA offset for LNA select
781 if (pAd->NicConfig2.field.ExternalLNAForG)
782 {
783 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62);
784 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46);
785 }
786 else
787 {
788 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x84);
789 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50);
790 }
791
792 // 5G band selection PIN, bit1 and bit2 are complement
793 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
794 Value &= (~0x6);
795 Value |= (0x04);
796 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
797
798 // Turn off unused PA or LNA when only 1T or 1R
799 if (pAd->Antenna.field.TxPath == 1)
800 {
801 TxPinCfg &= 0xFFFFFFF3;
802 }
803 if (pAd->Antenna.field.RxPath == 1)
804 {
805 TxPinCfg &= 0xFFFFF3FF;
806 }
807
808
809 RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
810
811 }
812 else
813 {
814 ULONG TxPinCfg = 0x00050F05;//Gary 2007/8/9 0x050505
815
816 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd)));
817 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd)));
818 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd)));
819 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.
820 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0xF2);
821
822 // Rx High power VGA offset for LNA select
823 if (pAd->NicConfig2.field.ExternalLNAForA)
824 {
825 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46);
826 }
827 else
828 {
829 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50);
830 }
831
832 // 5G band selection PIN, bit1 and bit2 are complement
833 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
834 Value &= (~0x6);
835 Value |= (0x02);
836 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
837
838 // Turn off unused PA or LNA when only 1T or 1R
839 if (pAd->Antenna.field.TxPath == 1)
840 {
841 TxPinCfg &= 0xFFFFFFF3;
842 }
843 if (pAd->Antenna.field.RxPath == 1)
844 {
845 TxPinCfg &= 0xFFFFF3FF;
846 }
847
848
849 RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
850
851 }
852
853 // R66 should be set according to Channel and use 20MHz when scanning
854 //RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, (0x2E + GET_LNA_GAIN(pAd)));
855 if (bScan)
856 RTMPSetAGCInitValue(pAd, BW_20);
857 else
858 RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW);
859
860 //
861 // On 11A, We should delay and wait RF/BBP to be stable
862 // and the appropriate time should be 1000 micro seconds
863 // 2005/06/05 - On 11G, We also need this delay time. Otherwise it's difficult to pass the WHQL.
864 //
865 RTMPusecDelay(1000);
866}
867
868VOID AsicResetBBPAgent(
869IN PRTMP_ADAPTER pAd)
870{
871 BBP_CSR_CFG_STRUC BbpCsr;
872 DBGPRINT(RT_DEBUG_ERROR, ("Reset BBP Agent busy bit.!! \n"));
873 // Still need to find why BBP agent keeps busy, but in fact, hardware still function ok. Now clear busy first.
874 RTMP_IO_READ32(pAd, H2M_BBP_AGENT, &BbpCsr.word);
875 BbpCsr.field.Busy = 0;
876 RTMP_IO_WRITE32(pAd, H2M_BBP_AGENT, BbpCsr.word);
877}
878
879/*
880 ==========================================================================
881 Description:
882 This function is required for 2421 only, and should not be used during
883 site survey. It's only required after NIC decided to stay at a channel
884 for a longer period.
885 When this function is called, it's always after AsicSwitchChannel().
886
887 IRQL = PASSIVE_LEVEL
888 IRQL = DISPATCH_LEVEL
889
890 ==========================================================================
891 */
892VOID AsicLockChannel(
893 IN PRTMP_ADAPTER pAd,
894 IN UCHAR Channel)
895{
896}
897
898VOID AsicRfTuningExec(
899 IN PVOID SystemSpecific1,
900 IN PVOID FunctionContext,
901 IN PVOID SystemSpecific2,
902 IN PVOID SystemSpecific3)
903{
904}
905
906/*
907 ==========================================================================
908 Description:
909 Gives CCK TX rate 2 more dB TX power.
910 This routine works only in LINK UP in INFRASTRUCTURE mode.
911
912 calculate desired Tx power in RF R3.Tx0~5, should consider -
913 0. if current radio is a noisy environment (pAd->DrsCounters.fNoisyEnvironment)
914 1. TxPowerPercentage
915 2. auto calibration based on TSSI feedback
916 3. extra 2 db for CCK
917 4. -10 db upon very-short distance (AvgRSSI >= -40db) to AP
918
919 NOTE: Since this routine requires the value of (pAd->DrsCounters.fNoisyEnvironment),
920 it should be called AFTER MlmeDynamicTxRatSwitching()
921 ==========================================================================
922 */
923VOID AsicAdjustTxPower(
924 IN PRTMP_ADAPTER pAd)
925{
926 INT i, j;
927 CHAR DeltaPwr = 0;
928 BOOLEAN bAutoTxAgc = FALSE;
929 UCHAR TssiRef, *pTssiMinusBoundary, *pTssiPlusBoundary, TxAgcStep;
930 UCHAR BbpR1 = 0, BbpR49 = 0, idx;
931 PCHAR pTxAgcCompensate;
932 ULONG TxPwr[5];
933 CHAR Value;
934 CHAR Rssi = -127;
935
936
937
938 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) ||
939#ifdef RTMP_MAC_PCI
940 (pAd->bPCIclkOff == TRUE) ||
941#endif // RTMP_MAC_PCI //
942 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF) ||
943 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
944 return;
945
946 Rssi = RTMPMaxRssi(pAd,
947 pAd->StaCfg.RssiSample.AvgRssi0,
948 pAd->StaCfg.RssiSample.AvgRssi1,
949 pAd->StaCfg.RssiSample.AvgRssi2);
950
951 if (pAd->CommonCfg.BBPCurrentBW == BW_40)
952 {
953 if (pAd->CommonCfg.CentralChannel > 14)
954 {
955 TxPwr[0] = pAd->Tx40MPwrCfgABand[0];
956 TxPwr[1] = pAd->Tx40MPwrCfgABand[1];
957 TxPwr[2] = pAd->Tx40MPwrCfgABand[2];
958 TxPwr[3] = pAd->Tx40MPwrCfgABand[3];
959 TxPwr[4] = pAd->Tx40MPwrCfgABand[4];
960 }
961 else
962 {
963 TxPwr[0] = pAd->Tx40MPwrCfgGBand[0];
964 TxPwr[1] = pAd->Tx40MPwrCfgGBand[1];
965 TxPwr[2] = pAd->Tx40MPwrCfgGBand[2];
966 TxPwr[3] = pAd->Tx40MPwrCfgGBand[3];
967 TxPwr[4] = pAd->Tx40MPwrCfgGBand[4];
968 }
969 }
970 else
971 {
972 if (pAd->CommonCfg.Channel > 14)
973 {
974 TxPwr[0] = pAd->Tx20MPwrCfgABand[0];
975 TxPwr[1] = pAd->Tx20MPwrCfgABand[1];
976 TxPwr[2] = pAd->Tx20MPwrCfgABand[2];
977 TxPwr[3] = pAd->Tx20MPwrCfgABand[3];
978 TxPwr[4] = pAd->Tx20MPwrCfgABand[4];
979 }
980 else
981 {
982 TxPwr[0] = pAd->Tx20MPwrCfgGBand[0];
983 TxPwr[1] = pAd->Tx20MPwrCfgGBand[1];
984 TxPwr[2] = pAd->Tx20MPwrCfgGBand[2];
985 TxPwr[3] = pAd->Tx20MPwrCfgGBand[3];
986 TxPwr[4] = pAd->Tx20MPwrCfgGBand[4];
987 }
988 }
989
990 // TX power compensation for temperature variation based on TSSI. try every 4 second
991 if (pAd->Mlme.OneSecPeriodicRound % 4 == 0)
992 {
993 if (pAd->CommonCfg.Channel <= 14)
994 {
995 /* bg channel */
996 bAutoTxAgc = pAd->bAutoTxAgcG;
997 TssiRef = pAd->TssiRefG;
998 pTssiMinusBoundary = &pAd->TssiMinusBoundaryG[0];
999 pTssiPlusBoundary = &pAd->TssiPlusBoundaryG[0];
1000 TxAgcStep = pAd->TxAgcStepG;
1001 pTxAgcCompensate = &pAd->TxAgcCompensateG;
1002 }
1003 else
1004 {
1005 /* a channel */
1006 bAutoTxAgc = pAd->bAutoTxAgcA;
1007 TssiRef = pAd->TssiRefA;
1008 pTssiMinusBoundary = &pAd->TssiMinusBoundaryA[0];
1009 pTssiPlusBoundary = &pAd->TssiPlusBoundaryA[0];
1010 TxAgcStep = pAd->TxAgcStepA;
1011 pTxAgcCompensate = &pAd->TxAgcCompensateA;
1012 }
1013
1014 if (bAutoTxAgc)
1015 {
1016 /* BbpR1 is unsigned char */
1017 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpR49);
1018
1019 /* (p) TssiPlusBoundaryG[0] = 0 = (m) TssiMinusBoundaryG[0] */
1020 /* compensate: +4 +3 +2 +1 0 -1 -2 -3 -4 * steps */
1021 /* step value is defined in pAd->TxAgcStepG for tx power value */
1022
1023 /* [4]+1+[4] p4 p3 p2 p1 o1 m1 m2 m3 m4 */
1024 /* ex: 0x00 0x15 0x25 0x45 0x88 0xA0 0xB5 0xD0 0xF0
1025 above value are examined in mass factory production */
1026 /* [4] [3] [2] [1] [0] [1] [2] [3] [4] */
1027
1028 /* plus (+) is 0x00 ~ 0x45, minus (-) is 0xa0 ~ 0xf0 */
1029 /* if value is between p1 ~ o1 or o1 ~ s1, no need to adjust tx power */
1030 /* if value is 0xa5, tx power will be -= TxAgcStep*(2-1) */
1031
1032 if (BbpR49 > pTssiMinusBoundary[1])
1033 {
1034 // Reading is larger than the reference value
1035 // check for how large we need to decrease the Tx power
1036 for (idx = 1; idx < 5; idx++)
1037 {
1038 if (BbpR49 <= pTssiMinusBoundary[idx]) // Found the range
1039 break;
1040 }
1041 // The index is the step we should decrease, idx = 0 means there is nothing to compensate
1042// if (R3 > (ULONG) (TxAgcStep * (idx-1)))
1043 *pTxAgcCompensate = -(TxAgcStep * (idx-1));
1044// else
1045// *pTxAgcCompensate = -((UCHAR)R3);
1046
1047 DeltaPwr += (*pTxAgcCompensate);
1048 DBGPRINT(RT_DEBUG_TRACE, ("-- Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = -%d\n",
1049 BbpR49, TssiRef, TxAgcStep, idx-1));
1050 }
1051 else if (BbpR49 < pTssiPlusBoundary[1])
1052 {
1053 // Reading is smaller than the reference value
1054 // check for how large we need to increase the Tx power
1055 for (idx = 1; idx < 5; idx++)
1056 {
1057 if (BbpR49 >= pTssiPlusBoundary[idx]) // Found the range
1058 break;
1059 }
1060 // The index is the step we should increase, idx = 0 means there is nothing to compensate
1061 *pTxAgcCompensate = TxAgcStep * (idx-1);
1062 DeltaPwr += (*pTxAgcCompensate);
1063 DBGPRINT(RT_DEBUG_TRACE, ("++ Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
1064 BbpR49, TssiRef, TxAgcStep, idx-1));
1065 }
1066 else
1067 {
1068 *pTxAgcCompensate = 0;
1069 DBGPRINT(RT_DEBUG_TRACE, (" Tx Power, BBP R49=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
1070 BbpR49, TssiRef, TxAgcStep, 0));
1071 }
1072 }
1073 }
1074 else
1075 {
1076 if (pAd->CommonCfg.Channel <= 14)
1077 {
1078 bAutoTxAgc = pAd->bAutoTxAgcG;
1079 pTxAgcCompensate = &pAd->TxAgcCompensateG;
1080 }
1081 else
1082 {
1083 bAutoTxAgc = pAd->bAutoTxAgcA;
1084 pTxAgcCompensate = &pAd->TxAgcCompensateA;
1085 }
1086
1087 if (bAutoTxAgc)
1088 DeltaPwr += (*pTxAgcCompensate);
1089 }
1090
1091 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpR1);
1092 BbpR1 &= 0xFC;
1093
1094
1095 /* calculate delta power based on the percentage specified from UI */
1096 // E2PROM setting is calibrated for maximum TX power (i.e. 100%)
1097 // We lower TX power here according to the percentage specified from UI
1098 if (pAd->CommonCfg.TxPowerPercentage == 0xffffffff) // AUTO TX POWER control
1099 {
1100 {
1101 // to patch high power issue with some APs, like Belkin N1.
1102 if (Rssi > -35)
1103 {
1104 BbpR1 |= 0x02; // DeltaPwr -= 12;
1105 }
1106 else if (Rssi > -40)
1107 {
1108 BbpR1 |= 0x01; // DeltaPwr -= 6;
1109 }
1110 else
1111 ;
1112 }
1113 }
1114 else if (pAd->CommonCfg.TxPowerPercentage > 90) // 91 ~ 100% & AUTO, treat as 100% in terms of mW
1115 ;
1116 else if (pAd->CommonCfg.TxPowerPercentage > 60) // 61 ~ 90%, treat as 75% in terms of mW // DeltaPwr -= 1;
1117 {
1118 DeltaPwr -= 1;
1119 }
1120 else if (pAd->CommonCfg.TxPowerPercentage > 30) // 31 ~ 60%, treat as 50% in terms of mW // DeltaPwr -= 3;
1121 {
1122 DeltaPwr -= 3;
1123 }
1124 else if (pAd->CommonCfg.TxPowerPercentage > 15) // 16 ~ 30%, treat as 25% in terms of mW // DeltaPwr -= 6;
1125 {
1126 BbpR1 |= 0x01;
1127 }
1128 else if (pAd->CommonCfg.TxPowerPercentage > 9) // 10 ~ 15%, treat as 12.5% in terms of mW // DeltaPwr -= 9;
1129 {
1130 BbpR1 |= 0x01;
1131 DeltaPwr -= 3;
1132 }
1133 else // 0 ~ 9 %, treat as MIN(~3%) in terms of mW // DeltaPwr -= 12;
1134 {
1135 BbpR1 |= 0x02;
1136 }
1137
1138 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpR1);
1139
1140 /* reset different new tx power for different TX rate */
1141 for(i=0; i<5; i++)
1142 {
1143 if (TxPwr[i] != 0xffffffff)
1144 {
1145 for (j=0; j<8; j++)
1146 {
1147 Value = (CHAR)((TxPwr[i] >> j*4) & 0x0F); /* 0 ~ 15 */
1148
1149 if ((Value + DeltaPwr) < 0)
1150 {
1151 Value = 0; /* min */
1152 }
1153 else if ((Value + DeltaPwr) > 0xF)
1154 {
1155 Value = 0xF; /* max */
1156 }
1157 else
1158 {
1159 Value += DeltaPwr; /* temperature compensation */
1160 }
1161
1162 /* fill new value to CSR offset */
1163 TxPwr[i] = (TxPwr[i] & ~(0x0000000F << j*4)) | (Value << j*4);
1164 }
1165
1166 /* write tx power value to CSR */
1167 /* TX_PWR_CFG_0 (8 tx rate) for TX power for OFDM 12M/18M
1168 TX power for OFDM 6M/9M
1169 TX power for CCK5.5M/11M
1170 TX power for CCK1M/2M */
1171 /* TX_PWR_CFG_1 ~ TX_PWR_CFG_4 */
1172 RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, TxPwr[i]);
1173 }
1174 }
1175
1176
1177}
1178
1179
1180/*
1181 ==========================================================================
1182 Description:
1183 put PHY to sleep here, and set next wakeup timer. PHY doesn't not wakeup
1184 automatically. Instead, MCU will issue a TwakeUpInterrupt to host after
1185 the wakeup timer timeout. Driver has to issue a separate command to wake
1186 PHY up.
1187
1188 IRQL = DISPATCH_LEVEL
1189
1190 ==========================================================================
1191 */
1192VOID AsicSleepThenAutoWakeup(
1193 IN PRTMP_ADAPTER pAd,
1194 IN USHORT TbttNumToNextWakeUp)
1195{
1196 RTMP_STA_SLEEP_THEN_AUTO_WAKEUP(pAd, TbttNumToNextWakeUp);
1197}
1198
1199/*
1200 ==========================================================================
1201 Description:
1202 AsicForceWakeup() is used whenever manual wakeup is required
1203 AsicForceSleep() should only be used when not in INFRA BSS. When
1204 in INFRA BSS, we should use AsicSleepThenAutoWakeup() instead.
1205 ==========================================================================
1206 */
1207VOID AsicForceSleep(
1208 IN PRTMP_ADAPTER pAd)
1209{
1210
1211}
1212
1213/*
1214 ==========================================================================
1215 Description:
1216 AsicForceWakeup() is used whenever Twakeup timer (set via AsicSleepThenAutoWakeup)
1217 expired.
1218
1219 IRQL = PASSIVE_LEVEL
1220 IRQL = DISPATCH_LEVEL
1221 ==========================================================================
1222 */
1223VOID AsicForceWakeup(
1224 IN PRTMP_ADAPTER pAd,
1225 IN BOOLEAN bFromTx)
1226{
1227 DBGPRINT(RT_DEBUG_INFO, ("--> AsicForceWakeup \n"));
1228 RTMP_STA_FORCE_WAKEUP(pAd, bFromTx);
1229}
1230
1231
1232/*
1233 ==========================================================================
1234 Description:
1235 Set My BSSID
1236
1237 IRQL = DISPATCH_LEVEL
1238
1239 ==========================================================================
1240 */
1241VOID AsicSetBssid(
1242 IN PRTMP_ADAPTER pAd,
1243 IN PUCHAR pBssid)
1244{
1245 ULONG Addr4;
1246 DBGPRINT(RT_DEBUG_TRACE, ("==============> AsicSetBssid %x:%x:%x:%x:%x:%x\n",
1247 pBssid[0],pBssid[1],pBssid[2],pBssid[3], pBssid[4],pBssid[5]));
1248
1249 Addr4 = (ULONG)(pBssid[0]) |
1250 (ULONG)(pBssid[1] << 8) |
1251 (ULONG)(pBssid[2] << 16) |
1252 (ULONG)(pBssid[3] << 24);
1253 RTMP_IO_WRITE32(pAd, MAC_BSSID_DW0, Addr4);
1254
1255 Addr4 = 0;
1256 // always one BSSID in STA mode
1257 Addr4 = (ULONG)(pBssid[4]) | (ULONG)(pBssid[5] << 8);
1258
1259 RTMP_IO_WRITE32(pAd, MAC_BSSID_DW1, Addr4);
1260}
1261
1262VOID AsicSetMcastWC(
1263 IN PRTMP_ADAPTER pAd)
1264{
1265 MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[MCAST_WCID];
1266 USHORT offset;
1267
1268 pEntry->Sst = SST_ASSOC;
1269 pEntry->Aid = MCAST_WCID; // Softap supports 1 BSSID and use WCID=0 as multicast Wcid index
1270 pEntry->PsMode = PWR_ACTIVE;
1271 pEntry->CurrTxRate = pAd->CommonCfg.MlmeRate;
1272 offset = MAC_WCID_BASE + BSS0Mcast_WCID * HW_WCID_ENTRY_SIZE;
1273}
1274
1275/*
1276 ==========================================================================
1277 Description:
1278
1279 IRQL = DISPATCH_LEVEL
1280
1281 ==========================================================================
1282 */
1283VOID AsicDelWcidTab(
1284 IN PRTMP_ADAPTER pAd,
1285 IN UCHAR Wcid)
1286{
1287 ULONG Addr0 = 0x0, Addr1 = 0x0;
1288 ULONG offset;
1289
1290 DBGPRINT(RT_DEBUG_TRACE, ("AsicDelWcidTab==>Wcid = 0x%x\n",Wcid));
1291 offset = MAC_WCID_BASE + Wcid * HW_WCID_ENTRY_SIZE;
1292 RTMP_IO_WRITE32(pAd, offset, Addr0);
1293 offset += 4;
1294 RTMP_IO_WRITE32(pAd, offset, Addr1);
1295}
1296
1297/*
1298 ==========================================================================
1299 Description:
1300
1301 IRQL = DISPATCH_LEVEL
1302
1303 ==========================================================================
1304 */
1305VOID AsicEnableRDG(
1306 IN PRTMP_ADAPTER pAd)
1307{
1308 TX_LINK_CFG_STRUC TxLinkCfg;
1309 UINT32 Data = 0;
1310
1311 RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word);
1312 TxLinkCfg.field.TxRDGEn = 1;
1313 RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word);
1314
1315 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1316 Data &= 0xFFFFFF00;
1317 Data |= 0x80;
1318 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1319
1320 //OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1321}
1322
1323/*
1324 ==========================================================================
1325 Description:
1326
1327 IRQL = DISPATCH_LEVEL
1328
1329 ==========================================================================
1330 */
1331VOID AsicDisableRDG(
1332 IN PRTMP_ADAPTER pAd)
1333{
1334 TX_LINK_CFG_STRUC TxLinkCfg;
1335 UINT32 Data = 0;
1336
1337
1338 RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word);
1339 TxLinkCfg.field.TxRDGEn = 0;
1340 RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word);
1341
1342 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1343
1344 Data &= 0xFFFFFF00;
1345 //Data |= 0x20;
1346#ifndef WIFI_TEST
1347 //if ( pAd->CommonCfg.bEnableTxBurst )
1348 // Data |= 0x60; // for performance issue not set the TXOP to 0
1349#endif
1350 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_DYNAMIC_BE_TXOP_ACTIVE)
1351 && (pAd->MacTab.fAnyStationMIMOPSDynamic == FALSE)
1352 )
1353 {
1354 // For CWC test, change txop from 0x30 to 0x20 in TxBurst mode
1355 if (pAd->CommonCfg.bEnableTxBurst)
1356 Data |= 0x20;
1357 }
1358 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1359}
1360
1361/*
1362 ==========================================================================
1363 Description:
1364
1365 IRQL = PASSIVE_LEVEL
1366 IRQL = DISPATCH_LEVEL
1367
1368 ==========================================================================
1369 */
1370VOID AsicDisableSync(
1371 IN PRTMP_ADAPTER pAd)
1372{
1373 BCN_TIME_CFG_STRUC csr;
1374
1375 DBGPRINT(RT_DEBUG_TRACE, ("--->Disable TSF synchronization\n"));
1376
1377 // 2003-12-20 disable TSF and TBTT while NIC in power-saving have side effect
1378 // that NIC will never wakes up because TSF stops and no more
1379 // TBTT interrupts
1380 pAd->TbttTickCount = 0;
1381 RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
1382 csr.field.bBeaconGen = 0;
1383 csr.field.bTBTTEnable = 0;
1384 csr.field.TsfSyncMode = 0;
1385 csr.field.bTsfTicking = 0;
1386 RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
1387
1388}
1389
1390/*
1391 ==========================================================================
1392 Description:
1393
1394 IRQL = DISPATCH_LEVEL
1395
1396 ==========================================================================
1397 */
1398VOID AsicEnableBssSync(
1399 IN PRTMP_ADAPTER pAd)
1400{
1401 BCN_TIME_CFG_STRUC csr;
1402
1403 DBGPRINT(RT_DEBUG_TRACE, ("--->AsicEnableBssSync(INFRA mode)\n"));
1404
1405 RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
1406// RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, 0x00000000);
1407 {
1408 csr.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4; // ASIC register in units of 1/16 TU
1409 csr.field.bTsfTicking = 1;
1410 csr.field.TsfSyncMode = 1; // sync TSF in INFRASTRUCTURE mode
1411 csr.field.bBeaconGen = 0; // do NOT generate BEACON
1412 csr.field.bTBTTEnable = 1;
1413 }
1414 RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
1415}
1416
1417/*
1418 ==========================================================================
1419 Description:
1420 Note:
1421 BEACON frame in shared memory should be built ok before this routine
1422 can be called. Otherwise, a garbage frame maybe transmitted out every
1423 Beacon period.
1424
1425 IRQL = DISPATCH_LEVEL
1426
1427 ==========================================================================
1428 */
1429VOID AsicEnableIbssSync(
1430 IN PRTMP_ADAPTER pAd)
1431{
1432 BCN_TIME_CFG_STRUC csr9;
1433 PUCHAR ptr;
1434 UINT i;
1435
1436 DBGPRINT(RT_DEBUG_TRACE, ("--->AsicEnableIbssSync(ADHOC mode. MPDUtotalByteCount = %d)\n", pAd->BeaconTxWI.MPDUtotalByteCount));
1437
1438 RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr9.word);
1439 csr9.field.bBeaconGen = 0;
1440 csr9.field.bTBTTEnable = 0;
1441 csr9.field.bTsfTicking = 0;
1442 RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word);
1443
1444#ifdef RTMP_MAC_PCI
1445 // move BEACON TXD and frame content to on-chip memory
1446 ptr = (PUCHAR)&pAd->BeaconTxWI;
1447 for (i=0; i<TXWI_SIZE; i+=4) // 16-byte TXWI field
1448 {
1449 UINT32 longptr = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
1450 RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + i, longptr);
1451 ptr += 4;
1452 }
1453
1454 // start right after the 16-byte TXWI field
1455 ptr = pAd->BeaconBuf;
1456 for (i=0; i< pAd->BeaconTxWI.MPDUtotalByteCount; i+=4)
1457 {
1458 UINT32 longptr = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
1459 RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, longptr);
1460 ptr +=4;
1461 }
1462#endif // RTMP_MAC_PCI //
1463#ifdef RTMP_MAC_USB
1464 // move BEACON TXD and frame content to on-chip memory
1465 ptr = (PUCHAR)&pAd->BeaconTxWI;
1466 for (i=0; i<TXWI_SIZE; i+=2) // 16-byte TXWI field
1467 {
1468 //UINT32 longptr = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
1469 //RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + i, longptr);
1470 RTUSBMultiWrite(pAd, HW_BEACON_BASE0 + i, ptr, 2);
1471 ptr += 2;
1472 }
1473
1474 // start right after the 16-byte TXWI field
1475 ptr = pAd->BeaconBuf;
1476 for (i=0; i< pAd->BeaconTxWI.MPDUtotalByteCount; i+=2)
1477 {
1478 //UINT32 longptr = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
1479 //RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, longptr);
1480 RTUSBMultiWrite(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, ptr, 2);
1481 ptr +=2;
1482 }
1483#endif // RTMP_MAC_USB //
1484
1485 //
1486 // For Wi-Fi faily generated beacons between participating stations.
1487 // Set TBTT phase adaptive adjustment step to 8us (default 16us)
1488 // don't change settings 2006-5- by Jerry
1489 //RTMP_IO_WRITE32(pAd, TBTT_SYNC_CFG, 0x00001010);
1490
1491 // start sending BEACON
1492 csr9.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4; // ASIC register in units of 1/16 TU
1493 csr9.field.bTsfTicking = 1;
1494 csr9.field.TsfSyncMode = 2; // sync TSF in IBSS mode
1495 csr9.field.bTBTTEnable = 1;
1496 csr9.field.bBeaconGen = 1;
1497 RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word);
1498}
1499
1500/*
1501 ==========================================================================
1502 Description:
1503
1504 IRQL = PASSIVE_LEVEL
1505 IRQL = DISPATCH_LEVEL
1506
1507 ==========================================================================
1508 */
1509VOID AsicSetEdcaParm(
1510 IN PRTMP_ADAPTER pAd,
1511 IN PEDCA_PARM pEdcaParm)
1512{
1513 EDCA_AC_CFG_STRUC Ac0Cfg, Ac1Cfg, Ac2Cfg, Ac3Cfg;
1514 AC_TXOP_CSR0_STRUC csr0;
1515 AC_TXOP_CSR1_STRUC csr1;
1516 AIFSN_CSR_STRUC AifsnCsr;
1517 CWMIN_CSR_STRUC CwminCsr;
1518 CWMAX_CSR_STRUC CwmaxCsr;
1519 int i;
1520
1521 Ac0Cfg.word = 0;
1522 Ac1Cfg.word = 0;
1523 Ac2Cfg.word = 0;
1524 Ac3Cfg.word = 0;
1525 if ((pEdcaParm == NULL) || (pEdcaParm->bValid == FALSE))
1526 {
1527 DBGPRINT(RT_DEBUG_TRACE,("AsicSetEdcaParm\n"));
1528 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_WMM_INUSED);
1529 for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
1530 {
1531 if (pAd->MacTab.Content[i].ValidAsCLI || pAd->MacTab.Content[i].ValidAsApCli)
1532 CLIENT_STATUS_CLEAR_FLAG(&pAd->MacTab.Content[i], fCLIENT_STATUS_WMM_CAPABLE);
1533 }
1534
1535 //========================================================
1536 // MAC Register has a copy .
1537 //========================================================
1538//#ifndef WIFI_TEST
1539 if( pAd->CommonCfg.bEnableTxBurst )
1540 {
1541 // For CWC test, change txop from 0x30 to 0x20 in TxBurst mode
1542 Ac0Cfg.field.AcTxop = 0x20; // Suggest by John for TxBurst in HT Mode
1543 }
1544 else
1545 Ac0Cfg.field.AcTxop = 0; // QID_AC_BE
1546//#else
1547// Ac0Cfg.field.AcTxop = 0; // QID_AC_BE
1548//#endif
1549 Ac0Cfg.field.Cwmin = CW_MIN_IN_BITS;
1550 Ac0Cfg.field.Cwmax = CW_MAX_IN_BITS;
1551 Ac0Cfg.field.Aifsn = 2;
1552 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Ac0Cfg.word);
1553
1554 Ac1Cfg.field.AcTxop = 0; // QID_AC_BK
1555 Ac1Cfg.field.Cwmin = CW_MIN_IN_BITS;
1556 Ac1Cfg.field.Cwmax = CW_MAX_IN_BITS;
1557 Ac1Cfg.field.Aifsn = 2;
1558 RTMP_IO_WRITE32(pAd, EDCA_AC1_CFG, Ac1Cfg.word);
1559
1560 if (pAd->CommonCfg.PhyMode == PHY_11B)
1561 {
1562 Ac2Cfg.field.AcTxop = 192; // AC_VI: 192*32us ~= 6ms
1563 Ac3Cfg.field.AcTxop = 96; // AC_VO: 96*32us ~= 3ms
1564 }
1565 else
1566 {
1567 Ac2Cfg.field.AcTxop = 96; // AC_VI: 96*32us ~= 3ms
1568 Ac3Cfg.field.AcTxop = 48; // AC_VO: 48*32us ~= 1.5ms
1569 }
1570 Ac2Cfg.field.Cwmin = CW_MIN_IN_BITS;
1571 Ac2Cfg.field.Cwmax = CW_MAX_IN_BITS;
1572 Ac2Cfg.field.Aifsn = 2;
1573 RTMP_IO_WRITE32(pAd, EDCA_AC2_CFG, Ac2Cfg.word);
1574 Ac3Cfg.field.Cwmin = CW_MIN_IN_BITS;
1575 Ac3Cfg.field.Cwmax = CW_MAX_IN_BITS;
1576 Ac3Cfg.field.Aifsn = 2;
1577 RTMP_IO_WRITE32(pAd, EDCA_AC3_CFG, Ac3Cfg.word);
1578
1579 //========================================================
1580 // DMA Register has a copy too.
1581 //========================================================
1582 csr0.field.Ac0Txop = 0; // QID_AC_BE
1583 csr0.field.Ac1Txop = 0; // QID_AC_BK
1584 RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word);
1585 if (pAd->CommonCfg.PhyMode == PHY_11B)
1586 {
1587 csr1.field.Ac2Txop = 192; // AC_VI: 192*32us ~= 6ms
1588 csr1.field.Ac3Txop = 96; // AC_VO: 96*32us ~= 3ms
1589 }
1590 else
1591 {
1592 csr1.field.Ac2Txop = 96; // AC_VI: 96*32us ~= 3ms
1593 csr1.field.Ac3Txop = 48; // AC_VO: 48*32us ~= 1.5ms
1594 }
1595 RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr1.word);
1596
1597 CwminCsr.word = 0;
1598 CwminCsr.field.Cwmin0 = CW_MIN_IN_BITS;
1599 CwminCsr.field.Cwmin1 = CW_MIN_IN_BITS;
1600 CwminCsr.field.Cwmin2 = CW_MIN_IN_BITS;
1601 CwminCsr.field.Cwmin3 = CW_MIN_IN_BITS;
1602 RTMP_IO_WRITE32(pAd, WMM_CWMIN_CFG, CwminCsr.word);
1603
1604 CwmaxCsr.word = 0;
1605 CwmaxCsr.field.Cwmax0 = CW_MAX_IN_BITS;
1606 CwmaxCsr.field.Cwmax1 = CW_MAX_IN_BITS;
1607 CwmaxCsr.field.Cwmax2 = CW_MAX_IN_BITS;
1608 CwmaxCsr.field.Cwmax3 = CW_MAX_IN_BITS;
1609 RTMP_IO_WRITE32(pAd, WMM_CWMAX_CFG, CwmaxCsr.word);
1610
1611 RTMP_IO_WRITE32(pAd, WMM_AIFSN_CFG, 0x00002222);
1612
1613 NdisZeroMemory(&pAd->CommonCfg.APEdcaParm, sizeof(EDCA_PARM));
1614 }
1615 else
1616 {
1617 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_WMM_INUSED);
1618 //========================================================
1619 // MAC Register has a copy.
1620 //========================================================
1621 //
1622 // Modify Cwmin/Cwmax/Txop on queue[QID_AC_VI], Recommend by Jerry 2005/07/27
1623 // To degrade our VIDO Queue's throughput for WiFi WMM S3T07 Issue.
1624 //
1625 //pEdcaParm->Txop[QID_AC_VI] = pEdcaParm->Txop[QID_AC_VI] * 7 / 10; // rt2860c need this
1626
1627 Ac0Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BE];
1628 Ac0Cfg.field.Cwmin= pEdcaParm->Cwmin[QID_AC_BE];
1629 Ac0Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_BE];
1630 Ac0Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BE]; //+1;
1631
1632 Ac1Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BK];
1633 Ac1Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_BK]; //+2;
1634 Ac1Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_BK];
1635 Ac1Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BK]; //+1;
1636
1637 Ac2Cfg.field.AcTxop = (pEdcaParm->Txop[QID_AC_VI] * 6) / 10;
1638 if(pAd->Antenna.field.TxPath == 1)
1639 {
1640 Ac2Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VI] + 1;
1641 Ac2Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VI] + 1;
1642 }
1643 else
1644 {
1645 Ac2Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VI];
1646 Ac2Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VI];
1647 }
1648 Ac2Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VI] + 1;
1649#ifdef RTMP_MAC_USB
1650 Ac2Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VI] + 3;
1651#endif // RTMP_MAC_USB //
1652
1653 {
1654 // Tuning for Wi-Fi WMM S06
1655 if (pAd->CommonCfg.bWiFiTest &&
1656 pEdcaParm->Aifsn[QID_AC_VI] == 10)
1657 Ac2Cfg.field.Aifsn -= 1;
1658
1659 // Tuning for TGn Wi-Fi 5.2.32
1660 // STA TestBed changes in this item: conexant legacy sta ==> broadcom 11n sta
1661 if (STA_TGN_WIFI_ON(pAd) &&
1662 pEdcaParm->Aifsn[QID_AC_VI] == 10)
1663 {
1664 Ac0Cfg.field.Aifsn = 3;
1665 Ac2Cfg.field.AcTxop = 5;
1666 }
1667#ifdef RT30xx
1668 if (pAd->RfIcType == RFIC_3020 || pAd->RfIcType == RFIC_2020)
1669 {
1670 // Tuning for WiFi WMM S3-T07: connexant legacy sta ==> broadcom 11n sta.
1671 Ac2Cfg.field.Aifsn = 5;
1672 }
1673#endif // RT30xx //
1674 }
1675
1676 Ac3Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_VO];
1677 Ac3Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VO];
1678 Ac3Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VO];
1679 Ac3Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VO];
1680
1681//#ifdef WIFI_TEST
1682 if (pAd->CommonCfg.bWiFiTest)
1683 {
1684 if (Ac3Cfg.field.AcTxop == 102)
1685 {
1686 Ac0Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BE] ? pEdcaParm->Txop[QID_AC_BE] : 10;
1687 Ac0Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BE]-1; /* AIFSN must >= 1 */
1688 Ac1Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BK];
1689 Ac1Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BK];
1690 Ac2Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_VI];
1691 } /* End of if */
1692 }
1693//#endif // WIFI_TEST //
1694
1695 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Ac0Cfg.word);
1696 RTMP_IO_WRITE32(pAd, EDCA_AC1_CFG, Ac1Cfg.word);
1697 RTMP_IO_WRITE32(pAd, EDCA_AC2_CFG, Ac2Cfg.word);
1698 RTMP_IO_WRITE32(pAd, EDCA_AC3_CFG, Ac3Cfg.word);
1699
1700
1701 //========================================================
1702 // DMA Register has a copy too.
1703 //========================================================
1704 csr0.field.Ac0Txop = Ac0Cfg.field.AcTxop;
1705 csr0.field.Ac1Txop = Ac1Cfg.field.AcTxop;
1706 RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word);
1707
1708 csr1.field.Ac2Txop = Ac2Cfg.field.AcTxop;
1709 csr1.field.Ac3Txop = Ac3Cfg.field.AcTxop;
1710 RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr1.word);
1711
1712 CwminCsr.word = 0;
1713 CwminCsr.field.Cwmin0 = pEdcaParm->Cwmin[QID_AC_BE];
1714 CwminCsr.field.Cwmin1 = pEdcaParm->Cwmin[QID_AC_BK];
1715 CwminCsr.field.Cwmin2 = pEdcaParm->Cwmin[QID_AC_VI];
1716 CwminCsr.field.Cwmin3 = pEdcaParm->Cwmin[QID_AC_VO] - 1; //for TGn wifi test
1717 RTMP_IO_WRITE32(pAd, WMM_CWMIN_CFG, CwminCsr.word);
1718
1719 CwmaxCsr.word = 0;
1720 CwmaxCsr.field.Cwmax0 = pEdcaParm->Cwmax[QID_AC_BE];
1721 CwmaxCsr.field.Cwmax1 = pEdcaParm->Cwmax[QID_AC_BK];
1722 CwmaxCsr.field.Cwmax2 = pEdcaParm->Cwmax[QID_AC_VI];
1723 CwmaxCsr.field.Cwmax3 = pEdcaParm->Cwmax[QID_AC_VO];
1724 RTMP_IO_WRITE32(pAd, WMM_CWMAX_CFG, CwmaxCsr.word);
1725
1726 AifsnCsr.word = 0;
1727 AifsnCsr.field.Aifsn0 = Ac0Cfg.field.Aifsn; //pEdcaParm->Aifsn[QID_AC_BE];
1728 AifsnCsr.field.Aifsn1 = Ac1Cfg.field.Aifsn; //pEdcaParm->Aifsn[QID_AC_BK];
1729 AifsnCsr.field.Aifsn2 = Ac2Cfg.field.Aifsn; //pEdcaParm->Aifsn[QID_AC_VI];
1730
1731 {
1732 // Tuning for Wi-Fi WMM S06
1733 if (pAd->CommonCfg.bWiFiTest &&
1734 pEdcaParm->Aifsn[QID_AC_VI] == 10)
1735 AifsnCsr.field.Aifsn2 = Ac2Cfg.field.Aifsn - 4;
1736
1737 // Tuning for TGn Wi-Fi 5.2.32
1738 // STA TestBed changes in this item: connexant legacy sta ==> broadcom 11n sta
1739 if (STA_TGN_WIFI_ON(pAd) &&
1740 pEdcaParm->Aifsn[QID_AC_VI] == 10)
1741 {
1742 AifsnCsr.field.Aifsn0 = 3;
1743 AifsnCsr.field.Aifsn2 = 7;
1744 }
1745
1746 if (INFRA_ON(pAd))
1747 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_WMM_CAPABLE);
1748 }
1749
1750 {
1751 AifsnCsr.field.Aifsn3 = Ac3Cfg.field.Aifsn - 1; //pEdcaParm->Aifsn[QID_AC_VO]; //for TGn wifi test
1752#ifdef RT30xx
1753 // TODO: Shiang, this modification also suitable for RT3052/RT3050 ???
1754 if (pAd->RfIcType == RFIC_3020 || pAd->RfIcType == RFIC_2020)
1755 {
1756 AifsnCsr.field.Aifsn2 = 0x2; //pEdcaParm->Aifsn[QID_AC_VI]; //for WiFi WMM S4-T04.
1757 }
1758#endif // RT30xx //
1759 }
1760 RTMP_IO_WRITE32(pAd, WMM_AIFSN_CFG, AifsnCsr.word);
1761
1762 NdisMoveMemory(&pAd->CommonCfg.APEdcaParm, pEdcaParm, sizeof(EDCA_PARM));
1763 if (!ADHOC_ON(pAd))
1764 {
1765 DBGPRINT(RT_DEBUG_TRACE,("EDCA [#%d]: AIFSN CWmin CWmax TXOP(us) ACM\n", pEdcaParm->EdcaUpdateCount));
1766 DBGPRINT(RT_DEBUG_TRACE,(" AC_BE %2d %2d %2d %4d %d\n",
1767 pEdcaParm->Aifsn[0],
1768 pEdcaParm->Cwmin[0],
1769 pEdcaParm->Cwmax[0],
1770 pEdcaParm->Txop[0]<<5,
1771 pEdcaParm->bACM[0]));
1772 DBGPRINT(RT_DEBUG_TRACE,(" AC_BK %2d %2d %2d %4d %d\n",
1773 pEdcaParm->Aifsn[1],
1774 pEdcaParm->Cwmin[1],
1775 pEdcaParm->Cwmax[1],
1776 pEdcaParm->Txop[1]<<5,
1777 pEdcaParm->bACM[1]));
1778 DBGPRINT(RT_DEBUG_TRACE,(" AC_VI %2d %2d %2d %4d %d\n",
1779 pEdcaParm->Aifsn[2],
1780 pEdcaParm->Cwmin[2],
1781 pEdcaParm->Cwmax[2],
1782 pEdcaParm->Txop[2]<<5,
1783 pEdcaParm->bACM[2]));
1784 DBGPRINT(RT_DEBUG_TRACE,(" AC_VO %2d %2d %2d %4d %d\n",
1785 pEdcaParm->Aifsn[3],
1786 pEdcaParm->Cwmin[3],
1787 pEdcaParm->Cwmax[3],
1788 pEdcaParm->Txop[3]<<5,
1789 pEdcaParm->bACM[3]));
1790 }
1791 }
1792
1793}
1794
1795/*
1796 ==========================================================================
1797 Description:
1798
1799 IRQL = PASSIVE_LEVEL
1800 IRQL = DISPATCH_LEVEL
1801
1802 ==========================================================================
1803 */
1804VOID AsicSetSlotTime(
1805 IN PRTMP_ADAPTER pAd,
1806 IN BOOLEAN bUseShortSlotTime)
1807{
1808 ULONG SlotTime;
1809 UINT32 RegValue = 0;
1810
1811 if (pAd->CommonCfg.Channel > 14)
1812 bUseShortSlotTime = TRUE;
1813
1814 if (bUseShortSlotTime && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED))
1815 return;
1816 else if ((!bUseShortSlotTime) && (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED)))
1817 return;
1818
1819 if (bUseShortSlotTime)
1820 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
1821 else
1822 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
1823
1824 SlotTime = (bUseShortSlotTime)? 9 : 20;
1825
1826 {
1827 // force using short SLOT time for FAE to demo performance when TxBurst is ON
1828 if (((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED)))
1829 || ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE) && (pAd->CommonCfg.BACapability.field.Policy == BA_NOTUSE))
1830 )
1831 {
1832 // In this case, we will think it is doing Wi-Fi test
1833 // And we will not set to short slot when bEnableTxBurst is TRUE.
1834 }
1835 else if (pAd->CommonCfg.bEnableTxBurst)
1836 {
1837 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
1838 SlotTime = 9;
1839 }
1840 }
1841
1842 //
1843 // For some reasons, always set it to short slot time.
1844 //
1845 // ToDo: Should consider capability with 11B
1846 //
1847 {
1848 if (pAd->StaCfg.BssType == BSS_ADHOC)
1849 {
1850 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
1851 SlotTime = 20;
1852 }
1853 }
1854
1855 RTMP_IO_READ32(pAd, BKOFF_SLOT_CFG, &RegValue);
1856 RegValue = RegValue & 0xFFFFFF00;
1857
1858 RegValue |= SlotTime;
1859
1860 RTMP_IO_WRITE32(pAd, BKOFF_SLOT_CFG, RegValue);
1861}
1862
1863/*
1864 ========================================================================
1865 Description:
1866 Add Shared key information into ASIC.
1867 Update shared key, TxMic and RxMic to Asic Shared key table
1868 Update its cipherAlg to Asic Shared key Mode.
1869
1870 Return:
1871 ========================================================================
1872*/
1873VOID AsicAddSharedKeyEntry(
1874 IN PRTMP_ADAPTER pAd,
1875 IN UCHAR BssIndex,
1876 IN UCHAR KeyIdx,
1877 IN UCHAR CipherAlg,
1878 IN PUCHAR pKey,
1879 IN PUCHAR pTxMic,
1880 IN PUCHAR pRxMic)
1881{
1882 ULONG offset; //, csr0;
1883 SHAREDKEY_MODE_STRUC csr1;
1884#ifdef RTMP_MAC_PCI
1885 INT i;
1886#endif // RTMP_MAC_PCI //
1887
1888 DBGPRINT(RT_DEBUG_TRACE, ("AsicAddSharedKeyEntry BssIndex=%d, KeyIdx=%d\n", BssIndex,KeyIdx));
1889//============================================================================================
1890
1891 DBGPRINT(RT_DEBUG_TRACE,("AsicAddSharedKeyEntry: %s key #%d\n", CipherName[CipherAlg], BssIndex*4 + KeyIdx));
1892 DBGPRINT_RAW(RT_DEBUG_TRACE, (" Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
1893 pKey[0],pKey[1],pKey[2],pKey[3],pKey[4],pKey[5],pKey[6],pKey[7],pKey[8],pKey[9],pKey[10],pKey[11],pKey[12],pKey[13],pKey[14],pKey[15]));
1894 if (pRxMic)
1895 {
1896 DBGPRINT_RAW(RT_DEBUG_TRACE, (" Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
1897 pRxMic[0],pRxMic[1],pRxMic[2],pRxMic[3],pRxMic[4],pRxMic[5],pRxMic[6],pRxMic[7]));
1898 }
1899 if (pTxMic)
1900 {
1901 DBGPRINT_RAW(RT_DEBUG_TRACE, (" Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
1902 pTxMic[0],pTxMic[1],pTxMic[2],pTxMic[3],pTxMic[4],pTxMic[5],pTxMic[6],pTxMic[7]));
1903 }
1904//============================================================================================
1905 //
1906 // fill key material - key + TX MIC + RX MIC
1907 //
1908#ifdef RTMP_MAC_PCI
1909 offset = SHARED_KEY_TABLE_BASE + (4*BssIndex + KeyIdx)*HW_KEY_ENTRY_SIZE;
1910 for (i=0; i<MAX_LEN_OF_SHARE_KEY; i++)
1911 {
1912 RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
1913 }
1914
1915 offset += MAX_LEN_OF_SHARE_KEY;
1916 if (pTxMic)
1917 {
1918 for (i=0; i<8; i++)
1919 {
1920 RTMP_IO_WRITE8(pAd, offset + i, pTxMic[i]);
1921 }
1922 }
1923
1924 offset += 8;
1925 if (pRxMic)
1926 {
1927 for (i=0; i<8; i++)
1928 {
1929 RTMP_IO_WRITE8(pAd, offset + i, pRxMic[i]);
1930 }
1931 }
1932#endif // RTMP_MAC_PCI //
1933#ifdef RTMP_MAC_USB
1934{
1935 offset = SHARED_KEY_TABLE_BASE + (4*BssIndex + KeyIdx)*HW_KEY_ENTRY_SIZE;
1936 RTUSBMultiWrite(pAd, offset, pKey, MAX_LEN_OF_SHARE_KEY);
1937
1938 offset += MAX_LEN_OF_SHARE_KEY;
1939 if (pTxMic)
1940 {
1941 RTUSBMultiWrite(pAd, offset, pTxMic, 8);
1942 }
1943
1944 offset += 8;
1945 if (pRxMic)
1946 {
1947 RTUSBMultiWrite(pAd, offset, pRxMic, 8);
1948 }
1949}
1950#endif // RTMP_MAC_USB //
1951
1952 //
1953 // Update cipher algorithm. WSTA always use BSS0
1954 //
1955 RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), &csr1.word);
1956 DBGPRINT(RT_DEBUG_TRACE,("Read: SHARED_KEY_MODE_BASE at this Bss[%d] KeyIdx[%d]= 0x%x \n", BssIndex,KeyIdx, csr1.word));
1957 if ((BssIndex%2) == 0)
1958 {
1959 if (KeyIdx == 0)
1960 csr1.field.Bss0Key0CipherAlg = CipherAlg;
1961 else if (KeyIdx == 1)
1962 csr1.field.Bss0Key1CipherAlg = CipherAlg;
1963 else if (KeyIdx == 2)
1964 csr1.field.Bss0Key2CipherAlg = CipherAlg;
1965 else
1966 csr1.field.Bss0Key3CipherAlg = CipherAlg;
1967 }
1968 else
1969 {
1970 if (KeyIdx == 0)
1971 csr1.field.Bss1Key0CipherAlg = CipherAlg;
1972 else if (KeyIdx == 1)
1973 csr1.field.Bss1Key1CipherAlg = CipherAlg;
1974 else if (KeyIdx == 2)
1975 csr1.field.Bss1Key2CipherAlg = CipherAlg;
1976 else
1977 csr1.field.Bss1Key3CipherAlg = CipherAlg;
1978 }
1979 DBGPRINT(RT_DEBUG_TRACE,("Write: SHARED_KEY_MODE_BASE at this Bss[%d] = 0x%x \n", BssIndex, csr1.word));
1980 RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), csr1.word);
1981
1982}
1983
1984// IRQL = DISPATCH_LEVEL
1985VOID AsicRemoveSharedKeyEntry(
1986 IN PRTMP_ADAPTER pAd,
1987 IN UCHAR BssIndex,
1988 IN UCHAR KeyIdx)
1989{
1990 //ULONG SecCsr0;
1991 SHAREDKEY_MODE_STRUC csr1;
1992
1993 DBGPRINT(RT_DEBUG_TRACE,("AsicRemoveSharedKeyEntry: #%d \n", BssIndex*4 + KeyIdx));
1994
1995 RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), &csr1.word);
1996 if ((BssIndex%2) == 0)
1997 {
1998 if (KeyIdx == 0)
1999 csr1.field.Bss0Key0CipherAlg = 0;
2000 else if (KeyIdx == 1)
2001 csr1.field.Bss0Key1CipherAlg = 0;
2002 else if (KeyIdx == 2)
2003 csr1.field.Bss0Key2CipherAlg = 0;
2004 else
2005 csr1.field.Bss0Key3CipherAlg = 0;
2006 }
2007 else
2008 {
2009 if (KeyIdx == 0)
2010 csr1.field.Bss1Key0CipherAlg = 0;
2011 else if (KeyIdx == 1)
2012 csr1.field.Bss1Key1CipherAlg = 0;
2013 else if (KeyIdx == 2)
2014 csr1.field.Bss1Key2CipherAlg = 0;
2015 else
2016 csr1.field.Bss1Key3CipherAlg = 0;
2017 }
2018 DBGPRINT(RT_DEBUG_TRACE,("Write: SHARED_KEY_MODE_BASE at this Bss[%d] = 0x%x \n", BssIndex, csr1.word));
2019 RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), csr1.word);
2020 ASSERT(BssIndex < 4);
2021 ASSERT(KeyIdx < 4);
2022
2023}
2024
2025
2026VOID AsicUpdateWCIDAttribute(
2027 IN PRTMP_ADAPTER pAd,
2028 IN USHORT WCID,
2029 IN UCHAR BssIndex,
2030 IN UCHAR CipherAlg,
2031 IN BOOLEAN bUsePairewiseKeyTable)
2032{
2033 ULONG WCIDAttri = 0, offset;
2034
2035 //
2036 // Update WCID attribute.
2037 // Only TxKey could update WCID attribute.
2038 //
2039 offset = MAC_WCID_ATTRIBUTE_BASE + (WCID * HW_WCID_ATTRI_SIZE);
2040 WCIDAttri = (BssIndex << 4) | (CipherAlg << 1) | (bUsePairewiseKeyTable);
2041 RTMP_IO_WRITE32(pAd, offset, WCIDAttri);
2042}
2043
2044VOID AsicUpdateWCIDIVEIV(
2045 IN PRTMP_ADAPTER pAd,
2046 IN USHORT WCID,
2047 IN ULONG uIV,
2048 IN ULONG uEIV)
2049{
2050 ULONG offset;
2051
2052 offset = MAC_IVEIV_TABLE_BASE + (WCID * HW_IVEIV_ENTRY_SIZE);
2053
2054 RTMP_IO_WRITE32(pAd, offset, uIV);
2055 RTMP_IO_WRITE32(pAd, offset + 4, uEIV);
2056}
2057
2058VOID AsicUpdateRxWCIDTable(
2059 IN PRTMP_ADAPTER pAd,
2060 IN USHORT WCID,
2061 IN PUCHAR pAddr)
2062{
2063 ULONG offset;
2064 ULONG Addr;
2065
2066 offset = MAC_WCID_BASE + (WCID * HW_WCID_ENTRY_SIZE);
2067 Addr = pAddr[0] + (pAddr[1] << 8) +(pAddr[2] << 16) +(pAddr[3] << 24);
2068 RTMP_IO_WRITE32(pAd, offset, Addr);
2069 Addr = pAddr[4] + (pAddr[5] << 8);
2070 RTMP_IO_WRITE32(pAd, offset + 4, Addr);
2071}
2072
2073
2074/*
2075 ========================================================================
2076
2077 Routine Description:
2078 Set Cipher Key, Cipher algorithm, IV/EIV to Asic
2079
2080 Arguments:
2081 pAd Pointer to our adapter
2082 WCID WCID Entry number.
2083 BssIndex BSSID index, station or none multiple BSSID support
2084 this value should be 0.
2085 KeyIdx This KeyIdx will set to IV's KeyID if bTxKey enabled
2086 pCipherKey Pointer to Cipher Key.
2087 bUsePairewiseKeyTable TRUE means saved the key in SharedKey table,
2088 otherwise PairewiseKey table
2089 bTxKey This is the transmit key if enabled.
2090
2091 Return Value:
2092 None
2093
2094 Note:
2095 This routine will set the relative key stuff to Asic including WCID attribute,
2096 Cipher Key, Cipher algorithm and IV/EIV.
2097
2098 IV/EIV will be update if this CipherKey is the transmission key because
2099 ASIC will base on IV's KeyID value to select Cipher Key.
2100
2101 If bTxKey sets to FALSE, this is not the TX key, but it could be
2102 RX key
2103
2104 For AP mode bTxKey must be always set to TRUE.
2105 ========================================================================
2106*/
2107VOID AsicAddKeyEntry(
2108 IN PRTMP_ADAPTER pAd,
2109 IN USHORT WCID,
2110 IN UCHAR BssIndex,
2111 IN UCHAR KeyIdx,
2112 IN PCIPHER_KEY pCipherKey,
2113 IN BOOLEAN bUsePairewiseKeyTable,
2114 IN BOOLEAN bTxKey)
2115{
2116 ULONG offset;
2117// ULONG WCIDAttri = 0;
2118 UCHAR IV4 = 0;
2119 PUCHAR pKey = pCipherKey->Key;
2120// ULONG KeyLen = pCipherKey->KeyLen;
2121 PUCHAR pTxMic = pCipherKey->TxMic;
2122 PUCHAR pRxMic = pCipherKey->RxMic;
2123 PUCHAR pTxtsc = pCipherKey->TxTsc;
2124 UCHAR CipherAlg = pCipherKey->CipherAlg;
2125 SHAREDKEY_MODE_STRUC csr1;
2126#ifdef RTMP_MAC_PCI
2127 UCHAR i;
2128#endif // RTMP_MAC_PCI //
2129
2130// ASSERT(KeyLen <= MAX_LEN_OF_PEER_KEY);
2131
2132 DBGPRINT(RT_DEBUG_TRACE, ("==> AsicAddKeyEntry\n"));
2133 //
2134 // 1.) decide key table offset
2135 //
2136 if (bUsePairewiseKeyTable)
2137 offset = PAIRWISE_KEY_TABLE_BASE + (WCID * HW_KEY_ENTRY_SIZE);
2138 else
2139 offset = SHARED_KEY_TABLE_BASE + (4 * BssIndex + KeyIdx) * HW_KEY_ENTRY_SIZE;
2140
2141 //
2142 // 2.) Set Key to Asic
2143 //
2144 //for (i = 0; i < KeyLen; i++)
2145#ifdef RTMP_MAC_PCI
2146 for (i = 0; i < MAX_LEN_OF_PEER_KEY; i++)
2147 {
2148 RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
2149 }
2150 offset += MAX_LEN_OF_PEER_KEY;
2151
2152 //
2153 // 3.) Set MIC key if available
2154 //
2155 if (pTxMic)
2156 {
2157 for (i = 0; i < 8; i++)
2158 {
2159 RTMP_IO_WRITE8(pAd, offset + i, pTxMic[i]);
2160 }
2161 }
2162 offset += LEN_TKIP_TXMICK;
2163
2164 if (pRxMic)
2165 {
2166 for (i = 0; i < 8; i++)
2167 {
2168 RTMP_IO_WRITE8(pAd, offset + i, pRxMic[i]);
2169 }
2170 }
2171#endif // RTMP_MAC_PCI //
2172#ifdef RTMP_MAC_USB
2173 RTUSBMultiWrite(pAd, offset, pKey, MAX_LEN_OF_PEER_KEY);
2174 offset += MAX_LEN_OF_PEER_KEY;
2175
2176 //
2177 // 3.) Set MIC key if available
2178 //
2179 if (pTxMic)
2180 {
2181 RTUSBMultiWrite(pAd, offset, pTxMic, 8);
2182 }
2183 offset += LEN_TKIP_TXMICK;
2184
2185 if (pRxMic)
2186 {
2187 RTUSBMultiWrite(pAd, offset, pRxMic, 8);
2188 }
2189#endif // RTMP_MAC_USB //
2190
2191 //
2192 // 4.) Modify IV/EIV if needs
2193 // This will force Asic to use this key ID by setting IV.
2194 //
2195 if (bTxKey)
2196 {
2197#ifdef RTMP_MAC_PCI
2198 offset = MAC_IVEIV_TABLE_BASE + (WCID * HW_IVEIV_ENTRY_SIZE);
2199 //
2200 // Write IV
2201 //
2202 RTMP_IO_WRITE8(pAd, offset, pTxtsc[1]);
2203 RTMP_IO_WRITE8(pAd, offset + 1, ((pTxtsc[1] | 0x20) & 0x7f));
2204 RTMP_IO_WRITE8(pAd, offset + 2, pTxtsc[0]);
2205
2206 IV4 = (KeyIdx << 6);
2207 if ((CipherAlg == CIPHER_TKIP) || (CipherAlg == CIPHER_TKIP_NO_MIC) ||(CipherAlg == CIPHER_AES))
2208 IV4 |= 0x20; // turn on extension bit means EIV existence
2209
2210 RTMP_IO_WRITE8(pAd, offset + 3, IV4);
2211
2212 //
2213 // Write EIV
2214 //
2215 offset += 4;
2216 for (i = 0; i < 4; i++)
2217 {
2218 RTMP_IO_WRITE8(pAd, offset + i, pTxtsc[i + 2]);
2219 }
2220#endif // RTMP_MAC_PCI //
2221#ifdef RTMP_MAC_USB
2222 UINT32 tmpVal;
2223
2224 //
2225 // Write IV
2226 //
2227 IV4 = (KeyIdx << 6);
2228 if ((CipherAlg == CIPHER_TKIP) || (CipherAlg == CIPHER_TKIP_NO_MIC) ||(CipherAlg == CIPHER_AES))
2229 IV4 |= 0x20; // turn on extension bit means EIV existence
2230
2231 tmpVal = pTxtsc[1] + (((pTxtsc[1] | 0x20) & 0x7f) << 8) + (pTxtsc[0] << 16) + (IV4 << 24);
2232 RTMP_IO_WRITE32(pAd, offset, tmpVal);
2233
2234 //
2235 // Write EIV
2236 //
2237 offset += 4;
2238 RTMP_IO_WRITE32(pAd, offset, *(PUINT32)&pCipherKey->TxTsc[2]);
2239#endif // RTMP_MAC_USB //
2240
2241 AsicUpdateWCIDAttribute(pAd, WCID, BssIndex, CipherAlg, bUsePairewiseKeyTable);
2242 }
2243
2244 if (!bUsePairewiseKeyTable)
2245 {
2246 //
2247 // Only update the shared key security mode
2248 //
2249 RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2), &csr1.word);
2250 if ((BssIndex % 2) == 0)
2251 {
2252 if (KeyIdx == 0)
2253 csr1.field.Bss0Key0CipherAlg = CipherAlg;
2254 else if (KeyIdx == 1)
2255 csr1.field.Bss0Key1CipherAlg = CipherAlg;
2256 else if (KeyIdx == 2)
2257 csr1.field.Bss0Key2CipherAlg = CipherAlg;
2258 else
2259 csr1.field.Bss0Key3CipherAlg = CipherAlg;
2260 }
2261 else
2262 {
2263 if (KeyIdx == 0)
2264 csr1.field.Bss1Key0CipherAlg = CipherAlg;
2265 else if (KeyIdx == 1)
2266 csr1.field.Bss1Key1CipherAlg = CipherAlg;
2267 else if (KeyIdx == 2)
2268 csr1.field.Bss1Key2CipherAlg = CipherAlg;
2269 else
2270 csr1.field.Bss1Key3CipherAlg = CipherAlg;
2271 }
2272 RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2), csr1.word);
2273 }
2274
2275 DBGPRINT(RT_DEBUG_TRACE, ("<== AsicAddKeyEntry\n"));
2276}
2277
2278
2279/*
2280 ========================================================================
2281 Description:
2282 Add Pair-wise key material into ASIC.
2283 Update pairwise key, TxMic and RxMic to Asic Pair-wise key table
2284
2285 Return:
2286 ========================================================================
2287*/
2288VOID AsicAddPairwiseKeyEntry(
2289 IN PRTMP_ADAPTER pAd,
2290 IN PUCHAR pAddr,
2291 IN UCHAR WCID,
2292 IN CIPHER_KEY *pCipherKey)
2293{
2294 INT i;
2295 ULONG offset;
2296 PUCHAR pKey = pCipherKey->Key;
2297 PUCHAR pTxMic = pCipherKey->TxMic;
2298 PUCHAR pRxMic = pCipherKey->RxMic;
2299#ifdef DBG
2300 UCHAR CipherAlg = pCipherKey->CipherAlg;
2301#endif // DBG //
2302
2303 // EKEY
2304 offset = PAIRWISE_KEY_TABLE_BASE + (WCID * HW_KEY_ENTRY_SIZE);
2305#ifdef RTMP_MAC_PCI
2306 for (i=0; i<MAX_LEN_OF_PEER_KEY; i++)
2307 {
2308 RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
2309 }
2310#endif // RTMP_MAC_PCI //
2311#ifdef RTMP_MAC_USB
2312 RTUSBMultiWrite(pAd, offset, &pCipherKey->Key[0], MAX_LEN_OF_PEER_KEY);
2313#endif // RTMP_MAC_USB //
2314 for (i=0; i<MAX_LEN_OF_PEER_KEY; i+=4)
2315 {
2316 UINT32 Value;
2317 RTMP_IO_READ32(pAd, offset + i, &Value);
2318 }
2319
2320 offset += MAX_LEN_OF_PEER_KEY;
2321
2322 // MIC KEY
2323 if (pTxMic)
2324 {
2325#ifdef RTMP_MAC_PCI
2326 for (i=0; i<8; i++)
2327 {
2328 RTMP_IO_WRITE8(pAd, offset+i, pTxMic[i]);
2329 }
2330#endif // RTMP_MAC_PCI //
2331#ifdef RTMP_MAC_USB
2332 RTUSBMultiWrite(pAd, offset, &pCipherKey->TxMic[0], 8);
2333#endif // RTMP_MAC_USB //
2334 }
2335 offset += 8;
2336 if (pRxMic)
2337 {
2338#ifdef RTMP_MAC_PCI
2339 for (i=0; i<8; i++)
2340 {
2341 RTMP_IO_WRITE8(pAd, offset+i, pRxMic[i]);
2342 }
2343#endif // RTMP_MAC_PCI //
2344#ifdef RTMP_MAC_USB
2345 RTUSBMultiWrite(pAd, offset, &pCipherKey->RxMic[0], 8);
2346#endif // RTMP_MAC_USB //
2347 }
2348
2349 DBGPRINT(RT_DEBUG_TRACE,("AsicAddPairwiseKeyEntry: WCID #%d Alg=%s\n",WCID, CipherName[CipherAlg]));
2350 DBGPRINT(RT_DEBUG_TRACE,(" Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
2351 pKey[0],pKey[1],pKey[2],pKey[3],pKey[4],pKey[5],pKey[6],pKey[7],pKey[8],pKey[9],pKey[10],pKey[11],pKey[12],pKey[13],pKey[14],pKey[15]));
2352 if (pRxMic)
2353 {
2354 DBGPRINT(RT_DEBUG_TRACE, (" Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
2355 pRxMic[0],pRxMic[1],pRxMic[2],pRxMic[3],pRxMic[4],pRxMic[5],pRxMic[6],pRxMic[7]));
2356 }
2357 if (pTxMic)
2358 {
2359 DBGPRINT(RT_DEBUG_TRACE, (" Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
2360 pTxMic[0],pTxMic[1],pTxMic[2],pTxMic[3],pTxMic[4],pTxMic[5],pTxMic[6],pTxMic[7]));
2361 }
2362}
2363/*
2364 ========================================================================
2365 Description:
2366 Remove Pair-wise key material from ASIC.
2367
2368 Return:
2369 ========================================================================
2370*/
2371VOID AsicRemovePairwiseKeyEntry(
2372 IN PRTMP_ADAPTER pAd,
2373 IN UCHAR BssIdx,
2374 IN UCHAR Wcid)
2375{
2376 ULONG WCIDAttri;
2377 USHORT offset;
2378
2379 // re-set the entry's WCID attribute as OPEN-NONE.
2380 offset = MAC_WCID_ATTRIBUTE_BASE + (Wcid * HW_WCID_ATTRI_SIZE);
2381 WCIDAttri = (BssIdx<<4) | PAIRWISEKEYTABLE;
2382 RTMP_IO_WRITE32(pAd, offset, WCIDAttri);
2383}
2384
2385BOOLEAN AsicSendCommandToMcu(
2386 IN PRTMP_ADAPTER pAd,
2387 IN UCHAR Command,
2388 IN UCHAR Token,
2389 IN UCHAR Arg0,
2390 IN UCHAR Arg1)
2391{
2392
2393 if (pAd->chipOps.sendCommandToMcu)
2394 pAd->chipOps.sendCommandToMcu(pAd, Command, Token, Arg0, Arg1);
2395
2396 return TRUE;
2397}
2398
2399
2400VOID AsicSetRxAnt(
2401 IN PRTMP_ADAPTER pAd,
2402 IN UCHAR Ant)
2403{
2404#ifdef RT30xx
2405 /* RT3572 ATE need not to do this. */
2406 RT30xxSetRxAnt(pAd, Ant);
2407#endif // RT30xx //
2408}
2409
2410
2411VOID AsicTurnOffRFClk(
2412 IN PRTMP_ADAPTER pAd,
2413 IN UCHAR Channel)
2414{
2415 if (pAd->chipOps.AsicRfTurnOff)
2416 {
2417 pAd->chipOps.AsicRfTurnOff(pAd);
2418 }
2419 else
2420 {
2421 // RF R2 bit 18 = 0
2422 UINT32 R1 = 0, R2 = 0, R3 = 0;
2423 UCHAR index;
2424 RTMP_RF_REGS *RFRegTable;
2425
2426 RFRegTable = RF2850RegTable;
2427
2428 switch (pAd->RfIcType)
2429 {
2430 case RFIC_2820:
2431 case RFIC_2850:
2432 case RFIC_2720:
2433 case RFIC_2750:
2434
2435 for (index = 0; index < NUM_OF_2850_CHNL; index++)
2436 {
2437 if (Channel == RFRegTable[index].Channel)
2438 {
2439 R1 = RFRegTable[index].R1 & 0xffffdfff;
2440 R2 = RFRegTable[index].R2 & 0xfffbffff;
2441 R3 = RFRegTable[index].R3 & 0xfff3ffff;
2442
2443 RTMP_RF_IO_WRITE32(pAd, R1);
2444 RTMP_RF_IO_WRITE32(pAd, R2);
2445
2446 // Program R1b13 to 1, R3/b18,19 to 0, R2b18 to 0.
2447 // Set RF R2 bit18=0, R3 bit[18:19]=0
2448 //if (pAd->StaCfg.bRadio == FALSE)
2449 if (1)
2450 {
2451 RTMP_RF_IO_WRITE32(pAd, R3);
2452
2453 DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x, R3 = 0x%08x \n",
2454 Channel, pAd->RfIcType, R2, R3));
2455 }
2456 else
2457 DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x \n",
2458 Channel, pAd->RfIcType, R2));
2459 break;
2460 }
2461 }
2462 break;
2463
2464 default:
2465 break;
2466 }
2467 }
2468}
2469
2470
2471VOID AsicTurnOnRFClk(
2472 IN PRTMP_ADAPTER pAd,
2473 IN UCHAR Channel)
2474{
2475 // RF R2 bit 18 = 0
2476 UINT32 R1 = 0, R2 = 0, R3 = 0;
2477 UCHAR index;
2478 RTMP_RF_REGS *RFRegTable;
2479
2480
2481 RFRegTable = RF2850RegTable;
2482
2483 switch (pAd->RfIcType)
2484 {
2485 case RFIC_2820:
2486 case RFIC_2850:
2487 case RFIC_2720:
2488 case RFIC_2750:
2489
2490 for (index = 0; index < NUM_OF_2850_CHNL; index++)
2491 {
2492 if (Channel == RFRegTable[index].Channel)
2493 {
2494 R3 = pAd->LatchRfRegs.R3;
2495 R3 &= 0xfff3ffff;
2496 R3 |= 0x00080000;
2497 RTMP_RF_IO_WRITE32(pAd, R3);
2498
2499 R1 = RFRegTable[index].R1;
2500 RTMP_RF_IO_WRITE32(pAd, R1);
2501
2502 R2 = RFRegTable[index].R2;
2503 if (pAd->Antenna.field.TxPath == 1)
2504 {
2505 R2 |= 0x4000; // If TXpath is 1, bit 14 = 1;
2506 }
2507
2508 if (pAd->Antenna.field.RxPath == 2)
2509 {
2510 R2 |= 0x40; // write 1 to off Rxpath.
2511 }
2512 else if (pAd->Antenna.field.RxPath == 1)
2513 {
2514 R2 |= 0x20040; // write 1 to off RxPath
2515 }
2516 RTMP_RF_IO_WRITE32(pAd, R2);
2517
2518 break;
2519 }
2520 }
2521 break;
2522
2523 default:
2524 break;
2525 }
2526
2527 DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOnRFClk#%d(RF=%d, ) , R2=0x%08x\n",
2528 Channel,
2529 pAd->RfIcType,
2530 R2));
2531}
diff --git a/drivers/staging/rt2860/common/cmm_cfg.c b/drivers/staging/rt2860/common/cmm_cfg.c
new file mode 100644
index 00000000000..c1cf2bf4680
--- /dev/null
+++ b/drivers/staging/rt2860/common/cmm_cfg.c
@@ -0,0 +1,290 @@
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
39
40#include "../rt_config.h"
41
42
43char* GetPhyMode(
44 int Mode)
45{
46 switch(Mode)
47 {
48 case MODE_CCK:
49 return "CCK";
50
51 case MODE_OFDM:
52 return "OFDM";
53 case MODE_HTMIX:
54 return "HTMIX";
55
56 case MODE_HTGREENFIELD:
57 return "GREEN";
58 default:
59 return "N/A";
60 }
61}
62
63
64char* GetBW(
65 int BW)
66{
67 switch(BW)
68 {
69 case BW_10:
70 return "10M";
71
72 case BW_20:
73 return "20M";
74 case BW_40:
75 return "40M";
76 default:
77 return "N/A";
78 }
79}
80
81
82/*
83 ==========================================================================
84 Description:
85 Set Country Region to pAd->CommonCfg.CountryRegion.
86 This command will not work, if the field of CountryRegion in eeprom is programmed.
87
88 Return:
89 TRUE if all parameters are OK, FALSE otherwise
90 ==========================================================================
91*/
92INT RT_CfgSetCountryRegion(
93 IN PRTMP_ADAPTER pAd,
94 IN PSTRING arg,
95 IN INT band)
96{
97 LONG region, regionMax;
98 UCHAR *pCountryRegion;
99
100 region = simple_strtol(arg, 0, 10);
101
102 if (band == BAND_24G)
103 {
104 pCountryRegion = &pAd->CommonCfg.CountryRegion;
105 regionMax = REGION_MAXIMUM_BG_BAND;
106 }
107 else
108 {
109 pCountryRegion = &pAd->CommonCfg.CountryRegionForABand;
110 regionMax = REGION_MAXIMUM_A_BAND;
111 }
112
113 // TODO: Is it neccesay for following check???
114 // Country can be set only when EEPROM not programmed
115 if (*pCountryRegion & 0x80)
116 {
117 DBGPRINT(RT_DEBUG_ERROR, ("CfgSetCountryRegion():CountryRegion in eeprom was programmed\n"));
118 return FALSE;
119 }
120
121 if((region >= 0) && (region <= REGION_MAXIMUM_BG_BAND))
122 {
123 *pCountryRegion= (UCHAR) region;
124 }
125 else if ((region == REGION_31_BG_BAND) && (band == BAND_24G))
126 {
127 *pCountryRegion = (UCHAR) region;
128 }
129 else
130 {
131 DBGPRINT(RT_DEBUG_ERROR, ("CfgSetCountryRegion():region(%ld) out of range!\n", region));
132 return FALSE;
133 }
134
135 return TRUE;
136
137}
138
139
140/*
141 ==========================================================================
142 Description:
143 Set Wireless Mode
144 Return:
145 TRUE if all parameters are OK, FALSE otherwise
146 ==========================================================================
147*/
148INT RT_CfgSetWirelessMode(
149 IN PRTMP_ADAPTER pAd,
150 IN PSTRING arg)
151{
152 INT MaxPhyMode = PHY_11G;
153 LONG WirelessMode;
154
155 MaxPhyMode = PHY_11N_5G;
156
157 WirelessMode = simple_strtol(arg, 0, 10);
158 if (WirelessMode <= MaxPhyMode)
159 {
160 pAd->CommonCfg.PhyMode = WirelessMode;
161 return TRUE;
162 }
163
164 return FALSE;
165
166}
167
168
169INT RT_CfgSetShortSlot(
170 IN PRTMP_ADAPTER pAd,
171 IN PSTRING arg)
172{
173 LONG ShortSlot;
174
175 ShortSlot = simple_strtol(arg, 0, 10);
176
177 if (ShortSlot == 1)
178 pAd->CommonCfg.bUseShortSlotTime = TRUE;
179 else if (ShortSlot == 0)
180 pAd->CommonCfg.bUseShortSlotTime = FALSE;
181 else
182 return FALSE; //Invalid argument
183
184 return TRUE;
185}
186
187
188/*
189 ==========================================================================
190 Description:
191 Set WEP KEY base on KeyIdx
192 Return:
193 TRUE if all parameters are OK, FALSE otherwise
194 ==========================================================================
195*/
196INT RT_CfgSetWepKey(
197 IN PRTMP_ADAPTER pAd,
198 IN PSTRING keyString,
199 IN CIPHER_KEY *pSharedKey,
200 IN INT keyIdx)
201{
202 INT KeyLen;
203 INT i;
204 UCHAR CipherAlg = CIPHER_NONE;
205 BOOLEAN bKeyIsHex = FALSE;
206
207 // TODO: Shall we do memset for the original key info??
208 memset(pSharedKey, 0, sizeof(CIPHER_KEY));
209 KeyLen = strlen(keyString);
210 switch (KeyLen)
211 {
212 case 5: //wep 40 Ascii type
213 case 13: //wep 104 Ascii type
214 bKeyIsHex = FALSE;
215 pSharedKey->KeyLen = KeyLen;
216 NdisMoveMemory(pSharedKey->Key, keyString, KeyLen);
217 break;
218
219 case 10: //wep 40 Hex type
220 case 26: //wep 104 Hex type
221 for(i=0; i < KeyLen; i++)
222 {
223 if( !isxdigit(*(keyString+i)) )
224 return FALSE; //Not Hex value;
225 }
226 bKeyIsHex = TRUE;
227 pSharedKey->KeyLen = KeyLen/2 ;
228 AtoH(keyString, pSharedKey->Key, pSharedKey->KeyLen);
229 break;
230
231 default: //Invalid argument
232 DBGPRINT(RT_DEBUG_TRACE, ("RT_CfgSetWepKey(keyIdx=%d):Invalid argument (arg=%s)\n", keyIdx, keyString));
233 return FALSE;
234 }
235
236 pSharedKey->CipherAlg = ((KeyLen % 5) ? CIPHER_WEP128 : CIPHER_WEP64);
237 DBGPRINT(RT_DEBUG_TRACE, ("RT_CfgSetWepKey:(KeyIdx=%d,type=%s, Alg=%s)\n",
238 keyIdx, (bKeyIsHex == FALSE ? "Ascii" : "Hex"), CipherName[CipherAlg]));
239
240 return TRUE;
241}
242
243
244/*
245 ==========================================================================
246 Description:
247 Set WPA PSK key
248
249 Arguments:
250 pAdapter Pointer to our adapter
251 keyString WPA pre-shared key string
252 pHashStr String used for password hash function
253 hashStrLen Lenght of the hash string
254 pPMKBuf Output buffer of WPAPSK key
255
256 Return:
257 TRUE if all parameters are OK, FALSE otherwise
258 ==========================================================================
259*/
260INT RT_CfgSetWPAPSKKey(
261 IN RTMP_ADAPTER *pAd,
262 IN PSTRING keyString,
263 IN UCHAR *pHashStr,
264 IN INT hashStrLen,
265 OUT PUCHAR pPMKBuf)
266{
267 int keyLen;
268 UCHAR keyMaterial[40];
269
270 keyLen = strlen(keyString);
271 if ((keyLen < 8) || (keyLen > 64))
272 {
273 DBGPRINT(RT_DEBUG_TRACE, ("WPAPSK Key length(%d) error, required 8 ~ 64 characters!(keyStr=%s)\n",
274 keyLen, keyString));
275 return FALSE;
276 }
277
278 memset(pPMKBuf, 0, 32);
279 if (keyLen == 64)
280 {
281 AtoH(keyString, pPMKBuf, 32);
282 }
283 else
284 {
285 PasswordHash(keyString, pHashStr, hashStrLen, keyMaterial);
286 NdisMoveMemory(pPMKBuf, keyMaterial, 32);
287 }
288
289 return TRUE;
290}
diff --git a/drivers/staging/rt2860/common/cmm_data.c b/drivers/staging/rt2860/common/cmm_data.c
index 774fabb0be4..36969134696 100644
--- a/drivers/staging/rt2860/common/cmm_data.c
+++ b/drivers/staging/rt2860/common/cmm_data.c
@@ -25,9 +25,8 @@
25 ************************************************************************* 25 *************************************************************************
26*/ 26*/
27 27
28#include "../rt_config.h"
29 28
30#define MAX_TX_IN_TBTT (16) 29#include "../rt_config.h"
31 30
32 31
33UCHAR SNAP_802_1H[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00}; 32UCHAR SNAP_802_1H[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
@@ -67,6 +66,7 @@ UCHAR RxwiMCSToOfdmRate[12] = {
67char* MCSToMbps[] = {"1Mbps","2Mbps","5.5Mbps","11Mbps","06Mbps","09Mbps","12Mbps","18Mbps","24Mbps","36Mbps","48Mbps","54Mbps","MM-0","MM-1","MM-2","MM-3","MM-4","MM-5","MM-6","MM-7","MM-8","MM-9","MM-10","MM-11","MM-12","MM-13","MM-14","MM-15","MM-32","ee1","ee2","ee3"}; 66char* MCSToMbps[] = {"1Mbps","2Mbps","5.5Mbps","11Mbps","06Mbps","09Mbps","12Mbps","18Mbps","24Mbps","36Mbps","48Mbps","54Mbps","MM-0","MM-1","MM-2","MM-3","MM-4","MM-5","MM-6","MM-7","MM-8","MM-9","MM-10","MM-11","MM-12","MM-13","MM-14","MM-15","MM-32","ee1","ee2","ee3"};
68 67
69UCHAR default_cwmin[]={CW_MIN_IN_BITS, CW_MIN_IN_BITS, CW_MIN_IN_BITS-1, CW_MIN_IN_BITS-2}; 68UCHAR default_cwmin[]={CW_MIN_IN_BITS, CW_MIN_IN_BITS, CW_MIN_IN_BITS-1, CW_MIN_IN_BITS-2};
69//UCHAR default_cwmax[]={CW_MAX_IN_BITS, CW_MAX_IN_BITS, CW_MIN_IN_BITS, CW_MIN_IN_BITS-1};
70UCHAR default_sta_aifsn[]={3,7,2,2}; 70UCHAR default_sta_aifsn[]={3,7,2,2};
71 71
72UCHAR MapUserPriorityToAccessCategory[8] = {QID_AC_BE, QID_AC_BK, QID_AC_BK, QID_AC_BE, QID_AC_VI, QID_AC_VI, QID_AC_VO, QID_AC_VO}; 72UCHAR MapUserPriorityToAccessCategory[8] = {QID_AC_BE, QID_AC_BK, QID_AC_BK, QID_AC_BE, QID_AC_VI, QID_AC_VI, QID_AC_VO, QID_AC_VO};
@@ -105,28 +105,38 @@ NDIS_STATUS MiniportMMRequest(
105 PNDIS_PACKET pPacket; 105 PNDIS_PACKET pPacket;
106 NDIS_STATUS Status = NDIS_STATUS_SUCCESS; 106 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
107 ULONG FreeNum; 107 ULONG FreeNum;
108#ifdef RT2860 108 UCHAR rtmpHwHdr[TXINFO_SIZE + TXWI_SIZE]; //RTMP_HW_HDR_LEN];
109#ifdef RTMP_MAC_PCI
109 unsigned long IrqFlags = 0; 110 unsigned long IrqFlags = 0;
110#endif
111 UCHAR IrqState; 111 UCHAR IrqState;
112 UCHAR rtmpHwHdr[TXINFO_SIZE + TXWI_SIZE]; //RTMP_HW_HDR_LEN]; 112#endif // RTMP_MAC_PCI //
113 BOOLEAN bUseDataQ = FALSE;
114 int retryCnt = 0;
113 115
114 ASSERT(Length <= MGMT_DMA_BUFFER_SIZE); 116 ASSERT(Length <= MGMT_DMA_BUFFER_SIZE);
115 117
116 QueIdx=3; 118 if ((QueIdx & MGMT_USE_QUEUE_FLAG) == MGMT_USE_QUEUE_FLAG)
119 {
120 bUseDataQ = TRUE;
121 QueIdx &= (~MGMT_USE_QUEUE_FLAG);
122 }
117 123
124#ifdef RTMP_MAC_PCI
118 // 2860C use Tx Ring 125 // 2860C use Tx Ring
119
120 IrqState = pAd->irq_disabled; 126 IrqState = pAd->irq_disabled;
121 127 if (pAd->MACVersion == 0x28600100)
122#ifdef RT2860 128 {
123 if ((pAd->MACVersion == 0x28600100) && (!IrqState)) 129 QueIdx = (bUseDataQ ==TRUE ? QueIdx : 3);
130 bUseDataQ = TRUE;
131 }
132 if (bUseDataQ && (!IrqState))
124 RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags); 133 RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
125#endif 134#endif // RTMP_MAC_PCI //
135
126 do 136 do
127 { 137 {
128 // Reset is in progress, stop immediately 138 // Reset is in progress, stop immediately
129 if ( RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) || 139 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
130 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)|| 140 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)||
131 !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP)) 141 !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP))
132 { 142 {
@@ -136,13 +146,16 @@ NDIS_STATUS MiniportMMRequest(
136 146
137 // Check Free priority queue 147 // Check Free priority queue
138 // Since we use PBF Queue2 for management frame. Its corresponding DMA ring should be using TxRing. 148 // Since we use PBF Queue2 for management frame. Its corresponding DMA ring should be using TxRing.
139 149#ifdef RTMP_MAC_PCI
140 // 2860C use Tx Ring 150 if (bUseDataQ)
141 if (pAd->MACVersion == 0x28600100)
142 { 151 {
152 retryCnt = MAX_DATAMM_RETRY;
153 // free Tx(QueIdx) resources
154 RTMPFreeTXDUponTxDmaDone(pAd, QueIdx);
143 FreeNum = GET_TXRING_FREENO(pAd, QueIdx); 155 FreeNum = GET_TXRING_FREENO(pAd, QueIdx);
144 } 156 }
145 else 157 else
158#endif // RTMP_MAC_PCI //
146 { 159 {
147 FreeNum = GET_MGMTRING_FREENO(pAd); 160 FreeNum = GET_MGMTRING_FREENO(pAd);
148 } 161 }
@@ -162,96 +175,51 @@ NDIS_STATUS MiniportMMRequest(
162 //pAd->CommonCfg.MlmeRate = RATE_2; 175 //pAd->CommonCfg.MlmeRate = RATE_2;
163 176
164 177
178#ifdef RTMP_MAC_PCI
179 if (bUseDataQ)
180 {
181 Status = MlmeDataHardTransmit(pAd, QueIdx, pPacket);
182 retryCnt--;
183 }
184 else
185#endif // RTMP_MAC_PCI //
165 Status = MlmeHardTransmit(pAd, QueIdx, pPacket); 186 Status = MlmeHardTransmit(pAd, QueIdx, pPacket);
166 if (Status != NDIS_STATUS_SUCCESS) 187 if (Status == NDIS_STATUS_SUCCESS)
188 retryCnt = 0;
189 else
167 RTMPFreeNdisPacket(pAd, pPacket); 190 RTMPFreeNdisPacket(pAd, pPacket);
168 } 191 }
169 else 192 else
170 { 193 {
171 pAd->RalinkCounters.MgmtRingFullCount++; 194 pAd->RalinkCounters.MgmtRingFullCount++;
195#ifdef RTMP_MAC_PCI
196 if (bUseDataQ)
197 {
198 retryCnt--;
199 DBGPRINT(RT_DEBUG_TRACE, ("retryCnt %d\n", retryCnt));
200 if (retryCnt == 0)
201 {
202 DBGPRINT(RT_DEBUG_ERROR, ("Qidx(%d), not enough space in DataRing, MgmtRingFullCount=%ld!\n",
203 QueIdx, pAd->RalinkCounters.MgmtRingFullCount));
204 }
205 }
206#endif // RTMP_MAC_PCI //
172 DBGPRINT(RT_DEBUG_ERROR, ("Qidx(%d), not enough space in MgmtRing, MgmtRingFullCount=%ld!\n", 207 DBGPRINT(RT_DEBUG_ERROR, ("Qidx(%d), not enough space in MgmtRing, MgmtRingFullCount=%ld!\n",
173 QueIdx, pAd->RalinkCounters.MgmtRingFullCount)); 208 QueIdx, pAd->RalinkCounters.MgmtRingFullCount));
174 } 209 }
210 } while (retryCnt > 0);
175 211
176 } while (FALSE);
177 212
178#ifdef RT2860 213#ifdef RTMP_MAC_PCI
179 // 2860C use Tx Ring 214 if (bUseDataQ && (!IrqState))
180 if ((pAd->MACVersion == 0x28600100) && (!IrqState))
181 RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags); 215 RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
182#endif 216#endif // RTMP_MAC_PCI //
217
183 return Status; 218 return Status;
184} 219}
185 220
186#ifdef RT2860
187NDIS_STATUS MiniportMMRequestUnlock(
188 IN PRTMP_ADAPTER pAd,
189 IN UCHAR QueIdx,
190 IN PUCHAR pData,
191 IN UINT Length)
192{
193 PNDIS_PACKET pPacket;
194 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
195 ULONG FreeNum;
196 TXWI_STRUC TXWI;
197 ULONG SW_TX_IDX;
198 PTXD_STRUC pTxD;
199
200 QueIdx = 3;
201 ASSERT(Length <= MGMT_DMA_BUFFER_SIZE);
202
203 do
204 {
205 // Reset is in progress, stop immediately
206 if ( RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
207 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)||
208 !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP))
209 {
210 Status = NDIS_STATUS_FAILURE;
211 break;
212 }
213
214 // Check Free priority queue
215 // Since we use PBF Queue2 for management frame. Its corresponding DMA ring should be using TxRing.
216 // 2860C use Tx Ring
217 if (pAd->MACVersion == 0x28600100)
218 {
219 FreeNum = GET_TXRING_FREENO(pAd, QueIdx);
220 SW_TX_IDX = pAd->TxRing[QueIdx].TxCpuIdx;
221 pTxD = (PTXD_STRUC) pAd->TxRing[QueIdx].Cell[SW_TX_IDX].AllocVa;
222 }
223 else
224 {
225 FreeNum = GET_MGMTRING_FREENO(pAd);
226 SW_TX_IDX = pAd->MgmtRing.TxCpuIdx;
227 pTxD = (PTXD_STRUC) pAd->MgmtRing.Cell[SW_TX_IDX].AllocVa;
228 }
229 if ((FreeNum > 0))
230 {
231 NdisZeroMemory(&TXWI, TXWI_SIZE);
232 Status = RTMPAllocateNdisPacket(pAd, &pPacket, (PUCHAR)&TXWI, TXWI_SIZE, pData, Length);
233 if (Status != NDIS_STATUS_SUCCESS)
234 {
235 DBGPRINT(RT_DEBUG_WARN, ("MiniportMMRequest (error:: can't allocate NDIS PACKET)\n"));
236 break;
237 }
238
239 Status = MlmeHardTransmit(pAd, QueIdx, pPacket);
240 if (Status != NDIS_STATUS_SUCCESS)
241 RTMPFreeNdisPacket(pAd, pPacket);
242 }
243 else
244 {
245 pAd->RalinkCounters.MgmtRingFullCount++;
246 DBGPRINT(RT_DEBUG_ERROR, ("Qidx(%d), not enough space in MgmtRing\n", QueIdx));
247 }
248
249 } while (FALSE);
250 221
251 222
252 return Status;
253}
254#endif
255 223
256/* 224/*
257 ======================================================================== 225 ========================================================================
@@ -282,203 +250,33 @@ NDIS_STATUS MlmeHardTransmit(
282 IN UCHAR QueIdx, 250 IN UCHAR QueIdx,
283 IN PNDIS_PACKET pPacket) 251 IN PNDIS_PACKET pPacket)
284{ 252{
285 if (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)
286 {
287 return NDIS_STATUS_FAILURE;
288 }
289
290#ifdef RT2860
291 if ( pAd->MACVersion == 0x28600100 )
292 return MlmeHardTransmitTxRing(pAd,QueIdx,pPacket);
293 else
294#endif
295 return MlmeHardTransmitMgmtRing(pAd,QueIdx,pPacket);
296
297}
298
299#ifdef RT2860
300NDIS_STATUS MlmeHardTransmitTxRing(
301 IN PRTMP_ADAPTER pAd,
302 IN UCHAR QueIdx,
303 IN PNDIS_PACKET pPacket)
304{
305 PACKET_INFO PacketInfo; 253 PACKET_INFO PacketInfo;
306 PUCHAR pSrcBufVA; 254 PUCHAR pSrcBufVA;
307 UINT SrcBufLen; 255 UINT SrcBufLen;
308 PTXD_STRUC pTxD;
309 PHEADER_802_11 pHeader_802_11; 256 PHEADER_802_11 pHeader_802_11;
310 BOOLEAN bAckRequired, bInsertTimestamp;
311 ULONG SrcBufPA;
312 UCHAR MlmeRate;
313 ULONG SwIdx = pAd->TxRing[QueIdx].TxCpuIdx;
314 PTXWI_STRUC pFirstTxWI;
315 ULONG FreeNum;
316 MAC_TABLE_ENTRY *pMacEntry = NULL;
317
318 257
319 RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen); 258 if ((pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)
320 259 )
321 if (pSrcBufVA == NULL)
322 {
323 // The buffer shouldn't be NULL
324 return NDIS_STATUS_FAILURE;
325 }
326
327 // Make sure MGMT ring resource won't be used by other threads
328 //NdisAcquireSpinLock(&pAd->TxRingLock);
329
330 FreeNum = GET_TXRING_FREENO(pAd, QueIdx);
331
332 if (FreeNum == 0)
333 { 260 {
334 //NdisReleaseSpinLock(&pAd->TxRingLock);
335 return NDIS_STATUS_FAILURE; 261 return NDIS_STATUS_FAILURE;
336 } 262 }
337 263
338 SwIdx = pAd->TxRing[QueIdx].TxCpuIdx; 264 RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
339 265 if (pSrcBufVA == NULL)
340 pTxD = (PTXD_STRUC) pAd->TxRing[QueIdx].Cell[SwIdx].AllocVa;
341
342 if (pAd->TxRing[QueIdx].Cell[SwIdx].pNdisPacket)
343 {
344 printk("MlmeHardTransmit Error\n");
345 return NDIS_STATUS_FAILURE; 266 return NDIS_STATUS_FAILURE;
346 }
347 267
348 // outgoing frame always wakeup PHY to prevent frame lost 268 pHeader_802_11 = (PHEADER_802_11) (pSrcBufVA + TXINFO_SIZE + TXWI_SIZE);
349 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
350 AsicForceWakeup(pAd, FROM_TX);
351 269
352 pFirstTxWI =(PTXWI_STRUC)pSrcBufVA;
353 270
354 pHeader_802_11 = (PHEADER_802_11) (pSrcBufVA + TXWI_SIZE); 271#ifdef RTMP_MAC_PCI
355 if (pHeader_802_11->Addr1[0] & 0x01) 272 if ( pAd->MACVersion == 0x28600100 )
356 { 273 return MlmeHardTransmitTxRing(pAd,QueIdx,pPacket);
357 MlmeRate = pAd->CommonCfg.BasicMlmeRate;
358 }
359 else
360 {
361 MlmeRate = pAd->CommonCfg.MlmeRate;
362 }
363
364 if ((pHeader_802_11->FC.Type == BTYPE_DATA) &&
365 (pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL))
366 {
367 pMacEntry = MacTableLookup(pAd, pHeader_802_11->Addr1);
368 }
369
370 // Verify Mlme rate for a / g bands.
371 if ((pAd->LatchRfRegs.Channel > 14) && (MlmeRate < RATE_6)) // 11A band
372 MlmeRate = RATE_6;
373
374 //
375 // Should not be hard code to set PwrMgmt to 0 (PWR_ACTIVE)
376 // Snice it's been set to 0 while on MgtMacHeaderInit
377 // By the way this will cause frame to be send on PWR_SAVE failed.
378 //
379 //
380 // In WMM-UAPSD, mlme frame should be set psm as power saving but probe request frame
381
382 // Data-Null packets alse pass through MMRequest in RT2860, however, we hope control the psm bit to pass APSD
383 if (pHeader_802_11->FC.Type != BTYPE_DATA)
384 {
385 if ((pHeader_802_11->FC.SubType == SUBTYPE_PROBE_REQ) || !(pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable))
386 {
387 pHeader_802_11->FC.PwrMgmt = PWR_ACTIVE;
388 }
389 else
390 {
391 pHeader_802_11->FC.PwrMgmt = pAd->CommonCfg.bAPSDForcePowerSave;
392 }
393 }
394
395 bInsertTimestamp = FALSE;
396 if (pHeader_802_11->FC.Type == BTYPE_CNTL) // must be PS-POLL
397 {
398 bAckRequired = FALSE;
399 }
400 else // BTYPE_MGMT or BTYPE_DATA(must be NULL frame)
401 {
402 if (pHeader_802_11->Addr1[0] & 0x01) // MULTICAST, BROADCAST
403 {
404 bAckRequired = FALSE;
405 pHeader_802_11->Duration = 0;
406 }
407 else
408 {
409 bAckRequired = TRUE;
410 pHeader_802_11->Duration = RTMPCalcDuration(pAd, MlmeRate, 14);
411 if (pHeader_802_11->FC.SubType == SUBTYPE_PROBE_RSP)
412 {
413 bInsertTimestamp = TRUE;
414 }
415 }
416 }
417 pHeader_802_11->Sequence = pAd->Sequence++;
418 if (pAd->Sequence > 0xfff)
419 pAd->Sequence = 0;
420 // Before radar detection done, mgmt frame can not be sent but probe req
421 // Because we need to use probe req to trigger driver to send probe req in passive scan
422 if ((pHeader_802_11->FC.SubType != SUBTYPE_PROBE_REQ)
423 && (pAd->CommonCfg.bIEEE80211H == 1)
424 && (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE))
425 {
426 DBGPRINT(RT_DEBUG_ERROR,("MlmeHardTransmit --> radar detect not in normal mode !!!\n"));
427 return (NDIS_STATUS_FAILURE);
428 }
429
430 //
431 // fill scatter-and-gather buffer list into TXD. Internally created NDIS PACKET
432 // should always has only one ohysical buffer, and the whole frame size equals
433 // to the first scatter buffer size
434 //
435
436 // Initialize TX Descriptor
437 // For inter-frame gap, the number is for this frame and next frame
438 // For MLME rate, we will fix as 2Mb to match other vendor's implement
439
440// management frame doesn't need encryption. so use RESERVED_WCID no matter u are sending to specific wcid or not.
441 // Only beacon use Nseq=TRUE. So here we use Nseq=FALSE.
442 if (pMacEntry == NULL)
443 {
444 RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, bInsertTimestamp, FALSE, bAckRequired, FALSE,
445 0, RESERVED_WCID, (SrcBufLen - TXWI_SIZE), PID_MGMT, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
446 }
447 else 274 else
448 { 275#endif // RTMP_MAC_PCI //
449 RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, 276 return MlmeHardTransmitMgmtRing(pAd,QueIdx,pPacket);
450 bInsertTimestamp, FALSE, bAckRequired, FALSE,
451 0, pMacEntry->Aid, (SrcBufLen - TXWI_SIZE),
452 pMacEntry->MaxHTPhyMode.field.MCS, 0,
453 (UCHAR)pMacEntry->MaxHTPhyMode.field.MCS,
454 IFS_BACKOFF, FALSE, &pMacEntry->MaxHTPhyMode);
455 }
456
457 pAd->TxRing[QueIdx].Cell[SwIdx].pNdisPacket = pPacket;
458 pAd->TxRing[QueIdx].Cell[SwIdx].pNextNdisPacket = NULL;
459
460 SrcBufPA = PCI_MAP_SINGLE(pAd, pSrcBufVA, SrcBufLen, 0, PCI_DMA_TODEVICE);
461
462
463 RTMPWriteTxDescriptor(pAd, pTxD, TRUE, FIFO_EDCA);
464 pTxD->LastSec0 = 1;
465 pTxD->LastSec1 = 1;
466 pTxD->SDLen0 = SrcBufLen;
467 pTxD->SDLen1 = 0;
468 pTxD->SDPtr0 = SrcBufPA;
469 pTxD->DMADONE = 0;
470
471 pAd->RalinkCounters.KickTxCount++;
472 pAd->RalinkCounters.OneSecTxDoneCount++;
473
474 // Increase TX_CTX_IDX, but write to register later.
475 INC_RING_INDEX(pAd->TxRing[QueIdx].TxCpuIdx, TX_RING_SIZE);
476
477 RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + QueIdx*0x10, pAd->TxRing[QueIdx].TxCpuIdx);
478 277
479 return NDIS_STATUS_SUCCESS;
480} 278}
481#endif /* RT2860 */ 279
482 280
483NDIS_STATUS MlmeHardTransmitMgmtRing( 281NDIS_STATUS MlmeHardTransmitMgmtRing(
484 IN PRTMP_ADAPTER pAd, 282 IN PRTMP_ADAPTER pAd,
@@ -493,25 +291,24 @@ NDIS_STATUS MlmeHardTransmitMgmtRing(
493 UCHAR MlmeRate; 291 UCHAR MlmeRate;
494 PTXWI_STRUC pFirstTxWI; 292 PTXWI_STRUC pFirstTxWI;
495 MAC_TABLE_ENTRY *pMacEntry = NULL; 293 MAC_TABLE_ENTRY *pMacEntry = NULL;
294 UCHAR PID;
496 295
497 RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen); 296 RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
498 RTMP_SEM_LOCK(&pAd->MgmtRingLock);
499
500 297
298 // Make sure MGMT ring resource won't be used by other threads
299 RTMP_SEM_LOCK(&pAd->MgmtRingLock);
501 if (pSrcBufVA == NULL) 300 if (pSrcBufVA == NULL)
502 { 301 {
302 // The buffer shouldn't be NULL
503 RTMP_SEM_UNLOCK(&pAd->MgmtRingLock); 303 RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);
504 return NDIS_STATUS_FAILURE; 304 return NDIS_STATUS_FAILURE;
505 } 305 }
506 306
307 {
507 // outgoing frame always wakeup PHY to prevent frame lost 308 // outgoing frame always wakeup PHY to prevent frame lost
508 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) 309 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
509#ifdef RT2860
510 AsicForceWakeup(pAd, FROM_TX);
511#endif
512#ifdef RT2870
513 AsicForceWakeup(pAd, TRUE); 310 AsicForceWakeup(pAd, TRUE);
514#endif 311 }
515 312
516 pFirstTxWI = (PTXWI_STRUC)(pSrcBufVA + TXINFO_SIZE); 313 pFirstTxWI = (PTXWI_STRUC)(pSrcBufVA + TXINFO_SIZE);
517 pHeader_802_11 = (PHEADER_802_11) (pSrcBufVA + TXINFO_SIZE + TXWI_SIZE); //TXWI_SIZE); 314 pHeader_802_11 = (PHEADER_802_11) (pSrcBufVA + TXINFO_SIZE + TXWI_SIZE); //TXWI_SIZE);
@@ -553,19 +350,28 @@ NDIS_STATUS MlmeHardTransmitMgmtRing(
553 // Snice it's been set to 0 while on MgtMacHeaderInit 350 // Snice it's been set to 0 while on MgtMacHeaderInit
554 // By the way this will cause frame to be send on PWR_SAVE failed. 351 // By the way this will cause frame to be send on PWR_SAVE failed.
555 // 352 //
556 // pHeader_802_11->FC.PwrMgmt = 0; // (pAd->StaCfg.Psm == PWR_SAVE); 353 pHeader_802_11->FC.PwrMgmt = PWR_ACTIVE; // (pAd->StaCfg.Psm == PWR_SAVE);
354
557 // 355 //
558 // In WMM-UAPSD, mlme frame should be set psm as power saving but probe request frame 356 // In WMM-UAPSD, mlme frame should be set psm as power saving but probe request frame
559
560 // Data-Null packets alse pass through MMRequest in RT2860, however, we hope control the psm bit to pass APSD 357 // Data-Null packets alse pass through MMRequest in RT2860, however, we hope control the psm bit to pass APSD
561 if ((pHeader_802_11->FC.Type != BTYPE_DATA) && (pHeader_802_11->FC.Type != BTYPE_CNTL)) 358// if ((pHeader_802_11->FC.Type != BTYPE_DATA) && (pHeader_802_11->FC.Type != BTYPE_CNTL))
562 { 359 {
563 if ((pAd->StaCfg.Psm == PWR_SAVE) && 360 if ((pHeader_802_11->FC.SubType == SUBTYPE_ACTION) ||
564 (pHeader_802_11->FC.SubType == SUBTYPE_ACTION)) 361 ((pHeader_802_11->FC.Type == BTYPE_DATA) &&
362 ((pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL) ||
363 (pHeader_802_11->FC.SubType == SUBTYPE_NULL_FUNC))))
364 {
365 if (pAd->StaCfg.Psm == PWR_SAVE)
565 pHeader_802_11->FC.PwrMgmt = PWR_SAVE; 366 pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
566 else 367 else
567 pHeader_802_11->FC.PwrMgmt = PWR_ACTIVE; 368 pHeader_802_11->FC.PwrMgmt = pAd->CommonCfg.bAPSDForcePowerSave;
568 } 369 }
370 }
371
372
373
374
569 375
570 bInsertTimestamp = FALSE; 376 bInsertTimestamp = FALSE;
571 if (pHeader_802_11->FC.Type == BTYPE_CNTL) // must be PS-POLL 377 if (pHeader_802_11->FC.Type == BTYPE_CNTL) // must be PS-POLL
@@ -579,6 +385,9 @@ NDIS_STATUS MlmeHardTransmitMgmtRing(
579 } 385 }
580 else // BTYPE_MGMT or BTYPE_DATA(must be NULL frame) 386 else // BTYPE_MGMT or BTYPE_DATA(must be NULL frame)
581 { 387 {
388 //pAd->Sequence++;
389 //pHeader_802_11->Sequence = pAd->Sequence;
390
582 if (pHeader_802_11->Addr1[0] & 0x01) // MULTICAST, BROADCAST 391 if (pHeader_802_11->Addr1[0] & 0x01) // MULTICAST, BROADCAST
583 { 392 {
584 bAckRequired = FALSE; 393 bAckRequired = FALSE;
@@ -588,9 +397,14 @@ NDIS_STATUS MlmeHardTransmitMgmtRing(
588 { 397 {
589 bAckRequired = TRUE; 398 bAckRequired = TRUE;
590 pHeader_802_11->Duration = RTMPCalcDuration(pAd, MlmeRate, 14); 399 pHeader_802_11->Duration = RTMPCalcDuration(pAd, MlmeRate, 14);
591 if (pHeader_802_11->FC.SubType == SUBTYPE_PROBE_RSP) 400 if ((pHeader_802_11->FC.SubType == SUBTYPE_PROBE_RSP) && (pHeader_802_11->FC.Type == BTYPE_MGMT))
592 { 401 {
593 bInsertTimestamp = TRUE; 402 bInsertTimestamp = TRUE;
403 bAckRequired = FALSE; // Disable ACK to prevent retry 0x1f for Probe Response
404 }
405 else if ((pHeader_802_11->FC.SubType == SUBTYPE_PROBE_REQ) && (pHeader_802_11->FC.Type == BTYPE_MGMT))
406 {
407 bAckRequired = FALSE; // Disable ACK to prevent retry 0x1f for Probe Request
594 } 408 }
595 } 409 }
596 } 410 }
@@ -606,28 +420,35 @@ NDIS_STATUS MlmeHardTransmitMgmtRing(
606 && (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)) 420 && (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE))
607 { 421 {
608 DBGPRINT(RT_DEBUG_ERROR,("MlmeHardTransmit --> radar detect not in normal mode !!!\n")); 422 DBGPRINT(RT_DEBUG_ERROR,("MlmeHardTransmit --> radar detect not in normal mode !!!\n"));
423// if (!IrqState)
609 RTMP_SEM_UNLOCK(&pAd->MgmtRingLock); 424 RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);
610 return (NDIS_STATUS_FAILURE); 425 return (NDIS_STATUS_FAILURE);
611 } 426 }
612 427
428
613 // 429 //
614 // fill scatter-and-gather buffer list into TXD. Internally created NDIS PACKET 430 // fill scatter-and-gather buffer list into TXD. Internally created NDIS PACKET
615 // should always has only one ohysical buffer, and the whole frame size equals 431 // should always has only one physical buffer, and the whole frame size equals
616 // to the first scatter buffer size 432 // to the first scatter buffer size
617 // 433 //
618 434
619 // Initialize TX Descriptor 435 // Initialize TX Descriptor
620 // For inter-frame gap, the number is for this frame and next frame 436 // For inter-frame gap, the number is for this frame and next frame
621 // For MLME rate, we will fix as 2Mb to match other vendor's implement 437 // For MLME rate, we will fix as 2Mb to match other vendor's implement
438// pAd->CommonCfg.MlmeTransmit.field.MODE = 1;
622 439
623// management frame doesn't need encryption. so use RESERVED_WCID no matter u are sending to specific wcid or not. 440// management frame doesn't need encryption. so use RESERVED_WCID no matter u are sending to specific wcid or not.
441 PID = PID_MGMT;
442
443
624 if (pMacEntry == NULL) 444 if (pMacEntry == NULL)
625 { 445 {
626 RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, bInsertTimestamp, FALSE, bAckRequired, FALSE, 446 RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, bInsertTimestamp, FALSE, bAckRequired, FALSE,
627 0, RESERVED_WCID, (SrcBufLen - TXINFO_SIZE - TXWI_SIZE), PID_MGMT, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit); 447 0, RESERVED_WCID, (SrcBufLen - TXINFO_SIZE - TXWI_SIZE), PID, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
628 } 448 }
629 else 449 else
630 { 450 {
451 /* dont use low rate to send QoS Null data frame */
631 RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, 452 RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE,
632 bInsertTimestamp, FALSE, bAckRequired, FALSE, 453 bInsertTimestamp, FALSE, bAckRequired, FALSE,
633 0, pMacEntry->Aid, (SrcBufLen - TXINFO_SIZE - TXWI_SIZE), 454 0, pMacEntry->Aid, (SrcBufLen - TXINFO_SIZE - TXWI_SIZE),
@@ -640,6 +461,7 @@ NDIS_STATUS MlmeHardTransmitMgmtRing(
640 HAL_KickOutMgmtTx(pAd, QueIdx, pPacket, pSrcBufVA, SrcBufLen); 461 HAL_KickOutMgmtTx(pAd, QueIdx, pPacket, pSrcBufVA, SrcBufLen);
641 462
642 // Make sure to release MGMT ring resource 463 // Make sure to release MGMT ring resource
464// if (!IrqState)
643 RTMP_SEM_UNLOCK(&pAd->MgmtRingLock); 465 RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);
644 return NDIS_STATUS_SUCCESS; 466 return NDIS_STATUS_SUCCESS;
645} 467}
@@ -737,10 +559,6 @@ static UCHAR TxPktClassification(
737 bHTRate = TRUE; 559 bHTRate = TRUE;
738 if (RTMP_GET_PACKET_MOREDATA(pPacket) || (pMacEntry->PsMode == PWR_SAVE)) 560 if (RTMP_GET_PACKET_MOREDATA(pPacket) || (pMacEntry->PsMode == PWR_SAVE))
739 TxFrameType = TX_LEGACY_FRAME; 561 TxFrameType = TX_LEGACY_FRAME;
740#ifdef UAPSD_AP_SUPPORT
741 else if (RTMP_GET_PACKET_EOSP(pPacket))
742 TxFrameType = TX_LEGACY_FRAME;
743#endif // UAPSD_AP_SUPPORT //
744 else if((pMacEntry->TXBAbitmap & (1<<(RTMP_GET_PACKET_UP(pPacket)))) != 0) 562 else if((pMacEntry->TXBAbitmap & (1<<(RTMP_GET_PACKET_UP(pPacket)))) != 0)
745 return TX_AMPDU_FRAME; 563 return TX_AMPDU_FRAME;
746 else if(CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_AMSDU_INUSED)) 564 else if(CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_AMSDU_INUSED))
@@ -799,12 +617,6 @@ BOOLEAN RTMP_FillTxBlkInfo(
799 { 617 {
800 pTxBlk->pMacEntry = NULL; 618 pTxBlk->pMacEntry = NULL;
801 { 619 {
802#ifdef MCAST_RATE_SPECIFIC
803 PUCHAR pDA = GET_OS_PKT_DATAPTR(pPacket);
804 if (((*pDA & 0x01) == 0x01) && (*pDA != 0xff))
805 pTxBlk->pTransmit = &pAd->CommonCfg.MCastPhyMode;
806 else
807#endif // MCAST_RATE_SPECIFIC //
808 pTxBlk->pTransmit = &pAd->MacTab.Content[MCAST_WCID].HTPhyMode; 620 pTxBlk->pTransmit = &pAd->MacTab.Content[MCAST_WCID].HTPhyMode;
809 } 621 }
810 622
@@ -832,16 +644,25 @@ BOOLEAN RTMP_FillTxBlkInfo(
832 else 644 else
833 TX_BLK_SET_FLAG(pTxBlk, fTX_bAckRequired); 645 TX_BLK_SET_FLAG(pTxBlk, fTX_bAckRequired);
834 646
647 if ((pAd->OpMode == OPMODE_STA) &&
648 (ADHOC_ON(pAd)) &&
649 (RX_FILTER_TEST_FLAG(pAd, fRX_FILTER_ACCEPT_PROMISCUOUS)))
835 { 650 {
651 if(pAd->CommonCfg.PSPXlink)
652 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired);
653 }
654
655 {
656 {
657
836 // If support WMM, enable it. 658 // If support WMM, enable it.
837#ifdef RT2860
838 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED))
839#endif
840#ifdef RT2870
841 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && 659 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) &&
842 CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE)) 660 CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE))
843#endif
844 TX_BLK_SET_FLAG(pTxBlk, fTX_bWMM); 661 TX_BLK_SET_FLAG(pTxBlk, fTX_bWMM);
662
663// if (pAd->StaCfg.bAutoTxRateSwitch)
664// TX_BLK_SET_FLAG(pTxBlk, fTX_AutoRateSwitch);
665 }
845 } 666 }
846 667
847 if (pTxBlk->TxFrameType == TX_LEGACY_FRAME) 668 if (pTxBlk->TxFrameType == TX_LEGACY_FRAME)
@@ -871,12 +692,6 @@ BOOLEAN RTMP_FillTxBlkInfo(
871 { 692 {
872 TX_BLK_SET_FLAG(pTxBlk, fTX_bMoreData); 693 TX_BLK_SET_FLAG(pTxBlk, fTX_bMoreData);
873 } 694 }
874#ifdef UAPSD_AP_SUPPORT
875 if (RTMP_GET_PACKET_EOSP(pPacket))
876 {
877 TX_BLK_SET_FLAG(pTxBlk, fTX_bWMM_UAPSD_EOSP);
878 }
879#endif // UAPSD_AP_SUPPORT //
880 } 695 }
881 else if (pTxBlk->TxFrameType == TX_FRAG_FRAME) 696 else if (pTxBlk->TxFrameType == TX_FRAG_FRAME)
882 { 697 {
@@ -896,7 +711,7 @@ BOOLEAN CanDoAggregateTransmit(
896 IN TX_BLK *pTxBlk) 711 IN TX_BLK *pTxBlk)
897{ 712{
898 713
899 //printk("Check if can do aggregation! TxFrameType=%d!\n", pTxBlk->TxFrameType); 714 //DBGPRINT(RT_DEBUG_TRACE, ("Check if can do aggregation! TxFrameType=%d!\n", pTxBlk->TxFrameType));
900 715
901 if (RTMP_GET_PACKET_WCID(pPacket) == MCAST_WCID) 716 if (RTMP_GET_PACKET_WCID(pPacket) == MCAST_WCID)
902 return FALSE; 717 return FALSE;
@@ -922,6 +737,7 @@ BOOLEAN CanDoAggregateTransmit(
922 return TRUE; 737 return TRUE;
923 else 738 else
924 return FALSE; 739 return FALSE;
740
925} 741}
926 742
927 743
@@ -970,7 +786,6 @@ VOID RTMPDeQueuePacket(
970 if (QIdx == NUM_OF_TX_RING) 786 if (QIdx == NUM_OF_TX_RING)
971 { 787 {
972 sQIdx = 0; 788 sQIdx = 0;
973//PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
974 eQIdx = 3; // 4 ACs, start from 0. 789 eQIdx = 3; // 4 ACs, start from 0.
975 } 790 }
976 else 791 else
@@ -982,7 +797,7 @@ VOID RTMPDeQueuePacket(
982 { 797 {
983 Count=0; 798 Count=0;
984 799
985 RT28XX_START_DEQUEUE(pAd, QueIdx, IrqFlags); 800 RTMP_START_DEQUEUE(pAd, QueIdx, IrqFlags);
986 801
987 802
988 while (1) 803 while (1)
@@ -993,7 +808,7 @@ VOID RTMPDeQueuePacket(
993 fRTMP_ADAPTER_HALT_IN_PROGRESS | 808 fRTMP_ADAPTER_HALT_IN_PROGRESS |
994 fRTMP_ADAPTER_NIC_NOT_EXIST)))) 809 fRTMP_ADAPTER_NIC_NOT_EXIST))))
995 { 810 {
996 RT28XX_STOP_DEQUEUE(pAd, QueIdx, IrqFlags); 811 RTMP_STOP_DEQUEUE(pAd, QueIdx, IrqFlags);
997 return; 812 return;
998 } 813 }
999 814
@@ -1006,7 +821,8 @@ VOID RTMPDeQueuePacket(
1006 DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags); 821 DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
1007 break; 822 break;
1008 } 823 }
1009#ifdef RT2860 824
825#ifdef RTMP_MAC_PCI
1010 FreeNumber[QueIdx] = GET_TXRING_FREENO(pAd, QueIdx); 826 FreeNumber[QueIdx] = GET_TXRING_FREENO(pAd, QueIdx);
1011 827
1012 828
@@ -1016,7 +832,8 @@ VOID RTMPDeQueuePacket(
1016 RTMPFreeTXDUponTxDmaDone(pAd, QueIdx); 832 RTMPFreeTXDUponTxDmaDone(pAd, QueIdx);
1017 FreeNumber[QueIdx] = GET_TXRING_FREENO(pAd, QueIdx); 833 FreeNumber[QueIdx] = GET_TXRING_FREENO(pAd, QueIdx);
1018 } 834 }
1019#endif /* RT2860 */ 835#endif // RTMP_MAC_PCI //
836
1020 // probe the Queue Head 837 // probe the Queue Head
1021 pQueue = &pAd->TxSwQueue[QueIdx]; 838 pQueue = &pAd->TxSwQueue[QueIdx];
1022 if ((pEntry = pQueue->Head) == NULL) 839 if ((pEntry = pQueue->Head) == NULL)
@@ -1027,12 +844,14 @@ VOID RTMPDeQueuePacket(
1027 844
1028 pTxBlk = &TxBlk; 845 pTxBlk = &TxBlk;
1029 NdisZeroMemory((PUCHAR)pTxBlk, sizeof(TX_BLK)); 846 NdisZeroMemory((PUCHAR)pTxBlk, sizeof(TX_BLK));
847 //InitializeQueueHeader(&pTxBlk->TxPacketList); // Didn't need it because we already memzero it.
1030 pTxBlk->QueIdx = QueIdx; 848 pTxBlk->QueIdx = QueIdx;
1031 849
1032 pPacket = QUEUE_ENTRY_TO_PKT(pEntry); 850 pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
851
1033 852
1034 // Early check to make sure we have enoguh Tx Resource. 853 // Early check to make sure we have enoguh Tx Resource.
1035 hasTxDesc = RT28XX_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, FreeNumber[QueIdx], pPacket); 854 hasTxDesc = RTMP_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, FreeNumber[QueIdx], pPacket);
1036 if (!hasTxDesc) 855 if (!hasTxDesc)
1037 { 856 {
1038 pAd->PrivateInfo.TxRingFullCnt++; 857 pAd->PrivateInfo.TxRingFullCnt++;
@@ -1065,16 +884,16 @@ VOID RTMPDeQueuePacket(
1065 break; 884 break;
1066 885
1067 // For TX_AMSDU_FRAME/TX_RALINK_FRAME, Need to check if next pakcet can do aggregation. 886 // For TX_AMSDU_FRAME/TX_RALINK_FRAME, Need to check if next pakcet can do aggregation.
1068 pPacket = QUEUE_ENTRY_TO_PKT(pEntry); 887 pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
1069 FreeNumber[QueIdx] = GET_TXRING_FREENO(pAd, QueIdx); 888 FreeNumber[QueIdx] = GET_TXRING_FREENO(pAd, QueIdx);
1070 hasTxDesc = RT28XX_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, FreeNumber[QueIdx], pPacket); 889 hasTxDesc = RTMP_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, FreeNumber[QueIdx], pPacket);
1071 if ((hasTxDesc == FALSE) || (CanDoAggregateTransmit(pAd, pPacket, pTxBlk) == FALSE)) 890 if ((hasTxDesc == FALSE) || (CanDoAggregateTransmit(pAd, pPacket, pTxBlk) == FALSE))
1072 break; 891 break;
1073 892
1074 //Remove the packet from the TxSwQueue and insert into pTxBlk 893 //Remove the packet from the TxSwQueue and insert into pTxBlk
1075 pEntry = RemoveHeadQueue(pQueue); 894 pEntry = RemoveHeadQueue(pQueue);
1076 ASSERT(pEntry); 895 ASSERT(pEntry);
1077 pPacket = QUEUE_ENTRY_TO_PKT(pEntry); 896 pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
1078 pTxBlk->TotalFrameNum++; 897 pTxBlk->TotalFrameNum++;
1079 pTxBlk->TotalFragNum += RTMP_GET_PACKET_FRAGMENTS(pPacket); // The real fragment number maybe vary 898 pTxBlk->TotalFragNum += RTMP_GET_PACKET_FRAGMENTS(pPacket); // The real fragment number maybe vary
1080 pTxBlk->TotalFrameLen += GET_OS_PKT_LEN(pPacket); 899 pTxBlk->TotalFrameLen += GET_OS_PKT_LEN(pPacket);
@@ -1085,29 +904,29 @@ VOID RTMPDeQueuePacket(
1085 pTxBlk->TxFrameType = TX_LEGACY_FRAME; 904 pTxBlk->TxFrameType = TX_LEGACY_FRAME;
1086 } 905 }
1087 906
1088#ifdef RT2870 907#ifdef RTMP_MAC_USB
1089 DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags); 908 DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
1090#endif // RT2870 // 909#endif // RTMP_MAC_USB //
1091
1092 Count += pTxBlk->TxPacketList.Number; 910 Count += pTxBlk->TxPacketList.Number;
1093 911
1094 // Do HardTransmit now. 912 // Do HardTransmit now.
1095 Status = STAHardTransmit(pAd, pTxBlk, QueIdx); 913 Status = STAHardTransmit(pAd, pTxBlk, QueIdx);
1096 914
1097#ifdef RT2860 915#ifdef RTMP_MAC_PCI
1098 DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags); 916 DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
1099 // static rate also need NICUpdateFifoStaCounters() function. 917 // static rate also need NICUpdateFifoStaCounters() function.
1100 //if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)) 918 //if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))
1101 NICUpdateFifoStaCounters(pAd); 919 NICUpdateFifoStaCounters(pAd);
1102#endif 920#endif // RTMP_MAC_PCI //
921
1103 } 922 }
1104 923
1105 RT28XX_STOP_DEQUEUE(pAd, QueIdx, IrqFlags); 924 RTMP_STOP_DEQUEUE(pAd, QueIdx, IrqFlags);
1106 925
1107#ifdef RT2870 926#ifdef RTMP_MAC_USB
1108 if (!hasTxDesc) 927 if (!hasTxDesc)
1109 RTUSBKickBulkOut(pAd); 928 RTUSBKickBulkOut(pAd);
1110#endif // RT2870 // 929#endif // RTMP_MAC_USB //
1111 } 930 }
1112 931
1113} 932}
@@ -1243,9 +1062,16 @@ VOID RTMPWriteTxWI(
1243 pTxWI->NSEQ = NSeq; 1062 pTxWI->NSEQ = NSeq;
1244 // John tune the performace with Intel Client in 20 MHz performance 1063 // John tune the performace with Intel Client in 20 MHz performance
1245 BASize = pAd->CommonCfg.TxBASize; 1064 BASize = pAd->CommonCfg.TxBASize;
1246 1065 if (pAd->MACVersion == 0x28720200)
1066 {
1067 if( BASize >13 )
1068 BASize =13;
1069 }
1070 else
1071 {
1247 if( BASize >7 ) 1072 if( BASize >7 )
1248 BASize =7; 1073 BASize =7;
1074 }
1249 pTxWI->BAWinSize = BASize; 1075 pTxWI->BAWinSize = BASize;
1250 pTxWI->ShortGI = pTransmit->field.ShortGI; 1076 pTxWI->ShortGI = pTransmit->field.ShortGI;
1251 pTxWI->STBC = pTransmit->field.STBC; 1077 pTxWI->STBC = pTransmit->field.STBC;
@@ -1387,7 +1213,7 @@ VOID RTMPWriteTxWI_Cache(
1387 IN OUT PTXWI_STRUC pTxWI, 1213 IN OUT PTXWI_STRUC pTxWI,
1388 IN TX_BLK *pTxBlk) 1214 IN TX_BLK *pTxBlk)
1389{ 1215{
1390 PHTTRANSMIT_SETTING pTransmit; 1216 PHTTRANSMIT_SETTING /*pTxHTPhyMode,*/ pTransmit;
1391 PMAC_TABLE_ENTRY pMacEntry; 1217 PMAC_TABLE_ENTRY pMacEntry;
1392 1218
1393 // 1219 //
@@ -1396,6 +1222,9 @@ VOID RTMPWriteTxWI_Cache(
1396 pMacEntry = pTxBlk->pMacEntry; 1222 pMacEntry = pTxBlk->pMacEntry;
1397 pTransmit = pTxBlk->pTransmit; 1223 pTransmit = pTxBlk->pTransmit;
1398 1224
1225 //if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))
1226 //if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pMacEntry))
1227 //if (TX_BLK_TEST_FLAG(pTxBlk, fTX_AutoRateSwitch))
1399 if (pMacEntry->bAutoTxRateSwitch) 1228 if (pMacEntry->bAutoTxRateSwitch)
1400 { 1229 {
1401 pTxWI->txop = IFS_HTTXOP; 1230 pTxWI->txop = IFS_HTTXOP;
@@ -1440,53 +1269,6 @@ VOID RTMPWriteTxWI_Cache(
1440} 1269}
1441 1270
1442 1271
1443/*
1444 ========================================================================
1445
1446 Routine Description:
1447 Calculates the duration which is required to transmit out frames
1448 with given size and specified rate.
1449
1450 Arguments:
1451 pTxD Pointer to transmit descriptor
1452 Ack Setting for Ack requirement bit
1453 Fragment Setting for Fragment bit
1454 RetryMode Setting for retry mode
1455 Ifs Setting for IFS gap
1456 Rate Setting for transmit rate
1457 Service Setting for service
1458 Length Frame length
1459 TxPreamble Short or Long preamble when using CCK rates
1460 QueIdx - 0-3, according to 802.11e/d4.4 June/2003
1461
1462 Return Value:
1463 None
1464
1465 IRQL = PASSIVE_LEVEL
1466 IRQL = DISPATCH_LEVEL
1467
1468 ========================================================================
1469*/
1470VOID RTMPWriteTxDescriptor(
1471 IN PRTMP_ADAPTER pAd,
1472 IN PTXD_STRUC pTxD,
1473 IN BOOLEAN bWIV,
1474 IN UCHAR QueueSEL)
1475{
1476 //
1477 // Always use Long preamble before verifiation short preamble functionality works well.
1478 // Todo: remove the following line if short preamble functionality works
1479 //
1480 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
1481
1482 pTxD->WIV = (bWIV) ? 1: 0;
1483 pTxD->QSEL= (QueueSEL);
1484 if (pAd->bGenOneHCCA == TRUE)
1485 pTxD->QSEL= FIFO_HCCA;
1486 pTxD->DMADONE = 0;
1487}
1488
1489
1490// should be called only when - 1272// should be called only when -
1491// 1. MEADIA_CONNECTED 1273// 1. MEADIA_CONNECTED
1492// 2. AGGREGATION_IN_USED 1274// 2. AGGREGATION_IN_USED
@@ -1582,12 +1364,14 @@ PQUEUE_HEADER RTMPCheckTxSwQueue(
1582{ 1364{
1583 1365
1584 ULONG Number; 1366 ULONG Number;
1367 // 2004-11-15 to be removed. test aggregation only
1368// if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED)) && (*pNumber < 2))
1369// return NULL;
1585 1370
1586 Number = pAd->TxSwQueue[QID_AC_BK].Number 1371 Number = pAd->TxSwQueue[QID_AC_BK].Number
1587 + pAd->TxSwQueue[QID_AC_BE].Number 1372 + pAd->TxSwQueue[QID_AC_BE].Number
1588 + pAd->TxSwQueue[QID_AC_VI].Number 1373 + pAd->TxSwQueue[QID_AC_VI].Number
1589 + pAd->TxSwQueue[QID_AC_VO].Number 1374 + pAd->TxSwQueue[QID_AC_VO].Number;
1590 + pAd->TxSwQueue[QID_HCCA].Number;
1591 1375
1592 if (pAd->TxSwQueue[QID_AC_VO].Head != NULL) 1376 if (pAd->TxSwQueue[QID_AC_VO].Head != NULL)
1593 { 1377 {
@@ -1609,11 +1393,6 @@ PQUEUE_HEADER RTMPCheckTxSwQueue(
1609 *pQueIdx = QID_AC_BK; 1393 *pQueIdx = QID_AC_BK;
1610 return (&pAd->TxSwQueue[QID_AC_BK]); 1394 return (&pAd->TxSwQueue[QID_AC_BK]);
1611 } 1395 }
1612 else if (pAd->TxSwQueue[QID_HCCA].Head != NULL)
1613 {
1614 *pQueIdx = QID_HCCA;
1615 return (&pAd->TxSwQueue[QID_HCCA]);
1616 }
1617 1396
1618 // No packet pending in Tx Sw queue 1397 // No packet pending in Tx Sw queue
1619 *pQueIdx = QID_AC_BK; 1398 *pQueIdx = QID_AC_BK;
@@ -1621,277 +1400,6 @@ PQUEUE_HEADER RTMPCheckTxSwQueue(
1621 return (NULL); 1400 return (NULL);
1622} 1401}
1623 1402
1624#ifdef RT2860
1625BOOLEAN RTMPFreeTXDUponTxDmaDone(
1626 IN PRTMP_ADAPTER pAd,
1627 IN UCHAR QueIdx)
1628{
1629 PRTMP_TX_RING pTxRing;
1630 PTXD_STRUC pTxD;
1631 PNDIS_PACKET pPacket;
1632 UCHAR FREE = 0;
1633 TXD_STRUC TxD, *pOriTxD;
1634 //ULONG IrqFlags;
1635 BOOLEAN bReschedule = FALSE;
1636
1637
1638 ASSERT(QueIdx < NUM_OF_TX_RING);
1639 pTxRing = &pAd->TxRing[QueIdx];
1640
1641 RTMP_IO_READ32(pAd, TX_DTX_IDX0 + QueIdx * RINGREG_DIFF, &pTxRing->TxDmaIdx);
1642 while (pTxRing->TxSwFreeIdx != pTxRing->TxDmaIdx)
1643 {
1644 // static rate also need NICUpdateFifoStaCounters() function.
1645 //if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))
1646 NICUpdateFifoStaCounters(pAd);
1647
1648 /* Note : If (pAd->ate.bQATxStart == TRUE), we will never reach here. */
1649 FREE++;
1650 pTxD = (PTXD_STRUC) (pTxRing->Cell[pTxRing->TxSwFreeIdx].AllocVa);
1651 pOriTxD = pTxD;
1652 NdisMoveMemory(&TxD, pTxD, sizeof(TXD_STRUC));
1653 pTxD = &TxD;
1654
1655 pTxD->DMADONE = 0;
1656
1657/*====================================================================*/
1658 {
1659 pPacket = pTxRing->Cell[pTxRing->TxSwFreeIdx].pNdisPacket;
1660 if (pPacket)
1661 {
1662#ifdef CONFIG_5VT_ENHANCE
1663 if (RTMP_GET_PACKET_5VT(pPacket))
1664 PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, 16, PCI_DMA_TODEVICE);
1665 else
1666#endif // CONFIG_5VT_ENHANCE //
1667 PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
1668 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
1669 }
1670 //Always assign pNdisPacket as NULL after clear
1671 pTxRing->Cell[pTxRing->TxSwFreeIdx].pNdisPacket = NULL;
1672
1673 pPacket = pTxRing->Cell[pTxRing->TxSwFreeIdx].pNextNdisPacket;
1674
1675 ASSERT(pPacket == NULL);
1676 if (pPacket)
1677 {
1678#ifdef CONFIG_5VT_ENHANCE
1679 if (RTMP_GET_PACKET_5VT(pPacket))
1680 PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, 16, PCI_DMA_TODEVICE);
1681 else
1682#endif // CONFIG_5VT_ENHANCE //
1683 PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
1684 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
1685 }
1686 //Always assign pNextNdisPacket as NULL after clear
1687 pTxRing->Cell[pTxRing->TxSwFreeIdx].pNextNdisPacket = NULL;
1688 }
1689/*====================================================================*/
1690
1691 pAd->RalinkCounters.TransmittedByteCount += (pTxD->SDLen1 + pTxD->SDLen0);
1692 pAd->RalinkCounters.OneSecDmaDoneCount[QueIdx] ++;
1693 INC_RING_INDEX(pTxRing->TxSwFreeIdx, TX_RING_SIZE);
1694 /* get tx_tdx_idx again */
1695 RTMP_IO_READ32(pAd, TX_DTX_IDX0 + QueIdx * RINGREG_DIFF , &pTxRing->TxDmaIdx);
1696
1697 NdisMoveMemory(pOriTxD, pTxD, sizeof(TXD_STRUC));
1698 }
1699
1700
1701 return bReschedule;
1702
1703}
1704
1705
1706/*
1707 ========================================================================
1708
1709 Routine Description:
1710 Process TX Rings DMA Done interrupt, running in DPC level
1711
1712 Arguments:
1713 Adapter Pointer to our adapter
1714
1715 Return Value:
1716 None
1717
1718 IRQL = DISPATCH_LEVEL
1719
1720 ========================================================================
1721*/
1722BOOLEAN RTMPHandleTxRingDmaDoneInterrupt(
1723 IN PRTMP_ADAPTER pAd,
1724 IN INT_SOURCE_CSR_STRUC TxRingBitmap)
1725{
1726 unsigned long IrqFlags;
1727 BOOLEAN bReschedule = FALSE;
1728
1729 // Make sure Tx ring resource won't be used by other threads
1730
1731 RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
1732
1733 if (TxRingBitmap.field.Ac0DmaDone)
1734 bReschedule = RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_BE);
1735
1736 if (TxRingBitmap.field.HccaDmaDone)
1737 bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_HCCA);
1738
1739 if (TxRingBitmap.field.Ac3DmaDone)
1740 bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_VO);
1741
1742 if (TxRingBitmap.field.Ac2DmaDone)
1743 bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_VI);
1744
1745 if (TxRingBitmap.field.Ac1DmaDone)
1746 bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_BK);
1747
1748 // Make sure to release Tx ring resource
1749 RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
1750
1751 // Dequeue outgoing frames from TxSwQueue[] and process it
1752 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1753
1754 return bReschedule;
1755}
1756
1757
1758/*
1759 ========================================================================
1760
1761 Routine Description:
1762 Process MGMT ring DMA done interrupt, running in DPC level
1763
1764 Arguments:
1765 pAd Pointer to our adapter
1766
1767 Return Value:
1768 None
1769
1770 IRQL = DISPATCH_LEVEL
1771
1772 Note:
1773
1774 ========================================================================
1775*/
1776VOID RTMPHandleMgmtRingDmaDoneInterrupt(
1777 IN PRTMP_ADAPTER pAd)
1778{
1779 PTXD_STRUC pTxD;
1780 PNDIS_PACKET pPacket;
1781 UCHAR FREE = 0;
1782 PRTMP_MGMT_RING pMgmtRing = &pAd->MgmtRing;
1783
1784 NdisAcquireSpinLock(&pAd->MgmtRingLock);
1785
1786 RTMP_IO_READ32(pAd, TX_MGMTDTX_IDX, &pMgmtRing->TxDmaIdx);
1787 while (pMgmtRing->TxSwFreeIdx!= pMgmtRing->TxDmaIdx)
1788 {
1789 FREE++;
1790 pTxD = (PTXD_STRUC) (pMgmtRing->Cell[pAd->MgmtRing.TxSwFreeIdx].AllocVa);
1791 pTxD->DMADONE = 0;
1792 pPacket = pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNdisPacket;
1793
1794
1795 if (pPacket)
1796 {
1797 PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, PCI_DMA_TODEVICE);
1798 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
1799 }
1800 pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNdisPacket = NULL;
1801
1802 pPacket = pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNextNdisPacket;
1803 if (pPacket)
1804 {
1805 PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
1806 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
1807 }
1808 pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNextNdisPacket = NULL;
1809 INC_RING_INDEX(pMgmtRing->TxSwFreeIdx, MGMT_RING_SIZE);
1810 }
1811 NdisReleaseSpinLock(&pAd->MgmtRingLock);
1812
1813}
1814
1815
1816/*
1817 ========================================================================
1818
1819 Routine Description:
1820 Arguments:
1821 Adapter Pointer to our adapter. Dequeue all power safe delayed braodcast frames after beacon.
1822
1823 IRQL = DISPATCH_LEVEL
1824
1825 ========================================================================
1826*/
1827VOID RTMPHandleTBTTInterrupt(
1828 IN PRTMP_ADAPTER pAd)
1829{
1830 {
1831 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
1832 {
1833 }
1834 }
1835}
1836
1837
1838/*
1839 ========================================================================
1840
1841 Routine Description:
1842 Arguments:
1843 Adapter Pointer to our adapter. Rewrite beacon content before next send-out.
1844
1845 IRQL = DISPATCH_LEVEL
1846
1847 ========================================================================
1848*/
1849VOID RTMPHandlePreTBTTInterrupt(
1850 IN PRTMP_ADAPTER pAd)
1851{
1852 {
1853 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
1854 {
1855 DBGPRINT(RT_DEBUG_TRACE, ("RTMPHandlePreTBTTInterrupt...\n"));
1856 }
1857 }
1858
1859
1860}
1861
1862VOID RTMPHandleRxCoherentInterrupt(
1863 IN PRTMP_ADAPTER pAd)
1864{
1865 WPDMA_GLO_CFG_STRUC GloCfg;
1866
1867 if (pAd == NULL)
1868 {
1869 DBGPRINT(RT_DEBUG_TRACE, ("====> pAd is NULL, return.\n"));
1870 return;
1871 }
1872
1873 DBGPRINT(RT_DEBUG_TRACE, ("==> RTMPHandleRxCoherentInterrupt \n"));
1874
1875 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG , &GloCfg.word);
1876
1877 GloCfg.field.EnTXWriteBackDDONE = 0;
1878 GloCfg.field.EnableRxDMA = 0;
1879 GloCfg.field.EnableTxDMA = 0;
1880 RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
1881
1882 RTMPRingCleanUp(pAd, QID_AC_BE);
1883 RTMPRingCleanUp(pAd, QID_AC_BK);
1884 RTMPRingCleanUp(pAd, QID_AC_VI);
1885 RTMPRingCleanUp(pAd, QID_AC_VO);
1886 RTMPRingCleanUp(pAd, QID_HCCA);
1887 RTMPRingCleanUp(pAd, QID_MGMT);
1888 RTMPRingCleanUp(pAd, QID_RX);
1889
1890 RTMPEnableRxTx(pAd);
1891
1892 DBGPRINT(RT_DEBUG_TRACE, ("<== RTMPHandleRxCoherentInterrupt \n"));
1893}
1894#endif /* RT2860 */
1895 1403
1896/* 1404/*
1897 ======================================================================== 1405 ========================================================================
@@ -1922,9 +1430,11 @@ VOID RTMPSuspendMsduTransmission(
1922 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &pAd->BbpTuning.R66CurrentValue); 1430 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &pAd->BbpTuning.R66CurrentValue);
1923 1431
1924 // set BBP_R66 to 0x30/0x40 when scanning (AsicSwitchChannel will set R66 according to channel when scanning) 1432 // set BBP_R66 to 0x30/0x40 when scanning (AsicSwitchChannel will set R66 according to channel when scanning)
1433 //RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, (0x26 + GET_LNA_GAIN(pAd)));
1925 RTMPSetAGCInitValue(pAd, BW_20); 1434 RTMPSetAGCInitValue(pAd, BW_20);
1926 1435
1927 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS); 1436 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
1437 //RTMP_IO_WRITE32(pAd, TX_CNTL_CSR, 0x000f0000); // abort all TX rings
1928} 1438}
1929 1439
1930 1440
@@ -1949,8 +1459,11 @@ VOID RTMPSuspendMsduTransmission(
1949VOID RTMPResumeMsduTransmission( 1459VOID RTMPResumeMsduTransmission(
1950 IN PRTMP_ADAPTER pAd) 1460 IN PRTMP_ADAPTER pAd)
1951{ 1461{
1462// UCHAR IrqState;
1463
1952 DBGPRINT(RT_DEBUG_TRACE,("SCAN done, resume MSDU transmission ...\n")); 1464 DBGPRINT(RT_DEBUG_TRACE,("SCAN done, resume MSDU transmission ...\n"));
1953 1465
1466
1954 // After finish BSS_SCAN_IN_PROGRESS, we need to restore Current R66 value 1467 // After finish BSS_SCAN_IN_PROGRESS, we need to restore Current R66 value
1955 // R66 should not be 0 1468 // R66 should not be 0
1956 if (pAd->BbpTuning.R66CurrentValue == 0) 1469 if (pAd->BbpTuning.R66CurrentValue == 0)
@@ -1962,6 +1475,11 @@ VOID RTMPResumeMsduTransmission(
1962 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, pAd->BbpTuning.R66CurrentValue); 1475 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, pAd->BbpTuning.R66CurrentValue);
1963 1476
1964 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS); 1477 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
1478// sample, for IRQ LOCK to SEM LOCK
1479// IrqState = pAd->irq_disabled;
1480// if (IrqState)
1481// RTMPDeQueuePacket(pAd, TRUE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1482// else
1965 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS); 1483 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1966} 1484}
1967 1485
@@ -1990,7 +1508,9 @@ UINT deaggregate_AMSDU_announce(
1990 1508
1991 nMSDU++; 1509 nMSDU++;
1992 1510
1511 //hex_dump("subheader", pData, 64);
1993 pAMSDUsubheader = (PHEADER_802_3)pData; 1512 pAMSDUsubheader = (PHEADER_802_3)pData;
1513 //pData += LENGTH_802_3;
1994 PayloadSize = pAMSDUsubheader->Octet[1] + (pAMSDUsubheader->Octet[0]<<8); 1514 PayloadSize = pAMSDUsubheader->Octet[1] + (pAMSDUsubheader->Octet[0]<<8);
1995 SubFrameSize = PayloadSize + LENGTH_802_3; 1515 SubFrameSize = PayloadSize + LENGTH_802_3;
1996 1516
@@ -2000,6 +1520,8 @@ UINT deaggregate_AMSDU_announce(
2000 break; 1520 break;
2001 } 1521 }
2002 1522
1523 //DBGPRINT(RT_DEBUG_TRACE,("%d subframe: Size = %d\n", nMSDU, PayloadSize));
1524
2003 pPayload = pData + LENGTH_802_3; 1525 pPayload = pData + LENGTH_802_3;
2004 pDA = pData; 1526 pDA = pData;
2005 pSA = pData + MAC_ADDR_LEN; 1527 pSA = pData + MAC_ADDR_LEN;
@@ -2009,15 +1531,17 @@ UINT deaggregate_AMSDU_announce(
2009 1531
2010 if ((Header802_3[12] == 0x88) && (Header802_3[13] == 0x8E) ) 1532 if ((Header802_3[12] == 0x88) && (Header802_3[13] == 0x8E) )
2011 { 1533 {
2012 // avoid local heap overflow, use dyanamic allocation 1534 /* avoid local heap overflow, use dyanamic allocation */
2013 MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG); 1535 MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
2014 if (Elem == NULL) 1536 if (Elem != NULL)
2015 return; 1537 {
2016 memmove(Elem->Msg+(LENGTH_802_11 + LENGTH_802_1_H), pPayload, PayloadSize); 1538 memmove(Elem->Msg+(LENGTH_802_11 + LENGTH_802_1_H), pPayload, PayloadSize);
2017 Elem->MsgLen = LENGTH_802_11 + LENGTH_802_1_H + PayloadSize; 1539 Elem->MsgLen = LENGTH_802_11 + LENGTH_802_1_H + PayloadSize;
2018 WpaEAPOLKeyAction(pAd, Elem); 1540 //WpaEAPOLKeyAction(pAd, Elem);
1541 REPORT_MGMT_FRAME_TO_MLME(pAd, BSSID_WCID, Elem->Msg, Elem->MsgLen, 0, 0, 0, 0);
2019 kfree(Elem); 1542 kfree(Elem);
2020 } 1543 }
1544 }
2021 1545
2022 { 1546 {
2023 if (pRemovedLLCSNAP) 1547 if (pRemovedLLCSNAP)
@@ -2121,6 +1645,8 @@ MAC_TABLE_ENTRY *MacTableInsertEntry(
2121 UCHAR HashIdx; 1645 UCHAR HashIdx;
2122 int i, FirstWcid; 1646 int i, FirstWcid;
2123 MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry; 1647 MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry;
1648// USHORT offset;
1649// ULONG addr;
2124 1650
2125 // if FULL, return 1651 // if FULL, return
2126 if (pAd->MacTab.Size >= MAX_LEN_OF_MAC_TABLE) 1652 if (pAd->MacTab.Size >= MAX_LEN_OF_MAC_TABLE)
@@ -2183,22 +1709,15 @@ MAC_TABLE_ENTRY *MacTableInsertEntry(
2183 pEntry->AuthMode = pAd->StaCfg.AuthMode; 1709 pEntry->AuthMode = pAd->StaCfg.AuthMode;
2184 pEntry->WepStatus = pAd->StaCfg.WepStatus; 1710 pEntry->WepStatus = pAd->StaCfg.WepStatus;
2185 pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll; 1711 pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
2186#ifdef RT2860 1712#ifdef RTMP_MAC_PCI
2187 AsicRemovePairwiseKeyEntry(pAd, pEntry->apidx, (UCHAR)i); 1713 AsicRemovePairwiseKeyEntry(pAd, pEntry->apidx, (UCHAR)i);
2188#endif 1714#endif // RTMP_MAC_PCI //
2189 } 1715 }
2190 } 1716 }
2191 1717
2192 pEntry->GTKState = REKEY_NEGOTIATING; 1718 pEntry->GTKState = REKEY_NEGOTIATING;
2193 pEntry->PairwiseKey.KeyLen = 0; 1719 pEntry->PairwiseKey.KeyLen = 0;
2194 pEntry->PairwiseKey.CipherAlg = CIPHER_NONE; 1720 pEntry->PairwiseKey.CipherAlg = CIPHER_NONE;
2195
2196#ifdef RT2860
2197 if ((pAd->OpMode == OPMODE_STA) &&
2198 (pAd->StaCfg.BssType == BSS_ADHOC))
2199 pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
2200 else
2201#endif
2202 pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED; 1721 pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED;
2203 1722
2204 pEntry->PMKID_CacheIdx = ENTRY_NOT_FOUND; 1723 pEntry->PMKID_CacheIdx = ENTRY_NOT_FOUND;
@@ -2210,13 +1729,14 @@ MAC_TABLE_ENTRY *MacTableInsertEntry(
2210 pEntry->PsMode = PWR_ACTIVE; 1729 pEntry->PsMode = PWR_ACTIVE;
2211 pEntry->PsQIdleCount = 0; 1730 pEntry->PsQIdleCount = 0;
2212 pEntry->NoDataIdleCount = 0; 1731 pEntry->NoDataIdleCount = 0;
1732 pEntry->AssocDeadLine = MAC_TABLE_ASSOC_TIMEOUT;
2213 pEntry->ContinueTxFailCnt = 0; 1733 pEntry->ContinueTxFailCnt = 0;
2214 InitializeQueueHeader(&pEntry->PsQueue); 1734 InitializeQueueHeader(&pEntry->PsQueue);
2215 1735
2216 1736
2217 pAd->MacTab.Size ++; 1737 pAd->MacTab.Size ++;
2218 // Add this entry into ASIC RX WCID search table 1738 // Add this entry into ASIC RX WCID search table
2219 RT28XX_STA_ENTRY_ADD(pAd, pEntry); 1739 RTMP_STA_ENTRY_ADD(pAd, pEntry);
2220 1740
2221 1741
2222 1742
@@ -2260,6 +1780,8 @@ BOOLEAN MacTableDeleteEntry(
2260 USHORT HashIdx; 1780 USHORT HashIdx;
2261 MAC_TABLE_ENTRY *pEntry, *pPrevEntry, *pProbeEntry; 1781 MAC_TABLE_ENTRY *pEntry, *pPrevEntry, *pProbeEntry;
2262 BOOLEAN Cancelled; 1782 BOOLEAN Cancelled;
1783 //USHORT offset; // unused variable
1784 //UCHAR j; // unused variable
2263 1785
2264 if (wcid >= MAX_LEN_OF_MAC_TABLE) 1786 if (wcid >= MAX_LEN_OF_MAC_TABLE)
2265 return FALSE; 1787 return FALSE;
@@ -2267,6 +1789,7 @@ BOOLEAN MacTableDeleteEntry(
2267 NdisAcquireSpinLock(&pAd->MacTabLock); 1789 NdisAcquireSpinLock(&pAd->MacTabLock);
2268 1790
2269 HashIdx = MAC_ADDR_HASH_INDEX(pAddr); 1791 HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
1792 //pEntry = pAd->MacTab.Hash[HashIdx];
2270 pEntry = &pAd->MacTab.Content[wcid]; 1793 pEntry = &pAd->MacTab.Content[wcid];
2271 1794
2272 if (pEntry && (pEntry->ValidAsCLI || pEntry->ValidAsApCli || pEntry->ValidAsWDS || pEntry->ValidAsMesh 1795 if (pEntry && (pEntry->ValidAsCLI || pEntry->ValidAsApCli || pEntry->ValidAsWDS || pEntry->ValidAsMesh
@@ -2276,7 +1799,7 @@ BOOLEAN MacTableDeleteEntry(
2276 { 1799 {
2277 1800
2278 // Delete this entry from ASIC on-chip WCID Table 1801 // Delete this entry from ASIC on-chip WCID Table
2279 RT28XX_STA_ENTRY_MAC_RESET(pAd, wcid); 1802 RTMP_STA_ENTRY_MAC_RESET(pAd, wcid);
2280 1803
2281 // free resources of BA 1804 // free resources of BA
2282 BASessionTearDownALL(pAd, pEntry->Aid); 1805 BASessionTearDownALL(pAd, pEntry->Aid);
@@ -2308,7 +1831,7 @@ BOOLEAN MacTableDeleteEntry(
2308 // not found !!! 1831 // not found !!!
2309 ASSERT(pProbeEntry != NULL); 1832 ASSERT(pProbeEntry != NULL);
2310 1833
2311 RT28XX_STA_ENTRY_KEY_DEL(pAd, BSS0, wcid); 1834 RTMP_STA_ENTRY_KEY_DEL(pAd, BSS0, wcid);
2312 1835
2313 1836
2314 if (pEntry->EnqueueEapolStartTimerRunning != EAPOL_START_DISABLE) 1837 if (pEntry->EnqueueEapolStartTimerRunning != EAPOL_START_DISABLE)
@@ -2324,7 +1847,7 @@ BOOLEAN MacTableDeleteEntry(
2324 } 1847 }
2325 else 1848 else
2326 { 1849 {
2327 printk("\n%s: Impossible Wcid = %d !!!!!\n", __func__, wcid); 1850 DBGPRINT(RT_DEBUG_OFF, ("\n%s: Impossible Wcid = %d !!!!!\n", __func__, wcid));
2328 } 1851 }
2329 } 1852 }
2330 1853
@@ -2334,13 +1857,8 @@ BOOLEAN MacTableDeleteEntry(
2334 if (pAd->MacTab.Size == 0) 1857 if (pAd->MacTab.Size == 0)
2335 { 1858 {
2336 pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode = 0; 1859 pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode = 0;
2337#ifdef RT2860 1860 //AsicUpdateProtect(pAd, 0 /*pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode*/, (ALLN_SETPROTECT), TRUE, 0 /*pAd->MacTab.fAnyStationNonGF*/);
2338 AsicUpdateProtect(pAd, 0 /*pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode*/, (ALLN_SETPROTECT), TRUE, 0 /*pAd->MacTab.fAnyStationNonGF*/); 1861 RTMP_UPDATE_PROTECT(pAd); // edit by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet
2339#else
2340 // edit by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet
2341 // Set MAC register value according operation mode
2342 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_UPDATE_PROTECT, NULL, 0);
2343#endif
2344 } 1862 }
2345 1863
2346 return TRUE; 1864 return TRUE;
@@ -2362,24 +1880,25 @@ VOID MacTableReset(
2362 DBGPRINT(RT_DEBUG_TRACE, ("MacTableReset\n")); 1880 DBGPRINT(RT_DEBUG_TRACE, ("MacTableReset\n"));
2363 //NdisAcquireSpinLock(&pAd->MacTabLock); 1881 //NdisAcquireSpinLock(&pAd->MacTabLock);
2364 1882
1883
2365 for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++) 1884 for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
2366 { 1885 {
2367#ifdef RT2860 1886#ifdef RTMP_MAC_PCI
2368 RT28XX_STA_ENTRY_MAC_RESET(pAd, i); 1887 RTMP_STA_ENTRY_MAC_RESET(pAd, i);
2369#endif 1888#endif // RTMP_MAC_PCI //
2370 if (pAd->MacTab.Content[i].ValidAsCLI == TRUE) 1889 if (pAd->MacTab.Content[i].ValidAsCLI == TRUE)
2371 { 1890 {
1891
1892
2372 // free resources of BA 1893 // free resources of BA
2373 BASessionTearDownALL(pAd, i); 1894 BASessionTearDownALL(pAd, i);
2374 1895
2375 pAd->MacTab.Content[i].ValidAsCLI = FALSE; 1896 pAd->MacTab.Content[i].ValidAsCLI = FALSE;
2376 1897
2377 1898#ifdef RTMP_MAC_USB
2378
2379#ifdef RT2870
2380 NdisZeroMemory(pAd->MacTab.Content[i].Addr, 6); 1899 NdisZeroMemory(pAd->MacTab.Content[i].Addr, 6);
2381 RT28XX_STA_ENTRY_MAC_RESET(pAd, i); 1900 RTMP_STA_ENTRY_MAC_RESET(pAd, i);
2382#endif // RT2870 // 1901#endif // RTMP_MAC_USB //
2383 1902
2384 //AsicDelWcidTab(pAd, i); 1903 //AsicDelWcidTab(pAd, i);
2385 } 1904 }
@@ -2544,7 +2063,7 @@ BOOLEAN RTMPCheckEtherType(
2544 RTMP_SET_PACKET_SPECIFIC(pPacket, 0); 2063 RTMP_SET_PACKET_SPECIFIC(pPacket, 0);
2545 2064
2546 // get Ethernet protocol field 2065 // get Ethernet protocol field
2547 TypeLen = (pSrcBuf[12] << 8) + pSrcBuf[13]; 2066 TypeLen = (pSrcBuf[12] << 8) | pSrcBuf[13];
2548 2067
2549 pSrcBuf += LENGTH_802_3; // Skip the Ethernet Header. 2068 pSrcBuf += LENGTH_802_3; // Skip the Ethernet Header.
2550 2069
@@ -2558,7 +2077,7 @@ BOOLEAN RTMPCheckEtherType(
2558 */ 2077 */
2559 if (pSrcBuf[0] == 0xAA && pSrcBuf[1] == 0xAA && pSrcBuf[2] == 0x03) 2078 if (pSrcBuf[0] == 0xAA && pSrcBuf[1] == 0xAA && pSrcBuf[2] == 0x03)
2560 { 2079 {
2561 Sniff2BytesFromNdisBuffer(pSrcBuf, 6, &Byte0, &Byte1); 2080 Sniff2BytesFromNdisBuffer((PNDIS_BUFFER)pSrcBuf, 6, &Byte0, &Byte1);
2562 RTMP_SET_PACKET_LLCSNAP(pPacket, 1); 2081 RTMP_SET_PACKET_LLCSNAP(pPacket, 1);
2563 TypeLen = (USHORT)((Byte0 << 8) + Byte1); 2082 TypeLen = (USHORT)((Byte0 << 8) + Byte1);
2564 pSrcBuf += 8; // Skip this LLC/SNAP header 2083 pSrcBuf += 8; // Skip this LLC/SNAP header
@@ -2584,7 +2103,7 @@ BOOLEAN RTMPCheckEtherType(
2584 Frame Check Sequence (4-bytes) */ 2103 Frame Check Sequence (4-bytes) */
2585 2104
2586 RTMP_SET_PACKET_VLAN(pPacket, 1); 2105 RTMP_SET_PACKET_VLAN(pPacket, 1);
2587 Sniff2BytesFromNdisBuffer(pSrcBuf, 2, &Byte0, &Byte1); 2106 Sniff2BytesFromNdisBuffer((PNDIS_BUFFER)pSrcBuf, 2, &Byte0, &Byte1);
2588 TypeLen = (USHORT)((Byte0 << 8) + Byte1); 2107 TypeLen = (USHORT)((Byte0 << 8) + Byte1);
2589 2108
2590 pSrcBuf += 4; // Skip the VLAN Header. 2109 pSrcBuf += 4; // Skip the VLAN Header.
@@ -2600,8 +2119,8 @@ BOOLEAN RTMPCheckEtherType(
2600 ASSERT((pktLen > 34)); // 14 for ethernet header, 20 for IP header 2119 ASSERT((pktLen > 34)); // 14 for ethernet header, 20 for IP header
2601 2120
2602 pSrcBuf += 20; // Skip the IP header 2121 pSrcBuf += 20; // Skip the IP header
2603 srcPort = OS_NTOHS(*((UINT16 *)pSrcBuf)); 2122 srcPort = OS_NTOHS(get_unaligned((PUINT16)(pSrcBuf)));
2604 dstPort = OS_NTOHS(*((UINT16 *)(pSrcBuf +2))); 2123 dstPort = OS_NTOHS(get_unaligned((PUINT16)(pSrcBuf+2)));
2605 2124
2606 if ((srcPort==0x44 && dstPort==0x43) || (srcPort==0x43 && dstPort==0x44)) 2125 if ((srcPort==0x44 && dstPort==0x43) || (srcPort==0x43 && dstPort==0x44))
2607 { //It's a BOOTP/DHCP packet 2126 { //It's a BOOTP/DHCP packet
@@ -2692,7 +2211,7 @@ VOID Indicate_Legacy_Packet(
2692 2211
2693 STATS_INC_RX_PACKETS(pAd, FromWhichBSSID); 2212 STATS_INC_RX_PACKETS(pAd, FromWhichBSSID);
2694 2213
2695#ifdef RT2870 2214#ifdef RTMP_MAC_USB
2696 if (pAd->CommonCfg.bDisableReordering == 0) 2215 if (pAd->CommonCfg.bDisableReordering == 0)
2697 { 2216 {
2698 PBA_REC_ENTRY pBAEntry; 2217 PBA_REC_ENTRY pBAEntry;
@@ -2701,7 +2220,7 @@ VOID Indicate_Legacy_Packet(
2701 UCHAR TID = pRxBlk->pRxWI->TID; 2220 UCHAR TID = pRxBlk->pRxWI->TID;
2702 USHORT Idx; 2221 USHORT Idx;
2703 2222
2704#define REORDERING_PACKET_TIMEOUT ((100 * HZ)/1000) // system ticks -- 100 ms 2223#define REORDERING_PACKET_TIMEOUT ((100 * OS_HZ)/1000) // system ticks -- 100 ms
2705 2224
2706 if (Wcid < MAX_LEN_OF_MAC_TABLE) 2225 if (Wcid < MAX_LEN_OF_MAC_TABLE)
2707 { 2226 {
@@ -2715,14 +2234,15 @@ VOID Indicate_Legacy_Packet(
2715 RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(REORDERING_PACKET_TIMEOUT))) 2234 RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(REORDERING_PACKET_TIMEOUT)))
2716 ) 2235 )
2717 { 2236 {
2718 printk("Indicate_Legacy_Packet():flush reordering_timeout_mpdus! RxWI->Flags=%d, pRxWI.TID=%d, RxD->AMPDU=%d!\n", pRxBlk->Flags, pRxBlk->pRxWI->TID, pRxBlk->RxD.AMPDU); 2237 DBGPRINT(RT_DEBUG_OFF, ("Indicate_Legacy_Packet():flush reordering_timeout_mpdus! RxWI->Flags=%d, pRxWI.TID=%d, RxD->AMPDU=%d!\n",
2238 pRxBlk->Flags, pRxBlk->pRxWI->TID, pRxBlk->RxD.AMPDU));
2719 hex_dump("Dump the legacy Packet:", GET_OS_PKT_DATAPTR(pRxBlk->pRxPacket), 64); 2239 hex_dump("Dump the legacy Packet:", GET_OS_PKT_DATAPTR(pRxBlk->pRxPacket), 64);
2720 ba_flush_reordering_timeout_mpdus(pAd, pBAEntry, Now32); 2240 ba_flush_reordering_timeout_mpdus(pAd, pBAEntry, Now32);
2721 } 2241 }
2722 } 2242 }
2723 } 2243 }
2724 } 2244 }
2725#endif // RT2870 // 2245#endif // RTMP_MAC_USB //
2726 2246
2727 wlan_802_11_to_802_3_packet(pAd, pRxBlk, Header802_3, FromWhichBSSID); 2247 wlan_802_11_to_802_3_packet(pAd, pRxBlk, Header802_3, FromWhichBSSID);
2728 2248
diff --git a/drivers/staging/rt2860/common/cmm_data_pci.c b/drivers/staging/rt2860/common/cmm_data_pci.c
new file mode 100644
index 00000000000..d808e7d7767
--- /dev/null
+++ b/drivers/staging/rt2860/common/cmm_data_pci.c
@@ -0,0 +1,1153 @@
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
35
36USHORT RtmpPCI_WriteTxResource(
37 IN PRTMP_ADAPTER pAd,
38 IN TX_BLK *pTxBlk,
39 IN BOOLEAN bIsLast,
40 OUT USHORT *FreeNumber)
41{
42
43 UCHAR *pDMAHeaderBufVA;
44 USHORT TxIdx, RetTxIdx;
45 PTXD_STRUC pTxD;
46 UINT32 BufBasePaLow;
47 PRTMP_TX_RING pTxRing;
48 USHORT hwHeaderLen;
49
50 //
51 // get Tx Ring Resource
52 //
53 pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
54 TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx;
55 pDMAHeaderBufVA = (PUCHAR) pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
56 BufBasePaLow = RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
57
58 // copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer
59 if (pTxBlk->TxFrameType == TX_AMSDU_FRAME)
60 {
61 //hwHeaderLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD, 4)+LENGTH_AMSDU_SUBFRAMEHEAD;
62 hwHeaderLen = pTxBlk->MpduHeaderLen - LENGTH_AMSDU_SUBFRAMEHEAD + pTxBlk->HdrPadLen + LENGTH_AMSDU_SUBFRAMEHEAD;
63 }
64 else
65 {
66 //hwHeaderLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4);
67 hwHeaderLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
68 }
69 NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf, TXINFO_SIZE + TXWI_SIZE + hwHeaderLen);
70
71 pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket;
72 pTxRing->Cell[TxIdx].pNextNdisPacket = NULL;
73
74 //
75 // build Tx Descriptor
76 //
77
78 pTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa;
79 NdisZeroMemory(pTxD, TXD_SIZE);
80
81 pTxD->SDPtr0 = BufBasePaLow;
82 pTxD->SDLen0 = TXINFO_SIZE + TXWI_SIZE + hwHeaderLen; // include padding
83 pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE);
84 pTxD->SDLen1 = pTxBlk->SrcBufLen;
85 pTxD->LastSec0 = 0;
86 pTxD->LastSec1 = (bIsLast) ? 1 : 0;
87
88 RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);
89
90 RetTxIdx = TxIdx;
91 //
92 // Update Tx index
93 //
94 INC_RING_INDEX(TxIdx, TX_RING_SIZE);
95 pTxRing->TxCpuIdx = TxIdx;
96
97 *FreeNumber -= 1;
98
99 return RetTxIdx;
100}
101
102
103USHORT RtmpPCI_WriteSingleTxResource(
104 IN PRTMP_ADAPTER pAd,
105 IN TX_BLK *pTxBlk,
106 IN BOOLEAN bIsLast,
107 OUT USHORT *FreeNumber)
108{
109
110 UCHAR *pDMAHeaderBufVA;
111 USHORT TxIdx, RetTxIdx;
112 PTXD_STRUC pTxD;
113 UINT32 BufBasePaLow;
114 PRTMP_TX_RING pTxRing;
115 USHORT hwHeaderLen;
116
117 //
118 // get Tx Ring Resource
119 //
120 pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
121 TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx;
122 pDMAHeaderBufVA = (PUCHAR) pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
123 BufBasePaLow = RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
124
125 // copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer
126 //hwHeaderLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4);
127 hwHeaderLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
128
129 NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf, TXINFO_SIZE + TXWI_SIZE + hwHeaderLen);
130
131 pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket;
132 pTxRing->Cell[TxIdx].pNextNdisPacket = NULL;
133
134 //
135 // build Tx Descriptor
136 //
137 pTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa;
138 NdisZeroMemory(pTxD, TXD_SIZE);
139
140 pTxD->SDPtr0 = BufBasePaLow;
141 pTxD->SDLen0 = TXINFO_SIZE + TXWI_SIZE + hwHeaderLen; // include padding
142 pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE);;
143 pTxD->SDLen1 = pTxBlk->SrcBufLen;
144 pTxD->LastSec0 = 0;
145 pTxD->LastSec1 = (bIsLast) ? 1 : 0;
146
147 RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);
148
149 RetTxIdx = TxIdx;
150 //
151 // Update Tx index
152 //
153 INC_RING_INDEX(TxIdx, TX_RING_SIZE);
154 pTxRing->TxCpuIdx = TxIdx;
155
156 *FreeNumber -= 1;
157
158 return RetTxIdx;
159}
160
161
162USHORT RtmpPCI_WriteMultiTxResource(
163 IN PRTMP_ADAPTER pAd,
164 IN TX_BLK *pTxBlk,
165 IN UCHAR frameNum,
166 OUT USHORT *FreeNumber)
167{
168 BOOLEAN bIsLast;
169 UCHAR *pDMAHeaderBufVA;
170 USHORT TxIdx, RetTxIdx;
171 PTXD_STRUC pTxD;
172 UINT32 BufBasePaLow;
173 PRTMP_TX_RING pTxRing;
174 USHORT hwHdrLen;
175 UINT32 firstDMALen;
176
177 bIsLast = ((frameNum == (pTxBlk->TotalFrameNum - 1)) ? 1 : 0);
178
179 //
180 // get Tx Ring Resource
181 //
182 pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
183 TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx;
184 pDMAHeaderBufVA = (PUCHAR) pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
185 BufBasePaLow = RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
186
187 if (frameNum == 0)
188 {
189 // copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer
190 if (pTxBlk->TxFrameType == TX_AMSDU_FRAME)
191 //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD, 4)+LENGTH_AMSDU_SUBFRAMEHEAD;
192 hwHdrLen = pTxBlk->MpduHeaderLen - LENGTH_AMSDU_SUBFRAMEHEAD + pTxBlk->HdrPadLen + LENGTH_AMSDU_SUBFRAMEHEAD;
193 else if (pTxBlk->TxFrameType == TX_RALINK_FRAME)
194 //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_ARALINK_HEADER_FIELD, 4)+LENGTH_ARALINK_HEADER_FIELD;
195 hwHdrLen = pTxBlk->MpduHeaderLen - LENGTH_ARALINK_HEADER_FIELD + pTxBlk->HdrPadLen + 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 }
202 else
203 {
204 firstDMALen = pTxBlk->MpduHeaderLen;
205 }
206
207 NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf, firstDMALen);
208
209 pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket;
210 pTxRing->Cell[TxIdx].pNextNdisPacket = NULL;
211
212 //
213 // build Tx Descriptor
214 //
215 pTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa;
216 NdisZeroMemory(pTxD, TXD_SIZE);
217
218 pTxD->SDPtr0 = BufBasePaLow;
219 pTxD->SDLen0 = firstDMALen; // include padding
220 pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE);;
221 pTxD->SDLen1 = pTxBlk->SrcBufLen;
222 pTxD->LastSec0 = 0;
223 pTxD->LastSec1 = (bIsLast) ? 1 : 0;
224
225 RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);
226
227
228 RetTxIdx = TxIdx;
229 //
230 // Update Tx index
231 //
232 INC_RING_INDEX(TxIdx, TX_RING_SIZE);
233 pTxRing->TxCpuIdx = TxIdx;
234
235 *FreeNumber -= 1;
236
237 return RetTxIdx;
238
239}
240
241
242VOID RtmpPCI_FinalWriteTxResource(
243 IN PRTMP_ADAPTER pAd,
244 IN TX_BLK *pTxBlk,
245 IN USHORT totalMPDUSize,
246 IN USHORT FirstTxIdx)
247{
248
249 PTXWI_STRUC pTxWI;
250 PRTMP_TX_RING pTxRing;
251
252 //
253 // get Tx Ring Resource
254 //
255 pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
256 pTxWI = (PTXWI_STRUC) pTxRing->Cell[FirstTxIdx].DmaBuf.AllocVa;
257 pTxWI->MPDUtotalByteCount = totalMPDUSize;
258
259}
260
261
262VOID RtmpPCIDataLastTxIdx(
263 IN PRTMP_ADAPTER pAd,
264 IN UCHAR QueIdx,
265 IN USHORT LastTxIdx)
266{
267 PTXD_STRUC pTxD;
268 PRTMP_TX_RING pTxRing;
269
270 //
271 // get Tx Ring Resource
272 //
273 pTxRing = &pAd->TxRing[QueIdx];
274
275 //
276 // build Tx Descriptor
277 //
278 pTxD = (PTXD_STRUC) pTxRing->Cell[LastTxIdx].AllocVa;
279
280 pTxD->LastSec1 = 1;
281
282
283}
284
285
286USHORT RtmpPCI_WriteFragTxResource(
287 IN PRTMP_ADAPTER pAd,
288 IN TX_BLK *pTxBlk,
289 IN UCHAR fragNum,
290 OUT USHORT *FreeNumber)
291{
292 UCHAR *pDMAHeaderBufVA;
293 USHORT TxIdx, RetTxIdx;
294 PTXD_STRUC pTxD;
295 UINT32 BufBasePaLow;
296 PRTMP_TX_RING pTxRing;
297 USHORT hwHeaderLen;
298 UINT32 firstDMALen;
299
300 //
301 // Get Tx Ring Resource
302 //
303 pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
304 TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx;
305 pDMAHeaderBufVA = (PUCHAR) pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
306 BufBasePaLow = RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
307
308 //
309 // Copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer
310 //
311 //hwHeaderLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4);
312 hwHeaderLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
313
314 firstDMALen = TXINFO_SIZE + TXWI_SIZE + hwHeaderLen;
315 NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf, firstDMALen);
316
317
318 //
319 // Build Tx Descriptor
320 //
321 pTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa;
322 NdisZeroMemory(pTxD, TXD_SIZE);
323
324 if (fragNum == pTxBlk->TotalFragNum)
325 {
326 pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket;
327 pTxRing->Cell[TxIdx].pNextNdisPacket = NULL;
328 }
329
330 pTxD->SDPtr0 = BufBasePaLow;
331 pTxD->SDLen0 = firstDMALen; // include padding
332 pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE);
333 pTxD->SDLen1 = pTxBlk->SrcBufLen;
334 pTxD->LastSec0 = 0;
335 pTxD->LastSec1 = 1;
336
337 RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);
338
339
340 RetTxIdx = TxIdx;
341 pTxBlk->Priv += pTxBlk->SrcBufLen;
342
343 //
344 // Update Tx index
345 //
346 INC_RING_INDEX(TxIdx, TX_RING_SIZE);
347 pTxRing->TxCpuIdx = TxIdx;
348
349 *FreeNumber -= 1;
350
351 return RetTxIdx;
352
353}
354
355
356/*
357 Must be run in Interrupt context
358 This function handle PCI specific TxDesc and cpu index update and kick the packet out.
359 */
360int RtmpPCIMgmtKickOut(
361 IN RTMP_ADAPTER *pAd,
362 IN UCHAR QueIdx,
363 IN PNDIS_PACKET pPacket,
364 IN PUCHAR pSrcBufVA,
365 IN UINT SrcBufLen)
366{
367 PTXD_STRUC pTxD;
368 ULONG SwIdx = pAd->MgmtRing.TxCpuIdx;
369
370 pTxD = (PTXD_STRUC) pAd->MgmtRing.Cell[SwIdx].AllocVa;
371
372 pAd->MgmtRing.Cell[SwIdx].pNdisPacket = pPacket;
373 pAd->MgmtRing.Cell[SwIdx].pNextNdisPacket = NULL;
374
375 RTMPWriteTxDescriptor(pAd, pTxD, TRUE, FIFO_MGMT);
376 pTxD->LastSec0 = 1;
377 pTxD->LastSec1 = 1;
378 pTxD->DMADONE = 0;
379 pTxD->SDLen1 = 0;
380 pTxD->SDPtr0 = PCI_MAP_SINGLE(pAd, pSrcBufVA, SrcBufLen, 0, PCI_DMA_TODEVICE);
381 pTxD->SDLen0 = SrcBufLen;
382
383
384//==================================================================
385/* DBGPRINT_RAW(RT_DEBUG_TRACE, ("MLMEHardTransmit\n"));
386 for (i = 0; i < (TXWI_SIZE+24); i++)
387 {
388
389 DBGPRINT_RAW(RT_DEBUG_TRACE, ("%x:", *(pSrcBufVA+i)));
390 if ( i%4 == 3)
391 DBGPRINT_RAW(RT_DEBUG_TRACE, (" :: "));
392 if ( i%16 == 15)
393 DBGPRINT_RAW(RT_DEBUG_TRACE, ("\n "));
394 }
395 DBGPRINT_RAW(RT_DEBUG_TRACE, ("\n "));*/
396//=======================================================================
397
398 pAd->RalinkCounters.KickTxCount++;
399 pAd->RalinkCounters.OneSecTxDoneCount++;
400
401 // Increase TX_CTX_IDX, but write to register later.
402 INC_RING_INDEX(pAd->MgmtRing.TxCpuIdx, MGMT_RING_SIZE);
403
404 RTMP_IO_WRITE32(pAd, TX_MGMTCTX_IDX, pAd->MgmtRing.TxCpuIdx);
405
406 return 0;
407}
408
409
410/*
411 ========================================================================
412
413 Routine Description:
414 Check Rx descriptor, return NDIS_STATUS_FAILURE if any error dound
415
416 Arguments:
417 pRxD Pointer to the Rx descriptor
418
419 Return Value:
420 NDIS_STATUS_SUCCESS No err
421 NDIS_STATUS_FAILURE Error
422
423 Note:
424
425 ========================================================================
426*/
427NDIS_STATUS RTMPCheckRxError(
428 IN PRTMP_ADAPTER pAd,
429 IN PHEADER_802_11 pHeader,
430 IN PRXWI_STRUC pRxWI,
431 IN PRT28XX_RXD_STRUC pRxD)
432{
433 PCIPHER_KEY pWpaKey;
434 INT dBm;
435
436 // Phy errors & CRC errors
437 if (/*(pRxD->PhyErr) ||*/ (pRxD->Crc))
438 {
439 // Check RSSI for Noise Hist statistic collection.
440 dBm = (INT) (pRxWI->RSSI0) - pAd->BbpRssiToDbmDelta;
441 if (dBm <= -87)
442 pAd->StaCfg.RPIDensity[0] += 1;
443 else if (dBm <= -82)
444 pAd->StaCfg.RPIDensity[1] += 1;
445 else if (dBm <= -77)
446 pAd->StaCfg.RPIDensity[2] += 1;
447 else if (dBm <= -72)
448 pAd->StaCfg.RPIDensity[3] += 1;
449 else if (dBm <= -67)
450 pAd->StaCfg.RPIDensity[4] += 1;
451 else if (dBm <= -62)
452 pAd->StaCfg.RPIDensity[5] += 1;
453 else if (dBm <= -57)
454 pAd->StaCfg.RPIDensity[6] += 1;
455 else if (dBm > -57)
456 pAd->StaCfg.RPIDensity[7] += 1;
457
458 return(NDIS_STATUS_FAILURE);
459 }
460
461 // Add Rx size to channel load counter, we should ignore error counts
462 pAd->StaCfg.CLBusyBytes += (pRxD->SDL0 + 14);
463
464 // Drop ToDs promiscous frame, it is opened due to CCX 2 channel load statistics
465 if (pHeader != NULL)
466 {
467 if (pHeader->FC.ToDs)
468 {
469 return(NDIS_STATUS_FAILURE);
470 }
471 }
472
473 // Drop not U2M frames, cant's drop here because we will drop beacon in this case
474 // I am kind of doubting the U2M bit operation
475 // if (pRxD->U2M == 0)
476 // return(NDIS_STATUS_FAILURE);
477
478 // drop decyption fail frame
479 if (pRxD->CipherErr)
480 {
481 if (pRxD->CipherErr == 2)
482 {DBGPRINT_RAW(RT_DEBUG_TRACE,("pRxD ERROR: ICV ok but MICErr "));}
483 else if (pRxD->CipherErr == 1)
484 {DBGPRINT_RAW(RT_DEBUG_TRACE,("pRxD ERROR: ICV Err "));}
485 else if (pRxD->CipherErr == 3)
486 DBGPRINT_RAW(RT_DEBUG_TRACE,("pRxD ERROR: Key not valid "));
487
488 if (((pRxD->CipherErr & 1) == 1) && pAd->CommonCfg.bWirelessEvent && INFRA_ON(pAd))
489 RTMPSendWirelessEvent(pAd, IW_ICV_ERROR_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
490
491 DBGPRINT_RAW(RT_DEBUG_TRACE,(" %d (len=%d, Mcast=%d, MyBss=%d, Wcid=%d, KeyId=%d)\n",
492 pRxD->CipherErr,
493 pRxD->SDL0,
494 pRxD->Mcast | pRxD->Bcast,
495 pRxD->MyBss,
496 pRxWI->WirelessCliID,
497// CipherName[pRxD->CipherAlg],
498 pRxWI->KeyIndex));
499
500 //
501 // MIC Error
502 //
503 if (pRxD->CipherErr == 2)
504 {
505 pWpaKey = &pAd->SharedKey[BSS0][pRxWI->KeyIndex];
506 if (pAd->StaCfg.WpaSupplicantUP)
507 WpaSendMicFailureToWpaSupplicant(pAd,
508 (pWpaKey->Type == PAIRWISEKEY) ? TRUE:FALSE);
509 else
510 RTMPReportMicError(pAd, pWpaKey);
511
512 if (((pRxD->CipherErr & 2) == 2) && pAd->CommonCfg.bWirelessEvent && INFRA_ON(pAd))
513 RTMPSendWirelessEvent(pAd, IW_MIC_ERROR_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
514
515 DBGPRINT_RAW(RT_DEBUG_ERROR,("Rx MIC Value error\n"));
516 }
517
518 if (pHeader == NULL)
519 return(NDIS_STATUS_SUCCESS);
520 /*if ((pRxD->CipherAlg == CIPHER_AES) &&
521 (pHeader->Sequence == pAd->FragFrame.Sequence))
522 {
523 //
524 // Acceptable since the First FragFrame no CipherErr problem.
525 //
526 return(NDIS_STATUS_SUCCESS);
527 }*/
528
529 return(NDIS_STATUS_FAILURE);
530 }
531
532 return(NDIS_STATUS_SUCCESS);
533}
534
535
536BOOLEAN RTMPFreeTXDUponTxDmaDone(
537 IN PRTMP_ADAPTER pAd,
538 IN UCHAR QueIdx)
539{
540 PRTMP_TX_RING pTxRing;
541 PTXD_STRUC pTxD;
542 PNDIS_PACKET pPacket;
543 UCHAR FREE = 0;
544 TXD_STRUC TxD, *pOriTxD;
545 //ULONG IrqFlags;
546 BOOLEAN bReschedule = FALSE;
547
548
549 ASSERT(QueIdx < NUM_OF_TX_RING);
550 pTxRing = &pAd->TxRing[QueIdx];
551
552 RTMP_IO_READ32(pAd, TX_DTX_IDX0 + QueIdx * RINGREG_DIFF, &pTxRing->TxDmaIdx);
553 while (pTxRing->TxSwFreeIdx != pTxRing->TxDmaIdx)
554 {
555// RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
556
557 // static rate also need NICUpdateFifoStaCounters() function.
558 //if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))
559 NICUpdateFifoStaCounters(pAd);
560
561 /* Note : If (pAd->ate.bQATxStart == TRUE), we will never reach here. */
562 FREE++;
563 pTxD = (PTXD_STRUC) (pTxRing->Cell[pTxRing->TxSwFreeIdx].AllocVa);
564 pOriTxD = pTxD;
565 NdisMoveMemory(&TxD, pTxD, sizeof(TXD_STRUC));
566 pTxD = &TxD;
567
568 pTxD->DMADONE = 0;
569
570
571 {
572 pPacket = pTxRing->Cell[pTxRing->TxSwFreeIdx].pNdisPacket;
573 if (pPacket)
574 {
575 PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
576 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
577 }
578 //Always assign pNdisPacket as NULL after clear
579 pTxRing->Cell[pTxRing->TxSwFreeIdx].pNdisPacket = NULL;
580
581 pPacket = pTxRing->Cell[pTxRing->TxSwFreeIdx].pNextNdisPacket;
582
583 ASSERT(pPacket == NULL);
584 if (pPacket)
585 {
586 PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
587 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
588 }
589 //Always assign pNextNdisPacket as NULL after clear
590 pTxRing->Cell[pTxRing->TxSwFreeIdx].pNextNdisPacket = NULL;
591 }
592
593 pAd->RalinkCounters.TransmittedByteCount += (pTxD->SDLen1 + pTxD->SDLen0);
594 pAd->RalinkCounters.OneSecDmaDoneCount[QueIdx] ++;
595 INC_RING_INDEX(pTxRing->TxSwFreeIdx, TX_RING_SIZE);
596 /* get tx_tdx_idx again */
597 RTMP_IO_READ32(pAd, TX_DTX_IDX0 + QueIdx * RINGREG_DIFF , &pTxRing->TxDmaIdx);
598 NdisMoveMemory(pOriTxD, pTxD, sizeof(TXD_STRUC));
599
600// RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
601 }
602
603
604 return bReschedule;
605
606}
607
608
609/*
610 ========================================================================
611
612 Routine Description:
613 Process TX Rings DMA Done interrupt, running in DPC level
614
615 Arguments:
616 Adapter Pointer to our adapter
617
618 Return Value:
619 None
620
621 IRQL = DISPATCH_LEVEL
622
623 ========================================================================
624*/
625BOOLEAN RTMPHandleTxRingDmaDoneInterrupt(
626 IN PRTMP_ADAPTER pAd,
627 IN INT_SOURCE_CSR_STRUC TxRingBitmap)
628{
629// UCHAR Count = 0;
630 unsigned long IrqFlags;
631 BOOLEAN bReschedule = FALSE;
632
633 // Make sure Tx ring resource won't be used by other threads
634 //NdisAcquireSpinLock(&pAd->TxRingLock);
635
636 RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
637
638 if (TxRingBitmap.field.Ac0DmaDone)
639 bReschedule = RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_BE);
640
641 if (TxRingBitmap.field.HccaDmaDone)
642 bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_HCCA);
643
644 if (TxRingBitmap.field.Ac3DmaDone)
645 bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_VO);
646
647 if (TxRingBitmap.field.Ac2DmaDone)
648 bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_VI);
649
650 if (TxRingBitmap.field.Ac1DmaDone)
651 bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_BK);
652
653 // Make sure to release Tx ring resource
654 //NdisReleaseSpinLock(&pAd->TxRingLock);
655 RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
656
657 // Dequeue outgoing frames from TxSwQueue[] and process it
658 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
659
660 return bReschedule;
661}
662
663
664/*
665 ========================================================================
666
667 Routine Description:
668 Process MGMT ring DMA done interrupt, running in DPC level
669
670 Arguments:
671 pAd Pointer to our adapter
672
673 Return Value:
674 None
675
676 IRQL = DISPATCH_LEVEL
677
678 Note:
679
680 ========================================================================
681*/
682VOID RTMPHandleMgmtRingDmaDoneInterrupt(
683 IN PRTMP_ADAPTER pAd)
684{
685 PTXD_STRUC pTxD;
686 PNDIS_PACKET pPacket;
687// int i;
688 UCHAR FREE = 0;
689 PRTMP_MGMT_RING pMgmtRing = &pAd->MgmtRing;
690
691 NdisAcquireSpinLock(&pAd->MgmtRingLock);
692
693 RTMP_IO_READ32(pAd, TX_MGMTDTX_IDX, &pMgmtRing->TxDmaIdx);
694 while (pMgmtRing->TxSwFreeIdx!= pMgmtRing->TxDmaIdx)
695 {
696 FREE++;
697 pTxD = (PTXD_STRUC) (pMgmtRing->Cell[pAd->MgmtRing.TxSwFreeIdx].AllocVa);
698 pTxD->DMADONE = 0;
699 pPacket = pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNdisPacket;
700
701
702 if (pPacket)
703 {
704 PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, PCI_DMA_TODEVICE);
705 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
706 }
707 pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNdisPacket = NULL;
708
709 pPacket = pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNextNdisPacket;
710 if (pPacket)
711 {
712 PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
713 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
714 }
715 pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNextNdisPacket = NULL;
716 INC_RING_INDEX(pMgmtRing->TxSwFreeIdx, MGMT_RING_SIZE);
717
718 }
719 NdisReleaseSpinLock(&pAd->MgmtRingLock);
720
721}
722
723
724/*
725 ========================================================================
726
727 Routine Description:
728 Arguments:
729 Adapter Pointer to our adapter. Dequeue all power safe delayed braodcast frames after beacon.
730
731 IRQL = DISPATCH_LEVEL
732
733 ========================================================================
734*/
735VOID RTMPHandleTBTTInterrupt(
736 IN PRTMP_ADAPTER pAd)
737{
738 {
739 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
740 {
741 }
742 }
743}
744
745
746/*
747 ========================================================================
748
749 Routine Description:
750 Arguments:
751 pAd Pointer to our adapter. Rewrite beacon content before next send-out.
752
753 IRQL = DISPATCH_LEVEL
754
755 ========================================================================
756*/
757VOID RTMPHandlePreTBTTInterrupt(
758 IN PRTMP_ADAPTER pAd)
759{
760 {
761 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
762 {
763 DBGPRINT(RT_DEBUG_TRACE, ("RTMPHandlePreTBTTInterrupt...\n"));
764 }
765 }
766
767
768}
769
770VOID RTMPHandleRxCoherentInterrupt(
771 IN PRTMP_ADAPTER pAd)
772{
773 WPDMA_GLO_CFG_STRUC GloCfg;
774
775 if (pAd == NULL)
776 {
777 DBGPRINT(RT_DEBUG_TRACE, ("====> pAd is NULL, return.\n"));
778 return;
779 }
780
781 DBGPRINT(RT_DEBUG_TRACE, ("==> RTMPHandleRxCoherentInterrupt \n"));
782
783 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG , &GloCfg.word);
784
785 GloCfg.field.EnTXWriteBackDDONE = 0;
786 GloCfg.field.EnableRxDMA = 0;
787 GloCfg.field.EnableTxDMA = 0;
788 RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
789
790 RTMPRingCleanUp(pAd, QID_AC_BE);
791 RTMPRingCleanUp(pAd, QID_AC_BK);
792 RTMPRingCleanUp(pAd, QID_AC_VI);
793 RTMPRingCleanUp(pAd, QID_AC_VO);
794 RTMPRingCleanUp(pAd, QID_HCCA);
795 RTMPRingCleanUp(pAd, QID_MGMT);
796 RTMPRingCleanUp(pAd, QID_RX);
797
798 RTMPEnableRxTx(pAd);
799
800 DBGPRINT(RT_DEBUG_TRACE, ("<== RTMPHandleRxCoherentInterrupt \n"));
801}
802
803PNDIS_PACKET GetPacketFromRxRing(
804 IN PRTMP_ADAPTER pAd,
805 OUT PRT28XX_RXD_STRUC pSaveRxD,
806 OUT BOOLEAN *pbReschedule,
807 IN OUT UINT32 *pRxPending)
808{
809 PRXD_STRUC pRxD;
810 PNDIS_PACKET pRxPacket = NULL;
811 PNDIS_PACKET pNewPacket;
812 PVOID AllocVa;
813 NDIS_PHYSICAL_ADDRESS AllocPa;
814 BOOLEAN bReschedule = FALSE;
815 RTMP_DMACB *pRxCell;
816
817 RTMP_SEM_LOCK(&pAd->RxRingLock);
818
819 if (*pRxPending == 0)
820 {
821 // Get how may packets had been received
822 RTMP_IO_READ32(pAd, RX_DRX_IDX , &pAd->RxRing.RxDmaIdx);
823
824 if (pAd->RxRing.RxSwReadIdx == pAd->RxRing.RxDmaIdx)
825 {
826 // no more rx packets
827 bReschedule = FALSE;
828 goto done;
829 }
830
831 // get rx pending count
832 if (pAd->RxRing.RxDmaIdx > pAd->RxRing.RxSwReadIdx)
833 *pRxPending = pAd->RxRing.RxDmaIdx - pAd->RxRing.RxSwReadIdx;
834 else
835 *pRxPending = pAd->RxRing.RxDmaIdx + RX_RING_SIZE - pAd->RxRing.RxSwReadIdx;
836
837 }
838
839 pRxCell = &pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx];
840
841 // Point to Rx indexed rx ring descriptor
842 pRxD = (PRXD_STRUC) pRxCell->AllocVa;
843
844 if (pRxD->DDONE == 0)
845 {
846 *pRxPending = 0;
847 // DMAIndx had done but DDONE bit not ready
848 bReschedule = TRUE;
849 goto done;
850 }
851
852
853 // return rx descriptor
854 NdisMoveMemory(pSaveRxD, pRxD, RXD_SIZE);
855
856 pNewPacket = RTMP_AllocateRxPacketBuffer(pAd, RX_BUFFER_AGGRESIZE, FALSE, &AllocVa, &AllocPa);
857
858 if (pNewPacket)
859 {
860 // unmap the rx buffer
861 PCI_UNMAP_SINGLE(pAd, pRxCell->DmaBuf.AllocPa,
862 pRxCell->DmaBuf.AllocSize, PCI_DMA_FROMDEVICE);
863 pRxPacket = pRxCell->pNdisPacket;
864
865 pRxCell->DmaBuf.AllocSize = RX_BUFFER_AGGRESIZE;
866 pRxCell->pNdisPacket = (PNDIS_PACKET) pNewPacket;
867 pRxCell->DmaBuf.AllocVa = AllocVa;
868 pRxCell->DmaBuf.AllocPa = AllocPa;
869 /* update SDP0 to new buffer of rx packet */
870 pRxD->SDP0 = AllocPa;
871 }
872 else
873 {
874 //DBGPRINT(RT_DEBUG_TRACE,("No Rx Buffer\n"));
875 pRxPacket = NULL;
876 bReschedule = TRUE;
877 }
878
879 pRxD->DDONE = 0;
880
881 // had handled one rx packet
882 *pRxPending = *pRxPending - 1;
883
884 // update rx descriptor and kick rx
885 INC_RING_INDEX(pAd->RxRing.RxSwReadIdx, RX_RING_SIZE);
886
887 pAd->RxRing.RxCpuIdx = (pAd->RxRing.RxSwReadIdx == 0) ? (RX_RING_SIZE-1) : (pAd->RxRing.RxSwReadIdx-1);
888 RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx);
889
890done:
891 RTMP_SEM_UNLOCK(&pAd->RxRingLock);
892 *pbReschedule = bReschedule;
893 return pRxPacket;
894}
895
896
897NDIS_STATUS MlmeHardTransmitTxRing(
898 IN PRTMP_ADAPTER pAd,
899 IN UCHAR QueIdx,
900 IN PNDIS_PACKET pPacket)
901{
902 PACKET_INFO PacketInfo;
903 PUCHAR pSrcBufVA;
904 UINT SrcBufLen;
905 PTXD_STRUC pTxD;
906 PHEADER_802_11 pHeader_802_11;
907 BOOLEAN bAckRequired, bInsertTimestamp;
908 ULONG SrcBufPA;
909 //UCHAR TxBufIdx;
910 UCHAR MlmeRate;
911 ULONG SwIdx = pAd->TxRing[QueIdx].TxCpuIdx;
912 PTXWI_STRUC pFirstTxWI;
913 //ULONG i;
914 //HTTRANSMIT_SETTING MlmeTransmit; //Rate for this MGMT frame.
915 ULONG FreeNum;
916 MAC_TABLE_ENTRY *pMacEntry = NULL;
917
918
919 RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
920
921
922 if (pSrcBufVA == NULL)
923 {
924 // The buffer shouldn't be NULL
925 return NDIS_STATUS_FAILURE;
926 }
927
928 // Make sure MGMT ring resource won't be used by other threads
929 //NdisAcquireSpinLock(&pAd->TxRingLock);
930
931 FreeNum = GET_TXRING_FREENO(pAd, QueIdx);
932
933 if (FreeNum == 0)
934 {
935 //NdisReleaseSpinLock(&pAd->TxRingLock);
936 return NDIS_STATUS_FAILURE;
937 }
938
939 SwIdx = pAd->TxRing[QueIdx].TxCpuIdx;
940
941 pTxD = (PTXD_STRUC) pAd->TxRing[QueIdx].Cell[SwIdx].AllocVa;
942
943 if (pAd->TxRing[QueIdx].Cell[SwIdx].pNdisPacket)
944 {
945 DBGPRINT(RT_DEBUG_OFF, ("MlmeHardTransmit Error\n"));
946 //NdisReleaseSpinLock(&pAd->TxRingLock);
947 return NDIS_STATUS_FAILURE;
948 }
949
950 {
951 // outgoing frame always wakeup PHY to prevent frame lost
952 // if (pAd->StaCfg.Psm == PWR_SAVE)
953 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
954 AsicForceWakeup(pAd, TRUE);
955 }
956 pFirstTxWI =(PTXWI_STRUC)pSrcBufVA;
957
958 pHeader_802_11 = (PHEADER_802_11) (pSrcBufVA + TXWI_SIZE);
959 if (pHeader_802_11->Addr1[0] & 0x01)
960 {
961 MlmeRate = pAd->CommonCfg.BasicMlmeRate;
962 }
963 else
964 {
965 MlmeRate = pAd->CommonCfg.MlmeRate;
966 }
967
968 if ((pHeader_802_11->FC.Type == BTYPE_DATA) &&
969 (pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL))
970 {
971 pMacEntry = MacTableLookup(pAd, pHeader_802_11->Addr1);
972 }
973
974 // Verify Mlme rate for a / g bands.
975 if ((pAd->LatchRfRegs.Channel > 14) && (MlmeRate < RATE_6)) // 11A band
976 MlmeRate = RATE_6;
977
978 //
979 // Should not be hard code to set PwrMgmt to 0 (PWR_ACTIVE)
980 // Snice it's been set to 0 while on MgtMacHeaderInit
981 // By the way this will cause frame to be send on PWR_SAVE failed.
982 //
983 //
984 // In WMM-UAPSD, mlme frame should be set psm as power saving but probe request frame
985 // Data-Null packets alse pass through MMRequest in RT2860, however, we hope control the psm bit to pass APSD
986 if (pHeader_802_11->FC.Type != BTYPE_DATA)
987 {
988 if ((pHeader_802_11->FC.SubType == SUBTYPE_PROBE_REQ) || !(pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable))
989 {
990 pHeader_802_11->FC.PwrMgmt = PWR_ACTIVE;
991 }
992 else
993 {
994 pHeader_802_11->FC.PwrMgmt = pAd->CommonCfg.bAPSDForcePowerSave;
995 }
996 }
997
998 bInsertTimestamp = FALSE;
999 if (pHeader_802_11->FC.Type == BTYPE_CNTL) // must be PS-POLL
1000 {
1001 bAckRequired = FALSE;
1002 }
1003 else // BTYPE_MGMT or BTYPE_DATA(must be NULL frame)
1004 {
1005 if (pHeader_802_11->Addr1[0] & 0x01) // MULTICAST, BROADCAST
1006 {
1007 bAckRequired = FALSE;
1008 pHeader_802_11->Duration = 0;
1009 }
1010 else
1011 {
1012 bAckRequired = TRUE;
1013 pHeader_802_11->Duration = RTMPCalcDuration(pAd, MlmeRate, 14);
1014 if (pHeader_802_11->FC.SubType == SUBTYPE_PROBE_RSP)
1015 {
1016 bInsertTimestamp = TRUE;
1017 }
1018 }
1019 }
1020 pHeader_802_11->Sequence = pAd->Sequence++;
1021 if (pAd->Sequence > 0xfff)
1022 pAd->Sequence = 0;
1023 // Before radar detection done, mgmt frame can not be sent but probe req
1024 // Because we need to use probe req to trigger driver to send probe req in passive scan
1025 if ((pHeader_802_11->FC.SubType != SUBTYPE_PROBE_REQ)
1026 && (pAd->CommonCfg.bIEEE80211H == 1)
1027 && (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE))
1028 {
1029 DBGPRINT(RT_DEBUG_ERROR,("MlmeHardTransmit --> radar detect not in normal mode !!!\n"));
1030 //NdisReleaseSpinLock(&pAd->TxRingLock);
1031 return (NDIS_STATUS_FAILURE);
1032 }
1033
1034 //
1035 // fill scatter-and-gather buffer list into TXD. Internally created NDIS PACKET
1036 // should always has only one ohysical buffer, and the whole frame size equals
1037 // to the first scatter buffer size
1038 //
1039
1040 // Initialize TX Descriptor
1041 // For inter-frame gap, the number is for this frame and next frame
1042 // For MLME rate, we will fix as 2Mb to match other vendor's implement
1043// pAd->CommonCfg.MlmeTransmit.field.MODE = 1;
1044
1045// management frame doesn't need encryption. so use RESERVED_WCID no matter u are sending to specific wcid or not.
1046 // Only beacon use Nseq=TRUE. So here we use Nseq=FALSE.
1047 if (pMacEntry == NULL)
1048 {
1049 RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, bInsertTimestamp, FALSE, bAckRequired, FALSE,
1050 0, RESERVED_WCID, (SrcBufLen - TXWI_SIZE), PID_MGMT, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
1051 }
1052 else
1053 {
1054 RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE,
1055 bInsertTimestamp, FALSE, bAckRequired, FALSE,
1056 0, pMacEntry->Aid, (SrcBufLen - TXWI_SIZE),
1057 pMacEntry->MaxHTPhyMode.field.MCS, 0,
1058 (UCHAR)pMacEntry->MaxHTPhyMode.field.MCS,
1059 IFS_BACKOFF, FALSE, &pMacEntry->MaxHTPhyMode);
1060 }
1061
1062 pAd->TxRing[QueIdx].Cell[SwIdx].pNdisPacket = pPacket;
1063 pAd->TxRing[QueIdx].Cell[SwIdx].pNextNdisPacket = NULL;
1064// pFirstTxWI->MPDUtotalByteCount = SrcBufLen - TXWI_SIZE;
1065 SrcBufPA = PCI_MAP_SINGLE(pAd, pSrcBufVA, SrcBufLen, 0, PCI_DMA_TODEVICE);
1066
1067
1068 RTMPWriteTxDescriptor(pAd, pTxD, TRUE, FIFO_EDCA);
1069 pTxD->LastSec0 = 1;
1070 pTxD->LastSec1 = 1;
1071 pTxD->SDLen0 = SrcBufLen;
1072 pTxD->SDLen1 = 0;
1073 pTxD->SDPtr0 = SrcBufPA;
1074 pTxD->DMADONE = 0;
1075
1076
1077 pAd->RalinkCounters.KickTxCount++;
1078 pAd->RalinkCounters.OneSecTxDoneCount++;
1079
1080 // Increase TX_CTX_IDX, but write to register later.
1081 INC_RING_INDEX(pAd->TxRing[QueIdx].TxCpuIdx, TX_RING_SIZE);
1082
1083 RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + QueIdx*0x10, pAd->TxRing[QueIdx].TxCpuIdx);
1084
1085 // Make sure to release MGMT ring resource
1086// NdisReleaseSpinLock(&pAd->TxRingLock);
1087
1088 return NDIS_STATUS_SUCCESS;
1089}
1090
1091
1092NDIS_STATUS MlmeDataHardTransmit(
1093 IN PRTMP_ADAPTER pAd,
1094 IN UCHAR QueIdx,
1095 IN PNDIS_PACKET pPacket)
1096{
1097 if ((pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)
1098 )
1099 {
1100 return NDIS_STATUS_FAILURE;
1101 }
1102
1103 return MlmeHardTransmitTxRing(pAd,QueIdx,pPacket);
1104}
1105
1106
1107/*
1108 ========================================================================
1109
1110 Routine Description:
1111 Calculates the duration which is required to transmit out frames
1112 with given size and specified rate.
1113
1114 Arguments:
1115 pTxD Pointer to transmit descriptor
1116 Ack Setting for Ack requirement bit
1117 Fragment Setting for Fragment bit
1118 RetryMode Setting for retry mode
1119 Ifs Setting for IFS gap
1120 Rate Setting for transmit rate
1121 Service Setting for service
1122 Length Frame length
1123 TxPreamble Short or Long preamble when using CCK rates
1124 QueIdx - 0-3, according to 802.11e/d4.4 June/2003
1125
1126 Return Value:
1127 None
1128
1129 IRQL = PASSIVE_LEVEL
1130 IRQL = DISPATCH_LEVEL
1131
1132 ========================================================================
1133*/
1134VOID RTMPWriteTxDescriptor(
1135 IN PRTMP_ADAPTER pAd,
1136 IN PTXD_STRUC pTxD,
1137 IN BOOLEAN bWIV,
1138 IN UCHAR QueueSEL)
1139{
1140 //
1141 // Always use Long preamble before verifiation short preamble functionality works well.
1142 // Todo: remove the following line if short preamble functionality works
1143 //
1144 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
1145
1146 pTxD->WIV = (bWIV) ? 1: 0;
1147 pTxD->QSEL= (QueueSEL);
1148 //RT2860c?? fixed using EDCA queue for test... We doubt Queue1 has problem. 2006-09-26 Jan
1149 //pTxD->QSEL= FIFO_EDCA;
1150 if (pAd->bGenOneHCCA == TRUE)
1151 pTxD->QSEL= FIFO_HCCA;
1152 pTxD->DMADONE = 0;
1153}
diff --git a/drivers/staging/rt2860/common/cmm_data_usb.c b/drivers/staging/rt2860/common/cmm_data_usb.c
new file mode 100644
index 00000000000..bd6f9d8de9b
--- /dev/null
+++ b/drivers/staging/rt2860/common/cmm_data_usb.c
@@ -0,0 +1,968 @@
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
37#include "../rt_config.h"
38
39
40/*
41 We can do copy the frame into pTxContext when match following conditions.
42 =>
43 =>
44 =>
45*/
46static inline NDIS_STATUS RtmpUSBCanDoWrite(
47 IN RTMP_ADAPTER *pAd,
48 IN UCHAR QueIdx,
49 IN HT_TX_CONTEXT *pHTTXContext)
50{
51 NDIS_STATUS canWrite = NDIS_STATUS_RESOURCES;
52
53 if (((pHTTXContext->CurWritePosition) < pHTTXContext->NextBulkOutPosition) && (pHTTXContext->CurWritePosition + LOCAL_TXBUF_SIZE) > pHTTXContext->NextBulkOutPosition)
54 {
55 DBGPRINT(RT_DEBUG_ERROR,("RtmpUSBCanDoWrite c1!\n"));
56 RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx));
57 }
58 else if ((pHTTXContext->CurWritePosition == 8) && (pHTTXContext->NextBulkOutPosition < LOCAL_TXBUF_SIZE))
59 {
60 DBGPRINT(RT_DEBUG_ERROR,("RtmpUSBCanDoWrite c2!\n"));
61 RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx));
62 }
63 else if (pHTTXContext->bCurWriting == TRUE)
64 {
65 DBGPRINT(RT_DEBUG_ERROR,("RtmpUSBCanDoWrite c3!\n"));
66 }
67 else
68 {
69 canWrite = NDIS_STATUS_SUCCESS;
70 }
71
72
73 return canWrite;
74}
75
76
77USHORT RtmpUSB_WriteSubTxResource(
78 IN PRTMP_ADAPTER pAd,
79 IN TX_BLK *pTxBlk,
80 IN BOOLEAN bIsLast,
81 OUT USHORT *FreeNumber)
82{
83
84 // Dummy function. Should be removed in the future.
85 return 0;
86
87}
88
89USHORT RtmpUSB_WriteFragTxResource(
90 IN PRTMP_ADAPTER pAd,
91 IN TX_BLK *pTxBlk,
92 IN UCHAR fragNum,
93 OUT USHORT *FreeNumber)
94{
95 HT_TX_CONTEXT *pHTTXContext;
96 USHORT hwHdrLen; // The hwHdrLen consist of 802.11 header length plus the header padding length.
97 UINT32 fillOffset;
98 TXINFO_STRUC *pTxInfo;
99 TXWI_STRUC *pTxWI;
100 PUCHAR pWirelessPacket = NULL;
101 UCHAR QueIdx;
102 NDIS_STATUS Status;
103 unsigned long IrqFlags;
104 UINT32 USBDMApktLen = 0, DMAHdrLen, padding;
105 BOOLEAN TxQLastRound = FALSE;
106
107 //
108 // get Tx Ring Resource & Dma Buffer address
109 //
110 QueIdx = pTxBlk->QueIdx;
111 pHTTXContext = &pAd->TxContext[QueIdx];
112
113 RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
114
115 pHTTXContext = &pAd->TxContext[QueIdx];
116 fillOffset = pHTTXContext->CurWritePosition;
117
118 if(fragNum == 0)
119 {
120 // Check if we have enough space for this bulk-out batch.
121 Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext);
122 if (Status == NDIS_STATUS_SUCCESS)
123 {
124 pHTTXContext->bCurWriting = TRUE;
125
126 // Reserve space for 8 bytes padding.
127 if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition))
128 {
129 pHTTXContext->ENextBulkOutPosition += 8;
130 pHTTXContext->CurWritePosition += 8;
131 fillOffset += 8;
132 }
133 pTxBlk->Priv = 0;
134 pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
135 }
136 else
137 {
138 RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
139
140 RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
141 return(Status);
142 }
143 }
144 else
145 {
146 // For sub-sequent frames of this bulk-out batch. Just copy it to our bulk-out buffer.
147 Status = ((pHTTXContext->bCurWriting == TRUE) ? NDIS_STATUS_SUCCESS : NDIS_STATUS_FAILURE);
148 if (Status == NDIS_STATUS_SUCCESS)
149 {
150 fillOffset += pTxBlk->Priv;
151 }
152 else
153 {
154 RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
155
156 RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
157 return(Status);
158 }
159 }
160
161 NdisZeroMemory((PUCHAR)(&pTxBlk->HeaderBuf[0]), TXINFO_SIZE);
162 pTxInfo = (PTXINFO_STRUC)(&pTxBlk->HeaderBuf[0]);
163 pTxWI= (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]);
164
165 pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset];
166
167 // copy TXWI + WLAN Header + LLC into DMA Header Buffer
168 //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4);
169 hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
170
171 // Build our URB for USBD
172 DMAHdrLen = TXWI_SIZE + hwHdrLen;
173 USBDMApktLen = DMAHdrLen + pTxBlk->SrcBufLen;
174 padding = (4 - (USBDMApktLen % 4)) & 0x03; // round up to 4 byte alignment
175 USBDMApktLen += padding;
176
177 pTxBlk->Priv += (TXINFO_SIZE + USBDMApktLen);
178
179 // For TxInfo, the length of USBDMApktLen = TXWI_SIZE + 802.11 header + payload
180 RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(USBDMApktLen), FALSE, FIFO_EDCA, FALSE /*NextValid*/, FALSE);
181
182 if (fragNum == pTxBlk->TotalFragNum)
183 {
184 pTxInfo->USBDMATxburst = 0;
185 if ((pHTTXContext->CurWritePosition + pTxBlk->Priv + 3906)> MAX_TXBULK_LIMIT)
186 {
187 pTxInfo->SwUseLastRound = 1;
188 TxQLastRound = TRUE;
189 }
190 }
191 else
192 {
193 pTxInfo->USBDMATxburst = 1;
194 }
195
196 NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
197 pWirelessPacket += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
198 pHTTXContext->CurWriteRealPos += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
199
200 RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
201
202 NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen);
203
204 // Zero the last padding.
205 pWirelessPacket += pTxBlk->SrcBufLen;
206 NdisZeroMemory(pWirelessPacket, padding + 8);
207
208 if (fragNum == pTxBlk->TotalFragNum)
209 {
210 RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
211
212 // Update the pHTTXContext->CurWritePosition. 3906 used to prevent the NextBulkOut is a A-RALINK/A-MSDU Frame.
213 pHTTXContext->CurWritePosition += pTxBlk->Priv;
214 if (TxQLastRound == TRUE)
215 pHTTXContext->CurWritePosition = 8;
216 pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
217
218
219 // Finally, set bCurWriting as FALSE
220 pHTTXContext->bCurWriting = FALSE;
221
222 RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
223
224 // succeed and release the skb buffer
225 RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS);
226 }
227
228
229 return(Status);
230
231}
232
233
234USHORT RtmpUSB_WriteSingleTxResource(
235 IN PRTMP_ADAPTER pAd,
236 IN TX_BLK *pTxBlk,
237 IN BOOLEAN bIsLast,
238 OUT USHORT *FreeNumber)
239{
240 HT_TX_CONTEXT *pHTTXContext;
241 USHORT hwHdrLen;
242 UINT32 fillOffset;
243 TXINFO_STRUC *pTxInfo;
244 TXWI_STRUC *pTxWI;
245 PUCHAR pWirelessPacket;
246 UCHAR QueIdx;
247 unsigned long IrqFlags;
248 NDIS_STATUS Status;
249 UINT32 USBDMApktLen = 0, DMAHdrLen, padding;
250 BOOLEAN bTxQLastRound = FALSE;
251
252 // For USB, didn't need PCI_MAP_SINGLE()
253 //SrcBufPA = PCI_MAP_SINGLE(pAd, (char *) pTxBlk->pSrcBufData, pTxBlk->SrcBufLen, PCI_DMA_TODEVICE);
254
255
256 //
257 // get Tx Ring Resource & Dma Buffer address
258 //
259 QueIdx = pTxBlk->QueIdx;
260
261 RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
262 pHTTXContext = &pAd->TxContext[QueIdx];
263 fillOffset = pHTTXContext->CurWritePosition;
264
265
266
267 // Check ring full.
268 Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext);
269 if(Status == NDIS_STATUS_SUCCESS)
270 {
271 pHTTXContext->bCurWriting = TRUE;
272
273 pTxInfo = (PTXINFO_STRUC)(&pTxBlk->HeaderBuf[0]);
274 pTxWI= (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]);
275
276 // Reserve space for 8 bytes padding.
277 if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition))
278 {
279 pHTTXContext->ENextBulkOutPosition += 8;
280 pHTTXContext->CurWritePosition += 8;
281 fillOffset += 8;
282 }
283 pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
284
285 pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset];
286
287 // copy TXWI + WLAN Header + LLC into DMA Header Buffer
288 //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4);
289 hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
290
291 // Build our URB for USBD
292 DMAHdrLen = TXWI_SIZE + hwHdrLen;
293 USBDMApktLen = DMAHdrLen + pTxBlk->SrcBufLen;
294 padding = (4 - (USBDMApktLen % 4)) & 0x03; // round up to 4 byte alignment
295 USBDMApktLen += padding;
296
297 pTxBlk->Priv = (TXINFO_SIZE + USBDMApktLen);
298
299 // For TxInfo, the length of USBDMApktLen = TXWI_SIZE + 802.11 header + payload
300 RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(USBDMApktLen), FALSE, FIFO_EDCA, FALSE /*NextValid*/, FALSE);
301
302 if ((pHTTXContext->CurWritePosition + 3906 + pTxBlk->Priv) > MAX_TXBULK_LIMIT)
303 {
304 pTxInfo->SwUseLastRound = 1;
305 bTxQLastRound = TRUE;
306 }
307 NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
308 pWirelessPacket += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
309
310 // We unlock it here to prevent the first 8 bytes maybe over-writed issue.
311 // 1. First we got CurWritePosition but the first 8 bytes still not write to the pTxcontext.
312 // 2. An interrupt break our routine and handle bulk-out complete.
313 // 3. In the bulk-out compllete, it need to do another bulk-out,
314 // if the ENextBulkOutPosition is just the same as CurWritePosition, it will save the first 8 bytes from CurWritePosition,
315 // but the payload still not copyed. the pTxContext->SavedPad[] will save as allzero. and set the bCopyPad = TRUE.
316 // 4. Interrupt complete.
317 // 5. Our interrupted routine go back and fill the first 8 bytes to pTxContext.
318 // 6. Next time when do bulk-out, it found the bCopyPad==TRUE and will copy the SavedPad[] to pTxContext->NextBulkOutPosition.
319 // and the packet will wrong.
320 pHTTXContext->CurWriteRealPos += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
321 RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
322
323 NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen);
324 pWirelessPacket += pTxBlk->SrcBufLen;
325 NdisZeroMemory(pWirelessPacket, padding + 8);
326
327 RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
328
329 pHTTXContext->CurWritePosition += pTxBlk->Priv;
330 if (bTxQLastRound)
331 pHTTXContext->CurWritePosition = 8;
332 pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
333
334 pHTTXContext->bCurWriting = FALSE;
335 }
336
337
338 RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
339
340
341 // succeed and release the skb buffer
342 RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS);
343
344 return(Status);
345
346}
347
348
349USHORT RtmpUSB_WriteMultiTxResource(
350 IN PRTMP_ADAPTER pAd,
351 IN TX_BLK *pTxBlk,
352 IN UCHAR frameNum,
353 OUT USHORT *FreeNumber)
354{
355 HT_TX_CONTEXT *pHTTXContext;
356 USHORT hwHdrLen; // The hwHdrLen consist of 802.11 header length plus the header padding length.
357 UINT32 fillOffset;
358 TXINFO_STRUC *pTxInfo;
359 TXWI_STRUC *pTxWI;
360 PUCHAR pWirelessPacket = NULL;
361 UCHAR QueIdx;
362 NDIS_STATUS Status;
363 unsigned long IrqFlags;
364 //UINT32 USBDMApktLen = 0, DMAHdrLen, padding;
365
366 //
367 // get Tx Ring Resource & Dma Buffer address
368 //
369 QueIdx = pTxBlk->QueIdx;
370 pHTTXContext = &pAd->TxContext[QueIdx];
371
372 RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
373
374 if(frameNum == 0)
375 {
376 // Check if we have enough space for this bulk-out batch.
377 Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext);
378 if (Status == NDIS_STATUS_SUCCESS)
379 {
380 pHTTXContext->bCurWriting = TRUE;
381
382 pTxInfo = (PTXINFO_STRUC)(&pTxBlk->HeaderBuf[0]);
383 pTxWI= (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]);
384
385
386 // Reserve space for 8 bytes padding.
387 if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition))
388 {
389
390 pHTTXContext->CurWritePosition += 8;
391 pHTTXContext->ENextBulkOutPosition += 8;
392 }
393 fillOffset = pHTTXContext->CurWritePosition;
394 pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
395
396 pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset];
397
398 //
399 // Copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer
400 //
401 if (pTxBlk->TxFrameType == TX_AMSDU_FRAME)
402 //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD, 4)+LENGTH_AMSDU_SUBFRAMEHEAD;
403 hwHdrLen = pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD + pTxBlk->HdrPadLen + LENGTH_AMSDU_SUBFRAMEHEAD;
404 else if (pTxBlk->TxFrameType == TX_RALINK_FRAME)
405 //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_ARALINK_HEADER_FIELD, 4)+LENGTH_ARALINK_HEADER_FIELD;
406 hwHdrLen = pTxBlk->MpduHeaderLen-LENGTH_ARALINK_HEADER_FIELD + pTxBlk->HdrPadLen + LENGTH_ARALINK_HEADER_FIELD;
407 else
408 //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4);
409 hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
410
411 // Update the pTxBlk->Priv.
412 pTxBlk->Priv = TXINFO_SIZE + TXWI_SIZE + hwHdrLen;
413
414 // pTxInfo->USBDMApktLen now just a temp value and will to correct latter.
415 RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(pTxBlk->Priv), FALSE, FIFO_EDCA, FALSE /*NextValid*/, FALSE);
416
417 // Copy it.
418 NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, pTxBlk->Priv);
419 pHTTXContext->CurWriteRealPos += pTxBlk->Priv;
420 pWirelessPacket += pTxBlk->Priv;
421 }
422 }
423 else
424 { // For sub-sequent frames of this bulk-out batch. Just copy it to our bulk-out buffer.
425
426 Status = ((pHTTXContext->bCurWriting == TRUE) ? NDIS_STATUS_SUCCESS : NDIS_STATUS_FAILURE);
427 if (Status == NDIS_STATUS_SUCCESS)
428 {
429 fillOffset = (pHTTXContext->CurWritePosition + pTxBlk->Priv);
430 pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset];
431
432 //hwHdrLen = pTxBlk->MpduHeaderLen;
433 NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, pTxBlk->MpduHeaderLen);
434 pWirelessPacket += (pTxBlk->MpduHeaderLen);
435 pTxBlk->Priv += pTxBlk->MpduHeaderLen;
436 }
437 else
438 { // It should not happened now unless we are going to shutdown.
439 DBGPRINT(RT_DEBUG_ERROR, ("WriteMultiTxResource():bCurWriting is FALSE when handle sub-sequent frames.\n"));
440 Status = NDIS_STATUS_FAILURE;
441 }
442 }
443
444
445 // We unlock it here to prevent the first 8 bytes maybe over-write issue.
446 // 1. First we got CurWritePosition but the first 8 bytes still not write to the pTxContext.
447 // 2. An interrupt break our routine and handle bulk-out complete.
448 // 3. In the bulk-out compllete, it need to do another bulk-out,
449 // if the ENextBulkOutPosition is just the same as CurWritePosition, it will save the first 8 bytes from CurWritePosition,
450 // but the payload still not copyed. the pTxContext->SavedPad[] will save as allzero. and set the bCopyPad = TRUE.
451 // 4. Interrupt complete.
452 // 5. Our interrupted routine go back and fill the first 8 bytes to pTxContext.
453 // 6. Next time when do bulk-out, it found the bCopyPad==TRUE and will copy the SavedPad[] to pTxContext->NextBulkOutPosition.
454 // and the packet will wrong.
455 RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
456
457 if (Status != NDIS_STATUS_SUCCESS)
458 {
459 DBGPRINT(RT_DEBUG_ERROR,("WriteMultiTxResource: CWPos = %ld, NBOutPos = %ld.\n", pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition));
460 goto done;
461 }
462
463 // Copy the frame content into DMA buffer and update the pTxBlk->Priv
464 NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen);
465 pWirelessPacket += pTxBlk->SrcBufLen;
466 pTxBlk->Priv += pTxBlk->SrcBufLen;
467
468done:
469 // Release the skb buffer here
470 RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS);
471
472 return(Status);
473
474}
475
476
477VOID RtmpUSB_FinalWriteTxResource(
478 IN PRTMP_ADAPTER pAd,
479 IN TX_BLK *pTxBlk,
480 IN USHORT totalMPDUSize,
481 IN USHORT TxIdx)
482{
483 UCHAR QueIdx;
484 HT_TX_CONTEXT *pHTTXContext;
485 UINT32 fillOffset;
486 TXINFO_STRUC *pTxInfo;
487 TXWI_STRUC *pTxWI;
488 UINT32 USBDMApktLen, padding;
489 unsigned long IrqFlags;
490 PUCHAR pWirelessPacket;
491
492 QueIdx = pTxBlk->QueIdx;
493 pHTTXContext = &pAd->TxContext[QueIdx];
494
495 RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
496
497 if (pHTTXContext->bCurWriting == TRUE)
498 {
499 fillOffset = pHTTXContext->CurWritePosition;
500 if (((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition) || ((pHTTXContext->ENextBulkOutPosition-8) == pHTTXContext->CurWritePosition))
501 && (pHTTXContext->bCopySavePad == TRUE))
502 pWirelessPacket = (PUCHAR)(&pHTTXContext->SavedPad[0]);
503 else
504 pWirelessPacket = (PUCHAR)(&pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset]);
505
506 //
507 // Update TxInfo->USBDMApktLen ,
508 // the length = TXWI_SIZE + 802.11_hdr + 802.11_hdr_pad + payload_of_all_batch_frames + Bulk-Out-padding
509 //
510 pTxInfo = (PTXINFO_STRUC)(pWirelessPacket);
511
512 // Calculate the bulk-out padding
513 USBDMApktLen = pTxBlk->Priv - TXINFO_SIZE;
514 padding = (4 - (USBDMApktLen % 4)) & 0x03; // round up to 4 byte alignment
515 USBDMApktLen += padding;
516
517 pTxInfo->USBDMATxPktLen = USBDMApktLen;
518
519 //
520 // Update TXWI->MPDUtotalByteCount ,
521 // the length = 802.11 header + payload_of_all_batch_frames
522 pTxWI= (PTXWI_STRUC)(pWirelessPacket + TXINFO_SIZE);
523 pTxWI->MPDUtotalByteCount = totalMPDUSize;
524
525 //
526 // Update the pHTTXContext->CurWritePosition
527 //
528 pHTTXContext->CurWritePosition += (TXINFO_SIZE + USBDMApktLen);
529 if ((pHTTXContext->CurWritePosition + 3906)> MAX_TXBULK_LIMIT)
530 { // Add 3906 for prevent the NextBulkOut packet size is a A-RALINK/A-MSDU Frame.
531 pHTTXContext->CurWritePosition = 8;
532 pTxInfo->SwUseLastRound = 1;
533 }
534 pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
535
536
537 //
538 // Zero the last padding.
539 //
540 pWirelessPacket = (&pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset + pTxBlk->Priv]);
541 NdisZeroMemory(pWirelessPacket, padding + 8);
542
543 // Finally, set bCurWriting as FALSE
544 pHTTXContext->bCurWriting = FALSE;
545
546 }
547 else
548 { // It should not happened now unless we are going to shutdown.
549 DBGPRINT(RT_DEBUG_ERROR, ("FinalWriteTxResource():bCurWriting is FALSE when handle last frames.\n"));
550 }
551
552 RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
553
554}
555
556
557VOID RtmpUSBDataLastTxIdx(
558 IN PRTMP_ADAPTER pAd,
559 IN UCHAR QueIdx,
560 IN USHORT TxIdx)
561{
562 // DO nothing for USB.
563}
564
565
566/*
567 When can do bulk-out:
568 1. TxSwFreeIdx < TX_RING_SIZE;
569 It means has at least one Ring entity is ready for bulk-out, kick it out.
570 2. If TxSwFreeIdx == TX_RING_SIZE
571 Check if the CurWriting flag is FALSE, if it's FALSE, we can do kick out.
572
573*/
574VOID RtmpUSBDataKickOut(
575 IN PRTMP_ADAPTER pAd,
576 IN TX_BLK *pTxBlk,
577 IN UCHAR QueIdx)
578{
579 RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx));
580 RTUSBKickBulkOut(pAd);
581
582}
583
584
585/*
586 Must be run in Interrupt context
587 This function handle RT2870 specific TxDesc and cpu index update and kick the packet out.
588 */
589int RtmpUSBMgmtKickOut(
590 IN RTMP_ADAPTER *pAd,
591 IN UCHAR QueIdx,
592 IN PNDIS_PACKET pPacket,
593 IN PUCHAR pSrcBufVA,
594 IN UINT SrcBufLen)
595{
596 PTXINFO_STRUC pTxInfo;
597 ULONG BulkOutSize;
598 UCHAR padLen;
599 PUCHAR pDest;
600 ULONG SwIdx = pAd->MgmtRing.TxCpuIdx;
601 PTX_CONTEXT pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[SwIdx].AllocVa;
602 unsigned long IrqFlags;
603
604
605 pTxInfo = (PTXINFO_STRUC)(pSrcBufVA);
606
607 // Build our URB for USBD
608 BulkOutSize = SrcBufLen;
609 BulkOutSize = (BulkOutSize + 3) & (~3);
610 RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(BulkOutSize - TXINFO_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
611
612 BulkOutSize += 4; // Always add 4 extra bytes at every packet.
613
614 // If BulkOutSize is multiple of BulkOutMaxPacketSize, add extra 4 bytes again.
615 if ((BulkOutSize % pAd->BulkOutMaxPacketSize) == 0)
616 BulkOutSize += 4;
617
618 padLen = BulkOutSize - SrcBufLen;
619 ASSERT((padLen <= RTMP_PKT_TAIL_PADDING));
620
621 // Now memzero all extra padding bytes.
622 pDest = (PUCHAR)(pSrcBufVA + SrcBufLen);
623 skb_put(GET_OS_PKT_TYPE(pPacket), padLen);
624 NdisZeroMemory(pDest, padLen);
625
626 RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags);
627
628 pAd->MgmtRing.Cell[pAd->MgmtRing.TxCpuIdx].pNdisPacket = pPacket;
629 pMLMEContext->TransferBuffer = (PTX_BUFFER)(GET_OS_PKT_DATAPTR(pPacket));
630
631 // Length in TxInfo should be 8 less than bulkout size.
632 pMLMEContext->BulkOutSize = BulkOutSize;
633 pMLMEContext->InUse = TRUE;
634 pMLMEContext->bWaitingBulkOut = TRUE;
635
636
637 //for debug
638 //hex_dump("RtmpUSBMgmtKickOut", &pMLMEContext->TransferBuffer->field.WirelessPacket[0], (pMLMEContext->BulkOutSize > 16 ? 16 : pMLMEContext->BulkOutSize));
639
640 //pAd->RalinkCounters.KickTxCount++;
641 //pAd->RalinkCounters.OneSecTxDoneCount++;
642
643 //if (pAd->MgmtRing.TxSwFreeIdx == MGMT_RING_SIZE)
644 // needKickOut = TRUE;
645
646 // Decrease the TxSwFreeIdx and Increase the TX_CTX_IDX
647 pAd->MgmtRing.TxSwFreeIdx--;
648 INC_RING_INDEX(pAd->MgmtRing.TxCpuIdx, MGMT_RING_SIZE);
649
650 RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags);
651
652 RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
653 //if (needKickOut)
654 RTUSBKickBulkOut(pAd);
655
656 return 0;
657}
658
659
660VOID RtmpUSBNullFrameKickOut(
661 IN RTMP_ADAPTER *pAd,
662 IN UCHAR QueIdx,
663 IN UCHAR *pNullFrame,
664 IN UINT32 frameLen)
665{
666 if (pAd->NullContext.InUse == FALSE)
667 {
668 PTX_CONTEXT pNullContext;
669 PTXINFO_STRUC pTxInfo;
670 PTXWI_STRUC pTxWI;
671 PUCHAR pWirelessPkt;
672
673 pNullContext = &(pAd->NullContext);
674
675 // Set the in use bit
676 pNullContext->InUse = TRUE;
677 pWirelessPkt = (PUCHAR)&pNullContext->TransferBuffer->field.WirelessPacket[0];
678
679 RTMPZeroMemory(&pWirelessPkt[0], 100);
680 pTxInfo = (PTXINFO_STRUC)&pWirelessPkt[0];
681 RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(sizeof(HEADER_802_11)+TXWI_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
682 pTxInfo->QSEL = FIFO_EDCA;
683 pTxWI = (PTXWI_STRUC)&pWirelessPkt[TXINFO_SIZE];
684 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, BSSID_WCID, (sizeof(HEADER_802_11)),
685 0, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_HTTXOP, FALSE, &pAd->CommonCfg.MlmeTransmit);
686
687 RTMPMoveMemory(&pWirelessPkt[TXWI_SIZE+TXINFO_SIZE], &pAd->NullFrame, sizeof(HEADER_802_11));
688 pAd->NullContext.BulkOutSize = TXINFO_SIZE + TXWI_SIZE + sizeof(pAd->NullFrame) + 4;
689
690 // Fill out frame length information for global Bulk out arbitor
691 //pNullContext->BulkOutSize = TransferBufferLength;
692 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - send NULL Frame @%d Mbps...\n", RateIdToMbps[pAd->CommonCfg.TxRate]));
693 RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL);
694
695 // Kick bulk out
696 RTUSBKickBulkOut(pAd);
697 }
698
699}
700
701
702/*
703========================================================================
704Routine Description:
705 Get a received packet.
706
707Arguments:
708 pAd device control block
709 pSaveRxD receive descriptor information
710 *pbReschedule need reschedule flag
711 *pRxPending pending received packet flag
712
713Return Value:
714 the recieved packet
715
716Note:
717========================================================================
718*/
719PNDIS_PACKET GetPacketFromRxRing(
720 IN PRTMP_ADAPTER pAd,
721 OUT PRT28XX_RXD_STRUC pSaveRxD,
722 OUT BOOLEAN *pbReschedule,
723 IN OUT UINT32 *pRxPending)
724{
725 PRX_CONTEXT pRxContext;
726 PNDIS_PACKET pSkb;
727 PUCHAR pData;
728 ULONG ThisFrameLen;
729 ULONG RxBufferLength;
730 PRXWI_STRUC pRxWI;
731
732 pRxContext = &pAd->RxContext[pAd->NextRxBulkInReadIndex];
733 if ((pRxContext->Readable == FALSE) || (pRxContext->InUse == TRUE))
734 return NULL;
735
736 RxBufferLength = pRxContext->BulkInOffset - pAd->ReadPosition;
737 if (RxBufferLength < (RT2870_RXDMALEN_FIELD_SIZE + sizeof(RXWI_STRUC) + sizeof(RXINFO_STRUC)))
738 {
739 goto label_null;
740 }
741
742 pData = &pRxContext->TransferBuffer[pAd->ReadPosition]; /* 4KB */
743 // The RXDMA field is 4 bytes, now just use the first 2 bytes. The Length including the (RXWI + MSDU + Padding)
744 ThisFrameLen = *pData + (*(pData+1)<<8);
745 if (ThisFrameLen == 0)
746 {
747 DBGPRINT(RT_DEBUG_TRACE, ("BIRIdx(%d): RXDMALen is zero.[%ld], BulkInBufLen = %ld)\n",
748 pAd->NextRxBulkInReadIndex, ThisFrameLen, pRxContext->BulkInOffset));
749 goto label_null;
750 }
751 if ((ThisFrameLen&0x3) != 0)
752 {
753 DBGPRINT(RT_DEBUG_ERROR, ("BIRIdx(%d): RXDMALen not multiple of 4.[%ld], BulkInBufLen = %ld)\n",
754 pAd->NextRxBulkInReadIndex, ThisFrameLen, pRxContext->BulkInOffset));
755 goto label_null;
756 }
757
758 if ((ThisFrameLen + 8)> RxBufferLength) // 8 for (RT2870_RXDMALEN_FIELD_SIZE + sizeof(RXINFO_STRUC))
759 {
760 DBGPRINT(RT_DEBUG_TRACE,("BIRIdx(%d):FrameLen(0x%lx) outranges. BulkInLen=0x%lx, remaining RxBufLen=0x%lx, ReadPos=0x%lx\n",
761 pAd->NextRxBulkInReadIndex, ThisFrameLen, pRxContext->BulkInOffset, RxBufferLength, pAd->ReadPosition));
762
763 // error frame. finish this loop
764 goto label_null;
765 }
766
767 // skip USB frame length field
768 pData += RT2870_RXDMALEN_FIELD_SIZE;
769 pRxWI = (PRXWI_STRUC)pData;
770 if (pRxWI->MPDUtotalByteCount > ThisFrameLen)
771 {
772 DBGPRINT(RT_DEBUG_ERROR, ("%s():pRxWIMPDUtotalByteCount(%d) large than RxDMALen(%ld)\n",
773 __FUNCTION__, pRxWI->MPDUtotalByteCount, ThisFrameLen));
774 goto label_null;
775 }
776
777 // allocate a rx packet
778 pSkb = dev_alloc_skb(ThisFrameLen);
779 if (pSkb == NULL)
780 {
781 DBGPRINT(RT_DEBUG_ERROR,("%s():Cannot Allocate sk buffer for this Bulk-In buffer!\n", __FUNCTION__));
782 goto label_null;
783 }
784
785 // copy the rx packet
786 memcpy(skb_put(pSkb, ThisFrameLen), pData, ThisFrameLen);
787 RTPKT_TO_OSPKT(pSkb)->dev = get_netdev_from_bssid(pAd, BSS0);
788 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pSkb), PKTSRC_NDIS);
789
790 // copy RxD
791 *pSaveRxD = *(PRXINFO_STRUC)(pData + ThisFrameLen);
792
793 // update next packet read position.
794 pAd->ReadPosition += (ThisFrameLen + RT2870_RXDMALEN_FIELD_SIZE + RXINFO_SIZE); // 8 for (RT2870_RXDMALEN_FIELD_SIZE + sizeof(RXINFO_STRUC))
795
796 return pSkb;
797
798label_null:
799
800 return NULL;
801}
802
803
804/*
805 ========================================================================
806
807 Routine Description:
808 Check Rx descriptor, return NDIS_STATUS_FAILURE if any error dound
809
810 Arguments:
811 pRxD Pointer to the Rx descriptor
812
813 Return Value:
814 NDIS_STATUS_SUCCESS No err
815 NDIS_STATUS_FAILURE Error
816
817 Note:
818
819 ========================================================================
820*/
821NDIS_STATUS RTMPCheckRxError(
822 IN PRTMP_ADAPTER pAd,
823 IN PHEADER_802_11 pHeader,
824 IN PRXWI_STRUC pRxWI,
825 IN PRT28XX_RXD_STRUC pRxINFO)
826{
827 PCIPHER_KEY pWpaKey;
828 INT dBm;
829
830 if (pAd->bPromiscuous == TRUE)
831 return(NDIS_STATUS_SUCCESS);
832 if(pRxINFO == NULL)
833 return(NDIS_STATUS_FAILURE);
834
835 // Phy errors & CRC errors
836 if (pRxINFO->Crc)
837 {
838 // Check RSSI for Noise Hist statistic collection.
839 dBm = (INT) (pRxWI->RSSI0) - pAd->BbpRssiToDbmDelta;
840 if (dBm <= -87)
841 pAd->StaCfg.RPIDensity[0] += 1;
842 else if (dBm <= -82)
843 pAd->StaCfg.RPIDensity[1] += 1;
844 else if (dBm <= -77)
845 pAd->StaCfg.RPIDensity[2] += 1;
846 else if (dBm <= -72)
847 pAd->StaCfg.RPIDensity[3] += 1;
848 else if (dBm <= -67)
849 pAd->StaCfg.RPIDensity[4] += 1;
850 else if (dBm <= -62)
851 pAd->StaCfg.RPIDensity[5] += 1;
852 else if (dBm <= -57)
853 pAd->StaCfg.RPIDensity[6] += 1;
854 else if (dBm > -57)
855 pAd->StaCfg.RPIDensity[7] += 1;
856
857 return(NDIS_STATUS_FAILURE);
858 }
859
860 // Add Rx size to channel load counter, we should ignore error counts
861 pAd->StaCfg.CLBusyBytes += (pRxWI->MPDUtotalByteCount+ 14);
862
863 // Drop ToDs promiscous frame, it is opened due to CCX 2 channel load statistics
864 if (pHeader->FC.ToDs)
865 {
866 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Err;FC.ToDs\n"));
867 return NDIS_STATUS_FAILURE;
868 }
869
870 // Paul 04-03 for OFDM Rx length issue
871 if (pRxWI->MPDUtotalByteCount > MAX_AGGREGATION_SIZE)
872 {
873 DBGPRINT_RAW(RT_DEBUG_ERROR, ("received packet too long\n"));
874 return NDIS_STATUS_FAILURE;
875 }
876
877 // Drop not U2M frames, cant's drop here because we will drop beacon in this case
878 // I am kind of doubting the U2M bit operation
879 // if (pRxD->U2M == 0)
880 // return(NDIS_STATUS_FAILURE);
881
882 // drop decyption fail frame
883 if (pRxINFO->Decrypted && pRxINFO->CipherErr)
884 {
885
886 if (((pRxINFO->CipherErr & 1) == 1) && pAd->CommonCfg.bWirelessEvent && INFRA_ON(pAd))
887 RTMPSendWirelessEvent(pAd, IW_ICV_ERROR_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
888
889 if (((pRxINFO->CipherErr & 2) == 2) && pAd->CommonCfg.bWirelessEvent && INFRA_ON(pAd))
890 RTMPSendWirelessEvent(pAd, IW_MIC_ERROR_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
891 //
892 // MIC Error
893 //
894 if ((pRxINFO->CipherErr == 2) && pRxINFO->MyBss)
895 {
896 pWpaKey = &pAd->SharedKey[BSS0][pRxWI->KeyIndex];
897 RTMPReportMicError(pAd, pWpaKey);
898 DBGPRINT_RAW(RT_DEBUG_ERROR,("Rx MIC Value error\n"));
899 }
900
901 if (pRxINFO->Decrypted &&
902 (pAd->SharedKey[BSS0][pRxWI->KeyIndex].CipherAlg == CIPHER_AES) &&
903 (pHeader->Sequence == pAd->FragFrame.Sequence))
904 {
905 //
906 // Acceptable since the First FragFrame no CipherErr problem.
907 //
908 return(NDIS_STATUS_SUCCESS);
909 }
910
911 return(NDIS_STATUS_FAILURE);
912 }
913
914 return(NDIS_STATUS_SUCCESS);
915}
916
917VOID RtmpUsbStaAsicForceWakeupTimeout(
918 IN PVOID SystemSpecific1,
919 IN PVOID FunctionContext,
920 IN PVOID SystemSpecific2,
921 IN PVOID SystemSpecific3)
922{
923 RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
924
925
926 if (pAd && pAd->Mlme.AutoWakeupTimerRunning)
927 {
928 AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02);
929
930 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
931 pAd->Mlme.AutoWakeupTimerRunning = FALSE;
932 }
933}
934
935VOID RT28xxUsbStaAsicForceWakeup(
936 IN PRTMP_ADAPTER pAd,
937 IN BOOLEAN bFromTx)
938{
939 BOOLEAN Canceled;
940
941 if (pAd->Mlme.AutoWakeupTimerRunning)
942 RTMPCancelTimer(&pAd->Mlme.AutoWakeupTimer, &Canceled);
943
944 AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02);
945
946 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
947}
948
949VOID RT28xxUsbStaAsicSleepThenAutoWakeup(
950 IN PRTMP_ADAPTER pAd,
951 IN USHORT TbttNumToNextWakeUp)
952{
953
954
955 // we have decided to SLEEP, so at least do it for a BEACON period.
956 if (TbttNumToNextWakeUp == 0)
957 TbttNumToNextWakeUp = 1;
958
959 RTMPSetTimer(&pAd->Mlme.AutoWakeupTimer, AUTO_WAKEUP_TIMEOUT);
960 pAd->Mlme.AutoWakeupTimerRunning = TRUE;
961
962 AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02); // send POWER-SAVE command to MCU. Timeout 40us.
963
964 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_DOZE);
965
966}
967
968#endif // RTMP_MAC_USB //
diff --git a/drivers/staging/rt2860/common/cmm_info.c b/drivers/staging/rt2860/common/cmm_info.c
index 019cc4474ce..49e9bdfad3d 100644
--- a/drivers/staging/rt2860/common/cmm_info.c
+++ b/drivers/staging/rt2860/common/cmm_info.c
@@ -23,154 +23,154 @@
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * * 24 * *
25 ************************************************************************* 25 *************************************************************************
26*/ 26 */
27 27
28#include <linux/sched.h> 28#include <linux/sched.h>
29#include "../rt_config.h" 29#include "../rt_config.h"
30 30
31INT Show_SSID_Proc( 31INT Show_SSID_Proc(
32 IN PRTMP_ADAPTER pAd, 32 IN PRTMP_ADAPTER pAd,
33 OUT PUCHAR pBuf); 33 OUT PSTRING pBuf);
34 34
35INT Show_WirelessMode_Proc( 35INT Show_WirelessMode_Proc(
36 IN PRTMP_ADAPTER pAd, 36 IN PRTMP_ADAPTER pAd,
37 OUT PUCHAR pBuf); 37 OUT PSTRING pBuf);
38 38
39INT Show_TxBurst_Proc( 39INT Show_TxBurst_Proc(
40 IN PRTMP_ADAPTER pAd, 40 IN PRTMP_ADAPTER pAd,
41 OUT PUCHAR pBuf); 41 OUT PSTRING pBuf);
42 42
43INT Show_TxPreamble_Proc( 43INT Show_TxPreamble_Proc(
44 IN PRTMP_ADAPTER pAd, 44 IN PRTMP_ADAPTER pAd,
45 OUT PUCHAR pBuf); 45 OUT PSTRING pBuf);
46 46
47INT Show_TxPower_Proc( 47INT Show_TxPower_Proc(
48 IN PRTMP_ADAPTER pAd, 48 IN PRTMP_ADAPTER pAd,
49 OUT PUCHAR pBuf); 49 OUT PSTRING pBuf);
50 50
51INT Show_Channel_Proc( 51INT Show_Channel_Proc(
52 IN PRTMP_ADAPTER pAd, 52 IN PRTMP_ADAPTER pAd,
53 OUT PUCHAR pBuf); 53 OUT PSTRING pBuf);
54 54
55INT Show_BGProtection_Proc( 55INT Show_BGProtection_Proc(
56 IN PRTMP_ADAPTER pAd, 56 IN PRTMP_ADAPTER pAd,
57 OUT PUCHAR pBuf); 57 OUT PSTRING pBuf);
58 58
59INT Show_RTSThreshold_Proc( 59INT Show_RTSThreshold_Proc(
60 IN PRTMP_ADAPTER pAd, 60 IN PRTMP_ADAPTER pAd,
61 OUT PUCHAR pBuf); 61 OUT PSTRING pBuf);
62 62
63INT Show_FragThreshold_Proc( 63INT Show_FragThreshold_Proc(
64 IN PRTMP_ADAPTER pAd, 64 IN PRTMP_ADAPTER pAd,
65 OUT PUCHAR pBuf); 65 OUT PSTRING pBuf);
66 66
67INT Show_HtBw_Proc( 67INT Show_HtBw_Proc(
68 IN PRTMP_ADAPTER pAd, 68 IN PRTMP_ADAPTER pAd,
69 OUT PUCHAR pBuf); 69 OUT PSTRING pBuf);
70 70
71INT Show_HtMcs_Proc( 71INT Show_HtMcs_Proc(
72 IN PRTMP_ADAPTER pAd, 72 IN PRTMP_ADAPTER pAd,
73 OUT PUCHAR pBuf); 73 OUT PSTRING pBuf);
74 74
75INT Show_HtGi_Proc( 75INT Show_HtGi_Proc(
76 IN PRTMP_ADAPTER pAd, 76 IN PRTMP_ADAPTER pAd,
77 OUT PUCHAR pBuf); 77 OUT PSTRING pBuf);
78 78
79INT Show_HtOpMode_Proc( 79INT Show_HtOpMode_Proc(
80 IN PRTMP_ADAPTER pAd, 80 IN PRTMP_ADAPTER pAd,
81 OUT PUCHAR pBuf); 81 OUT PSTRING pBuf);
82 82
83INT Show_HtExtcha_Proc( 83INT Show_HtExtcha_Proc(
84 IN PRTMP_ADAPTER pAd, 84 IN PRTMP_ADAPTER pAd,
85 OUT PUCHAR pBuf); 85 OUT PSTRING pBuf);
86 86
87INT Show_HtMpduDensity_Proc( 87INT Show_HtMpduDensity_Proc(
88 IN PRTMP_ADAPTER pAd, 88 IN PRTMP_ADAPTER pAd,
89 OUT PUCHAR pBuf); 89 OUT PSTRING pBuf);
90 90
91INT Show_HtBaWinSize_Proc( 91INT Show_HtBaWinSize_Proc(
92 IN PRTMP_ADAPTER pAd, 92 IN PRTMP_ADAPTER pAd,
93 OUT PUCHAR pBuf); 93 OUT PSTRING pBuf);
94 94
95INT Show_HtRdg_Proc( 95INT Show_HtRdg_Proc(
96 IN PRTMP_ADAPTER pAd, 96 IN PRTMP_ADAPTER pAd,
97 OUT PUCHAR pBuf); 97 OUT PSTRING pBuf);
98 98
99INT Show_HtAmsdu_Proc( 99INT Show_HtAmsdu_Proc(
100 IN PRTMP_ADAPTER pAd, 100 IN PRTMP_ADAPTER pAd,
101 OUT PUCHAR pBuf); 101 OUT PSTRING pBuf);
102 102
103INT Show_HtAutoBa_Proc( 103INT Show_HtAutoBa_Proc(
104 IN PRTMP_ADAPTER pAd, 104 IN PRTMP_ADAPTER pAd,
105 OUT PUCHAR pBuf); 105 OUT PSTRING pBuf);
106 106
107INT Show_CountryRegion_Proc( 107INT Show_CountryRegion_Proc(
108 IN PRTMP_ADAPTER pAd, 108 IN PRTMP_ADAPTER pAd,
109 OUT PUCHAR pBuf); 109 OUT PSTRING pBuf);
110 110
111INT Show_CountryRegionABand_Proc( 111INT Show_CountryRegionABand_Proc(
112 IN PRTMP_ADAPTER pAd, 112 IN PRTMP_ADAPTER pAd,
113 OUT PUCHAR pBuf); 113 OUT PSTRING pBuf);
114 114
115INT Show_CountryCode_Proc( 115INT Show_CountryCode_Proc(
116 IN PRTMP_ADAPTER pAd, 116 IN PRTMP_ADAPTER pAd,
117 OUT PUCHAR pBuf); 117 OUT PSTRING pBuf);
118 118
119#ifdef AGGREGATION_SUPPORT 119#ifdef AGGREGATION_SUPPORT
120INT Show_PktAggregate_Proc( 120INT Show_PktAggregate_Proc(
121 IN PRTMP_ADAPTER pAd, 121 IN PRTMP_ADAPTER pAd,
122 OUT PUCHAR pBuf); 122 OUT PSTRING pBuf);
123#endif // AGGREGATION_SUPPORT // 123#endif // AGGREGATION_SUPPORT //
124 124
125#ifdef WMM_SUPPORT 125#ifdef WMM_SUPPORT
126INT Show_WmmCapable_Proc( 126INT Show_WmmCapable_Proc(
127 IN PRTMP_ADAPTER pAd, 127 IN PRTMP_ADAPTER pAd,
128 OUT PUCHAR pBuf); 128 OUT PSTRING pBuf);
129#endif // WMM_SUPPORT // 129#endif // WMM_SUPPORT //
130 130
131INT Show_IEEE80211H_Proc( 131INT Show_IEEE80211H_Proc(
132 IN PRTMP_ADAPTER pAd, 132 IN PRTMP_ADAPTER pAd,
133 OUT PUCHAR pBuf); 133 OUT PSTRING pBuf);
134 134
135INT Show_NetworkType_Proc( 135INT Show_NetworkType_Proc(
136 IN PRTMP_ADAPTER pAd, 136 IN PRTMP_ADAPTER pAd,
137 OUT PUCHAR pBuf); 137 OUT PSTRING pBuf);
138 138
139INT Show_AuthMode_Proc( 139INT Show_AuthMode_Proc(
140 IN PRTMP_ADAPTER pAd, 140 IN PRTMP_ADAPTER pAd,
141 OUT PUCHAR pBuf); 141 OUT PSTRING pBuf);
142 142
143INT Show_EncrypType_Proc( 143INT Show_EncrypType_Proc(
144 IN PRTMP_ADAPTER pAd, 144 IN PRTMP_ADAPTER pAd,
145 OUT PUCHAR pBuf); 145 OUT PSTRING pBuf);
146 146
147INT Show_DefaultKeyID_Proc( 147INT Show_DefaultKeyID_Proc(
148 IN PRTMP_ADAPTER pAd, 148 IN PRTMP_ADAPTER pAd,
149 OUT PUCHAR pBuf); 149 OUT PSTRING pBuf);
150 150
151INT Show_Key1_Proc( 151INT Show_Key1_Proc(
152 IN PRTMP_ADAPTER pAd, 152 IN PRTMP_ADAPTER pAd,
153 OUT PUCHAR pBuf); 153 OUT PSTRING pBuf);
154 154
155INT Show_Key2_Proc( 155INT Show_Key2_Proc(
156 IN PRTMP_ADAPTER pAd, 156 IN PRTMP_ADAPTER pAd,
157 OUT PUCHAR pBuf); 157 OUT PSTRING pBuf);
158 158
159INT Show_Key3_Proc( 159INT Show_Key3_Proc(
160 IN PRTMP_ADAPTER pAd, 160 IN PRTMP_ADAPTER pAd,
161 OUT PUCHAR pBuf); 161 OUT PSTRING pBuf);
162 162
163INT Show_Key4_Proc( 163INT Show_Key4_Proc(
164 IN PRTMP_ADAPTER pAd, 164 IN PRTMP_ADAPTER pAd,
165 OUT PUCHAR pBuf); 165 OUT PSTRING pBuf);
166 166
167INT Show_WPAPSK_Proc( 167INT Show_WPAPSK_Proc(
168 IN PRTMP_ADAPTER pAd, 168 IN PRTMP_ADAPTER pAd,
169 OUT PUCHAR pBuf); 169 OUT PSTRING pBuf);
170 170
171static struct { 171static struct {
172 CHAR *name; 172 PSTRING name;
173 INT (*show_proc)(PRTMP_ADAPTER pAdapter, PUCHAR arg); 173 INT (*show_proc)(PRTMP_ADAPTER pAdapter, PSTRING arg);
174} *PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC, RTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC[] = { 174} *PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC, RTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC[] = {
175 {"SSID", Show_SSID_Proc}, 175 {"SSID", Show_SSID_Proc},
176 {"WirelessMode", Show_WirelessMode_Proc}, 176 {"WirelessMode", Show_WirelessMode_Proc},
@@ -224,8 +224,9 @@ static struct {
224*/ 224*/
225INT Set_DriverVersion_Proc( 225INT Set_DriverVersion_Proc(
226 IN PRTMP_ADAPTER pAd, 226 IN PRTMP_ADAPTER pAd,
227 IN PUCHAR arg) 227 IN PSTRING arg)
228{ 228{
229
229 DBGPRINT(RT_DEBUG_TRACE, ("Driver version-%s\n", STA_DRIVER_VERSION)); 230 DBGPRINT(RT_DEBUG_TRACE, ("Driver version-%s\n", STA_DRIVER_VERSION));
230 231
231 return TRUE; 232 return TRUE;
@@ -242,32 +243,14 @@ INT Set_DriverVersion_Proc(
242*/ 243*/
243INT Set_CountryRegion_Proc( 244INT Set_CountryRegion_Proc(
244 IN PRTMP_ADAPTER pAd, 245 IN PRTMP_ADAPTER pAd,
245 IN PUCHAR arg) 246 IN PSTRING arg)
246{ 247{
247 ULONG region; 248 int retval;
248 249
249 region = simple_strtol(arg, 0, 10);
250 250
251 // Country can be set only when EEPROM not programmed 251 retval = RT_CfgSetCountryRegion(pAd, arg, BAND_24G);
252 if (pAd->CommonCfg.CountryRegion & 0x80) 252 if (retval == FALSE)
253 {
254 DBGPRINT(RT_DEBUG_ERROR, ("Set_CountryRegion_Proc::parameter of CountryRegion in eeprom is programmed \n"));
255 return FALSE; 253 return FALSE;
256 }
257
258 if((region >= 0) && (region <= REGION_MAXIMUM_BG_BAND))
259 {
260 pAd->CommonCfg.CountryRegion = (UCHAR) region;
261 }
262 else if (region == REGION_31_BG_BAND)
263 {
264 pAd->CommonCfg.CountryRegion = (UCHAR) region;
265 }
266 else
267 {
268 DBGPRINT(RT_DEBUG_ERROR, ("Set_CountryRegion_Proc::parameters out of range\n"));
269 return FALSE;
270 }
271 254
272 // if set country region, driver needs to be reset 255 // if set country region, driver needs to be reset
273 BuildChannelList(pAd); 256 BuildChannelList(pAd);
@@ -288,28 +271,14 @@ INT Set_CountryRegion_Proc(
288*/ 271*/
289INT Set_CountryRegionABand_Proc( 272INT Set_CountryRegionABand_Proc(
290 IN PRTMP_ADAPTER pAd, 273 IN PRTMP_ADAPTER pAd,
291 IN PUCHAR arg) 274 IN PSTRING arg)
292{ 275{
293 ULONG region; 276 int retval;
294
295 region = simple_strtol(arg, 0, 10);
296 277
297 // Country can be set only when EEPROM not programmed
298 if (pAd->CommonCfg.CountryRegionForABand & 0x80)
299 {
300 DBGPRINT(RT_DEBUG_ERROR, ("Set_CountryRegionABand_Proc::parameter of CountryRegion in eeprom is programmed \n"));
301 return FALSE;
302 }
303 278
304 if((region >= 0) && (region <= REGION_MAXIMUM_A_BAND)) 279 retval = RT_CfgSetCountryRegion(pAd, arg, BAND_5G);
305 { 280 if (retval == FALSE)
306 pAd->CommonCfg.CountryRegionForABand = (UCHAR) region;
307 }
308 else
309 {
310 DBGPRINT(RT_DEBUG_ERROR, ("Set_CountryRegionABand_Proc::parameters out of range\n"));
311 return FALSE; 281 return FALSE;
312 }
313 282
314 // if set country region, driver needs to be reset 283 // if set country region, driver needs to be reset
315 BuildChannelList(pAd); 284 BuildChannelList(pAd);
@@ -329,22 +298,17 @@ INT Set_CountryRegionABand_Proc(
329*/ 298*/
330INT Set_WirelessMode_Proc( 299INT Set_WirelessMode_Proc(
331 IN PRTMP_ADAPTER pAd, 300 IN PRTMP_ADAPTER pAd,
332 IN PUCHAR arg) 301 IN PSTRING arg)
333{ 302{
334 ULONG WirelessMode;
335 INT success = TRUE; 303 INT success = TRUE;
336 304
337 WirelessMode = simple_strtol(arg, 0, 10); 305 success = RT_CfgSetWirelessMode(pAd, arg);
338 306 if (success)
339 { 307 {
340 INT MaxPhyMode = PHY_11G;
341
342 MaxPhyMode = PHY_11N_5G;
343
344 if (WirelessMode <= MaxPhyMode)
345 { 308 {
346 RTMPSetPhyMode(pAd, WirelessMode); 309 LONG WirelessMode = pAd->CommonCfg.PhyMode;
347 310
311 RTMPSetPhyMode(pAd, WirelessMode);
348 if (WirelessMode >= PHY_11ABGN_MIXED) 312 if (WirelessMode >= PHY_11ABGN_MIXED)
349 { 313 {
350 pAd->CommonCfg.BACapability.field.AutoBA = TRUE; 314 pAd->CommonCfg.BACapability.field.AutoBA = TRUE;
@@ -364,17 +328,10 @@ INT Set_WirelessMode_Proc(
364 AsicEnableIbssSync(pAd); // copy to on-chip memory 328 AsicEnableIbssSync(pAd); // copy to on-chip memory
365 } 329 }
366 } 330 }
367 else
368 {
369 success = FALSE;
370 }
371 }
372 331
373 // it is needed to set SSID to take effect 332 // it is needed to set SSID to take effect
374 if (success == TRUE)
375 {
376 SetCommonHT(pAd); 333 SetCommonHT(pAd);
377 DBGPRINT(RT_DEBUG_TRACE, ("Set_WirelessMode_Proc::(=%ld)\n", WirelessMode)); 334 DBGPRINT(RT_DEBUG_TRACE, ("Set_WirelessMode_Proc::(=%d)\n", pAd->CommonCfg.PhyMode));
378 } 335 }
379 else 336 else
380 { 337 {
@@ -394,7 +351,7 @@ INT Set_WirelessMode_Proc(
394*/ 351*/
395INT Set_Channel_Proc( 352INT Set_Channel_Proc(
396 IN PRTMP_ADAPTER pAd, 353 IN PRTMP_ADAPTER pAd,
397 IN PUCHAR arg) 354 IN PSTRING arg)
398{ 355{
399 INT success = TRUE; 356 INT success = TRUE;
400 UCHAR Channel; 357 UCHAR Channel;
@@ -451,24 +408,18 @@ INT Set_Channel_Proc(
451*/ 408*/
452INT Set_ShortSlot_Proc( 409INT Set_ShortSlot_Proc(
453 IN PRTMP_ADAPTER pAd, 410 IN PRTMP_ADAPTER pAd,
454 IN PUCHAR arg) 411 IN PSTRING arg)
455{ 412{
456 ULONG ShortSlot; 413 int retval;
457
458 ShortSlot = simple_strtol(arg, 0, 10);
459
460 if (ShortSlot == 1)
461 pAd->CommonCfg.bUseShortSlotTime = TRUE;
462 else if (ShortSlot == 0)
463 pAd->CommonCfg.bUseShortSlotTime = FALSE;
464 else
465 return FALSE; //Invalid argument
466 414
415 retval = RT_CfgSetShortSlot(pAd, arg);
416 if (retval == TRUE)
467 DBGPRINT(RT_DEBUG_TRACE, ("Set_ShortSlot_Proc::(ShortSlot=%d)\n", pAd->CommonCfg.bUseShortSlotTime)); 417 DBGPRINT(RT_DEBUG_TRACE, ("Set_ShortSlot_Proc::(ShortSlot=%d)\n", pAd->CommonCfg.bUseShortSlotTime));
468 418
469 return TRUE; 419 return retval;
470} 420}
471 421
422
472/* 423/*
473 ========================================================================== 424 ==========================================================================
474 Description: 425 Description:
@@ -479,12 +430,12 @@ INT Set_ShortSlot_Proc(
479*/ 430*/
480INT Set_TxPower_Proc( 431INT Set_TxPower_Proc(
481 IN PRTMP_ADAPTER pAd, 432 IN PRTMP_ADAPTER pAd,
482 IN PUCHAR arg) 433 IN PSTRING arg)
483{ 434{
484 ULONG TxPower; 435 LONG TxPower;
485 INT success = FALSE; 436 INT success = FALSE;
486 437
487 TxPower = (ULONG) simple_strtol(arg, 0, 10); 438 TxPower = simple_strtol(arg, 0, 10);
488 if (TxPower <= 100) 439 if (TxPower <= 100)
489 { 440 {
490 { 441 {
@@ -511,7 +462,7 @@ INT Set_TxPower_Proc(
511*/ 462*/
512INT Set_BGProtection_Proc( 463INT Set_BGProtection_Proc(
513 IN PRTMP_ADAPTER pAd, 464 IN PRTMP_ADAPTER pAd,
514 IN PUCHAR arg) 465 IN PSTRING arg)
515{ 466{
516 switch (simple_strtol(arg, 0, 10)) 467 switch (simple_strtol(arg, 0, 10))
517 { 468 {
@@ -544,7 +495,7 @@ INT Set_BGProtection_Proc(
544*/ 495*/
545INT Set_TxPreamble_Proc( 496INT Set_TxPreamble_Proc(
546 IN PRTMP_ADAPTER pAd, 497 IN PRTMP_ADAPTER pAd,
547 IN PUCHAR arg) 498 IN PSTRING arg)
548{ 499{
549 RT_802_11_PREAMBLE Preamble; 500 RT_802_11_PREAMBLE Preamble;
550 501
@@ -585,7 +536,7 @@ INT Set_TxPreamble_Proc(
585*/ 536*/
586INT Set_RTSThreshold_Proc( 537INT Set_RTSThreshold_Proc(
587 IN PRTMP_ADAPTER pAd, 538 IN PRTMP_ADAPTER pAd,
588 IN PUCHAR arg) 539 IN PSTRING arg)
589{ 540{
590 NDIS_802_11_RTS_THRESHOLD RtsThresh; 541 NDIS_802_11_RTS_THRESHOLD RtsThresh;
591 542
@@ -613,7 +564,7 @@ INT Set_RTSThreshold_Proc(
613*/ 564*/
614INT Set_FragThreshold_Proc( 565INT Set_FragThreshold_Proc(
615 IN PRTMP_ADAPTER pAd, 566 IN PRTMP_ADAPTER pAd,
616 IN PUCHAR arg) 567 IN PSTRING arg)
617{ 568{
618 NDIS_802_11_FRAGMENTATION_THRESHOLD FragThresh; 569 NDIS_802_11_FRAGMENTATION_THRESHOLD FragThresh;
619 570
@@ -657,9 +608,9 @@ INT Set_FragThreshold_Proc(
657*/ 608*/
658INT Set_TxBurst_Proc( 609INT Set_TxBurst_Proc(
659 IN PRTMP_ADAPTER pAd, 610 IN PRTMP_ADAPTER pAd,
660 IN PUCHAR arg) 611 IN PSTRING arg)
661{ 612{
662 ULONG TxBurst; 613 LONG TxBurst;
663 614
664 TxBurst = simple_strtol(arg, 0, 10); 615 TxBurst = simple_strtol(arg, 0, 10);
665 if (TxBurst == 1) 616 if (TxBurst == 1)
@@ -685,9 +636,9 @@ INT Set_TxBurst_Proc(
685*/ 636*/
686INT Set_PktAggregate_Proc( 637INT Set_PktAggregate_Proc(
687 IN PRTMP_ADAPTER pAd, 638 IN PRTMP_ADAPTER pAd,
688 IN PUCHAR arg) 639 IN PSTRING arg)
689{ 640{
690 ULONG aggre; 641 LONG aggre;
691 642
692 aggre = simple_strtol(arg, 0, 10); 643 aggre = simple_strtol(arg, 0, 10);
693 644
@@ -716,9 +667,9 @@ INT Set_PktAggregate_Proc(
716*/ 667*/
717INT Set_IEEE80211H_Proc( 668INT Set_IEEE80211H_Proc(
718 IN PRTMP_ADAPTER pAd, 669 IN PRTMP_ADAPTER pAd,
719 IN PUCHAR arg) 670 IN PSTRING arg)
720{ 671{
721 ULONG ieee80211h; 672 LONG ieee80211h;
722 673
723 ieee80211h = simple_strtol(arg, 0, 10); 674 ieee80211h = simple_strtol(arg, 0, 10);
724 675
@@ -746,7 +697,7 @@ INT Set_IEEE80211H_Proc(
746*/ 697*/
747INT Set_Debug_Proc( 698INT Set_Debug_Proc(
748 IN PRTMP_ADAPTER pAd, 699 IN PRTMP_ADAPTER pAd,
749 IN PUCHAR arg) 700 IN PSTRING arg)
750{ 701{
751 DBGPRINT(RT_DEBUG_TRACE, ("==> Set_Debug_Proc *******************\n")); 702 DBGPRINT(RT_DEBUG_TRACE, ("==> Set_Debug_Proc *******************\n"));
752 703
@@ -761,10 +712,11 @@ INT Set_Debug_Proc(
761 712
762INT Show_DescInfo_Proc( 713INT Show_DescInfo_Proc(
763 IN PRTMP_ADAPTER pAd, 714 IN PRTMP_ADAPTER pAd,
764 IN PUCHAR arg) 715 IN PSTRING arg)
765{ 716{
766#ifdef RT2860 717#ifdef RTMP_MAC_PCI
767 INT i, QueIdx=0; 718 INT i, QueIdx=0;
719// ULONG RegValue;
768 PRT28XX_RXD_STRUC pRxD; 720 PRT28XX_RXD_STRUC pRxD;
769 PTXD_STRUC pTxD; 721 PTXD_STRUC pTxD;
770 PRTMP_TX_RING pTxRing = &pAd->TxRing[QueIdx]; 722 PRTMP_TX_RING pTxRing = &pAd->TxRing[QueIdx];
@@ -774,27 +726,28 @@ INT Show_DescInfo_Proc(
774 for(i=0;i<TX_RING_SIZE;i++) 726 for(i=0;i<TX_RING_SIZE;i++)
775 { 727 {
776 pTxD = (PTXD_STRUC) pTxRing->Cell[i].AllocVa; 728 pTxD = (PTXD_STRUC) pTxRing->Cell[i].AllocVa;
777 printk("Desc #%d\n",i); 729 DBGPRINT(RT_DEBUG_OFF, ("Desc #%d\n",i));
778 hex_dump("Tx Descriptor", (char *)pTxD, 16); 730 hex_dump("Tx Descriptor", (PUCHAR)pTxD, 16);
779 printk("pTxD->DMADONE = %x\n", pTxD->DMADONE); 731 DBGPRINT(RT_DEBUG_OFF, ("pTxD->DMADONE = %x\n", pTxD->DMADONE));
780 } 732 }
781 printk("---------------------------------------------------\n"); 733 DBGPRINT(RT_DEBUG_OFF, ("---------------------------------------------------\n"));
782 for(i=0;i<MGMT_RING_SIZE;i++) 734 for(i=0;i<MGMT_RING_SIZE;i++)
783 { 735 {
784 pTxD = (PTXD_STRUC) pMgmtRing->Cell[i].AllocVa; 736 pTxD = (PTXD_STRUC) pMgmtRing->Cell[i].AllocVa;
785 printk("Desc #%d\n",i); 737 DBGPRINT(RT_DEBUG_OFF, ("Desc #%d\n",i));
786 hex_dump("Mgmt Descriptor", (char *)pTxD, 16); 738 hex_dump("Mgmt Descriptor", (PUCHAR)pTxD, 16);
787 printk("pMgmt->DMADONE = %x\n", pTxD->DMADONE); 739 DBGPRINT(RT_DEBUG_OFF, ("pMgmt->DMADONE = %x\n", pTxD->DMADONE));
788 } 740 }
789 printk("---------------------------------------------------\n"); 741 DBGPRINT(RT_DEBUG_OFF, ("---------------------------------------------------\n"));
790 for(i=0;i<RX_RING_SIZE;i++) 742 for(i=0;i<RX_RING_SIZE;i++)
791 { 743 {
792 pRxD = (PRT28XX_RXD_STRUC) pRxRing->Cell[i].AllocVa; 744 pRxD = (PRT28XX_RXD_STRUC) pRxRing->Cell[i].AllocVa;
793 printk("Desc #%d\n",i); 745 DBGPRINT(RT_DEBUG_OFF, ("Desc #%d\n",i));
794 hex_dump("Rx Descriptor", (char *)pRxD, 16); 746 hex_dump("Rx Descriptor", (PUCHAR)pRxD, 16);
795 printk("pRxD->DDONE = %x\n", pRxD->DDONE); 747 DBGPRINT(RT_DEBUG_OFF, ("pRxD->DDONE = %x\n", pRxD->DDONE));
796 } 748 }
797#endif /* RT2860 */ 749#endif // RTMP_MAC_PCI //
750
798 return TRUE; 751 return TRUE;
799} 752}
800 753
@@ -813,8 +766,11 @@ INT Show_DescInfo_Proc(
813*/ 766*/
814INT Set_ResetStatCounter_Proc( 767INT Set_ResetStatCounter_Proc(
815 IN PRTMP_ADAPTER pAd, 768 IN PRTMP_ADAPTER pAd,
816 IN PUCHAR arg) 769 IN PSTRING arg)
817{ 770{
771 //UCHAR i;
772 //MAC_TABLE_ENTRY *pEntry;
773
818 DBGPRINT(RT_DEBUG_TRACE, ("==>Set_ResetStatCounter_Proc\n")); 774 DBGPRINT(RT_DEBUG_TRACE, ("==>Set_ResetStatCounter_Proc\n"));
819 775
820 // add the most up-to-date h/w raw counters into software counters 776 // add the most up-to-date h/w raw counters into software counters
@@ -824,9 +780,33 @@ INT Set_ResetStatCounter_Proc(
824 NdisZeroMemory(&pAd->Counters8023, sizeof(COUNTER_802_3)); 780 NdisZeroMemory(&pAd->Counters8023, sizeof(COUNTER_802_3));
825 NdisZeroMemory(&pAd->RalinkCounters, sizeof(COUNTER_RALINK)); 781 NdisZeroMemory(&pAd->RalinkCounters, sizeof(COUNTER_RALINK));
826 782
783 // Reset HotSpot counter
784
785
827 return TRUE; 786 return TRUE;
828} 787}
829 788
789/*
790 ========================================================================
791
792 Routine Description:
793 Add WPA key process.
794 In Adhoc WPANONE, bPairwise = 0; KeyIdx = 0;
795
796 Arguments:
797 pAd Pointer to our adapter
798 pBuf Pointer to the where the key stored
799
800 Return Value:
801 NDIS_SUCCESS Add key successfully
802
803 IRQL = DISPATCH_LEVEL
804
805 Note:
806
807 ========================================================================
808*/
809
830BOOLEAN RTMPCheckStrPrintAble( 810BOOLEAN RTMPCheckStrPrintAble(
831 IN CHAR *pInPutStr, 811 IN CHAR *pInPutStr,
832 IN UCHAR strLen) 812 IN UCHAR strLen)
@@ -1100,7 +1080,7 @@ VOID RTMPWPARemoveAllKeys(
1100 UCHAR i; 1080 UCHAR i;
1101 1081
1102 DBGPRINT(RT_DEBUG_TRACE,("RTMPWPARemoveAllKeys(AuthMode=%d, WepStatus=%d)\n", pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus)); 1082 DBGPRINT(RT_DEBUG_TRACE,("RTMPWPARemoveAllKeys(AuthMode=%d, WepStatus=%d)\n", pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus));
1103 1083 RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
1104 // For WEP/CKIP, there is no need to remove it, since WinXP won't set it again after 1084 // For WEP/CKIP, there is no need to remove it, since WinXP won't set it again after
1105 // Link up. And it will be replaced if user changed it. 1085 // Link up. And it will be replaced if user changed it.
1106 if (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA) 1086 if (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
@@ -1122,9 +1102,33 @@ VOID RTMPWPARemoveAllKeys(
1122 1102
1123 AsicRemoveSharedKeyEntry(pAd, BSS0, i); 1103 AsicRemoveSharedKeyEntry(pAd, BSS0, i);
1124 } 1104 }
1125 1105 RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
1126} 1106}
1127 1107
1108
1109/*
1110 ========================================================================
1111
1112 Routine Description:
1113 As STA's BSSID is a WC too, it uses shared key table.
1114 This function write correct unicast TX key to ASIC WCID.
1115 And we still make a copy in our MacTab.Content[BSSID_WCID].PairwiseKey.
1116 Caller guarantee TKIP/AES always has keyidx = 0. (pairwise key)
1117 Caller guarantee WEP calls this function when set Txkey, default key index=0~3.
1118
1119 Arguments:
1120 pAd Pointer to our adapter
1121 pKey Pointer to the where the key stored
1122
1123 Return Value:
1124 NDIS_SUCCESS Add key successfully
1125
1126 IRQL = DISPATCH_LEVEL
1127
1128 Note:
1129
1130 ========================================================================
1131*/
1128/* 1132/*
1129 ======================================================================== 1133 ========================================================================
1130 Routine Description: 1134 Routine Description:
@@ -1147,6 +1151,11 @@ VOID RTMPSetPhyMode(
1147 INT i; 1151 INT i;
1148 // the selected phymode must be supported by the RF IC encoded in E2PROM 1152 // the selected phymode must be supported by the RF IC encoded in E2PROM
1149 1153
1154 // if no change, do nothing
1155 /* bug fix
1156 if (pAd->CommonCfg.PhyMode == phymode)
1157 return;
1158 */
1150 pAd->CommonCfg.PhyMode = (UCHAR)phymode; 1159 pAd->CommonCfg.PhyMode = (UCHAR)phymode;
1151 1160
1152 DBGPRINT(RT_DEBUG_TRACE,("RTMPSetPhyMode : PhyMode=%d, channel=%d \n", pAd->CommonCfg.PhyMode, pAd->CommonCfg.Channel)); 1161 DBGPRINT(RT_DEBUG_TRACE,("RTMPSetPhyMode : PhyMode=%d, channel=%d \n", pAd->CommonCfg.PhyMode, pAd->CommonCfg.Channel));
@@ -1466,7 +1475,10 @@ VOID RTMPSetHT(
1466 } 1475 }
1467 AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm); 1476 AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
1468 1477
1478 {
1469 RTMPSetIndividualHT(pAd, 0); 1479 RTMPSetIndividualHT(pAd, 0);
1480 }
1481
1470} 1482}
1471 1483
1472/* 1484/*
@@ -1657,12 +1669,8 @@ VOID RTMPAddWcidAttributeEntry(
1657 // 1. In ADHOC mode, the AID is wcid number. And NO mesh link exists. 1669 // 1. In ADHOC mode, the AID is wcid number. And NO mesh link exists.
1658 // 2. In Infra mode, the AID:1 MUST be wcid of infra STA. 1670 // 2. In Infra mode, the AID:1 MUST be wcid of infra STA.
1659 // the AID:2~ assign to mesh link entry. 1671 // the AID:2~ assign to mesh link entry.
1660 if (pEntry && ADHOC_ON(pAd)) 1672 if (pEntry)
1661 Wcid = pEntry->Aid; 1673 Wcid = pEntry->Aid;
1662 else if (pEntry && INFRA_ON(pAd))
1663 {
1664 Wcid = BSSID_WCID;
1665 }
1666 else 1674 else
1667 Wcid = MCAST_WCID; 1675 Wcid = MCAST_WCID;
1668 } 1676 }
@@ -1697,12 +1705,12 @@ VOID RTMPAddWcidAttributeEntry(
1697 } 1705 }
1698 1706
1699 // For key index and ext IV bit, so only need to update the position(offset+3). 1707 // For key index and ext IV bit, so only need to update the position(offset+3).
1700#ifdef RT2860 1708#ifdef RTMP_MAC_PCI
1701 RTMP_IO_WRITE8(pAd, offset+3, IVEIV); 1709 RTMP_IO_WRITE8(pAd, offset+3, IVEIV);
1702#endif 1710#endif // RTMP_MAC_PCI //
1703#ifdef RT2870 1711#ifdef RTMP_MAC_USB
1704 RTUSBMultiWrite_OneByte(pAd, offset+3, &IVEIV); 1712 RTUSBMultiWrite_OneByte(pAd, offset+3, &IVEIV);
1705#endif // RT2870 // 1713#endif // RTMP_MAC_USB //
1706 1714
1707 DBGPRINT(RT_DEBUG_TRACE,("RTMPAddWcidAttributeEntry: WCID #%d, KeyIndex #%d, Alg=%s\n",Wcid, KeyIdx, CipherName[CipherAlg])); 1715 DBGPRINT(RT_DEBUG_TRACE,("RTMPAddWcidAttributeEntry: WCID #%d, KeyIndex #%d, Alg=%s\n",Wcid, KeyIdx, CipherName[CipherAlg]));
1708 DBGPRINT(RT_DEBUG_TRACE,(" WCIDAttri = 0x%x \n", WCIDAttri)); 1716 DBGPRINT(RT_DEBUG_TRACE,(" WCIDAttri = 0x%x \n", WCIDAttri));
@@ -1723,7 +1731,7 @@ Arguments:
1723 Note: 1731 Note:
1724 ========================================================================== 1732 ==========================================================================
1725*/ 1733*/
1726CHAR *GetEncryptType(CHAR enc) 1734PSTRING GetEncryptType(CHAR enc)
1727{ 1735{
1728 if(enc == Ndis802_11WEPDisabled) 1736 if(enc == Ndis802_11WEPDisabled)
1729 return "NONE"; 1737 return "NONE";
@@ -1739,7 +1747,7 @@ CHAR *GetEncryptType(CHAR enc)
1739 return "UNKNOW"; 1747 return "UNKNOW";
1740} 1748}
1741 1749
1742CHAR *GetAuthMode(CHAR auth) 1750PSTRING GetAuthMode(CHAR auth)
1743{ 1751{
1744 if(auth == Ndis802_11AuthModeOpen) 1752 if(auth == Ndis802_11AuthModeOpen)
1745 return "OPEN"; 1753 return "OPEN";
@@ -1783,71 +1791,133 @@ CHAR *GetAuthMode(CHAR auth)
1783 3.) UI needs to prepare at least 4096bytes to get the results 1791 3.) UI needs to prepare at least 4096bytes to get the results
1784 ========================================================================== 1792 ==========================================================================
1785*/ 1793*/
1786#define LINE_LEN (4+33+20+8+10+9+7+3) // Channel+SSID+Bssid+WepStatus+AuthMode+Signal+WiressMode+NetworkType 1794#define LINE_LEN (4+33+20+23+9+7+7+3) // Channel+SSID+Bssid+Security+Signal+WiressMode+ExtCh+NetworkType
1787VOID RTMPIoctlGetSiteSurvey( 1795VOID RTMPCommSiteSurveyData(
1788 IN PRTMP_ADAPTER pAdapter, 1796 IN PSTRING msg,
1789 IN struct iwreq *wrq) 1797 IN PBSS_ENTRY pBss)
1790{ 1798{
1791 CHAR *msg; 1799 INT Rssi = 0;
1792 INT i=0;
1793 INT WaitCnt;
1794 INT Status=0;
1795 CHAR Ssid[MAX_LEN_OF_SSID +1];
1796 INT Rssi = 0, max_len = LINE_LEN;
1797 UINT Rssi_Quality = 0; 1800 UINT Rssi_Quality = 0;
1798 NDIS_802_11_NETWORK_TYPE wireless_mode; 1801 NDIS_802_11_NETWORK_TYPE wireless_mode;
1802 CHAR Ssid[MAX_LEN_OF_SSID +1];
1803 STRING SecurityStr[32] = {0};
1804 NDIS_802_11_ENCRYPTION_STATUS ap_cipher = Ndis802_11EncryptionDisabled;
1805 NDIS_802_11_AUTHENTICATION_MODE ap_auth_mode = Ndis802_11AuthModeOpen;
1799 1806
1800 os_alloc_mem(NULL, (PUCHAR *)&msg, sizeof(CHAR)*((MAX_LEN_OF_BSS_TABLE)*max_len));
1801
1802 if (msg == NULL)
1803 {
1804 DBGPRINT(RT_DEBUG_TRACE, ("RTMPIoctlGetSiteSurvey - msg memory alloc fail.\n"));
1805 return;
1806 }
1807
1808 memset(msg, 0 ,(MAX_LEN_OF_BSS_TABLE)*max_len );
1809 memset(Ssid, 0 ,(MAX_LEN_OF_SSID +1)); 1807 memset(Ssid, 0 ,(MAX_LEN_OF_SSID +1));
1810 sprintf(msg,"%s","\n");
1811 sprintf(msg+strlen(msg),"%-4s%-33s%-20s%-8s%-10s%-9s%-7s%-3s\n",
1812 "Ch", "SSID", "BSSID", "Enc", "Auth", "Siganl(%)", "W-Mode", " NT");
1813
1814 WaitCnt = 0;
1815 pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE;
1816
1817 while ((ScanRunning(pAdapter) == TRUE) && (WaitCnt++ < 200))
1818 OS_WAIT(500);
1819
1820 for(i=0; i<pAdapter->ScanTab.BssNr ;i++)
1821 {
1822 if( pAdapter->ScanTab.BssEntry[i].Channel==0)
1823 break;
1824
1825 if((strlen(msg)+max_len ) >= IW_SCAN_MAX_DATA)
1826 break;
1827 1808
1828 //Channel 1809 //Channel
1829 sprintf(msg+strlen(msg),"%-4d", pAdapter->ScanTab.BssEntry[i].Channel); 1810 sprintf(msg+strlen(msg),"%-4d", pBss->Channel);
1830 //SSID 1811 //SSID
1831 memcpy(Ssid, pAdapter->ScanTab.BssEntry[i].Ssid, pAdapter->ScanTab.BssEntry[i].SsidLen); 1812 memcpy(Ssid, pBss->Ssid, pBss->SsidLen);
1832 Ssid[pAdapter->ScanTab.BssEntry[i].SsidLen] = '\0'; 1813 Ssid[pBss->SsidLen] = '\0';
1833 sprintf(msg+strlen(msg),"%-33s", Ssid); 1814 sprintf(msg+strlen(msg),"%-33s", Ssid);
1834 //BSSID 1815 //BSSID
1835 sprintf(msg+strlen(msg),"%02x:%02x:%02x:%02x:%02x:%02x ", 1816 sprintf(msg+strlen(msg),"%02x:%02x:%02x:%02x:%02x:%02x ",
1836 pAdapter->ScanTab.BssEntry[i].Bssid[0], 1817 pBss->Bssid[0],
1837 pAdapter->ScanTab.BssEntry[i].Bssid[1], 1818 pBss->Bssid[1],
1838 pAdapter->ScanTab.BssEntry[i].Bssid[2], 1819 pBss->Bssid[2],
1839 pAdapter->ScanTab.BssEntry[i].Bssid[3], 1820 pBss->Bssid[3],
1840 pAdapter->ScanTab.BssEntry[i].Bssid[4], 1821 pBss->Bssid[4],
1841 pAdapter->ScanTab.BssEntry[i].Bssid[5]); 1822 pBss->Bssid[5]);
1842 //Encryption Type 1823
1843 sprintf(msg+strlen(msg),"%-8s",GetEncryptType(pAdapter->ScanTab.BssEntry[i].WepStatus)); 1824 //Security
1844 //Authentication Mode 1825 if ((Ndis802_11AuthModeWPA <= pBss->AuthMode) &&
1845 if (pAdapter->ScanTab.BssEntry[i].WepStatus == Ndis802_11WEPEnabled) 1826 (pBss->AuthMode <= Ndis802_11AuthModeWPA1PSKWPA2PSK))
1846 sprintf(msg+strlen(msg),"%-10s", "UNKNOW"); 1827 {
1828 if (pBss->AuthModeAux == Ndis802_11AuthModeWPANone)
1829 {
1830 ap_auth_mode = pBss->AuthMode;
1831 if (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled)
1832 ap_cipher = pBss->WPA.PairCipher;
1833 else
1834 ap_cipher = Ndis802_11Encryption4Enabled;
1835 }
1836 else if (pBss->AuthModeAux == Ndis802_11AuthModeOpen)
1837 {
1838 ap_auth_mode = pBss->AuthMode;
1839 if ((ap_auth_mode == Ndis802_11AuthModeWPA) ||
1840 (ap_auth_mode == Ndis802_11AuthModeWPAPSK))
1841 {
1842 if (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled)
1843 ap_cipher = pBss->WPA.PairCipher;
1844 else
1845 ap_cipher = Ndis802_11Encryption4Enabled;
1846 }
1847 else if ((ap_auth_mode == Ndis802_11AuthModeWPA2) ||
1848 (ap_auth_mode == Ndis802_11AuthModeWPA2PSK))
1849 {
1850 if (pBss->WPA2.PairCipherAux == Ndis802_11WEPDisabled)
1851 ap_cipher = pBss->WPA2.PairCipher;
1852 else
1853 ap_cipher = Ndis802_11Encryption4Enabled;
1854 }
1855 }
1856 else if ((pBss->AuthMode == Ndis802_11AuthModeWPAPSK) ||
1857 (pBss->AuthMode == Ndis802_11AuthModeWPA2PSK))
1858 {
1859 if ((pBss->AuthModeAux == Ndis802_11AuthModeWPAPSK) ||
1860 (pBss->AuthModeAux == Ndis802_11AuthModeWPA2PSK))
1861 ap_auth_mode = Ndis802_11AuthModeWPA1PSKWPA2PSK;
1862 else
1863 ap_auth_mode = pBss->AuthMode;
1864
1865 if (pBss->WPA.PairCipher != pBss->WPA2.PairCipher)
1866 ap_cipher = Ndis802_11Encryption4Enabled;
1867 else if ((pBss->WPA.PairCipher == pBss->WPA2.PairCipher) &&
1868 (pBss->WPA.PairCipherAux != pBss->WPA2.PairCipherAux))
1869 ap_cipher = Ndis802_11Encryption4Enabled;
1870 else if ((pBss->WPA.PairCipher == pBss->WPA2.PairCipher) &&
1871 (pBss->WPA.PairCipherAux == pBss->WPA2.PairCipherAux) &&
1872 (pBss->WPA.PairCipherAux != Ndis802_11WEPDisabled))
1873 ap_cipher = Ndis802_11Encryption4Enabled;
1874 else if ((pBss->WPA.PairCipher == pBss->WPA2.PairCipher) &&
1875 (pBss->WPA.PairCipherAux == pBss->WPA2.PairCipherAux) &&
1876 (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled))
1877 ap_cipher = pBss->WPA.PairCipher;
1878 }
1879 else if ((pBss->AuthMode == Ndis802_11AuthModeWPA) ||
1880 (pBss->AuthMode == Ndis802_11AuthModeWPA2))
1881 {
1882 if ((pBss->AuthModeAux == Ndis802_11AuthModeWPA) ||
1883 (pBss->AuthMode == Ndis802_11AuthModeWPA2))
1884 ap_auth_mode = Ndis802_11AuthModeWPA1WPA2;
1885 else
1886 ap_auth_mode = pBss->AuthMode;
1887
1888 if (pBss->WPA.PairCipher != pBss->WPA2.PairCipher)
1889 ap_cipher = Ndis802_11Encryption4Enabled;
1890 else if ((pBss->WPA.PairCipher == pBss->WPA2.PairCipher) &&
1891 (pBss->WPA.PairCipherAux != pBss->WPA2.PairCipherAux))
1892 ap_cipher = Ndis802_11Encryption4Enabled;
1893 else if ((pBss->WPA.PairCipher == pBss->WPA2.PairCipher) &&
1894 (pBss->WPA.PairCipherAux == pBss->WPA2.PairCipherAux) &&
1895 (pBss->WPA.PairCipherAux != Ndis802_11WEPDisabled))
1896 ap_cipher = Ndis802_11Encryption4Enabled;
1897 else if ((pBss->WPA.PairCipher == pBss->WPA2.PairCipher) &&
1898 (pBss->WPA.PairCipherAux == pBss->WPA2.PairCipherAux) &&
1899 (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled))
1900 ap_cipher = pBss->WPA.PairCipher;
1901 }
1902
1903 sprintf(SecurityStr, "%s/%s", GetAuthMode((CHAR)ap_auth_mode), GetEncryptType((CHAR)ap_cipher));
1904 }
1905 else
1906 {
1907 ap_auth_mode = pBss->AuthMode;
1908 ap_cipher = pBss->WepStatus;
1909 if (ap_cipher == Ndis802_11WEPDisabled)
1910 sprintf(SecurityStr, "NONE");
1911 else if (ap_cipher == Ndis802_11WEPEnabled)
1912 sprintf(SecurityStr, "WEP");
1847 else 1913 else
1848 sprintf(msg+strlen(msg),"%-10s",GetAuthMode(pAdapter->ScanTab.BssEntry[i].AuthMode)); 1914 sprintf(SecurityStr, "%s/%s", GetAuthMode((CHAR)ap_auth_mode), GetEncryptType((CHAR)ap_cipher));
1915 }
1916
1917 sprintf(msg+strlen(msg), "%-23s", SecurityStr);
1918
1849 // Rssi 1919 // Rssi
1850 Rssi = (INT)pAdapter->ScanTab.BssEntry[i].Rssi; 1920 Rssi = (INT)pBss->Rssi;
1851 if (Rssi >= -50) 1921 if (Rssi >= -50)
1852 Rssi_Quality = 100; 1922 Rssi_Quality = 100;
1853 else if (Rssi >= -80) // between -50 ~ -80dbm 1923 else if (Rssi >= -80) // between -50 ~ -80dbm
@@ -1858,7 +1928,7 @@ VOID RTMPIoctlGetSiteSurvey(
1858 Rssi_Quality = 0; 1928 Rssi_Quality = 0;
1859 sprintf(msg+strlen(msg),"%-9d", Rssi_Quality); 1929 sprintf(msg+strlen(msg),"%-9d", Rssi_Quality);
1860 // Wireless Mode 1930 // Wireless Mode
1861 wireless_mode = NetworkTypeInUseSanity(&pAdapter->ScanTab.BssEntry[i]); 1931 wireless_mode = NetworkTypeInUseSanity(pBss);
1862 if (wireless_mode == Ndis802_11FH || 1932 if (wireless_mode == Ndis802_11FH ||
1863 wireless_mode == Ndis802_11DS) 1933 wireless_mode == Ndis802_11DS)
1864 sprintf(msg+strlen(msg),"%-7s", "11b"); 1934 sprintf(msg+strlen(msg),"%-7s", "11b");
@@ -1872,13 +1942,79 @@ VOID RTMPIoctlGetSiteSurvey(
1872 sprintf(msg+strlen(msg),"%-7s", "11b/g/n"); 1942 sprintf(msg+strlen(msg),"%-7s", "11b/g/n");
1873 else 1943 else
1874 sprintf(msg+strlen(msg),"%-7s", "unknow"); 1944 sprintf(msg+strlen(msg),"%-7s", "unknow");
1945
1946 // Ext Channel
1947 if (pBss->AddHtInfoLen > 0)
1948 {
1949 if (pBss->AddHtInfo.AddHtInfo.ExtChanOffset == EXTCHA_ABOVE)
1950 sprintf(msg+strlen(msg),"%-7s", " ABOVE");
1951 else if (pBss->AddHtInfo.AddHtInfo.ExtChanOffset == EXTCHA_BELOW)
1952 sprintf(msg+strlen(msg),"%-7s", " BELOW");
1953 else
1954 sprintf(msg+strlen(msg),"%-7s", " NONE");
1955 }
1956 else
1957 {
1958 sprintf(msg+strlen(msg),"%-7s", " NONE");
1959 }
1960
1875 //Network Type 1961 //Network Type
1876 if (pAdapter->ScanTab.BssEntry[i].BssType == BSS_ADHOC) 1962 if (pBss->BssType == BSS_ADHOC)
1877 sprintf(msg+strlen(msg),"%-3s", " Ad"); 1963 sprintf(msg+strlen(msg),"%-3s", " Ad");
1878 else 1964 else
1879 sprintf(msg+strlen(msg),"%-3s", " In"); 1965 sprintf(msg+strlen(msg),"%-3s", " In");
1880 1966
1881 sprintf(msg+strlen(msg),"\n"); 1967 sprintf(msg+strlen(msg),"\n");
1968
1969 return;
1970}
1971
1972VOID RTMPIoctlGetSiteSurvey(
1973 IN PRTMP_ADAPTER pAdapter,
1974 IN struct iwreq *wrq)
1975{
1976 PSTRING msg;
1977 INT i=0;
1978 INT WaitCnt;
1979 INT Status=0;
1980 INT max_len = LINE_LEN;
1981 PBSS_ENTRY pBss;
1982
1983
1984 os_alloc_mem(NULL, (PUCHAR *)&msg, sizeof(CHAR)*((MAX_LEN_OF_BSS_TABLE)*max_len));
1985
1986 if (msg == NULL)
1987 {
1988 DBGPRINT(RT_DEBUG_TRACE, ("RTMPIoctlGetSiteSurvey - msg memory alloc fail.\n"));
1989 return;
1990 }
1991
1992 memset(msg, 0 ,(MAX_LEN_OF_BSS_TABLE)*max_len );
1993 sprintf(msg,"%s","\n");
1994 sprintf(msg+strlen(msg),"%-4s%-33s%-20s%-23s%-9s%-7s%-7s%-3s\n",
1995 "Ch", "SSID", "BSSID", "Security", "Siganl(%)", "W-Mode", " ExtCH"," NT");
1996
1997
1998
1999 WaitCnt = 0;
2000 pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE;
2001 while ((ScanRunning(pAdapter) == TRUE) && (WaitCnt++ < 200))
2002 OS_WAIT(500);
2003
2004 for(i=0; i<pAdapter->ScanTab.BssNr ;i++)
2005 {
2006 pBss = &pAdapter->ScanTab.BssEntry[i];
2007
2008 if( pBss->Channel==0)
2009 break;
2010
2011 if((strlen(msg)+max_len ) >= IW_SCAN_MAX_DATA)
2012 break;
2013
2014
2015 RTMPCommSiteSurveyData(msg, pBss);
2016
2017
1882 } 2018 }
1883 2019
1884 pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE; 2020 pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
@@ -1933,7 +2069,12 @@ VOID RTMPIoctlGetMacTable(
1933 DBGPRINT(RT_DEBUG_TRACE, ("%s: copy_to_user() fail\n", __func__)); 2069 DBGPRINT(RT_DEBUG_TRACE, ("%s: copy_to_user() fail\n", __func__));
1934 } 2070 }
1935 2071
1936 msg = (CHAR *) kmalloc(sizeof(CHAR)*(MAX_LEN_OF_MAC_TABLE*MAC_LINE_LEN), MEM_ALLOC_FLAG); 2072 msg = kmalloc(sizeof(CHAR)*(MAX_LEN_OF_MAC_TABLE*MAC_LINE_LEN), MEM_ALLOC_FLAG);
2073 if (msg == NULL)
2074 {
2075 DBGPRINT(RT_DEBUG_ERROR, ("%s():Alloc memory failed\n", __func__));
2076 return;
2077 }
1937 memset(msg, 0 ,MAX_LEN_OF_MAC_TABLE*MAC_LINE_LEN ); 2078 memset(msg, 0 ,MAX_LEN_OF_MAC_TABLE*MAC_LINE_LEN );
1938 sprintf(msg,"%s","\n"); 2079 sprintf(msg,"%s","\n");
1939 sprintf(msg+strlen(msg),"%-14s%-4s%-4s%-10s%-10s%-10s%-6s%-6s\n", 2080 sprintf(msg+strlen(msg),"%-14s%-4s%-4s%-10s%-10s%-10s%-6s%-6s\n",
@@ -1968,12 +2109,14 @@ VOID RTMPIoctlGetMacTable(
1968 kfree(msg); 2109 kfree(msg);
1969} 2110}
1970 2111
2112
1971INT Set_BASetup_Proc( 2113INT Set_BASetup_Proc(
1972 IN PRTMP_ADAPTER pAd, 2114 IN PRTMP_ADAPTER pAd,
1973 IN PUCHAR arg) 2115 IN PSTRING arg)
1974{ 2116{
1975 UCHAR mac[6], tid; 2117 UCHAR mac[6], tid;
1976 char *token, sepValue[] = ":", DASH = '-'; 2118 PSTRING token;
2119 STRING sepValue[] = ":", DASH = '-';
1977 INT i; 2120 INT i;
1978 MAC_TABLE_ENTRY *pEntry; 2121 MAC_TABLE_ENTRY *pEntry;
1979 2122
@@ -1982,6 +2125,7 @@ INT Set_BASetup_Proc(
1982 =>The six 2 digit hex-decimal number previous are the Mac address, 2125 =>The six 2 digit hex-decimal number previous are the Mac address,
1983 =>The seventh decimal number is the tid value. 2126 =>The seventh decimal number is the tid value.
1984*/ 2127*/
2128 //DBGPRINT(RT_DEBUG_TRACE,("\n%s\n", arg));
1985 2129
1986 if(strlen(arg) < 19) //Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and tid value in decimal format. 2130 if(strlen(arg) < 19) //Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and tid value in decimal format.
1987 return FALSE; 2131 return FALSE;
@@ -1989,7 +2133,7 @@ INT Set_BASetup_Proc(
1989 token = strchr(arg, DASH); 2133 token = strchr(arg, DASH);
1990 if ((token != NULL) && (strlen(token)>1)) 2134 if ((token != NULL) && (strlen(token)>1))
1991 { 2135 {
1992 tid = simple_strtol((token+1), 0, 10); 2136 tid = (UCHAR) simple_strtol((token+1), 0, 10);
1993 if (tid > 15) 2137 if (tid > 15)
1994 return FALSE; 2138 return FALSE;
1995 2139
@@ -1998,18 +2142,18 @@ INT Set_BASetup_Proc(
1998 { 2142 {
1999 if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1)))) 2143 if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1))))
2000 return FALSE; 2144 return FALSE;
2001 AtoH(token, (PUCHAR)(&mac[i]), 1); 2145 AtoH(token, (&mac[i]), 1);
2002 } 2146 }
2003 if(i != 6) 2147 if(i != 6)
2004 return FALSE; 2148 return FALSE;
2005 2149
2006 printk("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x\n", mac[0], mac[1], 2150 DBGPRINT(RT_DEBUG_OFF, ("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x\n",
2007 mac[2], mac[3], mac[4], mac[5], tid); 2151 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], tid));
2008 2152
2009 pEntry = MacTableLookup(pAd, mac); 2153 pEntry = MacTableLookup(pAd, (PUCHAR) mac);
2010 2154
2011 if (pEntry) { 2155 if (pEntry) {
2012 printk("\nSetup BA Session: Tid = %d\n", tid); 2156 DBGPRINT(RT_DEBUG_OFF, ("\nSetup BA Session: Tid = %d\n", tid));
2013 BAOriSessionSetUp(pAd, pEntry, tid, 0, 100, TRUE); 2157 BAOriSessionSetUp(pAd, pEntry, tid, 0, 100, TRUE);
2014 } 2158 }
2015 2159
@@ -2022,7 +2166,7 @@ INT Set_BASetup_Proc(
2022 2166
2023INT Set_BADecline_Proc( 2167INT Set_BADecline_Proc(
2024 IN PRTMP_ADAPTER pAd, 2168 IN PRTMP_ADAPTER pAd,
2025 IN PUCHAR arg) 2169 IN PSTRING arg)
2026{ 2170{
2027 ULONG bBADecline; 2171 ULONG bBADecline;
2028 2172
@@ -2048,13 +2192,15 @@ INT Set_BADecline_Proc(
2048 2192
2049INT Set_BAOriTearDown_Proc( 2193INT Set_BAOriTearDown_Proc(
2050 IN PRTMP_ADAPTER pAd, 2194 IN PRTMP_ADAPTER pAd,
2051 IN PUCHAR arg) 2195 IN PSTRING arg)
2052{ 2196{
2053 UCHAR mac[6], tid; 2197 UCHAR mac[6], tid;
2054 char *token, sepValue[] = ":", DASH = '-'; 2198 PSTRING token;
2199 STRING sepValue[] = ":", DASH = '-';
2055 INT i; 2200 INT i;
2056 MAC_TABLE_ENTRY *pEntry; 2201 MAC_TABLE_ENTRY *pEntry;
2057 2202
2203 //DBGPRINT(RT_DEBUG_TRACE,("\n%s\n", arg));
2058/* 2204/*
2059 The BAOriTearDown inupt string format should be xx:xx:xx:xx:xx:xx-d, 2205 The BAOriTearDown inupt string format should be xx:xx:xx:xx:xx:xx-d,
2060 =>The six 2 digit hex-decimal number previous are the Mac address, 2206 =>The six 2 digit hex-decimal number previous are the Mac address,
@@ -2075,18 +2221,18 @@ INT Set_BAOriTearDown_Proc(
2075 { 2221 {
2076 if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1)))) 2222 if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1))))
2077 return FALSE; 2223 return FALSE;
2078 AtoH(token, (PUCHAR)(&mac[i]), 1); 2224 AtoH(token, (&mac[i]), 1);
2079 } 2225 }
2080 if(i != 6) 2226 if(i != 6)
2081 return FALSE; 2227 return FALSE;
2082 2228
2083 printk("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x", mac[0], mac[1], 2229 DBGPRINT(RT_DEBUG_OFF, ("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x",
2084 mac[2], mac[3], mac[4], mac[5], tid); 2230 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], tid));
2085 2231
2086 pEntry = MacTableLookup(pAd, mac); 2232 pEntry = MacTableLookup(pAd, (PUCHAR) mac);
2087 2233
2088 if (pEntry) { 2234 if (pEntry) {
2089 printk("\nTear down Ori BA Session: Tid = %d\n", tid); 2235 DBGPRINT(RT_DEBUG_OFF, ("\nTear down Ori BA Session: Tid = %d\n", tid));
2090 BAOriSessionTearDown(pAd, pEntry->Aid, tid, FALSE, TRUE); 2236 BAOriSessionTearDown(pAd, pEntry->Aid, tid, FALSE, TRUE);
2091 } 2237 }
2092 2238
@@ -2099,14 +2245,15 @@ INT Set_BAOriTearDown_Proc(
2099 2245
2100INT Set_BARecTearDown_Proc( 2246INT Set_BARecTearDown_Proc(
2101 IN PRTMP_ADAPTER pAd, 2247 IN PRTMP_ADAPTER pAd,
2102 IN PUCHAR arg) 2248 IN PSTRING arg)
2103{ 2249{
2104 UCHAR mac[6], tid; 2250 UCHAR mac[6], tid;
2105 char *token, sepValue[] = ":", DASH = '-'; 2251 PSTRING token;
2252 STRING sepValue[] = ":", DASH = '-';
2106 INT i; 2253 INT i;
2107 MAC_TABLE_ENTRY *pEntry; 2254 MAC_TABLE_ENTRY *pEntry;
2108 2255
2109 //printk("\n%s\n", arg); 2256 //DBGPRINT(RT_DEBUG_TRACE,("\n%s\n", arg));
2110/* 2257/*
2111 The BARecTearDown inupt string format should be xx:xx:xx:xx:xx:xx-d, 2258 The BARecTearDown inupt string format should be xx:xx:xx:xx:xx:xx-d,
2112 =>The six 2 digit hex-decimal number previous are the Mac address, 2259 =>The six 2 digit hex-decimal number previous are the Mac address,
@@ -2127,18 +2274,18 @@ INT Set_BARecTearDown_Proc(
2127 { 2274 {
2128 if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1)))) 2275 if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1))))
2129 return FALSE; 2276 return FALSE;
2130 AtoH(token, (PUCHAR)(&mac[i]), 1); 2277 AtoH(token, (&mac[i]), 1);
2131 } 2278 }
2132 if(i != 6) 2279 if(i != 6)
2133 return FALSE; 2280 return FALSE;
2134 2281
2135 printk("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x", mac[0], mac[1], 2282 DBGPRINT(RT_DEBUG_OFF, ("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x",
2136 mac[2], mac[3], mac[4], mac[5], tid); 2283 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], tid));
2137 2284
2138 pEntry = MacTableLookup(pAd, mac); 2285 pEntry = MacTableLookup(pAd, (PUCHAR) mac);
2139 2286
2140 if (pEntry) { 2287 if (pEntry) {
2141 printk("\nTear down Rec BA Session: Tid = %d\n", tid); 2288 DBGPRINT(RT_DEBUG_OFF, ("\nTear down Rec BA Session: Tid = %d\n", tid));
2142 BARecSessionTearDown(pAd, pEntry->Aid, tid, FALSE); 2289 BARecSessionTearDown(pAd, pEntry->Aid, tid, FALSE);
2143 } 2290 }
2144 2291
@@ -2151,7 +2298,7 @@ INT Set_BARecTearDown_Proc(
2151 2298
2152INT Set_HtBw_Proc( 2299INT Set_HtBw_Proc(
2153 IN PRTMP_ADAPTER pAd, 2300 IN PRTMP_ADAPTER pAd,
2154 IN PUCHAR arg) 2301 IN PSTRING arg)
2155{ 2302{
2156 ULONG HtBw; 2303 ULONG HtBw;
2157 2304
@@ -2172,7 +2319,7 @@ INT Set_HtBw_Proc(
2172 2319
2173INT Set_HtMcs_Proc( 2320INT Set_HtMcs_Proc(
2174 IN PRTMP_ADAPTER pAd, 2321 IN PRTMP_ADAPTER pAd,
2175 IN PUCHAR arg) 2322 IN PSTRING arg)
2176{ 2323{
2177 ULONG HtMcs, Mcs_tmp; 2324 ULONG HtMcs, Mcs_tmp;
2178 BOOLEAN bAutoRate = FALSE; 2325 BOOLEAN bAutoRate = FALSE;
@@ -2226,7 +2373,7 @@ INT Set_HtMcs_Proc(
2226 2373
2227INT Set_HtGi_Proc( 2374INT Set_HtGi_Proc(
2228 IN PRTMP_ADAPTER pAd, 2375 IN PRTMP_ADAPTER pAd,
2229 IN PUCHAR arg) 2376 IN PSTRING arg)
2230{ 2377{
2231 ULONG HtGi; 2378 ULONG HtGi;
2232 2379
@@ -2249,7 +2396,7 @@ INT Set_HtGi_Proc(
2249 2396
2250INT Set_HtTxBASize_Proc( 2397INT Set_HtTxBASize_Proc(
2251 IN PRTMP_ADAPTER pAd, 2398 IN PRTMP_ADAPTER pAd,
2252 IN PUCHAR arg) 2399 IN PSTRING arg)
2253{ 2400{
2254 UCHAR Size; 2401 UCHAR Size;
2255 2402
@@ -2265,10 +2412,32 @@ INT Set_HtTxBASize_Proc(
2265 return TRUE; 2412 return TRUE;
2266} 2413}
2267 2414
2415INT Set_HtDisallowTKIP_Proc(
2416 IN PRTMP_ADAPTER pAd,
2417 IN PSTRING arg)
2418{
2419 ULONG Value;
2420
2421 Value = simple_strtol(arg, 0, 10);
2422
2423 if (Value == 1)
2424 {
2425 pAd->CommonCfg.HT_DisallowTKIP = TRUE;
2426 }
2427 else
2428 {
2429 pAd->CommonCfg.HT_DisallowTKIP = FALSE;
2430 }
2431
2432 DBGPRINT(RT_DEBUG_TRACE, ("Set_HtDisallowTKIP_Proc ::%s\n",
2433 (pAd->CommonCfg.HT_DisallowTKIP == TRUE) ? "enabled" : "disabled"));
2434
2435 return TRUE;
2436}
2268 2437
2269INT Set_HtOpMode_Proc( 2438INT Set_HtOpMode_Proc(
2270 IN PRTMP_ADAPTER pAd, 2439 IN PRTMP_ADAPTER pAd,
2271 IN PUCHAR arg) 2440 IN PSTRING arg)
2272{ 2441{
2273 2442
2274 ULONG Value; 2443 ULONG Value;
@@ -2292,7 +2461,7 @@ INT Set_HtOpMode_Proc(
2292 2461
2293INT Set_HtStbc_Proc( 2462INT Set_HtStbc_Proc(
2294 IN PRTMP_ADAPTER pAd, 2463 IN PRTMP_ADAPTER pAd,
2295 IN PUCHAR arg) 2464 IN PSTRING arg)
2296{ 2465{
2297 2466
2298 ULONG Value; 2467 ULONG Value;
@@ -2315,7 +2484,7 @@ INT Set_HtStbc_Proc(
2315 2484
2316INT Set_HtHtc_Proc( 2485INT Set_HtHtc_Proc(
2317 IN PRTMP_ADAPTER pAd, 2486 IN PRTMP_ADAPTER pAd,
2318 IN PUCHAR arg) 2487 IN PSTRING arg)
2319{ 2488{
2320 2489
2321 ULONG Value; 2490 ULONG Value;
@@ -2335,7 +2504,7 @@ INT Set_HtHtc_Proc(
2335 2504
2336INT Set_HtExtcha_Proc( 2505INT Set_HtExtcha_Proc(
2337 IN PRTMP_ADAPTER pAd, 2506 IN PRTMP_ADAPTER pAd,
2338 IN PUCHAR arg) 2507 IN PSTRING arg)
2339{ 2508{
2340 2509
2341 ULONG Value; 2510 ULONG Value;
@@ -2358,7 +2527,7 @@ INT Set_HtExtcha_Proc(
2358 2527
2359INT Set_HtMpduDensity_Proc( 2528INT Set_HtMpduDensity_Proc(
2360 IN PRTMP_ADAPTER pAd, 2529 IN PRTMP_ADAPTER pAd,
2361 IN PUCHAR arg) 2530 IN PSTRING arg)
2362{ 2531{
2363 ULONG Value; 2532 ULONG Value;
2364 2533
@@ -2378,7 +2547,7 @@ INT Set_HtMpduDensity_Proc(
2378 2547
2379INT Set_HtBaWinSize_Proc( 2548INT Set_HtBaWinSize_Proc(
2380 IN PRTMP_ADAPTER pAd, 2549 IN PRTMP_ADAPTER pAd,
2381 IN PUCHAR arg) 2550 IN PSTRING arg)
2382{ 2551{
2383 ULONG Value; 2552 ULONG Value;
2384 2553
@@ -2405,7 +2574,7 @@ INT Set_HtBaWinSize_Proc(
2405 2574
2406INT Set_HtRdg_Proc( 2575INT Set_HtRdg_Proc(
2407 IN PRTMP_ADAPTER pAd, 2576 IN PRTMP_ADAPTER pAd,
2408 IN PUCHAR arg) 2577 IN PSTRING arg)
2409{ 2578{
2410 ULONG Value; 2579 ULONG Value;
2411 2580
@@ -2430,7 +2599,7 @@ INT Set_HtRdg_Proc(
2430 2599
2431INT Set_HtLinkAdapt_Proc( 2600INT Set_HtLinkAdapt_Proc(
2432 IN PRTMP_ADAPTER pAd, 2601 IN PRTMP_ADAPTER pAd,
2433 IN PUCHAR arg) 2602 IN PSTRING arg)
2434{ 2603{
2435 ULONG Value; 2604 ULONG Value;
2436 2605
@@ -2452,7 +2621,7 @@ INT Set_HtLinkAdapt_Proc(
2452 2621
2453INT Set_HtAmsdu_Proc( 2622INT Set_HtAmsdu_Proc(
2454 IN PRTMP_ADAPTER pAd, 2623 IN PRTMP_ADAPTER pAd,
2455 IN PUCHAR arg) 2624 IN PSTRING arg)
2456{ 2625{
2457 ULONG Value; 2626 ULONG Value;
2458 2627
@@ -2473,7 +2642,7 @@ INT Set_HtAmsdu_Proc(
2473 2642
2474INT Set_HtAutoBa_Proc( 2643INT Set_HtAutoBa_Proc(
2475 IN PRTMP_ADAPTER pAd, 2644 IN PRTMP_ADAPTER pAd,
2476 IN PUCHAR arg) 2645 IN PSTRING arg)
2477{ 2646{
2478 ULONG Value; 2647 ULONG Value;
2479 2648
@@ -2504,7 +2673,7 @@ INT Set_HtAutoBa_Proc(
2504 2673
2505INT Set_HtProtect_Proc( 2674INT Set_HtProtect_Proc(
2506 IN PRTMP_ADAPTER pAd, 2675 IN PRTMP_ADAPTER pAd,
2507 IN PUCHAR arg) 2676 IN PSTRING arg)
2508{ 2677{
2509 ULONG Value; 2678 ULONG Value;
2510 2679
@@ -2523,14 +2692,15 @@ INT Set_HtProtect_Proc(
2523 2692
2524INT Set_SendPSMPAction_Proc( 2693INT Set_SendPSMPAction_Proc(
2525 IN PRTMP_ADAPTER pAd, 2694 IN PRTMP_ADAPTER pAd,
2526 IN PUCHAR arg) 2695 IN PSTRING arg)
2527{ 2696{
2528 UCHAR mac[6], mode; 2697 UCHAR mac[6], mode;
2529 char *token, sepValue[] = ":", DASH = '-'; 2698 PSTRING token;
2699 STRING sepValue[] = ":", DASH = '-';
2530 INT i; 2700 INT i;
2531 MAC_TABLE_ENTRY *pEntry; 2701 MAC_TABLE_ENTRY *pEntry;
2532 2702
2533 //printk("\n%s\n", arg); 2703 //DBGPRINT(RT_DEBUG_TRACE,("\n%s\n", arg));
2534/* 2704/*
2535 The BARecTearDown inupt string format should be xx:xx:xx:xx:xx:xx-d, 2705 The BARecTearDown inupt string format should be xx:xx:xx:xx:xx:xx-d,
2536 =>The six 2 digit hex-decimal number previous are the Mac address, 2706 =>The six 2 digit hex-decimal number previous are the Mac address,
@@ -2551,18 +2721,18 @@ INT Set_SendPSMPAction_Proc(
2551 { 2721 {
2552 if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1)))) 2722 if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1))))
2553 return FALSE; 2723 return FALSE;
2554 AtoH(token, (PUCHAR)(&mac[i]), 1); 2724 AtoH(token, (&mac[i]), 1);
2555 } 2725 }
2556 if(i != 6) 2726 if(i != 6)
2557 return FALSE; 2727 return FALSE;
2558 2728
2559 printk("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x", mac[0], mac[1], 2729 DBGPRINT(RT_DEBUG_OFF, ("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x",
2560 mac[2], mac[3], mac[4], mac[5], mode); 2730 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], mode));
2561 2731
2562 pEntry = MacTableLookup(pAd, mac); 2732 pEntry = MacTableLookup(pAd, mac);
2563 2733
2564 if (pEntry) { 2734 if (pEntry) {
2565 printk("\nSendPSMPAction MIPS mode = %d\n", mode); 2735 DBGPRINT(RT_DEBUG_OFF, ("\nSendPSMPAction MIPS mode = %d\n", mode));
2566 SendPSMPAction(pAd, pEntry->Aid, mode); 2736 SendPSMPAction(pAd, pEntry->Aid, mode);
2567 } 2737 }
2568 2738
@@ -2576,7 +2746,7 @@ INT Set_SendPSMPAction_Proc(
2576 2746
2577INT Set_HtMIMOPSmode_Proc( 2747INT Set_HtMIMOPSmode_Proc(
2578 IN PRTMP_ADAPTER pAd, 2748 IN PRTMP_ADAPTER pAd,
2579 IN PUCHAR arg) 2749 IN PSTRING arg)
2580{ 2750{
2581 ULONG Value; 2751 ULONG Value;
2582 2752
@@ -2597,7 +2767,7 @@ INT Set_HtMIMOPSmode_Proc(
2597 2767
2598INT Set_ForceShortGI_Proc( 2768INT Set_ForceShortGI_Proc(
2599 IN PRTMP_ADAPTER pAd, 2769 IN PRTMP_ADAPTER pAd,
2600 IN PUCHAR arg) 2770 IN PSTRING arg)
2601{ 2771{
2602 ULONG Value; 2772 ULONG Value;
2603 2773
@@ -2620,7 +2790,7 @@ INT Set_ForceShortGI_Proc(
2620 2790
2621INT Set_ForceGF_Proc( 2791INT Set_ForceGF_Proc(
2622 IN PRTMP_ADAPTER pAd, 2792 IN PRTMP_ADAPTER pAd,
2623 IN PUCHAR arg) 2793 IN PSTRING arg)
2624{ 2794{
2625 ULONG Value; 2795 ULONG Value;
2626 2796
@@ -2641,7 +2811,7 @@ INT Set_ForceGF_Proc(
2641 2811
2642INT Set_HtMimoPs_Proc( 2812INT Set_HtMimoPs_Proc(
2643 IN PRTMP_ADAPTER pAd, 2813 IN PRTMP_ADAPTER pAd,
2644 IN PUCHAR arg) 2814 IN PSTRING arg)
2645{ 2815{
2646 ULONG Value; 2816 ULONG Value;
2647 2817
@@ -2682,7 +2852,7 @@ INT SetCommonHT(
2682 2852
2683INT Set_FixedTxMode_Proc( 2853INT Set_FixedTxMode_Proc(
2684 IN PRTMP_ADAPTER pAd, 2854 IN PRTMP_ADAPTER pAd,
2685 IN PUCHAR arg) 2855 IN PSTRING arg)
2686{ 2856{
2687 UCHAR fix_tx_mode = FIXED_TXMODE_HT; 2857 UCHAR fix_tx_mode = FIXED_TXMODE_HT;
2688 2858
@@ -2702,8 +2872,57 @@ INT Set_FixedTxMode_Proc(
2702 return TRUE; 2872 return TRUE;
2703} 2873}
2704 2874
2875#if defined(RT305x)||defined(RT3070)
2876INT Set_HiPower_Proc(
2877 IN PRTMP_ADAPTER pAdapter,
2878 IN PSTRING arg)
2879{
2880 pAdapter->CommonCfg.HighPowerPatchDisabled = !(simple_strtol(arg, 0, 10));
2881
2882 if (pAdapter->CommonCfg.HighPowerPatchDisabled != 0)
2883 {
2884 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R82, 0x62);
2885 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R67, 0x20);
2886#ifdef RT3070
2887 if ((IS_RT3070(pAdapter) && ((pAdapter->MACVersion & 0xffff) < 0x0201)))
2888#endif // RT3070 //
2889 RT30xxWriteRFRegister(pAdapter, RF_R27, 0x23);
2890 }
2891 return TRUE;
2892}
2893#endif
2894
2895INT Set_LongRetryLimit_Proc(
2896 IN PRTMP_ADAPTER pAdapter,
2897 IN PSTRING arg)
2898{
2899 TX_RTY_CFG_STRUC tx_rty_cfg;
2900 UCHAR LongRetryLimit = (UCHAR)simple_strtol(arg, 0, 10);
2901
2902 RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
2903 tx_rty_cfg.field.LongRtyLimit = LongRetryLimit;
2904 RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
2905 DBGPRINT(RT_DEBUG_TRACE, ("IF Set_LongRetryLimit_Proc::(tx_rty_cfg=0x%x)\n", tx_rty_cfg.word));
2906 return TRUE;
2907}
2908
2909INT Set_ShortRetryLimit_Proc(
2910 IN PRTMP_ADAPTER pAdapter,
2911 IN PSTRING arg)
2912{
2913 TX_RTY_CFG_STRUC tx_rty_cfg;
2914 UCHAR ShortRetryLimit = (UCHAR)simple_strtol(arg, 0, 10);
2915
2916 RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
2917 tx_rty_cfg.field.ShortRtyLimit = ShortRetryLimit;
2918 RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
2919 DBGPRINT(RT_DEBUG_TRACE, ("IF Set_ShortRetryLimit_Proc::(tx_rty_cfg=0x%x)\n", tx_rty_cfg.word));
2920 return TRUE;
2921}
2922
2923
2705///////////////////////////////////////////////////////////////////////// 2924/////////////////////////////////////////////////////////////////////////
2706PCHAR RTMPGetRalinkAuthModeStr( 2925PSTRING RTMPGetRalinkAuthModeStr(
2707 IN NDIS_802_11_AUTHENTICATION_MODE authMode) 2926 IN NDIS_802_11_AUTHENTICATION_MODE authMode)
2708{ 2927{
2709 switch(authMode) 2928 switch(authMode)
@@ -2731,14 +2950,11 @@ PCHAR RTMPGetRalinkAuthModeStr(
2731 } 2950 }
2732} 2951}
2733 2952
2734PCHAR RTMPGetRalinkEncryModeStr( 2953PSTRING RTMPGetRalinkEncryModeStr(
2735 IN USHORT encryMode) 2954 IN USHORT encryMode)
2736{ 2955{
2737 switch(encryMode) 2956 switch(encryMode)
2738 { 2957 {
2739#if defined(RT2860) || defined(RT30xx)
2740 default:
2741#endif
2742 case Ndis802_11WEPDisabled: 2958 case Ndis802_11WEPDisabled:
2743 return "NONE"; 2959 return "NONE";
2744 case Ndis802_11WEPEnabled: 2960 case Ndis802_11WEPEnabled:
@@ -2749,17 +2965,15 @@ PCHAR RTMPGetRalinkEncryModeStr(
2749 return "AES"; 2965 return "AES";
2750 case Ndis802_11Encryption4Enabled: 2966 case Ndis802_11Encryption4Enabled:
2751 return "TKIPAES"; 2967 return "TKIPAES";
2752#if !defined(RT2860) && !defined(RT30xx)
2753 default: 2968 default:
2754 return "UNKNOW"; 2969 return "UNKNOW";
2755#endif
2756 } 2970 }
2757} 2971}
2758 2972
2759INT RTMPShowCfgValue( 2973INT RTMPShowCfgValue(
2760 IN PRTMP_ADAPTER pAd, 2974 IN PRTMP_ADAPTER pAd,
2761 IN PUCHAR pName, 2975 IN PSTRING pName,
2762 IN PUCHAR pBuf) 2976 IN PSTRING pBuf)
2763{ 2977{
2764 INT Status = 0; 2978 INT Status = 0;
2765 2979
@@ -2785,7 +2999,7 @@ INT RTMPShowCfgValue(
2785 2999
2786INT Show_SSID_Proc( 3000INT Show_SSID_Proc(
2787 IN PRTMP_ADAPTER pAd, 3001 IN PRTMP_ADAPTER pAd,
2788 OUT PUCHAR pBuf) 3002 OUT PSTRING pBuf)
2789{ 3003{
2790 sprintf(pBuf, "\t%s", pAd->CommonCfg.Ssid); 3004 sprintf(pBuf, "\t%s", pAd->CommonCfg.Ssid);
2791 return 0; 3005 return 0;
@@ -2793,7 +3007,7 @@ INT Show_SSID_Proc(
2793 3007
2794INT Show_WirelessMode_Proc( 3008INT Show_WirelessMode_Proc(
2795 IN PRTMP_ADAPTER pAd, 3009 IN PRTMP_ADAPTER pAd,
2796 OUT PUCHAR pBuf) 3010 OUT PSTRING pBuf)
2797{ 3011{
2798 switch(pAd->CommonCfg.PhyMode) 3012 switch(pAd->CommonCfg.PhyMode)
2799 { 3013 {
@@ -2843,7 +3057,7 @@ INT Show_WirelessMode_Proc(
2843 3057
2844INT Show_TxBurst_Proc( 3058INT Show_TxBurst_Proc(
2845 IN PRTMP_ADAPTER pAd, 3059 IN PRTMP_ADAPTER pAd,
2846 OUT PUCHAR pBuf) 3060 OUT PSTRING pBuf)
2847{ 3061{
2848 sprintf(pBuf, "\t%s", pAd->CommonCfg.bEnableTxBurst ? "TRUE":"FALSE"); 3062 sprintf(pBuf, "\t%s", pAd->CommonCfg.bEnableTxBurst ? "TRUE":"FALSE");
2849 return 0; 3063 return 0;
@@ -2851,7 +3065,7 @@ INT Show_TxBurst_Proc(
2851 3065
2852INT Show_TxPreamble_Proc( 3066INT Show_TxPreamble_Proc(
2853 IN PRTMP_ADAPTER pAd, 3067 IN PRTMP_ADAPTER pAd,
2854 OUT PUCHAR pBuf) 3068 OUT PSTRING pBuf)
2855{ 3069{
2856 switch(pAd->CommonCfg.TxPreamble) 3070 switch(pAd->CommonCfg.TxPreamble)
2857 { 3071 {
@@ -2874,7 +3088,7 @@ INT Show_TxPreamble_Proc(
2874 3088
2875INT Show_TxPower_Proc( 3089INT Show_TxPower_Proc(
2876 IN PRTMP_ADAPTER pAd, 3090 IN PRTMP_ADAPTER pAd,
2877 OUT PUCHAR pBuf) 3091 OUT PSTRING pBuf)
2878{ 3092{
2879 sprintf(pBuf, "\t%lu", pAd->CommonCfg.TxPowerPercentage); 3093 sprintf(pBuf, "\t%lu", pAd->CommonCfg.TxPowerPercentage);
2880 return 0; 3094 return 0;
@@ -2882,7 +3096,7 @@ INT Show_TxPower_Proc(
2882 3096
2883INT Show_Channel_Proc( 3097INT Show_Channel_Proc(
2884 IN PRTMP_ADAPTER pAd, 3098 IN PRTMP_ADAPTER pAd,
2885 OUT PUCHAR pBuf) 3099 OUT PSTRING pBuf)
2886{ 3100{
2887 sprintf(pBuf, "\t%d", pAd->CommonCfg.Channel); 3101 sprintf(pBuf, "\t%d", pAd->CommonCfg.Channel);
2888 return 0; 3102 return 0;
@@ -2890,7 +3104,7 @@ INT Show_Channel_Proc(
2890 3104
2891INT Show_BGProtection_Proc( 3105INT Show_BGProtection_Proc(
2892 IN PRTMP_ADAPTER pAd, 3106 IN PRTMP_ADAPTER pAd,
2893 OUT PUCHAR pBuf) 3107 OUT PSTRING pBuf)
2894{ 3108{
2895 switch(pAd->CommonCfg.UseBGProtection) 3109 switch(pAd->CommonCfg.UseBGProtection)
2896 { 3110 {
@@ -2912,7 +3126,7 @@ INT Show_BGProtection_Proc(
2912 3126
2913INT Show_RTSThreshold_Proc( 3127INT Show_RTSThreshold_Proc(
2914 IN PRTMP_ADAPTER pAd, 3128 IN PRTMP_ADAPTER pAd,
2915 OUT PUCHAR pBuf) 3129 OUT PSTRING pBuf)
2916{ 3130{
2917 sprintf(pBuf, "\t%u", pAd->CommonCfg.RtsThreshold); 3131 sprintf(pBuf, "\t%u", pAd->CommonCfg.RtsThreshold);
2918 return 0; 3132 return 0;
@@ -2920,7 +3134,7 @@ INT Show_RTSThreshold_Proc(
2920 3134
2921INT Show_FragThreshold_Proc( 3135INT Show_FragThreshold_Proc(
2922 IN PRTMP_ADAPTER pAd, 3136 IN PRTMP_ADAPTER pAd,
2923 OUT PUCHAR pBuf) 3137 OUT PSTRING pBuf)
2924{ 3138{
2925 sprintf(pBuf, "\t%u", pAd->CommonCfg.FragmentThreshold); 3139 sprintf(pBuf, "\t%u", pAd->CommonCfg.FragmentThreshold);
2926 return 0; 3140 return 0;
@@ -2928,7 +3142,7 @@ INT Show_FragThreshold_Proc(
2928 3142
2929INT Show_HtBw_Proc( 3143INT Show_HtBw_Proc(
2930 IN PRTMP_ADAPTER pAd, 3144 IN PRTMP_ADAPTER pAd,
2931 OUT PUCHAR pBuf) 3145 OUT PSTRING pBuf)
2932{ 3146{
2933 if (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40) 3147 if (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40)
2934 { 3148 {
@@ -2943,7 +3157,7 @@ INT Show_HtBw_Proc(
2943 3157
2944INT Show_HtMcs_Proc( 3158INT Show_HtMcs_Proc(
2945 IN PRTMP_ADAPTER pAd, 3159 IN PRTMP_ADAPTER pAd,
2946 OUT PUCHAR pBuf) 3160 OUT PSTRING pBuf)
2947{ 3161{
2948 sprintf(pBuf, "\t%u", pAd->StaCfg.DesiredTransmitSetting.field.MCS); 3162 sprintf(pBuf, "\t%u", pAd->StaCfg.DesiredTransmitSetting.field.MCS);
2949 return 0; 3163 return 0;
@@ -2951,7 +3165,7 @@ INT Show_HtMcs_Proc(
2951 3165
2952INT Show_HtGi_Proc( 3166INT Show_HtGi_Proc(
2953 IN PRTMP_ADAPTER pAd, 3167 IN PRTMP_ADAPTER pAd,
2954 OUT PUCHAR pBuf) 3168 OUT PSTRING pBuf)
2955{ 3169{
2956 switch(pAd->CommonCfg.RegTransmitSetting.field.ShortGI) 3170 switch(pAd->CommonCfg.RegTransmitSetting.field.ShortGI)
2957 { 3171 {
@@ -2970,7 +3184,7 @@ INT Show_HtGi_Proc(
2970 3184
2971INT Show_HtOpMode_Proc( 3185INT Show_HtOpMode_Proc(
2972 IN PRTMP_ADAPTER pAd, 3186 IN PRTMP_ADAPTER pAd,
2973 OUT PUCHAR pBuf) 3187 OUT PSTRING pBuf)
2974{ 3188{
2975 switch(pAd->CommonCfg.RegTransmitSetting.field.HTMODE) 3189 switch(pAd->CommonCfg.RegTransmitSetting.field.HTMODE)
2976 { 3190 {
@@ -2989,7 +3203,7 @@ INT Show_HtOpMode_Proc(
2989 3203
2990INT Show_HtExtcha_Proc( 3204INT Show_HtExtcha_Proc(
2991 IN PRTMP_ADAPTER pAd, 3205 IN PRTMP_ADAPTER pAd,
2992 OUT PUCHAR pBuf) 3206 OUT PSTRING pBuf)
2993{ 3207{
2994 switch(pAd->CommonCfg.RegTransmitSetting.field.EXTCHA) 3208 switch(pAd->CommonCfg.RegTransmitSetting.field.EXTCHA)
2995 { 3209 {
@@ -3009,7 +3223,7 @@ INT Show_HtExtcha_Proc(
3009 3223
3010INT Show_HtMpduDensity_Proc( 3224INT Show_HtMpduDensity_Proc(
3011 IN PRTMP_ADAPTER pAd, 3225 IN PRTMP_ADAPTER pAd,
3012 OUT PUCHAR pBuf) 3226 OUT PSTRING pBuf)
3013{ 3227{
3014 sprintf(pBuf, "\t%u", pAd->CommonCfg.BACapability.field.MpduDensity); 3228 sprintf(pBuf, "\t%u", pAd->CommonCfg.BACapability.field.MpduDensity);
3015 return 0; 3229 return 0;
@@ -3017,7 +3231,7 @@ INT Show_HtMpduDensity_Proc(
3017 3231
3018INT Show_HtBaWinSize_Proc( 3232INT Show_HtBaWinSize_Proc(
3019 IN PRTMP_ADAPTER pAd, 3233 IN PRTMP_ADAPTER pAd,
3020 OUT PUCHAR pBuf) 3234 OUT PSTRING pBuf)
3021{ 3235{
3022 sprintf(pBuf, "\t%u", pAd->CommonCfg.BACapability.field.RxBAWinLimit); 3236 sprintf(pBuf, "\t%u", pAd->CommonCfg.BACapability.field.RxBAWinLimit);
3023 return 0; 3237 return 0;
@@ -3025,7 +3239,7 @@ INT Show_HtBaWinSize_Proc(
3025 3239
3026INT Show_HtRdg_Proc( 3240INT Show_HtRdg_Proc(
3027 IN PRTMP_ADAPTER pAd, 3241 IN PRTMP_ADAPTER pAd,
3028 OUT PUCHAR pBuf) 3242 OUT PSTRING pBuf)
3029{ 3243{
3030 sprintf(pBuf, "\t%s", pAd->CommonCfg.bRdg ? "TRUE":"FALSE"); 3244 sprintf(pBuf, "\t%s", pAd->CommonCfg.bRdg ? "TRUE":"FALSE");
3031 return 0; 3245 return 0;
@@ -3033,7 +3247,7 @@ INT Show_HtRdg_Proc(
3033 3247
3034INT Show_HtAmsdu_Proc( 3248INT Show_HtAmsdu_Proc(
3035 IN PRTMP_ADAPTER pAd, 3249 IN PRTMP_ADAPTER pAd,
3036 OUT PUCHAR pBuf) 3250 OUT PSTRING pBuf)
3037{ 3251{
3038 sprintf(pBuf, "\t%s", pAd->CommonCfg.BACapability.field.AmsduEnable ? "TRUE":"FALSE"); 3252 sprintf(pBuf, "\t%s", pAd->CommonCfg.BACapability.field.AmsduEnable ? "TRUE":"FALSE");
3039 return 0; 3253 return 0;
@@ -3041,7 +3255,7 @@ INT Show_HtAmsdu_Proc(
3041 3255
3042INT Show_HtAutoBa_Proc( 3256INT Show_HtAutoBa_Proc(
3043 IN PRTMP_ADAPTER pAd, 3257 IN PRTMP_ADAPTER pAd,
3044 OUT PUCHAR pBuf) 3258 OUT PSTRING pBuf)
3045{ 3259{
3046 sprintf(pBuf, "\t%s", pAd->CommonCfg.BACapability.field.AutoBA ? "TRUE":"FALSE"); 3260 sprintf(pBuf, "\t%s", pAd->CommonCfg.BACapability.field.AutoBA ? "TRUE":"FALSE");
3047 return 0; 3261 return 0;
@@ -3049,7 +3263,7 @@ INT Show_HtAutoBa_Proc(
3049 3263
3050INT Show_CountryRegion_Proc( 3264INT Show_CountryRegion_Proc(
3051 IN PRTMP_ADAPTER pAd, 3265 IN PRTMP_ADAPTER pAd,
3052 OUT PUCHAR pBuf) 3266 OUT PSTRING pBuf)
3053{ 3267{
3054 sprintf(pBuf, "\t%d", pAd->CommonCfg.CountryRegion); 3268 sprintf(pBuf, "\t%d", pAd->CommonCfg.CountryRegion);
3055 return 0; 3269 return 0;
@@ -3057,7 +3271,7 @@ INT Show_CountryRegion_Proc(
3057 3271
3058INT Show_CountryRegionABand_Proc( 3272INT Show_CountryRegionABand_Proc(
3059 IN PRTMP_ADAPTER pAd, 3273 IN PRTMP_ADAPTER pAd,
3060 OUT PUCHAR pBuf) 3274 OUT PSTRING pBuf)
3061{ 3275{
3062 sprintf(pBuf, "\t%d", pAd->CommonCfg.CountryRegionForABand); 3276 sprintf(pBuf, "\t%d", pAd->CommonCfg.CountryRegionForABand);
3063 return 0; 3277 return 0;
@@ -3065,7 +3279,7 @@ INT Show_CountryRegionABand_Proc(
3065 3279
3066INT Show_CountryCode_Proc( 3280INT Show_CountryCode_Proc(
3067 IN PRTMP_ADAPTER pAd, 3281 IN PRTMP_ADAPTER pAd,
3068 OUT PUCHAR pBuf) 3282 OUT PSTRING pBuf)
3069{ 3283{
3070 sprintf(pBuf, "\t%s", pAd->CommonCfg.CountryCode); 3284 sprintf(pBuf, "\t%s", pAd->CommonCfg.CountryCode);
3071 return 0; 3285 return 0;
@@ -3074,7 +3288,7 @@ INT Show_CountryCode_Proc(
3074#ifdef AGGREGATION_SUPPORT 3288#ifdef AGGREGATION_SUPPORT
3075INT Show_PktAggregate_Proc( 3289INT Show_PktAggregate_Proc(
3076 IN PRTMP_ADAPTER pAd, 3290 IN PRTMP_ADAPTER pAd,
3077 OUT PUCHAR pBuf) 3291 OUT PSTRING pBuf)
3078{ 3292{
3079 sprintf(pBuf, "\t%s", pAd->CommonCfg.bAggregationCapable ? "TRUE":"FALSE"); 3293 sprintf(pBuf, "\t%s", pAd->CommonCfg.bAggregationCapable ? "TRUE":"FALSE");
3080 return 0; 3294 return 0;
@@ -3084,7 +3298,7 @@ INT Show_PktAggregate_Proc(
3084#ifdef WMM_SUPPORT 3298#ifdef WMM_SUPPORT
3085INT Show_WmmCapable_Proc( 3299INT Show_WmmCapable_Proc(
3086 IN PRTMP_ADAPTER pAd, 3300 IN PRTMP_ADAPTER pAd,
3087 OUT PUCHAR pBuf) 3301 OUT PSTRING pBuf)
3088{ 3302{
3089 sprintf(pBuf, "\t%s", pAd->CommonCfg.bWmmCapable ? "TRUE":"FALSE"); 3303 sprintf(pBuf, "\t%s", pAd->CommonCfg.bWmmCapable ? "TRUE":"FALSE");
3090 3304
@@ -3094,7 +3308,7 @@ INT Show_WmmCapable_Proc(
3094 3308
3095INT Show_IEEE80211H_Proc( 3309INT Show_IEEE80211H_Proc(
3096 IN PRTMP_ADAPTER pAd, 3310 IN PRTMP_ADAPTER pAd,
3097 OUT PUCHAR pBuf) 3311 OUT PSTRING pBuf)
3098{ 3312{
3099 sprintf(pBuf, "\t%s", pAd->CommonCfg.bIEEE80211H ? "TRUE":"FALSE"); 3313 sprintf(pBuf, "\t%s", pAd->CommonCfg.bIEEE80211H ? "TRUE":"FALSE");
3100 return 0; 3314 return 0;
@@ -3102,7 +3316,7 @@ INT Show_IEEE80211H_Proc(
3102 3316
3103INT Show_NetworkType_Proc( 3317INT Show_NetworkType_Proc(
3104 IN PRTMP_ADAPTER pAd, 3318 IN PRTMP_ADAPTER pAd,
3105 OUT PUCHAR pBuf) 3319 OUT PSTRING pBuf)
3106{ 3320{
3107 switch(pAd->StaCfg.BssType) 3321 switch(pAd->StaCfg.BssType)
3108 { 3322 {
@@ -3125,9 +3339,11 @@ INT Show_NetworkType_Proc(
3125 return 0; 3339 return 0;
3126} 3340}
3127 3341
3342
3343
3128INT Show_AuthMode_Proc( 3344INT Show_AuthMode_Proc(
3129 IN PRTMP_ADAPTER pAd, 3345 IN PRTMP_ADAPTER pAd,
3130 OUT PUCHAR pBuf) 3346 OUT PSTRING pBuf)
3131{ 3347{
3132 NDIS_802_11_AUTHENTICATION_MODE AuthMode = Ndis802_11AuthModeOpen; 3348 NDIS_802_11_AUTHENTICATION_MODE AuthMode = Ndis802_11AuthModeOpen;
3133 3349
@@ -3144,7 +3360,7 @@ INT Show_AuthMode_Proc(
3144 3360
3145INT Show_EncrypType_Proc( 3361INT Show_EncrypType_Proc(
3146 IN PRTMP_ADAPTER pAd, 3362 IN PRTMP_ADAPTER pAd,
3147 OUT PUCHAR pBuf) 3363 OUT PSTRING pBuf)
3148{ 3364{
3149 NDIS_802_11_WEP_STATUS WepStatus = Ndis802_11WEPDisabled; 3365 NDIS_802_11_WEP_STATUS WepStatus = Ndis802_11WEPDisabled;
3150 3366
@@ -3161,7 +3377,7 @@ INT Show_EncrypType_Proc(
3161 3377
3162INT Show_DefaultKeyID_Proc( 3378INT Show_DefaultKeyID_Proc(
3163 IN PRTMP_ADAPTER pAd, 3379 IN PRTMP_ADAPTER pAd,
3164 OUT PUCHAR pBuf) 3380 OUT PSTRING pBuf)
3165{ 3381{
3166 UCHAR DefaultKeyId = 0; 3382 UCHAR DefaultKeyId = 0;
3167 3383
@@ -3175,7 +3391,7 @@ INT Show_DefaultKeyID_Proc(
3175INT Show_WepKey_Proc( 3391INT Show_WepKey_Proc(
3176 IN PRTMP_ADAPTER pAd, 3392 IN PRTMP_ADAPTER pAd,
3177 IN INT KeyIdx, 3393 IN INT KeyIdx,
3178 OUT PUCHAR pBuf) 3394 OUT PSTRING pBuf)
3179{ 3395{
3180 UCHAR Key[16] = {0}, KeyLength = 0; 3396 UCHAR Key[16] = {0}, KeyLength = 0;
3181 INT index = BSS0; 3397 INT index = BSS0;
@@ -3184,7 +3400,7 @@ INT Show_WepKey_Proc(
3184 NdisMoveMemory(Key, pAd->SharedKey[index][KeyIdx].Key, KeyLength); 3400 NdisMoveMemory(Key, pAd->SharedKey[index][KeyIdx].Key, KeyLength);
3185 3401
3186 //check key string is ASCII or not 3402 //check key string is ASCII or not
3187 if (RTMPCheckStrPrintAble(Key, KeyLength)) 3403 if (RTMPCheckStrPrintAble((PCHAR)Key, KeyLength))
3188 sprintf(pBuf, "\t%s", Key); 3404 sprintf(pBuf, "\t%s", Key);
3189 else 3405 else
3190 { 3406 {
@@ -3198,7 +3414,7 @@ INT Show_WepKey_Proc(
3198 3414
3199INT Show_Key1_Proc( 3415INT Show_Key1_Proc(
3200 IN PRTMP_ADAPTER pAd, 3416 IN PRTMP_ADAPTER pAd,
3201 OUT PUCHAR pBuf) 3417 OUT PSTRING pBuf)
3202{ 3418{
3203 Show_WepKey_Proc(pAd, 0, pBuf); 3419 Show_WepKey_Proc(pAd, 0, pBuf);
3204 return 0; 3420 return 0;
@@ -3206,7 +3422,7 @@ INT Show_Key1_Proc(
3206 3422
3207INT Show_Key2_Proc( 3423INT Show_Key2_Proc(
3208 IN PRTMP_ADAPTER pAd, 3424 IN PRTMP_ADAPTER pAd,
3209 OUT PUCHAR pBuf) 3425 OUT PSTRING pBuf)
3210{ 3426{
3211 Show_WepKey_Proc(pAd, 1, pBuf); 3427 Show_WepKey_Proc(pAd, 1, pBuf);
3212 return 0; 3428 return 0;
@@ -3214,7 +3430,7 @@ INT Show_Key2_Proc(
3214 3430
3215INT Show_Key3_Proc( 3431INT Show_Key3_Proc(
3216 IN PRTMP_ADAPTER pAd, 3432 IN PRTMP_ADAPTER pAd,
3217 OUT PUCHAR pBuf) 3433 OUT PSTRING pBuf)
3218{ 3434{
3219 Show_WepKey_Proc(pAd, 2, pBuf); 3435 Show_WepKey_Proc(pAd, 2, pBuf);
3220 return 0; 3436 return 0;
@@ -3222,7 +3438,7 @@ INT Show_Key3_Proc(
3222 3438
3223INT Show_Key4_Proc( 3439INT Show_Key4_Proc(
3224 IN PRTMP_ADAPTER pAd, 3440 IN PRTMP_ADAPTER pAd,
3225 OUT PUCHAR pBuf) 3441 OUT PSTRING pBuf)
3226{ 3442{
3227 Show_WepKey_Proc(pAd, 3, pBuf); 3443 Show_WepKey_Proc(pAd, 3, pBuf);
3228 return 0; 3444 return 0;
@@ -3230,7 +3446,7 @@ INT Show_Key4_Proc(
3230 3446
3231INT Show_WPAPSK_Proc( 3447INT Show_WPAPSK_Proc(
3232 IN PRTMP_ADAPTER pAd, 3448 IN PRTMP_ADAPTER pAd,
3233 OUT PUCHAR pBuf) 3449 OUT PSTRING pBuf)
3234{ 3450{
3235 INT idx; 3451 INT idx;
3236 UCHAR PMK[32] = {0}; 3452 UCHAR PMK[32] = {0};
diff --git a/drivers/staging/rt2860/common/cmm_mac_pci.c b/drivers/staging/rt2860/common/cmm_mac_pci.c
new file mode 100644
index 00000000000..5aa6944d118
--- /dev/null
+++ b/drivers/staging/rt2860/common/cmm_mac_pci.c
@@ -0,0 +1,1504 @@
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#ifdef RTMP_MAC_PCI
30#include "../rt_config.h"
31
32
33/*
34 ========================================================================
35
36 Routine Description:
37 Allocate DMA memory blocks for send, receive
38
39 Arguments:
40 Adapter Pointer to our adapter
41
42 Return Value:
43 NDIS_STATUS_SUCCESS
44 NDIS_STATUS_FAILURE
45 NDIS_STATUS_RESOURCES
46
47 IRQL = PASSIVE_LEVEL
48
49 Note:
50
51 ========================================================================
52*/
53NDIS_STATUS RTMPAllocTxRxRingMemory(
54 IN PRTMP_ADAPTER pAd)
55{
56 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
57 ULONG RingBasePaHigh;
58 ULONG RingBasePaLow;
59 PVOID RingBaseVa;
60 INT index, num;
61 PTXD_STRUC pTxD;
62 PRXD_STRUC pRxD;
63 ULONG ErrorValue = 0;
64 PRTMP_TX_RING pTxRing;
65 PRTMP_DMABUF pDmaBuf;
66 PNDIS_PACKET pPacket;
67// PRTMP_REORDERBUF pReorderBuf;
68
69 DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocTxRxRingMemory\n"));
70 do
71 {
72 //
73 // Allocate all ring descriptors, include TxD, RxD, MgmtD.
74 // Although each size is different, to prevent cacheline and alignment
75 // issue, I intentional set them all to 64 bytes.
76 //
77 for (num=0; num<NUM_OF_TX_RING; num++)
78 {
79 ULONG BufBasePaHigh;
80 ULONG BufBasePaLow;
81 PVOID BufBaseVa;
82
83 //
84 // Allocate Tx ring descriptor's memory (5 TX rings = 4 ACs + 1 HCCA)
85 //
86 pAd->TxDescRing[num].AllocSize = TX_RING_SIZE * TXD_SIZE;
87 RTMP_AllocateTxDescMemory(
88 pAd,
89 num,
90 pAd->TxDescRing[num].AllocSize,
91 FALSE,
92 &pAd->TxDescRing[num].AllocVa,
93 &pAd->TxDescRing[num].AllocPa);
94
95 if (pAd->TxDescRing[num].AllocVa == NULL)
96 {
97 ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
98 DBGPRINT_ERR(("Failed to allocate a big buffer\n"));
99 Status = NDIS_STATUS_RESOURCES;
100 break;
101 }
102
103 // Zero init this memory block
104 NdisZeroMemory(pAd->TxDescRing[num].AllocVa, pAd->TxDescRing[num].AllocSize);
105
106 // Save PA & VA for further operation
107 RingBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->TxDescRing[num].AllocPa);
108 RingBasePaLow = RTMP_GetPhysicalAddressLow (pAd->TxDescRing[num].AllocPa);
109 RingBaseVa = pAd->TxDescRing[num].AllocVa;
110
111 //
112 // Allocate all 1st TXBuf's memory for this TxRing
113 //
114 pAd->TxBufSpace[num].AllocSize = TX_RING_SIZE * TX_DMA_1ST_BUFFER_SIZE;
115 RTMP_AllocateFirstTxBuffer(
116 pAd,
117 num,
118 pAd->TxBufSpace[num].AllocSize,
119 FALSE,
120 &pAd->TxBufSpace[num].AllocVa,
121 &pAd->TxBufSpace[num].AllocPa);
122
123 if (pAd->TxBufSpace[num].AllocVa == NULL)
124 {
125 ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
126 DBGPRINT_ERR(("Failed to allocate a big buffer\n"));
127 Status = NDIS_STATUS_RESOURCES;
128 break;
129 }
130
131 // Zero init this memory block
132 NdisZeroMemory(pAd->TxBufSpace[num].AllocVa, pAd->TxBufSpace[num].AllocSize);
133
134 // Save PA & VA for further operation
135 BufBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->TxBufSpace[num].AllocPa);
136 BufBasePaLow = RTMP_GetPhysicalAddressLow (pAd->TxBufSpace[num].AllocPa);
137 BufBaseVa = pAd->TxBufSpace[num].AllocVa;
138
139 //
140 // Initialize Tx Ring Descriptor and associated buffer memory
141 //
142 pTxRing = &pAd->TxRing[num];
143 for (index = 0; index < TX_RING_SIZE; index++)
144 {
145 pTxRing->Cell[index].pNdisPacket = NULL;
146 pTxRing->Cell[index].pNextNdisPacket = NULL;
147 // Init Tx Ring Size, Va, Pa variables
148 pTxRing->Cell[index].AllocSize = TXD_SIZE;
149 pTxRing->Cell[index].AllocVa = RingBaseVa;
150 RTMP_SetPhysicalAddressHigh(pTxRing->Cell[index].AllocPa, RingBasePaHigh);
151 RTMP_SetPhysicalAddressLow (pTxRing->Cell[index].AllocPa, RingBasePaLow);
152
153 // Setup Tx Buffer size & address. only 802.11 header will store in this space
154 pDmaBuf = &pTxRing->Cell[index].DmaBuf;
155 pDmaBuf->AllocSize = TX_DMA_1ST_BUFFER_SIZE;
156 pDmaBuf->AllocVa = BufBaseVa;
157 RTMP_SetPhysicalAddressHigh(pDmaBuf->AllocPa, BufBasePaHigh);
158 RTMP_SetPhysicalAddressLow(pDmaBuf->AllocPa, BufBasePaLow);
159
160 // link the pre-allocated TxBuf to TXD
161 pTxD = (PTXD_STRUC) pTxRing->Cell[index].AllocVa;
162 pTxD->SDPtr0 = BufBasePaLow;
163 // advance to next ring descriptor address
164 pTxD->DMADONE = 1;
165 RingBasePaLow += TXD_SIZE;
166 RingBaseVa = (PUCHAR) RingBaseVa + TXD_SIZE;
167
168 // advance to next TxBuf address
169 BufBasePaLow += TX_DMA_1ST_BUFFER_SIZE;
170 BufBaseVa = (PUCHAR) BufBaseVa + TX_DMA_1ST_BUFFER_SIZE;
171 }
172 DBGPRINT(RT_DEBUG_TRACE, ("TxRing[%d]: total %d entry allocated\n", num, index));
173 }
174 if (Status == NDIS_STATUS_RESOURCES)
175 break;
176
177 //
178 // Allocate MGMT ring descriptor's memory except Tx ring which allocated eariler
179 //
180 pAd->MgmtDescRing.AllocSize = MGMT_RING_SIZE * TXD_SIZE;
181 RTMP_AllocateMgmtDescMemory(
182 pAd,
183 pAd->MgmtDescRing.AllocSize,
184 FALSE,
185 &pAd->MgmtDescRing.AllocVa,
186 &pAd->MgmtDescRing.AllocPa);
187
188 if (pAd->MgmtDescRing.AllocVa == NULL)
189 {
190 ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
191 DBGPRINT_ERR(("Failed to allocate a big buffer\n"));
192 Status = NDIS_STATUS_RESOURCES;
193 break;
194 }
195
196 // Zero init this memory block
197 NdisZeroMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize);
198
199 // Save PA & VA for further operation
200 RingBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->MgmtDescRing.AllocPa);
201 RingBasePaLow = RTMP_GetPhysicalAddressLow (pAd->MgmtDescRing.AllocPa);
202 RingBaseVa = pAd->MgmtDescRing.AllocVa;
203
204 //
205 // Initialize MGMT Ring and associated buffer memory
206 //
207 for (index = 0; index < MGMT_RING_SIZE; index++)
208 {
209 pAd->MgmtRing.Cell[index].pNdisPacket = NULL;
210 pAd->MgmtRing.Cell[index].pNextNdisPacket = NULL;
211 // Init MGMT Ring Size, Va, Pa variables
212 pAd->MgmtRing.Cell[index].AllocSize = TXD_SIZE;
213 pAd->MgmtRing.Cell[index].AllocVa = RingBaseVa;
214 RTMP_SetPhysicalAddressHigh(pAd->MgmtRing.Cell[index].AllocPa, RingBasePaHigh);
215 RTMP_SetPhysicalAddressLow (pAd->MgmtRing.Cell[index].AllocPa, RingBasePaLow);
216
217 // Offset to next ring descriptor address
218 RingBasePaLow += TXD_SIZE;
219 RingBaseVa = (PUCHAR) RingBaseVa + TXD_SIZE;
220
221 // link the pre-allocated TxBuf to TXD
222 pTxD = (PTXD_STRUC) pAd->MgmtRing.Cell[index].AllocVa;
223 pTxD->DMADONE = 1;
224
225 // no pre-allocated buffer required in MgmtRing for scatter-gather case
226 }
227 DBGPRINT(RT_DEBUG_TRACE, ("MGMT Ring: total %d entry allocated\n", index));
228
229 //
230 // Allocate RX ring descriptor's memory except Tx ring which allocated eariler
231 //
232 pAd->RxDescRing.AllocSize = RX_RING_SIZE * RXD_SIZE;
233 RTMP_AllocateRxDescMemory(
234 pAd,
235 pAd->RxDescRing.AllocSize,
236 FALSE,
237 &pAd->RxDescRing.AllocVa,
238 &pAd->RxDescRing.AllocPa);
239
240 if (pAd->RxDescRing.AllocVa == NULL)
241 {
242 ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
243 DBGPRINT_ERR(("Failed to allocate a big buffer\n"));
244 Status = NDIS_STATUS_RESOURCES;
245 break;
246 }
247
248 // Zero init this memory block
249 NdisZeroMemory(pAd->RxDescRing.AllocVa, pAd->RxDescRing.AllocSize);
250
251
252 DBGPRINT(RT_DEBUG_OFF,
253 ("RX DESC %p size = %ld\n", pAd->RxDescRing.AllocVa, pAd->RxDescRing.AllocSize));
254
255 // Save PA & VA for further operation
256 RingBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->RxDescRing.AllocPa);
257 RingBasePaLow = RTMP_GetPhysicalAddressLow (pAd->RxDescRing.AllocPa);
258 RingBaseVa = pAd->RxDescRing.AllocVa;
259
260 //
261 // Initialize Rx Ring and associated buffer memory
262 //
263 for (index = 0; index < RX_RING_SIZE; index++)
264 {
265 // Init RX Ring Size, Va, Pa variables
266 pAd->RxRing.Cell[index].AllocSize = RXD_SIZE;
267 pAd->RxRing.Cell[index].AllocVa = RingBaseVa;
268 RTMP_SetPhysicalAddressHigh(pAd->RxRing.Cell[index].AllocPa, RingBasePaHigh);
269 RTMP_SetPhysicalAddressLow (pAd->RxRing.Cell[index].AllocPa, RingBasePaLow);
270
271 //NdisZeroMemory(RingBaseVa, RXD_SIZE);
272
273 // Offset to next ring descriptor address
274 RingBasePaLow += RXD_SIZE;
275 RingBaseVa = (PUCHAR) RingBaseVa + RXD_SIZE;
276
277 // Setup Rx associated Buffer size & allocate share memory
278 pDmaBuf = &pAd->RxRing.Cell[index].DmaBuf;
279 pDmaBuf->AllocSize = RX_BUFFER_AGGRESIZE;
280 pPacket = RTMP_AllocateRxPacketBuffer(
281 pAd,
282 pDmaBuf->AllocSize,
283 FALSE,
284 &pDmaBuf->AllocVa,
285 &pDmaBuf->AllocPa);
286
287 /* keep allocated rx packet */
288 pAd->RxRing.Cell[index].pNdisPacket = pPacket;
289
290 // Error handling
291 if (pDmaBuf->AllocVa == NULL)
292 {
293 ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
294 DBGPRINT_ERR(("Failed to allocate RxRing's 1st buffer\n"));
295 Status = NDIS_STATUS_RESOURCES;
296 break;
297 }
298
299 // Zero init this memory block
300 NdisZeroMemory(pDmaBuf->AllocVa, pDmaBuf->AllocSize);
301
302 // Write RxD buffer address & allocated buffer length
303 pRxD = (PRXD_STRUC) pAd->RxRing.Cell[index].AllocVa;
304 pRxD->SDP0 = RTMP_GetPhysicalAddressLow(pDmaBuf->AllocPa);
305 pRxD->DDONE = 0;
306
307 }
308
309 DBGPRINT(RT_DEBUG_TRACE, ("Rx Ring: total %d entry allocated\n", index));
310
311 } while (FALSE);
312
313
314 NdisZeroMemory(&pAd->FragFrame, sizeof(FRAGMENT_FRAME));
315 pAd->FragFrame.pFragPacket = RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE);
316
317 if (pAd->FragFrame.pFragPacket == NULL)
318 {
319 Status = NDIS_STATUS_RESOURCES;
320 }
321
322 if (Status != NDIS_STATUS_SUCCESS)
323 {
324 // Log error inforamtion
325 NdisWriteErrorLogEntry(
326 pAd->AdapterHandle,
327 NDIS_ERROR_CODE_OUT_OF_RESOURCES,
328 1,
329 ErrorValue);
330 }
331
332 // Following code segment get from original func:NICInitTxRxRingAndBacklogQueue(), now should integrate it to here.
333 {
334 DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitTxRxRingAndBacklogQueue\n"));
335
336/*
337 // Disable DMA.
338 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
339 GloCfg.word &= 0xff0;
340 GloCfg.field.EnTXWriteBackDDONE =1;
341 RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
342*/
343
344 // Initialize all transmit related software queues
345 for(index = 0; index < NUM_OF_TX_RING; index++)
346 {
347 InitializeQueueHeader(&pAd->TxSwQueue[index]);
348 // Init TX rings index pointer
349 pAd->TxRing[index].TxSwFreeIdx = 0;
350 pAd->TxRing[index].TxCpuIdx = 0;
351 //RTMP_IO_WRITE32(pAd, (TX_CTX_IDX0 + i * 0x10) , pAd->TxRing[i].TX_CTX_IDX);
352 }
353
354 // Init RX Ring index pointer
355 pAd->RxRing.RxSwReadIdx = 0;
356 pAd->RxRing.RxCpuIdx = RX_RING_SIZE - 1;
357 //RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RX_CRX_IDX0);
358
359
360 // init MGMT ring index pointer
361 pAd->MgmtRing.TxSwFreeIdx = 0;
362 pAd->MgmtRing.TxCpuIdx = 0;
363
364 pAd->PrivateInfo.TxRingFullCnt = 0;
365
366 DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitTxRxRingAndBacklogQueue\n"));
367 }
368
369 DBGPRINT_S(Status, ("<-- RTMPAllocTxRxRingMemory, Status=%x\n", Status));
370 return Status;
371}
372
373
374
375
376/*
377 ========================================================================
378
379 Routine Description:
380 Reset NIC Asics. Call after rest DMA. So reset TX_CTX_IDX to zero.
381
382 Arguments:
383 Adapter Pointer to our adapter
384
385 Return Value:
386 None
387
388 IRQL = PASSIVE_LEVEL
389 IRQL = DISPATCH_LEVEL
390
391 Note:
392 Reset NIC to initial state AS IS system boot up time.
393
394 ========================================================================
395*/
396VOID RTMPRingCleanUp(
397 IN PRTMP_ADAPTER pAd,
398 IN UCHAR RingType)
399{
400 PTXD_STRUC pTxD;
401 PRXD_STRUC pRxD;
402 PQUEUE_ENTRY pEntry;
403 PNDIS_PACKET pPacket;
404 int i;
405 PRTMP_TX_RING pTxRing;
406 unsigned long IrqFlags;
407 //UINT32 RxSwReadIdx;
408
409
410 DBGPRINT(RT_DEBUG_TRACE,("RTMPRingCleanUp(RingIdx=%d, Pending-NDIS=%ld)\n", RingType, pAd->RalinkCounters.PendingNdisPacketCount));
411 switch (RingType)
412 {
413 case QID_AC_BK:
414 case QID_AC_BE:
415 case QID_AC_VI:
416 case QID_AC_VO:
417 case QID_HCCA:
418
419 pTxRing = &pAd->TxRing[RingType];
420
421 RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
422 // We have to clean all descriptors in case some error happened with reset
423 for (i=0; i<TX_RING_SIZE; i++) // We have to scan all TX ring
424 {
425 pTxD = (PTXD_STRUC) pTxRing->Cell[i].AllocVa;
426
427 pPacket = (PNDIS_PACKET) pTxRing->Cell[i].pNdisPacket;
428 // release scatter-and-gather NDIS_PACKET
429 if (pPacket)
430 {
431 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
432 pTxRing->Cell[i].pNdisPacket = NULL;
433 }
434
435 pPacket = (PNDIS_PACKET) pTxRing->Cell[i].pNextNdisPacket;
436 // release scatter-and-gather NDIS_PACKET
437 if (pPacket)
438 {
439 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
440 pTxRing->Cell[i].pNextNdisPacket = NULL;
441 }
442 }
443
444 RTMP_IO_READ32(pAd, TX_DTX_IDX0 + RingType * 0x10, &pTxRing->TxDmaIdx);
445 pTxRing->TxSwFreeIdx = pTxRing->TxDmaIdx;
446 pTxRing->TxCpuIdx = pTxRing->TxDmaIdx;
447 RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + RingType * 0x10, pTxRing->TxCpuIdx);
448
449 RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
450
451 RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
452 while (pAd->TxSwQueue[RingType].Head != NULL)
453 {
454 pEntry = RemoveHeadQueue(&pAd->TxSwQueue[RingType]);
455 pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
456 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
457 DBGPRINT(RT_DEBUG_TRACE,("Release 1 NDIS packet from s/w backlog queue\n"));
458 }
459 RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
460 break;
461
462 case QID_MGMT:
463 // We have to clean all descriptors in case some error happened with reset
464 NdisAcquireSpinLock(&pAd->MgmtRingLock);
465
466 for (i=0; i<MGMT_RING_SIZE; i++)
467 {
468 pTxD = (PTXD_STRUC) pAd->MgmtRing.Cell[i].AllocVa;
469
470 pPacket = (PNDIS_PACKET) pAd->MgmtRing.Cell[i].pNdisPacket;
471 // rlease scatter-and-gather NDIS_PACKET
472 if (pPacket)
473 {
474 PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, PCI_DMA_TODEVICE);
475 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
476 }
477 pAd->MgmtRing.Cell[i].pNdisPacket = NULL;
478
479 pPacket = (PNDIS_PACKET) pAd->MgmtRing.Cell[i].pNextNdisPacket;
480 // release scatter-and-gather NDIS_PACKET
481 if (pPacket)
482 {
483 PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
484 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
485 }
486 pAd->MgmtRing.Cell[i].pNextNdisPacket = NULL;
487
488 }
489
490 RTMP_IO_READ32(pAd, TX_MGMTDTX_IDX, &pAd->MgmtRing.TxDmaIdx);
491 pAd->MgmtRing.TxSwFreeIdx = pAd->MgmtRing.TxDmaIdx;
492 pAd->MgmtRing.TxCpuIdx = pAd->MgmtRing.TxDmaIdx;
493 RTMP_IO_WRITE32(pAd, TX_MGMTCTX_IDX, pAd->MgmtRing.TxCpuIdx);
494
495 NdisReleaseSpinLock(&pAd->MgmtRingLock);
496 pAd->RalinkCounters.MgmtRingFullCount = 0;
497 break;
498
499 case QID_RX:
500 // We have to clean all descriptors in case some error happened with reset
501 NdisAcquireSpinLock(&pAd->RxRingLock);
502
503 for (i=0; i<RX_RING_SIZE; i++)
504 {
505 pRxD = (PRXD_STRUC) pAd->RxRing.Cell[i].AllocVa;
506 pRxD->DDONE = 0 ;
507 }
508
509 RTMP_IO_READ32(pAd, RX_DRX_IDX, &pAd->RxRing.RxDmaIdx);
510 pAd->RxRing.RxSwReadIdx = pAd->RxRing.RxDmaIdx;
511 pAd->RxRing.RxCpuIdx = ((pAd->RxRing.RxDmaIdx == 0) ? (RX_RING_SIZE-1) : (pAd->RxRing.RxDmaIdx-1));
512 RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx);
513
514 NdisReleaseSpinLock(&pAd->RxRingLock);
515 break;
516
517 default:
518 break;
519 }
520}
521
522
523VOID RTMPFreeTxRxRingMemory(
524 IN PRTMP_ADAPTER pAd)
525{
526 int index, num , j;
527 PRTMP_TX_RING pTxRing;
528 PTXD_STRUC pTxD;
529 PNDIS_PACKET pPacket;
530 unsigned int IrqFlags;
531
532 //POS_COOKIE pObj =(POS_COOKIE) pAd->OS_Cookie;
533
534 DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPFreeTxRxRingMemory\n"));
535
536 // Free TxSwQueue Packet
537 for (index=0; index <NUM_OF_TX_RING; index++)
538 {
539 PQUEUE_ENTRY pEntry;
540 PNDIS_PACKET pPacket;
541 PQUEUE_HEADER pQueue;
542
543 RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
544 pQueue = &pAd->TxSwQueue[index];
545 while (pQueue->Head)
546 {
547 pEntry = RemoveHeadQueue(pQueue);
548 pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
549 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
550 }
551 RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
552 }
553
554 // Free Tx Ring Packet
555 for (index=0;index< NUM_OF_TX_RING;index++)
556 {
557 pTxRing = &pAd->TxRing[index];
558
559 for (j=0; j< TX_RING_SIZE; j++)
560 {
561 pTxD = (PTXD_STRUC) (pTxRing->Cell[j].AllocVa);
562 pPacket = pTxRing->Cell[j].pNdisPacket;
563
564 if (pPacket)
565 {
566 PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, PCI_DMA_TODEVICE);
567 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
568 }
569 //Always assign pNdisPacket as NULL after clear
570 pTxRing->Cell[j].pNdisPacket = NULL;
571
572 pPacket = pTxRing->Cell[j].pNextNdisPacket;
573
574 if (pPacket)
575 {
576 PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
577 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
578 }
579 //Always assign pNextNdisPacket as NULL after clear
580 pTxRing->Cell[pTxRing->TxSwFreeIdx].pNextNdisPacket = NULL;
581
582 }
583 }
584
585 for (index = RX_RING_SIZE - 1 ; index >= 0; index--)
586 {
587 if ((pAd->RxRing.Cell[index].DmaBuf.AllocVa) && (pAd->RxRing.Cell[index].pNdisPacket))
588 {
589 PCI_UNMAP_SINGLE(pAd, pAd->RxRing.Cell[index].DmaBuf.AllocPa, pAd->RxRing.Cell[index].DmaBuf.AllocSize, PCI_DMA_FROMDEVICE);
590 RELEASE_NDIS_PACKET(pAd, pAd->RxRing.Cell[index].pNdisPacket, NDIS_STATUS_SUCCESS);
591 }
592 }
593 NdisZeroMemory(pAd->RxRing.Cell, RX_RING_SIZE * sizeof(RTMP_DMACB));
594
595 if (pAd->RxDescRing.AllocVa)
596 {
597 RTMP_FreeDescMemory(pAd, pAd->RxDescRing.AllocSize, pAd->RxDescRing.AllocVa, pAd->RxDescRing.AllocPa);
598 }
599 NdisZeroMemory(&pAd->RxDescRing, sizeof(RTMP_DMABUF));
600
601 if (pAd->MgmtDescRing.AllocVa)
602 {
603 RTMP_FreeDescMemory(pAd, pAd->MgmtDescRing.AllocSize, pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocPa);
604 }
605 NdisZeroMemory(&pAd->MgmtDescRing, sizeof(RTMP_DMABUF));
606
607 for (num = 0; num < NUM_OF_TX_RING; num++)
608 {
609 if (pAd->TxBufSpace[num].AllocVa)
610 {
611 RTMP_FreeFirstTxBuffer(pAd, pAd->TxBufSpace[num].AllocSize, FALSE, pAd->TxBufSpace[num].AllocVa, pAd->TxBufSpace[num].AllocPa);
612 }
613 NdisZeroMemory(&pAd->TxBufSpace[num], sizeof(RTMP_DMABUF));
614
615 if (pAd->TxDescRing[num].AllocVa)
616 {
617 RTMP_FreeDescMemory(pAd, pAd->TxDescRing[num].AllocSize, pAd->TxDescRing[num].AllocVa, pAd->TxDescRing[num].AllocPa);
618 }
619 NdisZeroMemory(&pAd->TxDescRing[num], sizeof(RTMP_DMABUF));
620 }
621
622 if (pAd->FragFrame.pFragPacket)
623 RELEASE_NDIS_PACKET(pAd, pAd->FragFrame.pFragPacket, NDIS_STATUS_SUCCESS);
624
625 DBGPRINT(RT_DEBUG_TRACE, ("<-- RTMPFreeTxRxRingMemory\n"));
626}
627
628
629/***************************************************************************
630 *
631 * register related procedures.
632 *
633 **************************************************************************/
634/*
635========================================================================
636Routine Description:
637 Disable DMA.
638
639Arguments:
640 *pAd the raxx interface data pointer
641
642Return Value:
643 None
644
645Note:
646========================================================================
647*/
648VOID RT28XXDMADisable(
649 IN RTMP_ADAPTER *pAd)
650{
651 WPDMA_GLO_CFG_STRUC GloCfg;
652
653
654 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
655 GloCfg.word &= 0xff0;
656 GloCfg.field.EnTXWriteBackDDONE =1;
657 RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
658}
659
660
661/*
662========================================================================
663Routine Description:
664 Enable DMA.
665
666Arguments:
667 *pAd the raxx interface data pointer
668
669Return Value:
670 None
671
672Note:
673========================================================================
674*/
675VOID RT28XXDMAEnable(
676 IN RTMP_ADAPTER *pAd)
677{
678 WPDMA_GLO_CFG_STRUC GloCfg;
679 int i = 0;
680
681 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x4);
682 do
683 {
684 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
685 if ((GloCfg.field.TxDMABusy == 0) && (GloCfg.field.RxDMABusy == 0))
686 break;
687
688 DBGPRINT(RT_DEBUG_TRACE, ("==> DMABusy\n"));
689 RTMPusecDelay(1000);
690 i++;
691 }while ( i <200);
692
693 RTMPusecDelay(50);
694
695 GloCfg.field.EnTXWriteBackDDONE = 1;
696 GloCfg.field.WPDMABurstSIZE = 2;
697 GloCfg.field.EnableRxDMA = 1;
698 GloCfg.field.EnableTxDMA = 1;
699
700 DBGPRINT(RT_DEBUG_TRACE, ("<== WRITE DMA offset 0x208 = 0x%x\n", GloCfg.word));
701 RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
702
703}
704
705
706BOOLEAN AsicCheckCommanOk(
707 IN PRTMP_ADAPTER pAd,
708 IN UCHAR Command)
709{
710 UINT32 CmdStatus = 0, CID = 0, i;
711 UINT32 ThisCIDMask = 0;
712
713 i = 0;
714 do
715 {
716 RTMP_IO_READ32(pAd, H2M_MAILBOX_CID, &CID);
717 // Find where the command is. Because this is randomly specified by firmware.
718 if ((CID & CID0MASK) == Command)
719 {
720 ThisCIDMask = CID0MASK;
721 break;
722 }
723 else if ((((CID & CID1MASK)>>8) & 0xff) == Command)
724 {
725 ThisCIDMask = CID1MASK;
726 break;
727 }
728 else if ((((CID & CID2MASK)>>16) & 0xff) == Command)
729 {
730 ThisCIDMask = CID2MASK;
731 break;
732 }
733 else if ((((CID & CID3MASK)>>24) & 0xff) == Command)
734 {
735 ThisCIDMask = CID3MASK;
736 break;
737 }
738
739 RTMPusecDelay(100);
740 i++;
741 }while (i < 200);
742
743 // Get CommandStatus Value
744 RTMP_IO_READ32(pAd, H2M_MAILBOX_STATUS, &CmdStatus);
745
746 // This command's status is at the same position as command. So AND command position's bitmask to read status.
747 if (i < 200)
748 {
749 // If Status is 1, the comamnd is success.
750 if (((CmdStatus & ThisCIDMask) == 0x1) || ((CmdStatus & ThisCIDMask) == 0x100)
751 || ((CmdStatus & ThisCIDMask) == 0x10000) || ((CmdStatus & ThisCIDMask) == 0x1000000))
752 {
753 DBGPRINT(RT_DEBUG_TRACE, ("--> AsicCheckCommanOk CID = 0x%x, CmdStatus= 0x%x \n", CID, CmdStatus));
754 RTMP_IO_WRITE32(pAd, H2M_MAILBOX_STATUS, 0xffffffff);
755 RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CID, 0xffffffff);
756 return TRUE;
757 }
758 DBGPRINT(RT_DEBUG_TRACE, ("--> AsicCheckCommanFail1 CID = 0x%x, CmdStatus= 0x%x \n", CID, CmdStatus));
759 }
760 else
761 {
762 DBGPRINT(RT_DEBUG_TRACE, ("--> AsicCheckCommanFail2 Timeout Command = %d, CmdStatus= 0x%x \n", Command, CmdStatus));
763 }
764 // Clear Command and Status.
765 RTMP_IO_WRITE32(pAd, H2M_MAILBOX_STATUS, 0xffffffff);
766 RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CID, 0xffffffff);
767
768 return FALSE;
769}
770
771
772/*
773========================================================================
774Routine Description:
775 Write Beacon buffer to Asic.
776
777Arguments:
778 *pAd the raxx interface data pointer
779
780Return Value:
781 None
782
783Note:
784========================================================================
785*/
786VOID RT28xx_UpdateBeaconToAsic(
787 IN RTMP_ADAPTER *pAd,
788 IN INT apidx,
789 IN ULONG FrameLen,
790 IN ULONG UpdatePos)
791{
792 ULONG CapInfoPos = 0;
793 UCHAR *ptr, *ptr_update, *ptr_capinfo;
794 UINT i;
795 BOOLEAN bBcnReq = FALSE;
796 UCHAR bcn_idx = 0;
797
798
799 {
800 DBGPRINT(RT_DEBUG_ERROR, ("%s() : No valid Interface be found.\n", __func__));
801 return;
802 }
803
804 //if ((pAd->WdsTab.Mode == WDS_BRIDGE_MODE)
805 // || ((pAd->ApCfg.MBSSID[apidx].MSSIDDev == NULL)
806 // || !(pAd->ApCfg.MBSSID[apidx].MSSIDDev->flags & IFF_UP))
807 // )
808 if (bBcnReq == FALSE)
809 {
810 /* when the ra interface is down, do not send its beacon frame */
811 /* clear all zero */
812 for(i=0; i<TXWI_SIZE; i+=4)
813 RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i, 0x00);
814 }
815 else
816 {
817 ptr = (PUCHAR)&pAd->BeaconTxWI;
818 for (i=0; i<TXWI_SIZE; i+=4) // 16-byte TXWI field
819 {
820 UINT32 longptr = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
821 RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i, longptr);
822 ptr += 4;
823 }
824
825 // Update CapabilityInfo in Beacon
826 for (i = CapInfoPos; i < (CapInfoPos+2); i++)
827 {
828 RTMP_IO_WRITE8(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, *ptr_capinfo);
829 ptr_capinfo ++;
830 }
831
832 if (FrameLen > UpdatePos)
833 {
834 for (i= UpdatePos; i< (FrameLen); i++)
835 {
836 RTMP_IO_WRITE8(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, *ptr_update);
837 ptr_update ++;
838 }
839 }
840
841 }
842
843}
844
845
846VOID RT28xxPciStaAsicForceWakeup(
847 IN PRTMP_ADAPTER pAd,
848 IN BOOLEAN bFromTx)
849{
850 AUTO_WAKEUP_STRUC AutoWakeupCfg;
851
852 if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
853 return;
854
855 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WAKEUP_NOW))
856 {
857 DBGPRINT(RT_DEBUG_TRACE, ("waking up now!\n"));
858 return;
859 }
860
861 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_WAKEUP_NOW);
862
863#ifdef RTMP_PCI_SUPPORT
864 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
865 {
866 // Support PCIe Advance Power Save
867 if (bFromTx == TRUE)
868 {
869 pAd->Mlme.bPsPollTimerRunning = FALSE;
870 RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_WAKEUP);
871 RTMPusecDelay(3000);
872 DBGPRINT(RT_DEBUG_TRACE, ("=======AsicForceWakeup===bFromTx\n"));
873 }
874
875 AutoWakeupCfg.word = 0;
876 RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
877
878 if (RT28xxPciAsicRadioOn(pAd, DOT11POWERSAVE))
879 {
880 {
881 // end johnli
882 // In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again.
883 if (INFRA_ON(pAd) && (pAd->CommonCfg.CentralChannel != pAd->CommonCfg.Channel)
884 && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
885 {
886 // Must using 40MHz.
887 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
888 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
889 }
890 else
891 {
892 // Must using 20MHz.
893 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
894 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
895 }
896 }
897 }
898 }
899 else
900#endif // RTMP_PCI_SUPPORT //
901 {
902 // PCI, 2860-PCIe
903 AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02);
904 AutoWakeupCfg.word = 0;
905 RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
906 }
907
908 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
909 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_WAKEUP_NOW);
910 DBGPRINT(RT_DEBUG_TRACE, ("<=======RT28xxPciStaAsicForceWakeup\n"));
911}
912
913
914VOID RT28xxPciStaAsicSleepThenAutoWakeup(
915 IN PRTMP_ADAPTER pAd,
916 IN USHORT TbttNumToNextWakeUp)
917{
918 BOOLEAN brc;
919
920 if (pAd->StaCfg.bRadio == FALSE)
921 {
922 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
923 return;
924 }
925 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
926 {
927 ULONG Now = 0;
928 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WAKEUP_NOW))
929 {
930 DBGPRINT(RT_DEBUG_TRACE, ("waking up now!\n"));
931 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
932 return;
933 }
934
935 NdisGetSystemUpTime(&Now);
936 // If last send NULL fram time is too close to this receiving beacon (within 8ms), don't go to sleep for this DTM.
937 // Because Some AP can't queuing outgoing frames immediately.
938 if (((pAd->Mlme.LastSendNULLpsmTime + 8) >= Now) && (pAd->Mlme.LastSendNULLpsmTime <= Now))
939 {
940 DBGPRINT(RT_DEBUG_TRACE, ("Now = %lu, LastSendNULLpsmTime=%lu : RxCountSinceLastNULL = %lu. \n", Now, pAd->Mlme.LastSendNULLpsmTime, pAd->RalinkCounters.RxCountSinceLastNULL));
941 return;
942 }
943 else if ((pAd->RalinkCounters.RxCountSinceLastNULL > 0) && ((pAd->Mlme.LastSendNULLpsmTime + pAd->CommonCfg.BeaconPeriod) >= Now))
944 {
945 DBGPRINT(RT_DEBUG_TRACE, ("Now = %lu, LastSendNULLpsmTime=%lu: RxCountSinceLastNULL = %lu > 0 \n", Now, pAd->Mlme.LastSendNULLpsmTime, pAd->RalinkCounters.RxCountSinceLastNULL));
946 return;
947 }
948
949 brc = RT28xxPciAsicRadioOff(pAd, DOT11POWERSAVE, TbttNumToNextWakeUp);
950 if (brc==TRUE)
951 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_DOZE);
952 }
953 else
954 {
955 AUTO_WAKEUP_STRUC AutoWakeupCfg;
956 // we have decided to SLEEP, so at least do it for a BEACON period.
957 if (TbttNumToNextWakeUp == 0)
958 TbttNumToNextWakeUp = 1;
959
960 //RTMP_IO_WRITE32(pAd, INT_MASK_CSR, AutoWakeupInt);
961
962 AutoWakeupCfg.word = 0;
963 RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
964 AutoWakeupCfg.field.NumofSleepingTbtt = TbttNumToNextWakeUp - 1;
965 AutoWakeupCfg.field.EnableAutoWakeup = 1;
966 AutoWakeupCfg.field.AutoLeadTime = 5;
967 RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
968 AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x00); // send POWER-SAVE command to MCU. Timeout 40us.
969 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_DOZE);
970 DBGPRINT(RT_DEBUG_TRACE, ("<-- %s, TbttNumToNextWakeUp=%d \n", __func__, TbttNumToNextWakeUp));
971 }
972
973}
974
975#ifdef RTMP_PCI_SUPPORT
976VOID PsPollWakeExec(
977 IN PVOID SystemSpecific1,
978 IN PVOID FunctionContext,
979 IN PVOID SystemSpecific2,
980 IN PVOID SystemSpecific3)
981{
982 RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
983 unsigned long flags;
984
985 DBGPRINT(RT_DEBUG_TRACE,("-->PsPollWakeExec \n"));
986 RTMP_INT_LOCK(&pAd->irq_lock, flags);
987 if (pAd->Mlme.bPsPollTimerRunning)
988 {
989 RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_WAKEUP);
990 }
991 pAd->Mlme.bPsPollTimerRunning = FALSE;
992 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
993}
994
995VOID RadioOnExec(
996 IN PVOID SystemSpecific1,
997 IN PVOID FunctionContext,
998 IN PVOID SystemSpecific2,
999 IN PVOID SystemSpecific3)
1000{
1001 RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
1002 RTMP_CHIP_OP *pChipOps = &pAd->chipOps;
1003 WPDMA_GLO_CFG_STRUC DmaCfg;
1004 BOOLEAN Cancelled;
1005
1006 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
1007 {
1008 DBGPRINT(RT_DEBUG_TRACE,("-->RadioOnExec() return on fOP_STATUS_DOZE == TRUE; \n"));
1009 RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 10);
1010 return;
1011 }
1012
1013 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
1014 {
1015 DBGPRINT(RT_DEBUG_TRACE,("-->RadioOnExec() return on SCAN_IN_PROGRESS; \n"));
1016 RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 10);
1017 return;
1018 }
1019 pAd->Mlme.bPsPollTimerRunning = FALSE;
1020 RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
1021 if (pAd->StaCfg.bRadio == TRUE)
1022 {
1023 pAd->bPCIclkOff = FALSE;
1024 RTMPRingCleanUp(pAd, QID_AC_BK);
1025 RTMPRingCleanUp(pAd, QID_AC_BE);
1026 RTMPRingCleanUp(pAd, QID_AC_VI);
1027 RTMPRingCleanUp(pAd, QID_AC_VO);
1028 RTMPRingCleanUp(pAd, QID_HCCA);
1029 RTMPRingCleanUp(pAd, QID_MGMT);
1030 RTMPRingCleanUp(pAd, QID_RX);
1031
1032 // 2. Send wake up command.
1033 AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00, 0x02);
1034 // 2-1. wait command ok.
1035 AsicCheckCommanOk(pAd, PowerWakeCID);
1036
1037 // When PCI clock is off, don't want to service interrupt. So when back to clock on, enable interrupt.
1038 //RTMP_IO_WRITE32(pAd, INT_MASK_CSR, (DELAYINTMASK|RxINT));
1039 RTMP_ASIC_INTERRUPT_ENABLE(pAd);
1040
1041 // 3. Enable Tx DMA.
1042 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &DmaCfg.word);
1043 DmaCfg.field.EnableTxDMA = 1;
1044 RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, DmaCfg.word);
1045
1046 // In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again.
1047 if (INFRA_ON(pAd) && (pAd->CommonCfg.CentralChannel != pAd->CommonCfg.Channel)
1048 && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
1049 {
1050 // Must using 40MHz.
1051 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
1052 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
1053 }
1054 else
1055 {
1056 // Must using 20MHz.
1057 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
1058 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
1059 }
1060
1061 if (pChipOps->AsicReverseRfFromSleepMode)
1062 pChipOps->AsicReverseRfFromSleepMode(pAd);
1063
1064 // Clear Radio off flag
1065 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
1066
1067 // Set LED
1068 RTMPSetLED(pAd, LED_RADIO_ON);
1069
1070 if (pAd->StaCfg.Psm == PWR_ACTIVE)
1071 {
1072 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3);
1073 }
1074 }
1075 else
1076 {
1077 RT28xxPciAsicRadioOff(pAd, GUIRADIO_OFF, 0);
1078 }
1079}
1080#endif // RTMP_PCI_SUPPORT //
1081
1082
1083/*
1084 ==========================================================================
1085 Description:
1086 This routine sends command to firmware and turn our chip to wake up mode from power save mode.
1087 Both RadioOn and .11 power save function needs to call this routine.
1088 Input:
1089 Level = GUIRADIO_OFF : call this function is from Radio Off to Radio On. Need to restore PCI host value.
1090 Level = other value : normal wake up function.
1091
1092 ==========================================================================
1093 */
1094BOOLEAN RT28xxPciAsicRadioOn(
1095 IN PRTMP_ADAPTER pAd,
1096 IN UCHAR Level)
1097{
1098 //WPDMA_GLO_CFG_STRUC DmaCfg;
1099 BOOLEAN Cancelled;
1100 //UINT32 MACValue;
1101
1102 if (pAd->OpMode == OPMODE_AP && Level==DOT11POWERSAVE)
1103 return FALSE;
1104
1105#ifdef RTMP_PCI_SUPPORT
1106 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
1107 {
1108 pAd->Mlme.bPsPollTimerRunning = FALSE;
1109 RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
1110 if ((Level == GUIRADIO_OFF) || (Level == GUI_IDLE_POWER_SAVE))
1111 {
1112 DBGPRINT(RT_DEBUG_TRACE, ("RT28xxPciAsicRadioOn ()\n"));
1113 // 1. Set PCI Link Control in Configuration Space.
1114 RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_WAKEUP);
1115 RTMPusecDelay(6000);
1116 }
1117 }
1118#endif // RTMP_PCI_SUPPORT //
1119
1120 pAd->bPCIclkOff = FALSE;
1121 // 2. Send wake up command.
1122 AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00, 0x02);
1123 pAd->bPCIclkOff = FALSE;
1124 // 2-1. wait command ok.
1125 AsicCheckCommanOk(pAd, PowerWakeCID);
1126 RTMP_ASIC_INTERRUPT_ENABLE(pAd);
1127
1128
1129 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF);
1130 if (Level == GUI_IDLE_POWER_SAVE)
1131 {
1132 {
1133 // In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again.
1134 {
1135 if (INFRA_ON(pAd) && (pAd->CommonCfg.CentralChannel != pAd->CommonCfg.Channel)
1136 && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
1137 {
1138 // Must using 40MHz.
1139 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
1140 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
1141 }
1142 else
1143 {
1144 // Must using 20MHz.
1145 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
1146 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
1147 }
1148 }
1149
1150 }
1151 }
1152 return TRUE;
1153
1154}
1155
1156
1157/*
1158 ==========================================================================
1159 Description:
1160 This routine sends command to firmware and turn our chip to power save mode.
1161 Both RadioOff and .11 power save function needs to call this routine.
1162 Input:
1163 Level = GUIRADIO_OFF : GUI Radio Off mode
1164 Level = DOT11POWERSAVE : 802.11 power save mode
1165 Level = RTMP_HALT : When Disable device.
1166
1167 ==========================================================================
1168 */
1169BOOLEAN RT28xxPciAsicRadioOff(
1170 IN PRTMP_ADAPTER pAd,
1171 IN UCHAR Level,
1172 IN USHORT TbttNumToNextWakeUp)
1173{
1174 WPDMA_GLO_CFG_STRUC DmaCfg;
1175 UCHAR i, tempBBP_R3 = 0;
1176 BOOLEAN brc = FALSE, Cancelled;
1177 UINT32 TbTTTime = 0;
1178 UINT32 PsPollTime = 0/*, MACValue*/;
1179 ULONG BeaconPeriodTime;
1180 UINT32 RxDmaIdx, RxCpuIdx;
1181 DBGPRINT(RT_DEBUG_TRACE, ("AsicRadioOff ===> Lv= %d, TxCpuIdx = %d, TxDmaIdx = %d. RxCpuIdx = %d, RxDmaIdx = %d.\n", Level,pAd->TxRing[0].TxCpuIdx, pAd->TxRing[0].TxDmaIdx, pAd->RxRing.RxCpuIdx, pAd->RxRing.RxDmaIdx));
1182
1183 if (pAd->OpMode == OPMODE_AP && Level==DOT11POWERSAVE)
1184 return FALSE;
1185
1186 // Check Rx DMA busy status, if more than half is occupied, give up this radio off.
1187 RTMP_IO_READ32(pAd, RX_DRX_IDX , &RxDmaIdx);
1188 RTMP_IO_READ32(pAd, RX_CRX_IDX , &RxCpuIdx);
1189 if ((RxDmaIdx > RxCpuIdx) && ((RxDmaIdx - RxCpuIdx) > RX_RING_SIZE/3))
1190 {
1191 DBGPRINT(RT_DEBUG_TRACE, ("AsicRadioOff ===> return1. RxDmaIdx = %d , RxCpuIdx = %d. \n", RxDmaIdx, RxCpuIdx));
1192 return FALSE;
1193 }
1194 else if ((RxCpuIdx >= RxDmaIdx) && ((RxCpuIdx - RxDmaIdx) < RX_RING_SIZE/3))
1195 {
1196 DBGPRINT(RT_DEBUG_TRACE, ("AsicRadioOff ===> return2. RxCpuIdx = %d. RxDmaIdx = %d , \n", RxCpuIdx, RxDmaIdx));
1197 return FALSE;
1198 }
1199
1200 // Once go into this function, disable tx because don't want too many packets in queue to prevent HW stops.
1201 pAd->bPCIclkOffDisableTx = TRUE;
1202
1203 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE) && pAd->OpMode == OPMODE_STA)
1204 {
1205 printk("==>fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE\n");
1206 RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer, &Cancelled);
1207 RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
1208
1209 if (Level == DOT11POWERSAVE)
1210 {
1211 RTMP_IO_READ32(pAd, TBTT_TIMER, &TbTTTime);
1212 TbTTTime &= 0x1ffff;
1213 // 00. check if need to do sleep in this DTIM period. If next beacon will arrive within 30ms , ...doesn't necessarily sleep.
1214 // TbTTTime uint = 64us, LEAD_TIME unit = 1024us, PsPollTime unit = 1ms
1215 if (((64*TbTTTime) <((LEAD_TIME*1024) + 40000)) && (TbttNumToNextWakeUp == 0))
1216 {
1217 DBGPRINT(RT_DEBUG_TRACE, ("TbTTTime = 0x%x , give up this sleep. \n", TbTTTime));
1218 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
1219 pAd->bPCIclkOffDisableTx = FALSE;
1220 return FALSE;
1221 }
1222 else
1223 {
1224 PsPollTime = (64*TbTTTime- LEAD_TIME*1024)/1000;
1225 PsPollTime -= 3;
1226
1227 BeaconPeriodTime = pAd->CommonCfg.BeaconPeriod*102/100;
1228 if (TbttNumToNextWakeUp > 0)
1229 PsPollTime += ((TbttNumToNextWakeUp -1) * BeaconPeriodTime);
1230
1231 pAd->Mlme.bPsPollTimerRunning = TRUE;
1232 RTMPSetTimer(&pAd->Mlme.PsPollTimer, PsPollTime);
1233 }
1234 }
1235 }
1236
1237 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF);
1238
1239 // Set to 1R.
1240 if (pAd->Antenna.field.RxPath > 1 && pAd->OpMode == OPMODE_STA)
1241 {
1242 tempBBP_R3 = (pAd->StaCfg.BBPR3 & 0xE7);
1243 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, tempBBP_R3);
1244 }
1245
1246 // In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again.
1247 if ((INFRA_ON(pAd) || pAd->OpMode == OPMODE_AP) && (pAd->CommonCfg.CentralChannel != pAd->CommonCfg.Channel)
1248 && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
1249 {
1250 // Must using 40MHz.
1251 AsicTurnOffRFClk(pAd, pAd->CommonCfg.CentralChannel);
1252 }
1253 else
1254 {
1255 // Must using 20MHz.
1256 AsicTurnOffRFClk(pAd, pAd->CommonCfg.Channel);
1257 }
1258
1259 if (Level != RTMP_HALT)
1260 {
1261 // Change Interrupt bitmask.
1262 // When PCI clock is off, don't want to service interrupt.
1263 RTMP_IO_WRITE32(pAd, INT_MASK_CSR, AutoWakeupInt);
1264 }
1265 else
1266 {
1267 RTMP_ASIC_INTERRUPT_DISABLE(pAd);
1268 }
1269
1270
1271 RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx);
1272 // 2. Send Sleep command
1273 RTMP_IO_WRITE32(pAd, H2M_MAILBOX_STATUS, 0xffffffff);
1274 RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CID, 0xffffffff);
1275 // send POWER-SAVE command to MCU. high-byte = 1 save power as much as possible. high byte = 0 save less power
1276 AsicSendCommandToMcu(pAd, 0x30, PowerSafeCID, 0xff, 0x1);
1277 // 2-1. Wait command success
1278 // Status = 1 : success, Status = 2, already sleep, Status = 3, Maybe MAC is busy so can't finish this task.
1279 brc = AsicCheckCommanOk(pAd, PowerSafeCID);
1280
1281 // 3. After 0x30 command is ok, send radio off command. lowbyte = 0 for power safe.
1282 // If 0x30 command is not ok this time, we can ignore 0x35 command. It will make sure not cause firmware'r problem.
1283 if ((Level == DOT11POWERSAVE) && (brc == TRUE))
1284 {
1285 AsicSendCommandToMcu(pAd, 0x35, PowerRadioOffCID, 0, 0x00); // lowbyte = 0 means to do power safe, NOT turn off radio.
1286 // 3-1. Wait command success
1287 AsicCheckCommanOk(pAd, PowerRadioOffCID);
1288 }
1289 else if (brc == TRUE)
1290 {
1291 AsicSendCommandToMcu(pAd, 0x35, PowerRadioOffCID, 1, 0x00); // lowbyte = 0 means to do power safe, NOT turn off radio.
1292 // 3-1. Wait command success
1293 AsicCheckCommanOk(pAd, PowerRadioOffCID);
1294 }
1295
1296 // 1. Wait DMA not busy
1297 i = 0;
1298 do
1299 {
1300 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &DmaCfg.word);
1301 if ((DmaCfg.field.RxDMABusy == 0) && (DmaCfg.field.TxDMABusy == 0))
1302 break;
1303 RTMPusecDelay(20);
1304 i++;
1305 }while(i < 50);
1306
1307 /*
1308 if (i >= 50)
1309 {
1310 pAd->CheckDmaBusyCount++;
1311 DBGPRINT(RT_DEBUG_TRACE, ("DMA Rx keeps busy. return on AsicRadioOff () CheckDmaBusyCount = %d \n", pAd->CheckDmaBusyCount));
1312 }
1313 else
1314 {
1315 pAd->CheckDmaBusyCount = 0;
1316 }
1317 */
1318
1319 if (Level == DOT11POWERSAVE)
1320 {
1321 AUTO_WAKEUP_STRUC AutoWakeupCfg;
1322 //RTMPSetTimer(&pAd->Mlme.PsPollTimer, 90);
1323
1324 // we have decided to SLEEP, so at least do it for a BEACON period.
1325 if (TbttNumToNextWakeUp == 0)
1326 TbttNumToNextWakeUp = 1;
1327
1328 AutoWakeupCfg.word = 0;
1329 RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
1330
1331 // 1. Set auto wake up timer.
1332 AutoWakeupCfg.field.NumofSleepingTbtt = TbttNumToNextWakeUp - 1;
1333 AutoWakeupCfg.field.EnableAutoWakeup = 1;
1334 AutoWakeupCfg.field.AutoLeadTime = LEAD_TIME;
1335 RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
1336 }
1337
1338#ifdef RTMP_PCI_SUPPORT
1339 // 4-1. If it's to disable our device. Need to restore PCI Configuration Space to its original value.
1340 if (Level == RTMP_HALT && pAd->OpMode == OPMODE_STA)
1341 {
1342 if ((brc == TRUE) && (i < 50))
1343 RTMPPCIeLinkCtrlSetting(pAd, 1);
1344 }
1345 // 4. Set PCI configuration Space Link Comtrol fields. Only Radio Off needs to call this function
1346 else if (pAd->OpMode == OPMODE_STA)
1347 {
1348 if ((brc == TRUE) && (i < 50))
1349 RTMPPCIeLinkCtrlSetting(pAd, 3);
1350 }
1351#endif // RTMP_PCI_SUPPORT //
1352
1353 pAd->bPCIclkOffDisableTx = FALSE;
1354 return TRUE;
1355}
1356
1357
1358
1359
1360VOID RT28xxPciMlmeRadioOn(
1361 IN PRTMP_ADAPTER pAd)
1362{
1363 if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
1364 return;
1365
1366 DBGPRINT(RT_DEBUG_TRACE,("%s===>\n", __func__));
1367
1368 if ((pAd->OpMode == OPMODE_AP) ||
1369 ((pAd->OpMode == OPMODE_STA) && (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))))
1370 {
1371 if (pAd->OpMode == OPMODE_AP)
1372 RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE);
1373
1374 //NICResetFromError(pAd);
1375
1376 RTMPRingCleanUp(pAd, QID_AC_BK);
1377 RTMPRingCleanUp(pAd, QID_AC_BE);
1378 RTMPRingCleanUp(pAd, QID_AC_VI);
1379 RTMPRingCleanUp(pAd, QID_AC_VO);
1380 RTMPRingCleanUp(pAd, QID_HCCA);
1381 RTMPRingCleanUp(pAd, QID_MGMT);
1382 RTMPRingCleanUp(pAd, QID_RX);
1383
1384 if (pAd->OpMode == OPMODE_STA)
1385 {
1386 AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02);
1387 RTMPusecDelay(10000);
1388 }
1389
1390 // Enable Tx/Rx
1391 RTMPEnableRxTx(pAd);
1392
1393 // Clear Radio off flag
1394 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
1395
1396 // Set LED
1397 RTMPSetLED(pAd, LED_RADIO_ON);
1398 }
1399
1400#ifdef RTMP_PCI_SUPPORT
1401 if ((pAd->OpMode == OPMODE_STA) &&
1402 (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)))
1403 {
1404 BOOLEAN Cancelled;
1405
1406 RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_WAKEUP);
1407
1408 pAd->Mlme.bPsPollTimerRunning = FALSE;
1409 RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
1410 RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer, &Cancelled);
1411 RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 10);
1412 }
1413#endif // RTMP_PCI_SUPPORT //
1414}
1415
1416
1417VOID RT28xxPciMlmeRadioOFF(
1418 IN PRTMP_ADAPTER pAd)
1419{
1420 BOOLEAN brc=TRUE;
1421
1422 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
1423 return;
1424
1425 // Link down first if any association exists
1426 if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
1427 {
1428 if (INFRA_ON(pAd) || ADHOC_ON(pAd))
1429 {
1430 MLME_DISASSOC_REQ_STRUCT DisReq;
1431 MLME_QUEUE_ELEM *pMsgElem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
1432
1433 if (pMsgElem)
1434 {
1435 COPY_MAC_ADDR(&DisReq.Addr, pAd->CommonCfg.Bssid);
1436 DisReq.Reason = REASON_DISASSOC_STA_LEAVING;
1437
1438 pMsgElem->Machine = ASSOC_STATE_MACHINE;
1439 pMsgElem->MsgType = MT2_MLME_DISASSOC_REQ;
1440 pMsgElem->MsgLen = sizeof(MLME_DISASSOC_REQ_STRUCT);
1441 NdisMoveMemory(pMsgElem->Msg, &DisReq, sizeof(MLME_DISASSOC_REQ_STRUCT));
1442
1443 MlmeDisassocReqAction(pAd, pMsgElem);
1444 kfree(pMsgElem);
1445
1446 RTMPusecDelay(1000);
1447 }
1448 }
1449 }
1450
1451 DBGPRINT(RT_DEBUG_TRACE,("%s===>\n", __func__));
1452
1453 // Set Radio off flag
1454 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
1455
1456 {
1457 BOOLEAN Cancelled;
1458 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
1459 {
1460 RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled);
1461 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
1462 }
1463
1464 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
1465 {
1466 BOOLEAN Cancelled;
1467 pAd->Mlme.bPsPollTimerRunning = FALSE;
1468 RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
1469 RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer, &Cancelled);
1470 }
1471
1472 // Link down first if any association exists
1473 if (INFRA_ON(pAd) || ADHOC_ON(pAd))
1474 LinkDown(pAd, FALSE);
1475 RTMPusecDelay(10000);
1476 //==========================================
1477 // Clean up old bss table
1478 BssTableInit(&pAd->ScanTab);
1479
1480 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
1481 {
1482 RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 10);
1483 return;
1484 }
1485 }
1486
1487 // Set LED
1488 RTMPSetLED(pAd, LED_RADIO_OFF);
1489
1490 if (pAd->OpMode == OPMODE_AP)
1491 brc=RT28xxPciAsicRadioOff(pAd, GUIRADIO_OFF, 0);
1492
1493 if (brc==FALSE)
1494 {
1495 DBGPRINT(RT_DEBUG_ERROR,("%s call RT28xxPciAsicRadioOff fail !!\n", __func__));
1496 }
1497
1498
1499 if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE) &&
1500 (pAd->OpMode == OPMODE_STA))
1501 AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02);
1502}
1503
1504#endif // RTMP_MAC_PCI //
diff --git a/drivers/staging/rt2860/common/cmm_mac_usb.c b/drivers/staging/rt2860/common/cmm_mac_usb.c
new file mode 100644
index 00000000000..ad8c6017647
--- /dev/null
+++ b/drivers/staging/rt2860/common/cmm_mac_usb.c
@@ -0,0 +1,1216 @@
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
31#include "../rt_config.h"
32
33
34/*
35========================================================================
36Routine Description:
37 Initialize receive data structures.
38
39Arguments:
40 pAd Pointer to our adapter
41
42Return Value:
43 NDIS_STATUS_SUCCESS
44 NDIS_STATUS_RESOURCES
45
46Note:
47 Initialize all receive releated private buffer, include those define
48 in RTMP_ADAPTER structure and all private data structures. The mahor
49 work is to allocate buffer for each packet and chain buffer to
50 NDIS packet descriptor.
51========================================================================
52*/
53NDIS_STATUS NICInitRecv(
54 IN PRTMP_ADAPTER pAd)
55{
56 UCHAR i;
57 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
58 POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
59
60
61 DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitRecv\n"));
62 pObj = pObj;
63
64 //InterlockedExchange(&pAd->PendingRx, 0);
65 pAd->PendingRx = 0;
66 pAd->NextRxBulkInReadIndex = 0; // Next Rx Read index
67 pAd->NextRxBulkInIndex = 0 ; //RX_RING_SIZE -1; // Rx Bulk pointer
68 pAd->NextRxBulkInPosition = 0;
69
70 for (i = 0; i < (RX_RING_SIZE); i++)
71 {
72 PRX_CONTEXT pRxContext = &(pAd->RxContext[i]);
73
74 //Allocate URB
75 pRxContext->pUrb = RTUSB_ALLOC_URB(0);
76 if (pRxContext->pUrb == NULL)
77 {
78 Status = NDIS_STATUS_RESOURCES;
79 goto out1;
80 }
81
82 // Allocate transfer buffer
83 pRxContext->TransferBuffer = RTUSB_URB_ALLOC_BUFFER(pObj->pUsb_Dev, MAX_RXBULK_SIZE, &pRxContext->data_dma);
84 if (pRxContext->TransferBuffer == NULL)
85 {
86 Status = NDIS_STATUS_RESOURCES;
87 goto out1;
88 }
89
90 NdisZeroMemory(pRxContext->TransferBuffer, MAX_RXBULK_SIZE);
91
92 pRxContext->pAd = pAd;
93 pRxContext->pIrp = NULL;
94 pRxContext->InUse = FALSE;
95 pRxContext->IRPPending = FALSE;
96 pRxContext->Readable = FALSE;
97 //pRxContext->ReorderInUse = FALSE;
98 pRxContext->bRxHandling = FALSE;
99 pRxContext->BulkInOffset = 0;
100 }
101
102 DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitRecv(Status=%d)\n", Status));
103 return Status;
104
105out1:
106 for (i = 0; i < (RX_RING_SIZE); i++)
107 {
108 PRX_CONTEXT pRxContext = &(pAd->RxContext[i]);
109
110 if (NULL != pRxContext->TransferBuffer)
111 {
112 RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, MAX_RXBULK_SIZE,
113 pRxContext->TransferBuffer, pRxContext->data_dma);
114 pRxContext->TransferBuffer = NULL;
115 }
116
117 if (NULL != pRxContext->pUrb)
118 {
119 RTUSB_UNLINK_URB(pRxContext->pUrb);
120 RTUSB_FREE_URB(pRxContext->pUrb);
121 pRxContext->pUrb = NULL;
122 }
123 }
124
125 return Status;
126}
127
128
129/*
130========================================================================
131Routine Description:
132 Initialize transmit data structures.
133
134Arguments:
135 pAd Pointer to our adapter
136
137Return Value:
138 NDIS_STATUS_SUCCESS
139 NDIS_STATUS_RESOURCES
140
141Note:
142========================================================================
143*/
144NDIS_STATUS NICInitTransmit(
145 IN PRTMP_ADAPTER pAd)
146{
147#define LM_USB_ALLOC(pObj, Context, TB_Type, BufferSize, Status, msg1, err1, msg2, err2) \
148 Context->pUrb = RTUSB_ALLOC_URB(0); \
149 if (Context->pUrb == NULL) { \
150 DBGPRINT(RT_DEBUG_ERROR, msg1); \
151 Status = NDIS_STATUS_RESOURCES; \
152 goto err1; } \
153 \
154 Context->TransferBuffer = \
155 (TB_Type)RTUSB_URB_ALLOC_BUFFER(pObj->pUsb_Dev, BufferSize, &Context->data_dma); \
156 if (Context->TransferBuffer == NULL) { \
157 DBGPRINT(RT_DEBUG_ERROR, msg2); \
158 Status = NDIS_STATUS_RESOURCES; \
159 goto err2; }
160
161#define LM_URB_FREE(pObj, Context, BufferSize) \
162 if (NULL != Context->pUrb) { \
163 RTUSB_UNLINK_URB(Context->pUrb); \
164 RTUSB_FREE_URB(Context->pUrb); \
165 Context->pUrb = NULL; } \
166 if (NULL != Context->TransferBuffer) { \
167 RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, BufferSize, \
168 Context->TransferBuffer, \
169 Context->data_dma); \
170 Context->TransferBuffer = NULL; }
171
172 UCHAR i, acidx;
173 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
174 PTX_CONTEXT pNullContext = &(pAd->NullContext);
175 PTX_CONTEXT pPsPollContext = &(pAd->PsPollContext);
176 PTX_CONTEXT pRTSContext = &(pAd->RTSContext);
177 PTX_CONTEXT pMLMEContext = NULL;
178// PHT_TX_CONTEXT pHTTXContext = NULL;
179 POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
180 PVOID RingBaseVa;
181// RTMP_TX_RING *pTxRing;
182 RTMP_MGMT_RING *pMgmtRing;
183
184 DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitTransmit\n"));
185 pObj = pObj;
186
187 // Init 4 set of Tx parameters
188 for(acidx = 0; acidx < NUM_OF_TX_RING; acidx++)
189 {
190 // Initialize all Transmit releated queues
191 InitializeQueueHeader(&pAd->TxSwQueue[acidx]);
192
193 // Next Local tx ring pointer waiting for buck out
194 pAd->NextBulkOutIndex[acidx] = acidx;
195 pAd->BulkOutPending[acidx] = FALSE; // Buck Out control flag
196 //pAd->DataBulkDoneIdx[acidx] = 0;
197 }
198
199 //pAd->NextMLMEIndex = 0;
200 //pAd->PushMgmtIndex = 0;
201 //pAd->PopMgmtIndex = 0;
202 //InterlockedExchange(&pAd->MgmtQueueSize, 0);
203 //InterlockedExchange(&pAd->TxCount, 0);
204
205 //pAd->PrioRingFirstIndex = 0;
206 //pAd->PrioRingTxCnt = 0;
207
208 do
209 {
210 //
211 // TX_RING_SIZE, 4 ACs
212 //
213 for(acidx=0; acidx<4; acidx++)
214 {
215 PHT_TX_CONTEXT pHTTXContext = &(pAd->TxContext[acidx]);
216
217 NdisZeroMemory(pHTTXContext, sizeof(HT_TX_CONTEXT));
218 //Allocate URB
219 LM_USB_ALLOC(pObj, pHTTXContext, PHTTX_BUFFER, sizeof(HTTX_BUFFER), Status,
220 ("<-- ERROR in Alloc TX TxContext[%d] urb!! \n", acidx),
221 done,
222 ("<-- ERROR in Alloc TX TxContext[%d] HTTX_BUFFER !! \n", acidx),
223 out1);
224
225 NdisZeroMemory(pHTTXContext->TransferBuffer->Aggregation, 4);
226 pHTTXContext->pAd = pAd;
227 pHTTXContext->pIrp = NULL;
228 pHTTXContext->IRPPending = FALSE;
229 pHTTXContext->NextBulkOutPosition = 0;
230 pHTTXContext->ENextBulkOutPosition = 0;
231 pHTTXContext->CurWritePosition = 0;
232 pHTTXContext->CurWriteRealPos = 0;
233 pHTTXContext->BulkOutSize = 0;
234 pHTTXContext->BulkOutPipeId = acidx;
235 pHTTXContext->bRingEmpty = TRUE;
236 pHTTXContext->bCopySavePad = FALSE;
237 pAd->BulkOutPending[acidx] = FALSE;
238 }
239
240
241 //
242 // MGMT_RING_SIZE
243 //
244
245 // Allocate MGMT ring descriptor's memory
246 pAd->MgmtDescRing.AllocSize = MGMT_RING_SIZE * sizeof(TX_CONTEXT);
247 os_alloc_mem(pAd, (PUCHAR *)(&pAd->MgmtDescRing.AllocVa), pAd->MgmtDescRing.AllocSize);
248 if (pAd->MgmtDescRing.AllocVa == NULL)
249 {
250 DBGPRINT_ERR(("Failed to allocate a big buffer for MgmtDescRing!\n"));
251 Status = NDIS_STATUS_RESOURCES;
252 goto out1;
253 }
254 NdisZeroMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize);
255 RingBaseVa = pAd->MgmtDescRing.AllocVa;
256
257 // Initialize MGMT Ring and associated buffer memory
258 pMgmtRing = &pAd->MgmtRing;
259 for (i = 0; i < MGMT_RING_SIZE; i++)
260 {
261 // link the pre-allocated Mgmt buffer to MgmtRing.Cell
262 pMgmtRing->Cell[i].AllocSize = sizeof(TX_CONTEXT);
263 pMgmtRing->Cell[i].AllocVa = RingBaseVa;
264 pMgmtRing->Cell[i].pNdisPacket = NULL;
265 pMgmtRing->Cell[i].pNextNdisPacket = NULL;
266
267 //Allocate URB for MLMEContext
268 pMLMEContext = (PTX_CONTEXT) pAd->MgmtRing.Cell[i].AllocVa;
269 pMLMEContext->pUrb = RTUSB_ALLOC_URB(0);
270 if (pMLMEContext->pUrb == NULL)
271 {
272 DBGPRINT(RT_DEBUG_ERROR, ("<-- ERROR in Alloc TX MLMEContext[%d] urb!! \n", i));
273 Status = NDIS_STATUS_RESOURCES;
274 goto out2;
275 }
276 pMLMEContext->pAd = pAd;
277 pMLMEContext->pIrp = NULL;
278 pMLMEContext->TransferBuffer = NULL;
279 pMLMEContext->InUse = FALSE;
280 pMLMEContext->IRPPending = FALSE;
281 pMLMEContext->bWaitingBulkOut = FALSE;
282 pMLMEContext->BulkOutSize = 0;
283 pMLMEContext->SelfIdx = i;
284
285 // Offset to next ring descriptor address
286 RingBaseVa = (PUCHAR) RingBaseVa + sizeof(TX_CONTEXT);
287 }
288 DBGPRINT(RT_DEBUG_TRACE, ("MGMT Ring: total %d entry allocated\n", i));
289
290 //pAd->MgmtRing.TxSwFreeIdx = (MGMT_RING_SIZE - 1);
291 pAd->MgmtRing.TxSwFreeIdx = MGMT_RING_SIZE;
292 pAd->MgmtRing.TxCpuIdx = 0;
293 pAd->MgmtRing.TxDmaIdx = 0;
294
295 //
296 // BEACON_RING_SIZE
297 //
298 for(i=0; i<BEACON_RING_SIZE; i++) // 2
299 {
300 PTX_CONTEXT pBeaconContext = &(pAd->BeaconContext[i]);
301
302
303 NdisZeroMemory(pBeaconContext, sizeof(TX_CONTEXT));
304
305 //Allocate URB
306 LM_USB_ALLOC(pObj, pBeaconContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
307 ("<-- ERROR in Alloc TX BeaconContext[%d] urb!! \n", i),
308 out2,
309 ("<-- ERROR in Alloc TX BeaconContext[%d] TX_BUFFER !! \n", i),
310 out3);
311
312 pBeaconContext->pAd = pAd;
313 pBeaconContext->pIrp = NULL;
314 pBeaconContext->InUse = FALSE;
315 pBeaconContext->IRPPending = FALSE;
316 }
317
318 //
319 // NullContext
320 //
321 NdisZeroMemory(pNullContext, sizeof(TX_CONTEXT));
322
323 //Allocate URB
324 LM_USB_ALLOC(pObj, pNullContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
325 ("<-- ERROR in Alloc TX NullContext urb!! \n"),
326 out3,
327 ("<-- ERROR in Alloc TX NullContext TX_BUFFER !! \n"),
328 out4);
329
330 pNullContext->pAd = pAd;
331 pNullContext->pIrp = NULL;
332 pNullContext->InUse = FALSE;
333 pNullContext->IRPPending = FALSE;
334
335 //
336 // RTSContext
337 //
338 NdisZeroMemory(pRTSContext, sizeof(TX_CONTEXT));
339
340 //Allocate URB
341 LM_USB_ALLOC(pObj, pRTSContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
342 ("<-- ERROR in Alloc TX RTSContext urb!! \n"),
343 out4,
344 ("<-- ERROR in Alloc TX RTSContext TX_BUFFER !! \n"),
345 out5);
346
347 pRTSContext->pAd = pAd;
348 pRTSContext->pIrp = NULL;
349 pRTSContext->InUse = FALSE;
350 pRTSContext->IRPPending = FALSE;
351
352 //
353 // PsPollContext
354 //
355 //NdisZeroMemory(pPsPollContext, sizeof(TX_CONTEXT));
356 //Allocate URB
357 LM_USB_ALLOC(pObj, pPsPollContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
358 ("<-- ERROR in Alloc TX PsPollContext urb!! \n"),
359 out5,
360 ("<-- ERROR in Alloc TX PsPollContext TX_BUFFER !! \n"),
361 out6);
362
363 pPsPollContext->pAd = pAd;
364 pPsPollContext->pIrp = NULL;
365 pPsPollContext->InUse = FALSE;
366 pPsPollContext->IRPPending = FALSE;
367 pPsPollContext->bAggregatible = FALSE;
368 pPsPollContext->LastOne = TRUE;
369
370 } while (FALSE);
371
372
373done:
374 DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitTransmit(Status=%d)\n", Status));
375
376 return Status;
377
378 /* --------------------------- ERROR HANDLE --------------------------- */
379out6:
380 LM_URB_FREE(pObj, pPsPollContext, sizeof(TX_BUFFER));
381
382out5:
383 LM_URB_FREE(pObj, pRTSContext, sizeof(TX_BUFFER));
384
385out4:
386 LM_URB_FREE(pObj, pNullContext, sizeof(TX_BUFFER));
387
388out3:
389 for(i=0; i<BEACON_RING_SIZE; i++)
390 {
391 PTX_CONTEXT pBeaconContext = &(pAd->BeaconContext[i]);
392 if (pBeaconContext)
393 LM_URB_FREE(pObj, pBeaconContext, sizeof(TX_BUFFER));
394 }
395
396out2:
397 if (pAd->MgmtDescRing.AllocVa)
398 {
399 pMgmtRing = &pAd->MgmtRing;
400 for(i=0; i<MGMT_RING_SIZE; i++)
401 {
402 pMLMEContext = (PTX_CONTEXT) pAd->MgmtRing.Cell[i].AllocVa;
403 if (pMLMEContext)
404 LM_URB_FREE(pObj, pMLMEContext, sizeof(TX_BUFFER));
405 }
406 os_free_mem(pAd, pAd->MgmtDescRing.AllocVa);
407 pAd->MgmtDescRing.AllocVa = NULL;
408 }
409
410out1:
411 for (acidx = 0; acidx < 4; acidx++)
412 {
413 PHT_TX_CONTEXT pTxContext = &(pAd->TxContext[acidx]);
414 if (pTxContext)
415 LM_URB_FREE(pObj, pTxContext, sizeof(HTTX_BUFFER));
416 }
417
418 // Here we didn't have any pre-allocated memory need to free.
419
420 return Status;
421}
422
423
424/*
425========================================================================
426Routine Description:
427 Allocate DMA memory blocks for send, receive.
428
429Arguments:
430 pAd Pointer to our adapter
431
432Return Value:
433 NDIS_STATUS_SUCCESS
434 NDIS_STATUS_FAILURE
435 NDIS_STATUS_RESOURCES
436
437Note:
438========================================================================
439*/
440NDIS_STATUS RTMPAllocTxRxRingMemory(
441 IN PRTMP_ADAPTER pAd)
442{
443// COUNTER_802_11 pCounter = &pAd->WlanCounters;
444 NDIS_STATUS Status;
445 INT num;
446
447
448 DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocTxRxRingMemory\n"));
449
450
451 do
452 {
453 // Init the CmdQ and CmdQLock
454 NdisAllocateSpinLock(&pAd->CmdQLock);
455 NdisAcquireSpinLock(&pAd->CmdQLock);
456 RTUSBInitializeCmdQ(&pAd->CmdQ);
457 NdisReleaseSpinLock(&pAd->CmdQLock);
458
459
460 NdisAllocateSpinLock(&pAd->MLMEBulkOutLock);
461 //NdisAllocateSpinLock(&pAd->MLMEWaitQueueLock);
462 NdisAllocateSpinLock(&pAd->BulkOutLock[0]);
463 NdisAllocateSpinLock(&pAd->BulkOutLock[1]);
464 NdisAllocateSpinLock(&pAd->BulkOutLock[2]);
465 NdisAllocateSpinLock(&pAd->BulkOutLock[3]);
466 NdisAllocateSpinLock(&pAd->BulkOutLock[4]);
467 NdisAllocateSpinLock(&pAd->BulkOutLock[5]);
468 NdisAllocateSpinLock(&pAd->BulkInLock);
469
470 for (num = 0; num < NUM_OF_TX_RING; num++)
471 {
472 NdisAllocateSpinLock(&pAd->TxContextQueueLock[num]);
473 }
474
475
476// NdisAllocateSpinLock(&pAd->MemLock); // Not used in RT28XX
477
478// NdisAllocateSpinLock(&pAd->MacTabLock); // init it in UserCfgInit()
479// NdisAllocateSpinLock(&pAd->BATabLock); // init it in BATableInit()
480
481// for(num=0; num<MAX_LEN_OF_BA_REC_TABLE; num++)
482// {
483// NdisAllocateSpinLock(&pAd->BATable.BARecEntry[num].RxReRingLock);
484// }
485
486 //
487 // Init Mac Table
488 //
489// MacTableInitialize(pAd);
490
491 //
492 // Init send data structures and related parameters
493 //
494 Status = NICInitTransmit(pAd);
495 if (Status != NDIS_STATUS_SUCCESS)
496 break;
497
498 //
499 // Init receive data structures and related parameters
500 //
501 Status = NICInitRecv(pAd);
502 if (Status != NDIS_STATUS_SUCCESS)
503 break;
504
505 pAd->PendingIoCount = 1;
506
507 } while (FALSE);
508
509 NdisZeroMemory(&pAd->FragFrame, sizeof(FRAGMENT_FRAME));
510 pAd->FragFrame.pFragPacket = RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE);
511
512 if (pAd->FragFrame.pFragPacket == NULL)
513 {
514 Status = NDIS_STATUS_RESOURCES;
515 }
516
517 DBGPRINT_S(Status, ("<-- RTMPAllocTxRxRingMemory, Status=%x\n", Status));
518 return Status;
519}
520
521
522/*
523========================================================================
524Routine Description:
525 Calls USB_InterfaceStop and frees memory allocated for the URBs
526 calls NdisMDeregisterDevice and frees the memory
527 allocated in VNetInitialize for the Adapter Object
528
529Arguments:
530 *pAd the raxx interface data pointer
531
532Return Value:
533 None
534
535Note:
536========================================================================
537*/
538VOID RTMPFreeTxRxRingMemory(
539 IN PRTMP_ADAPTER pAd)
540{
541#define LM_URB_FREE(pObj, Context, BufferSize) \
542 if (NULL != Context->pUrb) { \
543 RTUSB_UNLINK_URB(Context->pUrb); \
544 RTUSB_FREE_URB(Context->pUrb); \
545 Context->pUrb = NULL; } \
546 if (NULL != Context->TransferBuffer) { \
547 RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, BufferSize, \
548 Context->TransferBuffer, \
549 Context->data_dma); \
550 Context->TransferBuffer = NULL; }
551
552
553 UINT i, acidx;
554 PTX_CONTEXT pNullContext = &pAd->NullContext;
555 PTX_CONTEXT pPsPollContext = &pAd->PsPollContext;
556 PTX_CONTEXT pRTSContext = &pAd->RTSContext;
557// PHT_TX_CONTEXT pHTTXContext;
558 //PRTMP_REORDERBUF pReorderBuf;
559 POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
560// RTMP_TX_RING *pTxRing;
561
562 DBGPRINT(RT_DEBUG_ERROR, ("---> RTMPFreeTxRxRingMemory\n"));
563 pObj = pObj;
564
565 // Free all resources for the RECEIVE buffer queue.
566 for(i=0; i<(RX_RING_SIZE); i++)
567 {
568 PRX_CONTEXT pRxContext = &(pAd->RxContext[i]);
569 if (pRxContext)
570 LM_URB_FREE(pObj, pRxContext, MAX_RXBULK_SIZE);
571 }
572
573 // Free PsPoll frame resource
574 LM_URB_FREE(pObj, pPsPollContext, sizeof(TX_BUFFER));
575
576 // Free NULL frame resource
577 LM_URB_FREE(pObj, pNullContext, sizeof(TX_BUFFER));
578
579 // Free RTS frame resource
580 LM_URB_FREE(pObj, pRTSContext, sizeof(TX_BUFFER));
581
582
583 // Free beacon frame resource
584 for(i=0; i<BEACON_RING_SIZE; i++)
585 {
586 PTX_CONTEXT pBeaconContext = &(pAd->BeaconContext[i]);
587 if (pBeaconContext)
588 LM_URB_FREE(pObj, pBeaconContext, sizeof(TX_BUFFER));
589 }
590
591
592 // Free mgmt frame resource
593 for(i = 0; i < MGMT_RING_SIZE; i++)
594 {
595 PTX_CONTEXT pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[i].AllocVa;
596 //LM_URB_FREE(pObj, pMLMEContext, sizeof(TX_BUFFER));
597 if (NULL != pAd->MgmtRing.Cell[i].pNdisPacket)
598 {
599 RTMPFreeNdisPacket(pAd, pAd->MgmtRing.Cell[i].pNdisPacket);
600 pAd->MgmtRing.Cell[i].pNdisPacket = NULL;
601 pMLMEContext->TransferBuffer = NULL;
602 }
603
604 if (pMLMEContext)
605 {
606 if (NULL != pMLMEContext->pUrb)
607 {
608 RTUSB_UNLINK_URB(pMLMEContext->pUrb);
609 RTUSB_FREE_URB(pMLMEContext->pUrb);
610 pMLMEContext->pUrb = NULL;
611 }
612 }
613 }
614 if (pAd->MgmtDescRing.AllocVa)
615 os_free_mem(pAd, pAd->MgmtDescRing.AllocVa);
616
617
618 // Free Tx frame resource
619 for (acidx = 0; acidx < 4; acidx++)
620 {
621 PHT_TX_CONTEXT pHTTXContext = &(pAd->TxContext[acidx]);
622 if (pHTTXContext)
623 LM_URB_FREE(pObj, pHTTXContext, sizeof(HTTX_BUFFER));
624 }
625
626 if (pAd->FragFrame.pFragPacket)
627 RELEASE_NDIS_PACKET(pAd, pAd->FragFrame.pFragPacket, NDIS_STATUS_SUCCESS);
628
629 for(i=0; i<6; i++)
630 {
631 NdisFreeSpinLock(&pAd->BulkOutLock[i]);
632 }
633
634 NdisFreeSpinLock(&pAd->BulkInLock);
635 NdisFreeSpinLock(&pAd->MLMEBulkOutLock);
636
637 NdisFreeSpinLock(&pAd->CmdQLock);
638 // Clear all pending bulk-out request flags.
639 RTUSB_CLEAR_BULK_FLAG(pAd, 0xffffffff);
640
641// NdisFreeSpinLock(&pAd->MacTabLock);
642
643// for(i=0; i<MAX_LEN_OF_BA_REC_TABLE; i++)
644// {
645// NdisFreeSpinLock(&pAd->BATable.BARecEntry[i].RxReRingLock);
646// }
647
648 DBGPRINT(RT_DEBUG_ERROR, ("<--- RTMPFreeTxRxRingMemory\n"));
649}
650
651
652/*
653========================================================================
654Routine Description:
655 Write WLAN MAC address to USB 2870.
656
657Arguments:
658 pAd Pointer to our adapter
659
660Return Value:
661 NDIS_STATUS_SUCCESS
662
663Note:
664========================================================================
665*/
666NDIS_STATUS RTUSBWriteHWMACAddress(
667 IN PRTMP_ADAPTER pAd)
668{
669 MAC_DW0_STRUC StaMacReg0;
670 MAC_DW1_STRUC StaMacReg1;
671 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
672 LARGE_INTEGER NOW;
673
674
675 // initialize the random number generator
676 RTMP_GetCurrentSystemTime(&NOW);
677
678 if (pAd->bLocalAdminMAC != TRUE)
679 {
680 pAd->CurrentAddress[0] = pAd->PermanentAddress[0];
681 pAd->CurrentAddress[1] = pAd->PermanentAddress[1];
682 pAd->CurrentAddress[2] = pAd->PermanentAddress[2];
683 pAd->CurrentAddress[3] = pAd->PermanentAddress[3];
684 pAd->CurrentAddress[4] = pAd->PermanentAddress[4];
685 pAd->CurrentAddress[5] = pAd->PermanentAddress[5];
686 }
687 // Write New MAC address to MAC_CSR2 & MAC_CSR3 & let ASIC know our new MAC
688 StaMacReg0.field.Byte0 = pAd->CurrentAddress[0];
689 StaMacReg0.field.Byte1 = pAd->CurrentAddress[1];
690 StaMacReg0.field.Byte2 = pAd->CurrentAddress[2];
691 StaMacReg0.field.Byte3 = pAd->CurrentAddress[3];
692 StaMacReg1.field.Byte4 = pAd->CurrentAddress[4];
693 StaMacReg1.field.Byte5 = pAd->CurrentAddress[5];
694 StaMacReg1.field.U2MeMask = 0xff;
695 DBGPRINT_RAW(RT_DEBUG_TRACE, ("Local MAC = %02x:%02x:%02x:%02x:%02x:%02x\n",
696 pAd->CurrentAddress[0], pAd->CurrentAddress[1], pAd->CurrentAddress[2],
697 pAd->CurrentAddress[3], pAd->CurrentAddress[4], pAd->CurrentAddress[5]));
698
699 RTUSBWriteMACRegister(pAd, MAC_ADDR_DW0, StaMacReg0.word);
700 RTUSBWriteMACRegister(pAd, MAC_ADDR_DW1, StaMacReg1.word);
701 return Status;
702}
703
704
705/*
706========================================================================
707Routine Description:
708 Disable DMA.
709
710Arguments:
711 *pAd the raxx interface data pointer
712
713Return Value:
714 None
715
716Note:
717========================================================================
718*/
719VOID RT28XXDMADisable(
720 IN RTMP_ADAPTER *pAd)
721{
722 // no use
723}
724
725
726/*
727========================================================================
728Routine Description:
729 Enable DMA.
730
731Arguments:
732 *pAd the raxx interface data pointer
733
734Return Value:
735 None
736
737Note:
738========================================================================
739*/
740VOID RT28XXDMAEnable(
741 IN RTMP_ADAPTER *pAd)
742{
743 WPDMA_GLO_CFG_STRUC GloCfg;
744 USB_DMA_CFG_STRUC UsbCfg;
745 int i = 0;
746
747
748 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x4);
749 do
750 {
751 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
752 if ((GloCfg.field.TxDMABusy == 0) && (GloCfg.field.RxDMABusy == 0))
753 break;
754
755 DBGPRINT(RT_DEBUG_TRACE, ("==> DMABusy\n"));
756 RTMPusecDelay(1000);
757 i++;
758 }while ( i <200);
759
760
761 RTMPusecDelay(50);
762 GloCfg.field.EnTXWriteBackDDONE = 1;
763 GloCfg.field.EnableRxDMA = 1;
764 GloCfg.field.EnableTxDMA = 1;
765 DBGPRINT(RT_DEBUG_TRACE, ("<== WRITE DMA offset 0x208 = 0x%x\n", GloCfg.word));
766 RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
767
768 UsbCfg.word = 0;
769 UsbCfg.field.phyclear = 0;
770 /* usb version is 1.1,do not use bulk in aggregation */
771 if (pAd->BulkInMaxPacketSize == 512)
772 UsbCfg.field.RxBulkAggEn = 1;
773 /* for last packet, PBF might use more than limited, so minus 2 to prevent from error */
774 UsbCfg.field.RxBulkAggLmt = (MAX_RXBULK_SIZE /1024)-3;
775 UsbCfg.field.RxBulkAggTOut = 0x80; /* 2006-10-18 */
776 UsbCfg.field.RxBulkEn = 1;
777 UsbCfg.field.TxBulkEn = 1;
778
779 RTUSBWriteMACRegister(pAd, USB_DMA_CFG, UsbCfg.word);
780
781}
782
783/********************************************************************
784 *
785 * 2870 Beacon Update Related functions.
786 *
787 ********************************************************************/
788
789/*
790========================================================================
791Routine Description:
792 Write Beacon buffer to Asic.
793
794Arguments:
795 *pAd the raxx interface data pointer
796
797Return Value:
798 None
799
800Note:
801========================================================================
802*/
803VOID RT28xx_UpdateBeaconToAsic(
804 IN RTMP_ADAPTER *pAd,
805 IN INT apidx,
806 IN ULONG FrameLen,
807 IN ULONG UpdatePos)
808{
809 PUCHAR pBeaconFrame = NULL;
810 UCHAR *ptr;
811 UINT i, padding;
812 BEACON_SYNC_STRUCT *pBeaconSync = pAd->CommonCfg.pBeaconSync;
813 UINT32 longValue;
814// USHORT shortValue;
815 BOOLEAN bBcnReq = FALSE;
816 UCHAR bcn_idx = 0;
817
818
819 if (pBeaconFrame == NULL)
820 {
821 DBGPRINT(RT_DEBUG_ERROR,("pBeaconFrame is NULL!\n"));
822 return;
823 }
824
825 if (pBeaconSync == NULL)
826 {
827 DBGPRINT(RT_DEBUG_ERROR,("pBeaconSync is NULL!\n"));
828 return;
829 }
830
831 //if ((pAd->WdsTab.Mode == WDS_BRIDGE_MODE) ||
832 // ((pAd->ApCfg.MBSSID[apidx].MSSIDDev == NULL) || !(pAd->ApCfg.MBSSID[apidx].MSSIDDev->flags & IFF_UP))
833 // )
834 if (bBcnReq == FALSE)
835 {
836 /* when the ra interface is down, do not send its beacon frame */
837 /* clear all zero */
838 for(i=0; i<TXWI_SIZE; i+=4) {
839 RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i, 0x00);
840 }
841 pBeaconSync->BeaconBitMap &= (~(BEACON_BITMAP_MASK & (1 << bcn_idx)));
842 NdisZeroMemory(pBeaconSync->BeaconTxWI[bcn_idx], TXWI_SIZE);
843 }
844 else
845 {
846 ptr = (PUCHAR)&pAd->BeaconTxWI;
847 if (NdisEqualMemory(pBeaconSync->BeaconTxWI[bcn_idx], &pAd->BeaconTxWI, TXWI_SIZE) == FALSE)
848 { // If BeaconTxWI changed, we need to rewrite the TxWI for the Beacon frames.
849 pBeaconSync->BeaconBitMap &= (~(BEACON_BITMAP_MASK & (1 << bcn_idx)));
850 NdisMoveMemory(pBeaconSync->BeaconTxWI[bcn_idx], &pAd->BeaconTxWI, TXWI_SIZE);
851 }
852
853 if ((pBeaconSync->BeaconBitMap & (1 << bcn_idx)) != (1 << bcn_idx))
854 {
855 for (i=0; i<TXWI_SIZE; i+=4) // 16-byte TXWI field
856 {
857 longValue = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
858 RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i, longValue);
859 ptr += 4;
860 }
861 }
862
863 ptr = pBeaconSync->BeaconBuf[bcn_idx];
864 padding = (FrameLen & 0x01);
865 NdisZeroMemory((PUCHAR)(pBeaconFrame + FrameLen), padding);
866 FrameLen += padding;
867 for (i = 0 ; i < FrameLen /*HW_BEACON_OFFSET*/; i += 2)
868 {
869 if (NdisEqualMemory(ptr, pBeaconFrame, 2) == FALSE)
870 {
871 NdisMoveMemory(ptr, pBeaconFrame, 2);
872 //shortValue = *ptr + (*(ptr+1)<<8);
873 //RTMP_IO_WRITE8(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, shortValue);
874 RTUSBMultiWrite(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, ptr, 2);
875 }
876 ptr +=2;
877 pBeaconFrame += 2;
878 }
879
880 pBeaconSync->BeaconBitMap |= (1 << bcn_idx);
881
882 // For AP interface, set the DtimBitOn so that we can send Bcast/Mcast frame out after this beacon frame.
883}
884
885}
886
887
888VOID RTUSBBssBeaconStop(
889 IN RTMP_ADAPTER *pAd)
890{
891 BEACON_SYNC_STRUCT *pBeaconSync;
892 int i, offset;
893 BOOLEAN Cancelled = TRUE;
894
895 pBeaconSync = pAd->CommonCfg.pBeaconSync;
896 if (pBeaconSync && pBeaconSync->EnableBeacon)
897 {
898 INT NumOfBcn;
899
900 {
901 NumOfBcn = MAX_MESH_NUM;
902 }
903
904 RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled);
905
906 for(i=0; i<NumOfBcn; i++)
907 {
908 NdisZeroMemory(pBeaconSync->BeaconBuf[i], HW_BEACON_OFFSET);
909 NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
910
911 for (offset=0; offset<HW_BEACON_OFFSET; offset+=4)
912 RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[i] + offset, 0x00);
913
914 pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
915 pBeaconSync->TimIELocationInBeacon[i] = 0;
916 }
917 pBeaconSync->BeaconBitMap = 0;
918 pBeaconSync->DtimBitOn = 0;
919 }
920}
921
922
923VOID RTUSBBssBeaconStart(
924 IN RTMP_ADAPTER *pAd)
925{
926 int apidx;
927 BEACON_SYNC_STRUCT *pBeaconSync;
928// LARGE_INTEGER tsfTime, deltaTime;
929
930 pBeaconSync = pAd->CommonCfg.pBeaconSync;
931 if (pBeaconSync && pBeaconSync->EnableBeacon)
932 {
933 INT NumOfBcn;
934
935 {
936 NumOfBcn = MAX_MESH_NUM;
937 }
938
939 for(apidx=0; apidx<NumOfBcn; apidx++)
940 {
941 UCHAR CapabilityInfoLocationInBeacon = 0;
942 UCHAR TimIELocationInBeacon = 0;
943
944
945 NdisZeroMemory(pBeaconSync->BeaconBuf[apidx], HW_BEACON_OFFSET);
946 pBeaconSync->CapabilityInfoLocationInBeacon[apidx] = CapabilityInfoLocationInBeacon;
947 pBeaconSync->TimIELocationInBeacon[apidx] = TimIELocationInBeacon;
948 NdisZeroMemory(pBeaconSync->BeaconTxWI[apidx], TXWI_SIZE);
949 }
950 pBeaconSync->BeaconBitMap = 0;
951 pBeaconSync->DtimBitOn = 0;
952 pAd->CommonCfg.BeaconUpdateTimer.Repeat = TRUE;
953
954 pAd->CommonCfg.BeaconAdjust = 0;
955 pAd->CommonCfg.BeaconFactor = 0xffffffff / (pAd->CommonCfg.BeaconPeriod << 10);
956 pAd->CommonCfg.BeaconRemain = (0xffffffff % (pAd->CommonCfg.BeaconPeriod << 10)) + 1;
957 DBGPRINT(RT_DEBUG_TRACE, ("RTUSBBssBeaconStart:BeaconFactor=%d, BeaconRemain=%d!\n",
958 pAd->CommonCfg.BeaconFactor, pAd->CommonCfg.BeaconRemain));
959 RTMPSetTimer(&pAd->CommonCfg.BeaconUpdateTimer, 10 /*pAd->CommonCfg.BeaconPeriod*/);
960
961 }
962}
963
964
965VOID RTUSBBssBeaconInit(
966 IN RTMP_ADAPTER *pAd)
967{
968 BEACON_SYNC_STRUCT *pBeaconSync;
969 int i;
970
971 os_alloc_mem(pAd, (PUCHAR *)(&pAd->CommonCfg.pBeaconSync), sizeof(BEACON_SYNC_STRUCT));
972 //NdisAllocMemory(pAd->CommonCfg.pBeaconSync, sizeof(BEACON_SYNC_STRUCT), MEM_ALLOC_FLAG);
973 if (pAd->CommonCfg.pBeaconSync)
974 {
975 pBeaconSync = pAd->CommonCfg.pBeaconSync;
976 NdisZeroMemory(pBeaconSync, sizeof(BEACON_SYNC_STRUCT));
977 for(i=0; i < HW_BEACON_MAX_COUNT; i++)
978 {
979 NdisZeroMemory(pBeaconSync->BeaconBuf[i], HW_BEACON_OFFSET);
980 pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
981 pBeaconSync->TimIELocationInBeacon[i] = 0;
982 NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
983 }
984 pBeaconSync->BeaconBitMap = 0;
985
986 //RTMPInitTimer(pAd, &pAd->CommonCfg.BeaconUpdateTimer, GET_TIMER_FUNCTION(BeaconUpdateExec), pAd, TRUE);
987 pBeaconSync->EnableBeacon = TRUE;
988 }
989}
990
991
992VOID RTUSBBssBeaconExit(
993 IN RTMP_ADAPTER *pAd)
994{
995 BEACON_SYNC_STRUCT *pBeaconSync;
996 BOOLEAN Cancelled = TRUE;
997 int i;
998
999 if (pAd->CommonCfg.pBeaconSync)
1000 {
1001 pBeaconSync = pAd->CommonCfg.pBeaconSync;
1002 pBeaconSync->EnableBeacon = FALSE;
1003 RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled);
1004 pBeaconSync->BeaconBitMap = 0;
1005
1006 for(i=0; i<HW_BEACON_MAX_COUNT; i++)
1007 {
1008 NdisZeroMemory(pBeaconSync->BeaconBuf[i], HW_BEACON_OFFSET);
1009 pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
1010 pBeaconSync->TimIELocationInBeacon[i] = 0;
1011 NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
1012 }
1013
1014 os_free_mem(pAd, pAd->CommonCfg.pBeaconSync);
1015 pAd->CommonCfg.pBeaconSync = NULL;
1016 }
1017}
1018
1019
1020/*
1021 ========================================================================
1022 Routine Description:
1023 For device work as AP mode but didn't have TBTT interrupt event, we need a mechanism
1024 to update the beacon context in each Beacon interval. Here we use a periodical timer
1025 to simulate the TBTT interrupt to handle the beacon context update.
1026
1027 Arguments:
1028 SystemSpecific1 - Not used.
1029 FunctionContext - Pointer to our Adapter context.
1030 SystemSpecific2 - Not used.
1031 SystemSpecific3 - Not used.
1032
1033 Return Value:
1034 None
1035
1036 ========================================================================
1037*/
1038VOID BeaconUpdateExec(
1039 IN PVOID SystemSpecific1,
1040 IN PVOID FunctionContext,
1041 IN PVOID SystemSpecific2,
1042 IN PVOID SystemSpecific3)
1043{
1044 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)FunctionContext;
1045 LARGE_INTEGER tsfTime_a;//, tsfTime_b, deltaTime_exp, deltaTime_ab;
1046 UINT32 delta, delta2MS, period2US, remain, remain_low, remain_high;
1047// BOOLEAN positive;
1048
1049 if (pAd->CommonCfg.IsUpdateBeacon==TRUE)
1050 {
1051 ReSyncBeaconTime(pAd);
1052
1053
1054 }
1055
1056 RTMP_IO_READ32(pAd, TSF_TIMER_DW0, &tsfTime_a.u.LowPart);
1057 RTMP_IO_READ32(pAd, TSF_TIMER_DW1, &tsfTime_a.u.HighPart);
1058
1059
1060 //positive=getDeltaTime(tsfTime_a, expectedTime, &deltaTime_exp);
1061 period2US = (pAd->CommonCfg.BeaconPeriod << 10);
1062 remain_high = pAd->CommonCfg.BeaconRemain * tsfTime_a.u.HighPart;
1063 remain_low = tsfTime_a.u.LowPart % (pAd->CommonCfg.BeaconPeriod << 10);
1064 remain = (remain_high + remain_low)%(pAd->CommonCfg.BeaconPeriod << 10);
1065 delta = (pAd->CommonCfg.BeaconPeriod << 10) - remain;
1066
1067 delta2MS = (delta>>10);
1068 if (delta2MS > 150)
1069 {
1070 pAd->CommonCfg.BeaconUpdateTimer.TimerValue = 100;
1071 pAd->CommonCfg.IsUpdateBeacon=FALSE;
1072 }
1073 else
1074 {
1075 pAd->CommonCfg.BeaconUpdateTimer.TimerValue = delta2MS + 10;
1076 pAd->CommonCfg.IsUpdateBeacon=TRUE;
1077 }
1078
1079}
1080
1081
1082/********************************************************************
1083 *
1084 * 2870 Radio on/off Related functions.
1085 *
1086 ********************************************************************/
1087VOID RT28xxUsbMlmeRadioOn(
1088 IN PRTMP_ADAPTER pAd)
1089{
1090 RTMP_CHIP_OP *pChipOps = &pAd->chipOps;
1091
1092 DBGPRINT(RT_DEBUG_TRACE,("RT28xxUsbMlmeRadioOn()\n"));
1093
1094 if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
1095 return;
1096
1097 {
1098 AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02);
1099 RTMPusecDelay(10000);
1100 }
1101 //NICResetFromError(pAd);
1102
1103 // Enable Tx/Rx
1104 RTMPEnableRxTx(pAd);
1105
1106 if (pChipOps->AsicReverseRfFromSleepMode)
1107 pChipOps->AsicReverseRfFromSleepMode(pAd);
1108
1109 // Clear Radio off flag
1110 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
1111
1112 RTUSBBulkReceive(pAd);
1113
1114 // Set LED
1115 RTMPSetLED(pAd, LED_RADIO_ON);
1116}
1117
1118
1119VOID RT28xxUsbMlmeRadioOFF(
1120 IN PRTMP_ADAPTER pAd)
1121{
1122 WPDMA_GLO_CFG_STRUC GloCfg;
1123 UINT32 Value, i;
1124
1125 DBGPRINT(RT_DEBUG_TRACE,("RT28xxUsbMlmeRadioOFF()\n"));
1126
1127 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
1128 return;
1129
1130 // Clear PMKID cache.
1131 pAd->StaCfg.SavedPMKNum = 0;
1132 RTMPZeroMemory(pAd->StaCfg.SavedPMK, (PMKID_NO * sizeof(BSSID_INFO)));
1133
1134 // Link down first if any association exists
1135 if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
1136 {
1137 if (INFRA_ON(pAd) || ADHOC_ON(pAd))
1138 {
1139 MLME_DISASSOC_REQ_STRUCT DisReq;
1140 MLME_QUEUE_ELEM *pMsgElem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
1141
1142 if (pMsgElem)
1143 {
1144 COPY_MAC_ADDR(&DisReq.Addr, pAd->CommonCfg.Bssid);
1145 DisReq.Reason = REASON_DISASSOC_STA_LEAVING;
1146
1147 pMsgElem->Machine = ASSOC_STATE_MACHINE;
1148 pMsgElem->MsgType = MT2_MLME_DISASSOC_REQ;
1149 pMsgElem->MsgLen = sizeof(MLME_DISASSOC_REQ_STRUCT);
1150 NdisMoveMemory(pMsgElem->Msg, &DisReq, sizeof(MLME_DISASSOC_REQ_STRUCT));
1151
1152 MlmeDisassocReqAction(pAd, pMsgElem);
1153 kfree(pMsgElem);
1154
1155 RTMPusecDelay(1000);
1156 }
1157 }
1158 }
1159
1160 // Set Radio off flag
1161 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
1162
1163 {
1164 // Link down first if any association exists
1165 if (INFRA_ON(pAd) || ADHOC_ON(pAd))
1166 LinkDown(pAd, FALSE);
1167 RTMPusecDelay(10000);
1168
1169 //==========================================
1170 // Clean up old bss table
1171 BssTableInit(&pAd->ScanTab);
1172 }
1173
1174 // Set LED
1175 RTMPSetLED(pAd, LED_RADIO_OFF);
1176
1177
1178 if (pAd->CommonCfg.BBPCurrentBW == BW_40)
1179 {
1180 // Must using 40MHz.
1181 AsicTurnOffRFClk(pAd, pAd->CommonCfg.CentralChannel);
1182 }
1183 else
1184 {
1185 // Must using 20MHz.
1186 AsicTurnOffRFClk(pAd, pAd->CommonCfg.Channel);
1187 }
1188
1189 // Disable Tx/Rx DMA
1190 RTUSBReadMACRegister(pAd, WPDMA_GLO_CFG, &GloCfg.word); // disable DMA
1191 GloCfg.field.EnableTxDMA = 0;
1192 GloCfg.field.EnableRxDMA = 0;
1193 RTUSBWriteMACRegister(pAd, WPDMA_GLO_CFG, GloCfg.word); // abort all TX rings
1194
1195 // Waiting for DMA idle
1196 i = 0;
1197 do
1198 {
1199 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
1200 if ((GloCfg.field.TxDMABusy == 0) && (GloCfg.field.RxDMABusy == 0))
1201 break;
1202
1203 RTMPusecDelay(1000);
1204 }while (i++ < 100);
1205
1206 // Disable MAC Tx/Rx
1207 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
1208 Value &= (0xfffffff3);
1209 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
1210
1211 {
1212 AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02);
1213 }
1214}
1215
1216#endif // RTMP_MAC_USB //
diff --git a/drivers/staging/rt2860/common/cmm_profile.c b/drivers/staging/rt2860/common/cmm_profile.c
new file mode 100644
index 00000000000..2d28524c139
--- /dev/null
+++ b/drivers/staging/rt2860/common/cmm_profile.c
@@ -0,0 +1,1736 @@
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
30
31#define ETH_MAC_ADDR_STR_LEN 17 // in format of xx:xx:xx:xx:xx:xx
32
33// We assume the s1 is a sting, s2 is a memory space with 6 bytes. and content of s1 will be changed.
34BOOLEAN rtstrmactohex(PSTRING s1, PSTRING s2)
35{
36 int i = 0;
37 PSTRING ptokS = s1, ptokE = s1;
38
39 if (strlen(s1) != ETH_MAC_ADDR_STR_LEN)
40 return FALSE;
41
42 while((*ptokS) != '\0')
43 {
44 if((ptokE = strchr(ptokS, ':')) != NULL)
45 *ptokE++ = '\0';
46 if ((strlen(ptokS) != 2) || (!isxdigit(*ptokS)) || (!isxdigit(*(ptokS+1))))
47 break; // fail
48 AtoH(ptokS, (PUCHAR)&s2[i++], 1);
49 ptokS = ptokE;
50 if (i == 6)
51 break; // parsing finished
52 }
53
54 return ( i == 6 ? TRUE : FALSE);
55
56}
57
58
59// we assume the s1 and s2 both are strings.
60BOOLEAN rtstrcasecmp(PSTRING s1, PSTRING s2)
61{
62 PSTRING p1 = s1, p2 = s2;
63
64 if (strlen(s1) != strlen(s2))
65 return FALSE;
66
67 while(*p1 != '\0')
68 {
69 if((*p1 != *p2) && ((*p1 ^ *p2) != 0x20))
70 return FALSE;
71 p1++;
72 p2++;
73 }
74
75 return TRUE;
76}
77
78// we assume the s1 (buffer) and s2 (key) both are strings.
79PSTRING rtstrstruncasecmp(PSTRING s1, PSTRING s2)
80{
81 INT l1, l2, i;
82 char temp1, temp2;
83
84 l2 = strlen(s2);
85 if (!l2)
86 return (char *) s1;
87
88 l1 = strlen(s1);
89
90 while (l1 >= l2)
91 {
92 l1--;
93
94 for(i=0; i<l2; i++)
95 {
96 temp1 = *(s1+i);
97 temp2 = *(s2+i);
98
99 if (('a' <= temp1) && (temp1 <= 'z'))
100 temp1 = 'A'+(temp1-'a');
101 if (('a' <= temp2) && (temp2 <= 'z'))
102 temp2 = 'A'+(temp2-'a');
103
104 if (temp1 != temp2)
105 break;
106 }
107
108 if (i == l2)
109 return (char *) s1;
110
111 s1++;
112 }
113
114 return NULL; // not found
115}
116
117//add by kathy
118
119 /**
120 * strstr - Find the first substring in a %NUL terminated string
121 * @s1: The string to be searched
122 * @s2: The string to search for
123 */
124PSTRING rtstrstr(PSTRING s1,const PSTRING s2)
125{
126 INT l1, l2;
127
128 l2 = strlen(s2);
129 if (!l2)
130 return s1;
131
132 l1 = strlen(s1);
133
134 while (l1 >= l2)
135 {
136 l1--;
137 if (!memcmp(s1,s2,l2))
138 return s1;
139 s1++;
140 }
141
142 return NULL;
143}
144
145/**
146 * rstrtok - Split a string into tokens
147 * @s: The string to be searched
148 * @ct: The characters to search for
149 * * WARNING: strtok is deprecated, use strsep instead. However strsep is not compatible with old architecture.
150 */
151PSTRING __rstrtok;
152PSTRING rstrtok(PSTRING s,const PSTRING ct)
153{
154 PSTRING sbegin, send;
155
156 sbegin = s ? s : __rstrtok;
157 if (!sbegin)
158 {
159 return NULL;
160 }
161
162 sbegin += strspn(sbegin,ct);
163 if (*sbegin == '\0')
164 {
165 __rstrtok = NULL;
166 return( NULL );
167 }
168
169 send = strpbrk( sbegin, ct);
170 if (send && *send != '\0')
171 *send++ = '\0';
172
173 __rstrtok = send;
174
175 return (sbegin);
176}
177
178/**
179 * delimitcnt - return the count of a given delimiter in a given string.
180 * @s: The string to be searched.
181 * @ct: The delimiter to search for.
182 * Notice : We suppose the delimiter is a single-char string(for example : ";").
183 */
184INT delimitcnt(PSTRING s,PSTRING ct)
185{
186 INT count = 0;
187 /* point to the beginning of the line */
188 PSTRING token = s;
189
190 for ( ;; )
191 {
192 token = strpbrk(token, ct); /* search for delimiters */
193
194 if ( token == NULL )
195 {
196 /* advanced to the terminating null character */
197 break;
198 }
199 /* skip the delimiter */
200 ++token;
201
202 /*
203 * Print the found text: use len with %.*s to specify field width.
204 */
205
206 /* accumulate delimiter count */
207 ++count;
208 }
209 return count;
210}
211
212/*
213 * converts the Internet host address from the standard numbers-and-dots notation
214 * into binary data.
215 * returns nonzero if the address is valid, zero if not.
216 */
217int rtinet_aton(PSTRING cp, unsigned int *addr)
218{
219 unsigned int val;
220 int base, n;
221 STRING c;
222 unsigned int parts[4];
223 unsigned int *pp = parts;
224
225 for (;;)
226 {
227 /*
228 * Collect number up to ``.''.
229 * Values are specified as for C:
230 * 0x=hex, 0=octal, other=decimal.
231 */
232 val = 0;
233 base = 10;
234 if (*cp == '0')
235 {
236 if (*++cp == 'x' || *cp == 'X')
237 base = 16, cp++;
238 else
239 base = 8;
240 }
241 while ((c = *cp) != '\0')
242 {
243 if (isdigit((unsigned char) c))
244 {
245 val = (val * base) + (c - '0');
246 cp++;
247 continue;
248 }
249 if (base == 16 && isxdigit((unsigned char) c))
250 {
251 val = (val << 4) +
252 (c + 10 - (islower((unsigned char) c) ? 'a' : 'A'));
253 cp++;
254 continue;
255 }
256 break;
257 }
258 if (*cp == '.')
259 {
260 /*
261 * Internet format: a.b.c.d a.b.c (with c treated as 16-bits)
262 * a.b (with b treated as 24 bits)
263 */
264 if (pp >= parts + 3 || val > 0xff)
265 return 0;
266 *pp++ = val, cp++;
267 }
268 else
269 break;
270 }
271
272 /*
273 * Check for trailing junk.
274 */
275 while (*cp)
276 if (!isspace((unsigned char) *cp++))
277 return 0;
278
279 /*
280 * Concoct the address according to the number of parts specified.
281 */
282 n = pp - parts + 1;
283 switch (n)
284 {
285
286 case 1: /* a -- 32 bits */
287 break;
288
289 case 2: /* a.b -- 8.24 bits */
290 if (val > 0xffffff)
291 return 0;
292 val |= parts[0] << 24;
293 break;
294
295 case 3: /* a.b.c -- 8.8.16 bits */
296 if (val > 0xffff)
297 return 0;
298 val |= (parts[0] << 24) | (parts[1] << 16);
299 break;
300
301 case 4: /* a.b.c.d -- 8.8.8.8 bits */
302 if (val > 0xff)
303 return 0;
304 val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
305 break;
306 }
307
308 *addr = htonl(val);
309 return 1;
310
311}
312
313/*
314 ========================================================================
315
316 Routine Description:
317 Find key section for Get key parameter.
318
319 Arguments:
320 buffer Pointer to the buffer to start find the key section
321 section the key of the secion to be find
322
323 Return Value:
324 NULL Fail
325 Others Success
326 ========================================================================
327*/
328PSTRING RTMPFindSection(
329 IN PSTRING buffer)
330{
331 STRING temp_buf[32];
332 PSTRING ptr;
333
334 strcpy(temp_buf, "Default");
335
336 if((ptr = rtstrstr(buffer, temp_buf)) != NULL)
337 return (ptr+strlen("\n"));
338 else
339 return NULL;
340}
341
342/*
343 ========================================================================
344
345 Routine Description:
346 Get key parameter.
347
348 Arguments:
349 key Pointer to key string
350 dest Pointer to destination
351 destsize The datasize of the destination
352 buffer Pointer to the buffer to start find the key
353 bTrimSpace Set true if you want to strip the space character of the result pattern
354
355 Return Value:
356 TRUE Success
357 FALSE Fail
358
359 Note:
360 This routine get the value with the matched key (case case-sensitive)
361 For SSID and security key related parameters, we SHALL NOT trim the space(' ') character.
362 ========================================================================
363*/
364INT RTMPGetKeyParameter(
365 IN PSTRING key,
366 OUT PSTRING dest,
367 IN INT destsize,
368 IN PSTRING buffer,
369 IN BOOLEAN bTrimSpace)
370{
371 PSTRING pMemBuf, temp_buf1 = NULL, temp_buf2 = NULL;
372 PSTRING start_ptr, end_ptr;
373 PSTRING ptr;
374 PSTRING offset = NULL;
375 INT len, keyLen;
376
377
378 keyLen = strlen(key);
379 os_alloc_mem(NULL, (PUCHAR *)&pMemBuf, MAX_PARAM_BUFFER_SIZE * 2);
380 if (pMemBuf == NULL)
381 return (FALSE);
382
383 memset(pMemBuf, 0, MAX_PARAM_BUFFER_SIZE * 2);
384 temp_buf1 = pMemBuf;
385 temp_buf2 = (PSTRING)(pMemBuf + MAX_PARAM_BUFFER_SIZE);
386
387
388 //find section
389 if((offset = RTMPFindSection(buffer)) == NULL)
390 {
391 os_free_mem(NULL, (PUCHAR)pMemBuf);
392 return (FALSE);
393 }
394
395 strcpy(temp_buf1, "\n");
396 strcat(temp_buf1, key);
397 strcat(temp_buf1, "=");
398
399 //search key
400 if((start_ptr=rtstrstr(offset, temp_buf1)) == NULL)
401 {
402 os_free_mem(NULL, (PUCHAR)pMemBuf);
403 return (FALSE);
404 }
405
406 start_ptr += strlen("\n");
407 if((end_ptr = rtstrstr(start_ptr, "\n"))==NULL)
408 end_ptr = start_ptr+strlen(start_ptr);
409
410 if (end_ptr<start_ptr)
411 {
412 os_free_mem(NULL, (PUCHAR)pMemBuf);
413 return (FALSE);
414 }
415
416 NdisMoveMemory(temp_buf2, start_ptr, end_ptr-start_ptr);
417 temp_buf2[end_ptr-start_ptr]='\0';
418 if((start_ptr=rtstrstr(temp_buf2, "=")) == NULL)
419 {
420 os_free_mem(NULL, (PUCHAR)pMemBuf);
421 return (FALSE);
422 }
423 ptr = (start_ptr +1);
424 //trim special characters, i.e., TAB or space
425 while(*start_ptr != 0x00)
426 {
427 if( ((*ptr == ' ') && bTrimSpace) || (*ptr == '\t') )
428 ptr++;
429 else
430 break;
431 }
432 len = strlen(start_ptr);
433
434 memset(dest, 0x00, destsize);
435 strncpy(dest, ptr, ((len >= destsize) ? destsize: len));
436
437 os_free_mem(NULL, (PUCHAR)pMemBuf);
438
439 return TRUE;
440}
441
442
443/*
444 ========================================================================
445
446 Routine Description:
447 Get multiple key parameter.
448
449 Arguments:
450 key Pointer to key string
451 dest Pointer to destination
452 destsize The datasize of the destination
453 buffer Pointer to the buffer to start find the key
454
455 Return Value:
456 TRUE Success
457 FALSE Fail
458
459 Note:
460 This routine get the value with the matched key (case case-sensitive)
461 ========================================================================
462*/
463INT RTMPGetKeyParameterWithOffset(
464 IN PSTRING key,
465 OUT PSTRING dest,
466 OUT USHORT *end_offset,
467 IN INT destsize,
468 IN PSTRING buffer,
469 IN BOOLEAN bTrimSpace)
470{
471 PSTRING temp_buf1 = NULL;
472 PSTRING temp_buf2 = NULL;
473 PSTRING start_ptr;
474 PSTRING end_ptr;
475 PSTRING ptr;
476 PSTRING offset = 0;
477 INT len;
478
479 if (*end_offset >= MAX_INI_BUFFER_SIZE)
480 return (FALSE);
481
482 os_alloc_mem(NULL, (PUCHAR *)&temp_buf1, MAX_PARAM_BUFFER_SIZE);
483
484 if(temp_buf1 == NULL)
485 return (FALSE);
486
487 os_alloc_mem(NULL, (PUCHAR *)&temp_buf2, MAX_PARAM_BUFFER_SIZE);
488 if(temp_buf2 == NULL)
489 {
490 os_free_mem(NULL, (PUCHAR)temp_buf1);
491 return (FALSE);
492 }
493
494 //find section
495 if(*end_offset == 0)
496 {
497 if ((offset = RTMPFindSection(buffer)) == NULL)
498 {
499 os_free_mem(NULL, (PUCHAR)temp_buf1);
500 os_free_mem(NULL, (PUCHAR)temp_buf2);
501 return (FALSE);
502 }
503 }
504 else
505 offset = buffer + (*end_offset);
506
507 strcpy(temp_buf1, "\n");
508 strcat(temp_buf1, key);
509 strcat(temp_buf1, "=");
510
511 //search key
512 if((start_ptr=rtstrstr(offset, temp_buf1))==NULL)
513 {
514 os_free_mem(NULL, (PUCHAR)temp_buf1);
515 os_free_mem(NULL, (PUCHAR)temp_buf2);
516 return (FALSE);
517 }
518
519 start_ptr+=strlen("\n");
520 if((end_ptr=rtstrstr(start_ptr, "\n"))==NULL)
521 end_ptr=start_ptr+strlen(start_ptr);
522
523 if (end_ptr<start_ptr)
524 {
525 os_free_mem(NULL, (PUCHAR)temp_buf1);
526 os_free_mem(NULL, (PUCHAR)temp_buf2);
527 return (FALSE);
528 }
529
530 *end_offset = end_ptr - buffer;
531
532 NdisMoveMemory(temp_buf2, start_ptr, end_ptr-start_ptr);
533 temp_buf2[end_ptr-start_ptr]='\0';
534 len = strlen(temp_buf2);
535 strcpy(temp_buf1, temp_buf2);
536 if((start_ptr=rtstrstr(temp_buf1, "=")) == NULL)
537 {
538 os_free_mem(NULL, (PUCHAR)temp_buf1);
539 os_free_mem(NULL, (PUCHAR)temp_buf2);
540 return (FALSE);
541 }
542
543 strcpy(temp_buf2, start_ptr+1);
544 ptr = temp_buf2;
545 //trim space or tab
546 while(*ptr != 0x00)
547 {
548 if((bTrimSpace && (*ptr == ' ')) || (*ptr == '\t') )
549 ptr++;
550 else
551 break;
552 }
553
554 len = strlen(ptr);
555 memset(dest, 0x00, destsize);
556 strncpy(dest, ptr, len >= destsize ? destsize: len);
557
558 os_free_mem(NULL, (PUCHAR)temp_buf1);
559 os_free_mem(NULL, (PUCHAR)temp_buf2);
560 return TRUE;
561}
562
563
564static int rtmp_parse_key_buffer_from_file(IN PRTMP_ADAPTER pAd,IN PSTRING buffer,IN ULONG KeyType,IN INT BSSIdx,IN INT KeyIdx)
565{
566 PSTRING keybuff;
567 //INT i = BSSIdx, idx = KeyIdx, retVal;
568 ULONG KeyLen;
569 //UCHAR CipherAlg = CIPHER_WEP64;
570 CIPHER_KEY *pSharedKey;
571
572 keybuff = buffer;
573 KeyLen = strlen(keybuff);
574 pSharedKey = &pAd->SharedKey[BSSIdx][KeyIdx];
575
576 if(((KeyType != 0) && (KeyType != 1)) ||
577 ((KeyType == 0) && (KeyLen != 10) && (KeyLen != 26)) ||
578 ((KeyType== 1) && (KeyLen != 5) && (KeyLen != 13)))
579 {
580 DBGPRINT(RT_DEBUG_ERROR, ("Key%dStr is Invalid key length(%ld) or Type(%ld)\n",
581 KeyIdx+1, KeyLen, KeyType));
582 return FALSE;
583 }
584 else
585 {
586 return RT_CfgSetWepKey(pAd, buffer, pSharedKey, KeyIdx);
587 }
588
589}
590
591
592static void rtmp_read_key_parms_from_file(IN PRTMP_ADAPTER pAd, PSTRING tmpbuf, PSTRING buffer)
593{
594 STRING tok_str[16];
595 PSTRING macptr;
596 INT i = 0, idx;
597 ULONG KeyType[MAX_MBSSID_NUM];
598 ULONG KeyIdx;
599
600 NdisZeroMemory(KeyType, sizeof(KeyType));
601
602 //DefaultKeyID
603 if(RTMPGetKeyParameter("DefaultKeyID", tmpbuf, 25, buffer, TRUE))
604 {
605 {
606 KeyIdx = simple_strtol(tmpbuf, 0, 10);
607 if((KeyIdx >= 1 ) && (KeyIdx <= 4))
608 pAd->StaCfg.DefaultKeyId = (UCHAR) (KeyIdx - 1);
609 else
610 pAd->StaCfg.DefaultKeyId = 0;
611
612 DBGPRINT(RT_DEBUG_TRACE, ("DefaultKeyID(0~3)=%d\n", pAd->StaCfg.DefaultKeyId));
613 }
614 }
615
616
617 for (idx = 0; idx < 4; idx++)
618 {
619 sprintf(tok_str, "Key%dType", idx + 1);
620 //Key1Type
621 if (RTMPGetKeyParameter(tok_str, tmpbuf, 128, buffer, TRUE))
622 {
623 for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
624 {
625 /*
626 do sanity check for KeyType length;
627 or in station mode, the KeyType length > 1,
628 the code will overwrite the stack of caller
629 (RTMPSetProfileParameters) and cause srcbuf = NULL
630 */
631 if (i < MAX_MBSSID_NUM)
632 KeyType[i] = simple_strtol(macptr, 0, 10);
633 }
634
635 {
636 sprintf(tok_str, "Key%dStr", idx + 1);
637 if (RTMPGetKeyParameter(tok_str, tmpbuf, 128, buffer, FALSE))
638 {
639 rtmp_parse_key_buffer_from_file(pAd, tmpbuf, KeyType[BSS0], BSS0, idx);
640 }
641 }
642 }
643 }
644}
645
646
647
648static void rtmp_read_sta_wmm_parms_from_file(IN PRTMP_ADAPTER pAd, char *tmpbuf, char *buffer)
649{
650 PSTRING macptr;
651 INT i=0;
652 BOOLEAN bWmmEnable = FALSE;
653
654 //WmmCapable
655 if(RTMPGetKeyParameter("WmmCapable", tmpbuf, 32, buffer, TRUE))
656 {
657 if(simple_strtol(tmpbuf, 0, 10) != 0) //Enable
658 {
659 pAd->CommonCfg.bWmmCapable = TRUE;
660 bWmmEnable = TRUE;
661 }
662 else //Disable
663 {
664 pAd->CommonCfg.bWmmCapable = FALSE;
665 }
666
667 DBGPRINT(RT_DEBUG_TRACE, ("WmmCapable=%d\n", pAd->CommonCfg.bWmmCapable));
668 }
669
670
671 //AckPolicy for AC_BK, AC_BE, AC_VI, AC_VO
672 if(RTMPGetKeyParameter("AckPolicy", tmpbuf, 32, buffer, TRUE))
673 {
674 for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
675 {
676 pAd->CommonCfg.AckPolicy[i] = (UCHAR)simple_strtol(macptr, 0, 10);
677
678 DBGPRINT(RT_DEBUG_TRACE, ("AckPolicy[%d]=%d\n", i, pAd->CommonCfg.AckPolicy[i]));
679 }
680 }
681
682 if (bWmmEnable)
683 {
684 //APSDCapable
685 if(RTMPGetKeyParameter("APSDCapable", tmpbuf, 10, buffer, TRUE))
686 {
687 if(simple_strtol(tmpbuf, 0, 10) != 0) //Enable
688 pAd->CommonCfg.bAPSDCapable = TRUE;
689 else
690 pAd->CommonCfg.bAPSDCapable = FALSE;
691
692 DBGPRINT(RT_DEBUG_TRACE, ("APSDCapable=%d\n", pAd->CommonCfg.bAPSDCapable));
693 }
694
695 //MaxSPLength
696 if(RTMPGetKeyParameter("MaxSPLength", tmpbuf, 10, buffer, TRUE))
697 {
698 pAd->CommonCfg.MaxSPLength = simple_strtol(tmpbuf, 0, 10);
699
700 DBGPRINT(RT_DEBUG_TRACE, ("MaxSPLength=%d\n", pAd->CommonCfg.MaxSPLength));
701 }
702
703 //APSDAC for AC_BE, AC_BK, AC_VI, AC_VO
704 if(RTMPGetKeyParameter("APSDAC", tmpbuf, 32, buffer, TRUE))
705 {
706 BOOLEAN apsd_ac[4];
707
708 for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
709 {
710 apsd_ac[i] = (BOOLEAN)simple_strtol(macptr, 0, 10);
711
712 DBGPRINT(RT_DEBUG_TRACE, ("APSDAC%d %d\n", i, apsd_ac[i]));
713 }
714
715 pAd->CommonCfg.bAPSDAC_BE = apsd_ac[0];
716 pAd->CommonCfg.bAPSDAC_BK = apsd_ac[1];
717 pAd->CommonCfg.bAPSDAC_VI = apsd_ac[2];
718 pAd->CommonCfg.bAPSDAC_VO = apsd_ac[3];
719
720 pAd->CommonCfg.bACMAPSDTr[0] = apsd_ac[0];
721 pAd->CommonCfg.bACMAPSDTr[1] = apsd_ac[1];
722 pAd->CommonCfg.bACMAPSDTr[2] = apsd_ac[2];
723 pAd->CommonCfg.bACMAPSDTr[3] = apsd_ac[3];
724 }
725 }
726
727}
728
729
730static void HTParametersHook(
731 IN PRTMP_ADAPTER pAd,
732 IN PSTRING pValueStr,
733 IN PSTRING pInput)
734{
735
736 long Value;
737
738 if (RTMPGetKeyParameter("HT_PROTECT", pValueStr, 25, pInput, TRUE))
739 {
740 Value = simple_strtol(pValueStr, 0, 10);
741 if (Value == 0)
742 {
743 pAd->CommonCfg.bHTProtect = FALSE;
744 }
745 else
746 {
747 pAd->CommonCfg.bHTProtect = TRUE;
748 }
749 DBGPRINT(RT_DEBUG_TRACE, ("HT: Protection = %s\n", (Value==0) ? "Disable" : "Enable"));
750 }
751
752 if (RTMPGetKeyParameter("HT_MIMOPSEnable", pValueStr, 25, pInput, TRUE))
753 {
754 Value = simple_strtol(pValueStr, 0, 10);
755 if (Value == 0)
756 {
757 pAd->CommonCfg.bMIMOPSEnable = FALSE;
758 }
759 else
760 {
761 pAd->CommonCfg.bMIMOPSEnable = TRUE;
762 }
763 DBGPRINT(RT_DEBUG_TRACE, ("HT: MIMOPSEnable = %s\n", (Value==0) ? "Disable" : "Enable"));
764 }
765
766
767 if (RTMPGetKeyParameter("HT_MIMOPSMode", pValueStr, 25, pInput, TRUE))
768 {
769 Value = simple_strtol(pValueStr, 0, 10);
770 if (Value > MMPS_ENABLE)
771 {
772 pAd->CommonCfg.BACapability.field.MMPSmode = MMPS_ENABLE;
773 }
774 else
775 {
776 //TODO: add mimo power saving mechanism
777 pAd->CommonCfg.BACapability.field.MMPSmode = MMPS_ENABLE;
778 //pAd->CommonCfg.BACapability.field.MMPSmode = Value;
779 }
780 DBGPRINT(RT_DEBUG_TRACE, ("HT: MIMOPS Mode = %d\n", (INT) Value));
781 }
782
783 if (RTMPGetKeyParameter("HT_BADecline", pValueStr, 25, pInput, TRUE))
784 {
785 Value = simple_strtol(pValueStr, 0, 10);
786 if (Value == 0)
787 {
788 pAd->CommonCfg.bBADecline = FALSE;
789 }
790 else
791 {
792 pAd->CommonCfg.bBADecline = TRUE;
793 }
794 DBGPRINT(RT_DEBUG_TRACE, ("HT: BA Decline = %s\n", (Value==0) ? "Disable" : "Enable"));
795 }
796
797
798 if (RTMPGetKeyParameter("HT_DisableReordering", pValueStr, 25, pInput, TRUE))
799 {
800 Value = simple_strtol(pValueStr, 0, 10);
801 if (Value == 0)
802 {
803 pAd->CommonCfg.bDisableReordering = FALSE;
804 }
805 else
806 {
807 pAd->CommonCfg.bDisableReordering = TRUE;
808 }
809 DBGPRINT(RT_DEBUG_TRACE, ("HT: DisableReordering = %s\n", (Value==0) ? "Disable" : "Enable"));
810 }
811
812 if (RTMPGetKeyParameter("HT_AutoBA", pValueStr, 25, pInput, TRUE))
813 {
814 Value = simple_strtol(pValueStr, 0, 10);
815 if (Value == 0)
816 {
817 pAd->CommonCfg.BACapability.field.AutoBA = FALSE;
818 pAd->CommonCfg.BACapability.field.Policy = BA_NOTUSE;
819 }
820 else
821 {
822 pAd->CommonCfg.BACapability.field.AutoBA = TRUE;
823 pAd->CommonCfg.BACapability.field.Policy = IMMED_BA;
824 }
825 pAd->CommonCfg.REGBACapability.field.AutoBA = pAd->CommonCfg.BACapability.field.AutoBA;
826 DBGPRINT(RT_DEBUG_TRACE, ("HT: Auto BA = %s\n", (Value==0) ? "Disable" : "Enable"));
827 }
828
829 // Tx_+HTC frame
830 if (RTMPGetKeyParameter("HT_HTC", pValueStr, 25, pInput, TRUE))
831 {
832 Value = simple_strtol(pValueStr, 0, 10);
833 if (Value == 0)
834 {
835 pAd->HTCEnable = FALSE;
836 }
837 else
838 {
839 pAd->HTCEnable = TRUE;
840 }
841 DBGPRINT(RT_DEBUG_TRACE, ("HT: Tx +HTC frame = %s\n", (Value==0) ? "Disable" : "Enable"));
842 }
843
844 // Enable HT Link Adaptation Control
845 if (RTMPGetKeyParameter("HT_LinkAdapt", pValueStr, 25, pInput, TRUE))
846 {
847 Value = simple_strtol(pValueStr, 0, 10);
848 if (Value == 0)
849 {
850 pAd->bLinkAdapt = FALSE;
851 }
852 else
853 {
854 pAd->HTCEnable = TRUE;
855 pAd->bLinkAdapt = TRUE;
856 }
857 DBGPRINT(RT_DEBUG_TRACE, ("HT: Link Adaptation Control = %s\n", (Value==0) ? "Disable" : "Enable(+HTC)"));
858 }
859
860 // Reverse Direction Mechanism
861 if (RTMPGetKeyParameter("HT_RDG", pValueStr, 25, pInput, TRUE))
862 {
863 Value = simple_strtol(pValueStr, 0, 10);
864 if (Value == 0)
865 {
866 pAd->CommonCfg.bRdg = FALSE;
867 }
868 else
869 {
870 pAd->HTCEnable = TRUE;
871 pAd->CommonCfg.bRdg = TRUE;
872 }
873 DBGPRINT(RT_DEBUG_TRACE, ("HT: RDG = %s\n", (Value==0) ? "Disable" : "Enable(+HTC)"));
874 }
875
876
877
878
879 // Tx A-MSUD ?
880 if (RTMPGetKeyParameter("HT_AMSDU", pValueStr, 25, pInput, TRUE))
881 {
882 Value = simple_strtol(pValueStr, 0, 10);
883 if (Value == 0)
884 {
885 pAd->CommonCfg.BACapability.field.AmsduEnable = FALSE;
886 }
887 else
888 {
889 pAd->CommonCfg.BACapability.field.AmsduEnable = TRUE;
890 }
891 DBGPRINT(RT_DEBUG_TRACE, ("HT: Tx A-MSDU = %s\n", (Value==0) ? "Disable" : "Enable"));
892 }
893
894 // MPDU Density
895 if (RTMPGetKeyParameter("HT_MpduDensity", pValueStr, 25, pInput, TRUE))
896 {
897 Value = simple_strtol(pValueStr, 0, 10);
898 if (Value <=7 && Value >= 0)
899 {
900 pAd->CommonCfg.BACapability.field.MpduDensity = Value;
901 DBGPRINT(RT_DEBUG_TRACE, ("HT: MPDU Density = %d\n", (INT) Value));
902 }
903 else
904 {
905 pAd->CommonCfg.BACapability.field.MpduDensity = 4;
906 DBGPRINT(RT_DEBUG_TRACE, ("HT: MPDU Density = %d (Default)\n", 4));
907 }
908 }
909
910 // Max Rx BA Window Size
911 if (RTMPGetKeyParameter("HT_BAWinSize", pValueStr, 25, pInput, TRUE))
912 {
913 Value = simple_strtol(pValueStr, 0, 10);
914
915 if (Value >=1 && Value <= 64)
916 {
917 pAd->CommonCfg.REGBACapability.field.RxBAWinLimit = Value;
918 pAd->CommonCfg.BACapability.field.RxBAWinLimit = Value;
919 DBGPRINT(RT_DEBUG_TRACE, ("HT: BA Windw Size = %d\n", (INT) Value));
920 }
921 else
922 {
923 pAd->CommonCfg.REGBACapability.field.RxBAWinLimit = 64;
924 pAd->CommonCfg.BACapability.field.RxBAWinLimit = 64;
925 DBGPRINT(RT_DEBUG_TRACE, ("HT: BA Windw Size = 64 (Defualt)\n"));
926 }
927
928 }
929
930 // Guard Interval
931 if (RTMPGetKeyParameter("HT_GI", pValueStr, 25, pInput, TRUE))
932 {
933 Value = simple_strtol(pValueStr, 0, 10);
934
935 if (Value == GI_400)
936 {
937 pAd->CommonCfg.RegTransmitSetting.field.ShortGI = GI_400;
938 }
939 else
940 {
941 pAd->CommonCfg.RegTransmitSetting.field.ShortGI = GI_800;
942 }
943
944 DBGPRINT(RT_DEBUG_TRACE, ("HT: Guard Interval = %s\n", (Value==GI_400) ? "400" : "800" ));
945 }
946
947 // HT Operation Mode : Mixed Mode , Green Field
948 if (RTMPGetKeyParameter("HT_OpMode", pValueStr, 25, pInput, TRUE))
949 {
950 Value = simple_strtol(pValueStr, 0, 10);
951
952 if (Value == HTMODE_GF)
953 {
954
955 pAd->CommonCfg.RegTransmitSetting.field.HTMODE = HTMODE_GF;
956 }
957 else
958 {
959 pAd->CommonCfg.RegTransmitSetting.field.HTMODE = HTMODE_MM;
960 }
961
962 DBGPRINT(RT_DEBUG_TRACE, ("HT: Operate Mode = %s\n", (Value==HTMODE_GF) ? "Green Field" : "Mixed Mode" ));
963 }
964
965 // Fixed Tx mode : CCK, OFDM
966 if (RTMPGetKeyParameter("FixedTxMode", pValueStr, 25, pInput, TRUE))
967 {
968 UCHAR fix_tx_mode;
969
970 {
971 fix_tx_mode = FIXED_TXMODE_HT;
972
973 if (strcmp(pValueStr, "OFDM") == 0 || strcmp(pValueStr, "ofdm") == 0)
974 {
975 fix_tx_mode = FIXED_TXMODE_OFDM;
976 }
977 else if (strcmp(pValueStr, "CCK") == 0 || strcmp(pValueStr, "cck") == 0)
978 {
979 fix_tx_mode = FIXED_TXMODE_CCK;
980 }
981 else if (strcmp(pValueStr, "HT") == 0 || strcmp(pValueStr, "ht") == 0)
982 {
983 fix_tx_mode = FIXED_TXMODE_HT;
984 }
985 else
986 {
987 Value = simple_strtol(pValueStr, 0, 10);
988 // 1 : CCK
989 // 2 : OFDM
990 // otherwise : HT
991 if (Value == FIXED_TXMODE_CCK || Value == FIXED_TXMODE_OFDM)
992 fix_tx_mode = Value;
993 else
994 fix_tx_mode = FIXED_TXMODE_HT;
995 }
996
997 pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode = fix_tx_mode;
998 DBGPRINT(RT_DEBUG_TRACE, ("Fixed Tx Mode = %d\n", fix_tx_mode));
999
1000 }
1001 }
1002
1003
1004 // Channel Width
1005 if (RTMPGetKeyParameter("HT_BW", pValueStr, 25, pInput, TRUE))
1006 {
1007 Value = simple_strtol(pValueStr, 0, 10);
1008
1009 if (Value == BW_40)
1010 {
1011 pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40;
1012 }
1013 else
1014 {
1015 pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
1016 }
1017
1018 DBGPRINT(RT_DEBUG_TRACE, ("HT: Channel Width = %s\n", (Value==BW_40) ? "40 MHz" : "20 MHz" ));
1019 }
1020
1021 if (RTMPGetKeyParameter("HT_EXTCHA", pValueStr, 25, pInput, TRUE))
1022 {
1023 Value = simple_strtol(pValueStr, 0, 10);
1024
1025 if (Value == 0)
1026 {
1027
1028 pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_BELOW;
1029 }
1030 else
1031 {
1032 pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_ABOVE;
1033 }
1034
1035 DBGPRINT(RT_DEBUG_TRACE, ("HT: Ext Channel = %s\n", (Value==0) ? "BELOW" : "ABOVE" ));
1036 }
1037
1038 // MSC
1039 if (RTMPGetKeyParameter("HT_MCS", pValueStr, 50, pInput, TRUE))
1040 {
1041 {
1042 Value = simple_strtol(pValueStr, 0, 10);
1043
1044// if ((Value >= 0 && Value <= 15) || (Value == 32))
1045 if ((Value >= 0 && Value <= 23) || (Value == 32)) // 3*3
1046 {
1047 pAd->StaCfg.DesiredTransmitSetting.field.MCS = Value;
1048 pAd->StaCfg.bAutoTxRateSwitch = FALSE;
1049 DBGPRINT(RT_DEBUG_TRACE, ("HT: MCS = %d\n", pAd->StaCfg.DesiredTransmitSetting.field.MCS));
1050 }
1051 else
1052 {
1053 pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
1054 pAd->StaCfg.bAutoTxRateSwitch = TRUE;
1055 DBGPRINT(RT_DEBUG_TRACE, ("HT: MCS = AUTO\n"));
1056 }
1057 }
1058 }
1059
1060 // STBC
1061 if (RTMPGetKeyParameter("HT_STBC", pValueStr, 25, pInput, TRUE))
1062 {
1063 Value = simple_strtol(pValueStr, 0, 10);
1064 if (Value == STBC_USE)
1065 {
1066 pAd->CommonCfg.RegTransmitSetting.field.STBC = STBC_USE;
1067 }
1068 else
1069 {
1070 pAd->CommonCfg.RegTransmitSetting.field.STBC = STBC_NONE;
1071 }
1072 DBGPRINT(RT_DEBUG_TRACE, ("HT: STBC = %d\n", pAd->CommonCfg.RegTransmitSetting.field.STBC));
1073 }
1074
1075 // 40_Mhz_Intolerant
1076 if (RTMPGetKeyParameter("HT_40MHZ_INTOLERANT", pValueStr, 25, pInput, TRUE))
1077 {
1078 Value = simple_strtol(pValueStr, 0, 10);
1079 if (Value == 0)
1080 {
1081 pAd->CommonCfg.bForty_Mhz_Intolerant = FALSE;
1082 }
1083 else
1084 {
1085 pAd->CommonCfg.bForty_Mhz_Intolerant = TRUE;
1086 }
1087 DBGPRINT(RT_DEBUG_TRACE, ("HT: 40MHZ INTOLERANT = %d\n", pAd->CommonCfg.bForty_Mhz_Intolerant));
1088 }
1089 //HT_TxStream
1090 if(RTMPGetKeyParameter("HT_TxStream", pValueStr, 10, pInput, TRUE))
1091 {
1092 switch (simple_strtol(pValueStr, 0, 10))
1093 {
1094 case 1:
1095 pAd->CommonCfg.TxStream = 1;
1096 break;
1097 case 2:
1098 pAd->CommonCfg.TxStream = 2;
1099 break;
1100 case 3: // 3*3
1101 default:
1102 pAd->CommonCfg.TxStream = 3;
1103
1104 if (pAd->MACVersion < RALINK_2883_VERSION)
1105 pAd->CommonCfg.TxStream = 2; // only 2 tx streams for RT2860 series
1106 break;
1107 }
1108 DBGPRINT(RT_DEBUG_TRACE, ("HT: Tx Stream = %d\n", pAd->CommonCfg.TxStream));
1109 }
1110 //HT_RxStream
1111 if(RTMPGetKeyParameter("HT_RxStream", pValueStr, 10, pInput, TRUE))
1112 {
1113 switch (simple_strtol(pValueStr, 0, 10))
1114 {
1115 case 1:
1116 pAd->CommonCfg.RxStream = 1;
1117 break;
1118 case 2:
1119 pAd->CommonCfg.RxStream = 2;
1120 break;
1121 case 3:
1122 default:
1123 pAd->CommonCfg.RxStream = 3;
1124
1125 if (pAd->MACVersion < RALINK_2883_VERSION)
1126 pAd->CommonCfg.RxStream = 2; // only 2 rx streams for RT2860 series
1127 break;
1128 }
1129 DBGPRINT(RT_DEBUG_TRACE, ("HT: Rx Stream = %d\n", pAd->CommonCfg.RxStream));
1130 }
1131 //2008/11/05: KH add to support Antenna power-saving of AP<--
1132 //Green AP
1133 if(RTMPGetKeyParameter("GreenAP", pValueStr, 10, pInput, TRUE))
1134 {
1135 Value = simple_strtol(pValueStr, 0, 10);
1136 if (Value == 0)
1137 {
1138 pAd->CommonCfg.bGreenAPEnable = FALSE;
1139 }
1140 else
1141 {
1142 pAd->CommonCfg.bGreenAPEnable = TRUE;
1143 }
1144 DBGPRINT(RT_DEBUG_TRACE, ("HT: Green AP= %d\n", pAd->CommonCfg.bGreenAPEnable));
1145 }
1146
1147 // HT_DisallowTKIP
1148 if (RTMPGetKeyParameter("HT_DisallowTKIP", pValueStr, 25, pInput, TRUE))
1149 {
1150 Value = simple_strtol(pValueStr, 0, 10);
1151
1152 if (Value == 1)
1153 {
1154 pAd->CommonCfg.HT_DisallowTKIP = TRUE;
1155 }
1156 else
1157 {
1158 pAd->CommonCfg.HT_DisallowTKIP = FALSE;
1159 }
1160
1161 DBGPRINT(RT_DEBUG_TRACE, ("HT: Disallow TKIP mode = %s\n", (pAd->CommonCfg.HT_DisallowTKIP == TRUE) ? "ON" : "OFF" ));
1162 }
1163
1164
1165 //2008/11/05:KH add to support Antenna power-saving of AP-->
1166}
1167
1168
1169NDIS_STATUS RTMPSetProfileParameters(
1170 IN RTMP_ADAPTER *pAd,
1171 IN PSTRING pBuffer)
1172{
1173 PSTRING tmpbuf;
1174 ULONG RtsThresh;
1175 ULONG FragThresh;
1176 PSTRING macptr;
1177 INT i = 0, retval;
1178 tmpbuf = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG);
1179 if(tmpbuf == NULL)
1180 return NDIS_STATUS_FAILURE;
1181
1182 do
1183 {
1184 // set file parameter to portcfg
1185 //CountryRegion
1186 if(RTMPGetKeyParameter("CountryRegion", tmpbuf, 25, pBuffer, TRUE))
1187 {
1188 retval = RT_CfgSetCountryRegion(pAd, tmpbuf, BAND_24G);
1189 DBGPRINT(RT_DEBUG_TRACE, ("CountryRegion=%d\n", pAd->CommonCfg.CountryRegion));
1190 }
1191 //CountryRegionABand
1192 if(RTMPGetKeyParameter("CountryRegionABand", tmpbuf, 25, pBuffer, TRUE))
1193 {
1194 retval = RT_CfgSetCountryRegion(pAd, tmpbuf, BAND_5G);
1195 DBGPRINT(RT_DEBUG_TRACE, ("CountryRegionABand=%d\n", pAd->CommonCfg.CountryRegionForABand));
1196 }
1197#ifdef RTMP_EFUSE_SUPPORT
1198#ifdef RT30xx
1199 //EfuseBufferMode
1200 if(RTMPGetKeyParameter("EfuseBufferMode", tmpbuf, 25, pBuffer, TRUE))
1201 {
1202 pAd->bEEPROMFile = (UCHAR) simple_strtol(tmpbuf, 0, 10);
1203 DBGPRINT(RT_DEBUG_TRACE, ("EfuseBufferMode=%d\n", pAd->bUseEfuse));
1204 }
1205#endif // RT30xx //
1206#endif // RTMP_EFUSE_SUPPORT //
1207 //CountryCode
1208 if(RTMPGetKeyParameter("CountryCode", tmpbuf, 25, pBuffer, TRUE))
1209 {
1210 NdisMoveMemory(pAd->CommonCfg.CountryCode, tmpbuf , 2);
1211 if (strlen((PSTRING) pAd->CommonCfg.CountryCode) != 0)
1212 {
1213 pAd->CommonCfg.bCountryFlag = TRUE;
1214 }
1215 DBGPRINT(RT_DEBUG_TRACE, ("CountryCode=%s\n", pAd->CommonCfg.CountryCode));
1216 }
1217 //ChannelGeography
1218 if(RTMPGetKeyParameter("ChannelGeography", tmpbuf, 25, pBuffer, TRUE))
1219 {
1220 UCHAR Geography = (UCHAR) simple_strtol(tmpbuf, 0, 10);
1221 if (Geography <= BOTH)
1222 {
1223 pAd->CommonCfg.Geography = Geography;
1224 pAd->CommonCfg.CountryCode[2] =
1225 (pAd->CommonCfg.Geography == BOTH) ? ' ' : ((pAd->CommonCfg.Geography == IDOR) ? 'I' : 'O');
1226 DBGPRINT(RT_DEBUG_TRACE, ("ChannelGeography=%d\n", pAd->CommonCfg.Geography));
1227 }
1228 }
1229 else
1230 {
1231 pAd->CommonCfg.Geography = BOTH;
1232 pAd->CommonCfg.CountryCode[2] = ' ';
1233 }
1234
1235 {
1236 //SSID
1237 if (RTMPGetKeyParameter("SSID", tmpbuf, 256, pBuffer, FALSE))
1238 {
1239 if (strlen(tmpbuf) <= 32)
1240 {
1241 pAd->CommonCfg.SsidLen = (UCHAR) strlen(tmpbuf);
1242 NdisZeroMemory(pAd->CommonCfg.Ssid, NDIS_802_11_LENGTH_SSID);
1243 NdisMoveMemory(pAd->CommonCfg.Ssid, tmpbuf, pAd->CommonCfg.SsidLen);
1244 pAd->MlmeAux.AutoReconnectSsidLen = pAd->CommonCfg.SsidLen;
1245 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, NDIS_802_11_LENGTH_SSID);
1246 NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, tmpbuf, pAd->MlmeAux.AutoReconnectSsidLen);
1247 pAd->MlmeAux.SsidLen = pAd->CommonCfg.SsidLen;
1248 NdisZeroMemory(pAd->MlmeAux.Ssid, NDIS_802_11_LENGTH_SSID);
1249 NdisMoveMemory(pAd->MlmeAux.Ssid, tmpbuf, pAd->MlmeAux.SsidLen);
1250 DBGPRINT(RT_DEBUG_TRACE, ("%s::(SSID=%s)\n", __func__, tmpbuf));
1251 }
1252 }
1253 }
1254
1255 {
1256 //NetworkType
1257 if (RTMPGetKeyParameter("NetworkType", tmpbuf, 25, pBuffer, TRUE))
1258 {
1259 pAd->bConfigChanged = TRUE;
1260 if (strcmp(tmpbuf, "Adhoc") == 0)
1261 pAd->StaCfg.BssType = BSS_ADHOC;
1262 else //Default Infrastructure mode
1263 pAd->StaCfg.BssType = BSS_INFRA;
1264 // Reset Ralink supplicant to not use, it will be set to start when UI set PMK key
1265 pAd->StaCfg.WpaState = SS_NOTUSE;
1266 DBGPRINT(RT_DEBUG_TRACE, ("%s::(NetworkType=%d)\n", __func__, pAd->StaCfg.BssType));
1267 }
1268 }
1269 //Channel
1270 if(RTMPGetKeyParameter("Channel", tmpbuf, 10, pBuffer, TRUE))
1271 {
1272 pAd->CommonCfg.Channel = (UCHAR) simple_strtol(tmpbuf, 0, 10);
1273 DBGPRINT(RT_DEBUG_TRACE, ("Channel=%d\n", pAd->CommonCfg.Channel));
1274 }
1275 //WirelessMode
1276 if(RTMPGetKeyParameter("WirelessMode", tmpbuf, 10, pBuffer, TRUE))
1277 {
1278 RT_CfgSetWirelessMode(pAd, tmpbuf);
1279 DBGPRINT(RT_DEBUG_TRACE, ("PhyMode=%d\n", pAd->CommonCfg.PhyMode));
1280 }
1281 //BasicRate
1282 if(RTMPGetKeyParameter("BasicRate", tmpbuf, 10, pBuffer, TRUE))
1283 {
1284 pAd->CommonCfg.BasicRateBitmap = (ULONG) simple_strtol(tmpbuf, 0, 10);
1285 DBGPRINT(RT_DEBUG_TRACE, ("BasicRate=%ld\n", pAd->CommonCfg.BasicRateBitmap));
1286 }
1287 //BeaconPeriod
1288 if(RTMPGetKeyParameter("BeaconPeriod", tmpbuf, 10, pBuffer, TRUE))
1289 {
1290 pAd->CommonCfg.BeaconPeriod = (USHORT) simple_strtol(tmpbuf, 0, 10);
1291 DBGPRINT(RT_DEBUG_TRACE, ("BeaconPeriod=%d\n", pAd->CommonCfg.BeaconPeriod));
1292 }
1293 //TxPower
1294 if(RTMPGetKeyParameter("TxPower", tmpbuf, 10, pBuffer, TRUE))
1295 {
1296 pAd->CommonCfg.TxPowerPercentage = (ULONG) simple_strtol(tmpbuf, 0, 10);
1297 pAd->CommonCfg.TxPowerDefault = pAd->CommonCfg.TxPowerPercentage;
1298 DBGPRINT(RT_DEBUG_TRACE, ("TxPower=%ld\n", pAd->CommonCfg.TxPowerPercentage));
1299 }
1300 //BGProtection
1301 if(RTMPGetKeyParameter("BGProtection", tmpbuf, 10, pBuffer, TRUE))
1302 {
1303 //#if 0 //#ifndef WIFI_TEST
1304 // pAd->CommonCfg.UseBGProtection = 2;// disable b/g protection for throughput test
1305 //#else
1306 switch (simple_strtol(tmpbuf, 0, 10))
1307 {
1308 case 1: //Always On
1309 pAd->CommonCfg.UseBGProtection = 1;
1310 break;
1311 case 2: //Always OFF
1312 pAd->CommonCfg.UseBGProtection = 2;
1313 break;
1314 case 0: //AUTO
1315 default:
1316 pAd->CommonCfg.UseBGProtection = 0;
1317 break;
1318 }
1319 //#endif
1320 DBGPRINT(RT_DEBUG_TRACE, ("BGProtection=%ld\n", pAd->CommonCfg.UseBGProtection));
1321 }
1322 //OLBCDetection
1323 if(RTMPGetKeyParameter("DisableOLBC", tmpbuf, 10, pBuffer, TRUE))
1324 {
1325 switch (simple_strtol(tmpbuf, 0, 10))
1326 {
1327 case 1: //disable OLBC Detection
1328 pAd->CommonCfg.DisableOLBCDetect = 1;
1329 break;
1330 case 0: //enable OLBC Detection
1331 pAd->CommonCfg.DisableOLBCDetect = 0;
1332 break;
1333 default:
1334 pAd->CommonCfg.DisableOLBCDetect= 0;
1335 break;
1336 }
1337 DBGPRINT(RT_DEBUG_TRACE, ("OLBCDetection=%ld\n", pAd->CommonCfg.DisableOLBCDetect));
1338 }
1339 //TxPreamble
1340 if(RTMPGetKeyParameter("TxPreamble", tmpbuf, 10, pBuffer, TRUE))
1341 {
1342 switch (simple_strtol(tmpbuf, 0, 10))
1343 {
1344 case Rt802_11PreambleShort:
1345 pAd->CommonCfg.TxPreamble = Rt802_11PreambleShort;
1346 break;
1347 case Rt802_11PreambleLong:
1348 default:
1349 pAd->CommonCfg.TxPreamble = Rt802_11PreambleLong;
1350 break;
1351 }
1352 DBGPRINT(RT_DEBUG_TRACE, ("TxPreamble=%ld\n", pAd->CommonCfg.TxPreamble));
1353 }
1354 //RTSThreshold
1355 if(RTMPGetKeyParameter("RTSThreshold", tmpbuf, 10, pBuffer, TRUE))
1356 {
1357 RtsThresh = simple_strtol(tmpbuf, 0, 10);
1358 if( (RtsThresh >= 1) && (RtsThresh <= MAX_RTS_THRESHOLD) )
1359 pAd->CommonCfg.RtsThreshold = (USHORT)RtsThresh;
1360 else
1361 pAd->CommonCfg.RtsThreshold = MAX_RTS_THRESHOLD;
1362
1363 DBGPRINT(RT_DEBUG_TRACE, ("RTSThreshold=%d\n", pAd->CommonCfg.RtsThreshold));
1364 }
1365 //FragThreshold
1366 if(RTMPGetKeyParameter("FragThreshold", tmpbuf, 10, pBuffer, TRUE))
1367 {
1368 FragThresh = simple_strtol(tmpbuf, 0, 10);
1369 pAd->CommonCfg.bUseZeroToDisableFragment = FALSE;
1370
1371 if (FragThresh > MAX_FRAG_THRESHOLD || FragThresh < MIN_FRAG_THRESHOLD)
1372 { //illegal FragThresh so we set it to default
1373 pAd->CommonCfg.FragmentThreshold = MAX_FRAG_THRESHOLD;
1374 pAd->CommonCfg.bUseZeroToDisableFragment = TRUE;
1375 }
1376 else if (FragThresh % 2 == 1)
1377 {
1378 // The length of each fragment shall always be an even number of octets, except for the last fragment
1379 // of an MSDU or MMPDU, which may be either an even or an odd number of octets.
1380 pAd->CommonCfg.FragmentThreshold = (USHORT)(FragThresh - 1);
1381 }
1382 else
1383 {
1384 pAd->CommonCfg.FragmentThreshold = (USHORT)FragThresh;
1385 }
1386 //pAd->CommonCfg.AllowFragSize = (pAd->CommonCfg.FragmentThreshold) - LENGTH_802_11 - LENGTH_CRC;
1387 DBGPRINT(RT_DEBUG_TRACE, ("FragThreshold=%d\n", pAd->CommonCfg.FragmentThreshold));
1388 }
1389 //TxBurst
1390 if(RTMPGetKeyParameter("TxBurst", tmpbuf, 10, pBuffer, TRUE))
1391 {
1392 //#ifdef WIFI_TEST
1393 // pAd->CommonCfg.bEnableTxBurst = FALSE;
1394 //#else
1395 if(simple_strtol(tmpbuf, 0, 10) != 0) //Enable
1396 pAd->CommonCfg.bEnableTxBurst = TRUE;
1397 else //Disable
1398 pAd->CommonCfg.bEnableTxBurst = FALSE;
1399 //#endif
1400 DBGPRINT(RT_DEBUG_TRACE, ("TxBurst=%d\n", pAd->CommonCfg.bEnableTxBurst));
1401 }
1402
1403#ifdef AGGREGATION_SUPPORT
1404 //PktAggregate
1405 if(RTMPGetKeyParameter("PktAggregate", tmpbuf, 10, pBuffer, TRUE))
1406 {
1407 if(simple_strtol(tmpbuf, 0, 10) != 0) //Enable
1408 pAd->CommonCfg.bAggregationCapable = TRUE;
1409 else //Disable
1410 pAd->CommonCfg.bAggregationCapable = FALSE;
1411#ifdef PIGGYBACK_SUPPORT
1412 pAd->CommonCfg.bPiggyBackCapable = pAd->CommonCfg.bAggregationCapable;
1413#endif // PIGGYBACK_SUPPORT //
1414 DBGPRINT(RT_DEBUG_TRACE, ("PktAggregate=%d\n", pAd->CommonCfg.bAggregationCapable));
1415 }
1416#else
1417 pAd->CommonCfg.bAggregationCapable = FALSE;
1418 pAd->CommonCfg.bPiggyBackCapable = FALSE;
1419#endif // AGGREGATION_SUPPORT //
1420
1421 // WmmCapable
1422
1423 rtmp_read_sta_wmm_parms_from_file(pAd, tmpbuf, pBuffer);
1424
1425 //ShortSlot
1426 if(RTMPGetKeyParameter("ShortSlot", tmpbuf, 10, pBuffer, TRUE))
1427 {
1428 RT_CfgSetShortSlot(pAd, tmpbuf);
1429 DBGPRINT(RT_DEBUG_TRACE, ("ShortSlot=%d\n", pAd->CommonCfg.bUseShortSlotTime));
1430 }
1431 //IEEE80211H
1432 if(RTMPGetKeyParameter("IEEE80211H", tmpbuf, 10, pBuffer, TRUE))
1433 {
1434 for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
1435 {
1436 if(simple_strtol(macptr, 0, 10) != 0) //Enable
1437 pAd->CommonCfg.bIEEE80211H = TRUE;
1438 else //Disable
1439 pAd->CommonCfg.bIEEE80211H = FALSE;
1440
1441 DBGPRINT(RT_DEBUG_TRACE, ("IEEE80211H=%d\n", pAd->CommonCfg.bIEEE80211H));
1442 }
1443 }
1444 //CSPeriod
1445 if(RTMPGetKeyParameter("CSPeriod", tmpbuf, 10, pBuffer, TRUE))
1446 {
1447 if(simple_strtol(tmpbuf, 0, 10) != 0)
1448 pAd->CommonCfg.RadarDetect.CSPeriod = simple_strtol(tmpbuf, 0, 10);
1449 else
1450 pAd->CommonCfg.RadarDetect.CSPeriod = 0;
1451
1452 DBGPRINT(RT_DEBUG_TRACE, ("CSPeriod=%d\n", pAd->CommonCfg.RadarDetect.CSPeriod));
1453 }
1454
1455 //RDRegion
1456 if(RTMPGetKeyParameter("RDRegion", tmpbuf, 128, pBuffer, TRUE))
1457 {
1458 RADAR_DETECT_STRUCT *pRadarDetect = &pAd->CommonCfg.RadarDetect;
1459 if ((strncmp(tmpbuf, "JAP_W53", 7) == 0) || (strncmp(tmpbuf, "jap_w53", 7) == 0))
1460 {
1461 pRadarDetect->RDDurRegion = JAP_W53;
1462 pRadarDetect->DfsSessionTime = 15;
1463 }
1464 else if ((strncmp(tmpbuf, "JAP_W56", 7) == 0) || (strncmp(tmpbuf, "jap_w56", 7) == 0))
1465 {
1466 pRadarDetect->RDDurRegion = JAP_W56;
1467 pRadarDetect->DfsSessionTime = 13;
1468 }
1469 else if ((strncmp(tmpbuf, "JAP", 3) == 0) || (strncmp(tmpbuf, "jap", 3) == 0))
1470 {
1471 pRadarDetect->RDDurRegion = JAP;
1472 pRadarDetect->DfsSessionTime = 5;
1473 }
1474 else if ((strncmp(tmpbuf, "FCC", 3) == 0) || (strncmp(tmpbuf, "fcc", 3) == 0))
1475 {
1476 pRadarDetect->RDDurRegion = FCC;
1477 pRadarDetect->DfsSessionTime = 5;
1478 }
1479 else if ((strncmp(tmpbuf, "CE", 2) == 0) || (strncmp(tmpbuf, "ce", 2) == 0))
1480 {
1481 pRadarDetect->RDDurRegion = CE;
1482 pRadarDetect->DfsSessionTime = 13;
1483 }
1484 else
1485 {
1486 pRadarDetect->RDDurRegion = CE;
1487 pRadarDetect->DfsSessionTime = 13;
1488 }
1489
1490 DBGPRINT(RT_DEBUG_TRACE, ("RDRegion=%d\n", pRadarDetect->RDDurRegion));
1491 }
1492 else
1493 {
1494 pAd->CommonCfg.RadarDetect.RDDurRegion = CE;
1495 pAd->CommonCfg.RadarDetect.DfsSessionTime = 13;
1496 }
1497
1498 //WirelessEvent
1499 if(RTMPGetKeyParameter("WirelessEvent", tmpbuf, 10, pBuffer, TRUE))
1500 {
1501 if(simple_strtol(tmpbuf, 0, 10) != 0)
1502 pAd->CommonCfg.bWirelessEvent = simple_strtol(tmpbuf, 0, 10);
1503 else
1504 pAd->CommonCfg.bWirelessEvent = 0; // disable
1505 DBGPRINT(RT_DEBUG_TRACE, ("WirelessEvent=%d\n", pAd->CommonCfg.bWirelessEvent));
1506 }
1507 if(RTMPGetKeyParameter("WiFiTest", tmpbuf, 10, pBuffer, TRUE))
1508 {
1509 if(simple_strtol(tmpbuf, 0, 10) != 0)
1510 pAd->CommonCfg.bWiFiTest= simple_strtol(tmpbuf, 0, 10);
1511 else
1512 pAd->CommonCfg.bWiFiTest = 0; // disable
1513
1514 DBGPRINT(RT_DEBUG_TRACE, ("WiFiTest=%d\n", pAd->CommonCfg.bWiFiTest));
1515 }
1516 //AuthMode
1517 if(RTMPGetKeyParameter("AuthMode", tmpbuf, 128, pBuffer, TRUE))
1518 {
1519 {
1520 if ((strcmp(tmpbuf, "WEPAUTO") == 0) || (strcmp(tmpbuf, "wepauto") == 0))
1521 pAd->StaCfg.AuthMode = Ndis802_11AuthModeAutoSwitch;
1522 else if ((strcmp(tmpbuf, "SHARED") == 0) || (strcmp(tmpbuf, "shared") == 0))
1523 pAd->StaCfg.AuthMode = Ndis802_11AuthModeShared;
1524 else if ((strcmp(tmpbuf, "WPAPSK") == 0) || (strcmp(tmpbuf, "wpapsk") == 0))
1525 pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPAPSK;
1526 else if ((strcmp(tmpbuf, "WPANONE") == 0) || (strcmp(tmpbuf, "wpanone") == 0))
1527 pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPANone;
1528 else if ((strcmp(tmpbuf, "WPA2PSK") == 0) || (strcmp(tmpbuf, "wpa2psk") == 0))
1529 pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPA2PSK;
1530 else if ((strcmp(tmpbuf, "WPA") == 0) || (strcmp(tmpbuf, "wpa") == 0))
1531 pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPA;
1532 else if ((strcmp(tmpbuf, "WPA2") == 0) || (strcmp(tmpbuf, "wpa2") == 0))
1533 pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPA2;
1534 else
1535 pAd->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
1536
1537 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
1538
1539 DBGPRINT(RT_DEBUG_TRACE, ("%s::(AuthMode=%d)\n", __func__, pAd->StaCfg.AuthMode));
1540 }
1541 }
1542 //EncrypType
1543 if(RTMPGetKeyParameter("EncrypType", tmpbuf, 128, pBuffer, TRUE))
1544 {
1545 {
1546 if ((strcmp(tmpbuf, "WEP") == 0) || (strcmp(tmpbuf, "wep") == 0))
1547 pAd->StaCfg.WepStatus = Ndis802_11WEPEnabled;
1548 else if ((strcmp(tmpbuf, "TKIP") == 0) || (strcmp(tmpbuf, "tkip") == 0))
1549 pAd->StaCfg.WepStatus = Ndis802_11Encryption2Enabled;
1550 else if ((strcmp(tmpbuf, "AES") == 0) || (strcmp(tmpbuf, "aes") == 0))
1551 pAd->StaCfg.WepStatus = Ndis802_11Encryption3Enabled;
1552 else
1553 pAd->StaCfg.WepStatus = Ndis802_11WEPDisabled;
1554
1555 // Update all wepstatus related
1556 pAd->StaCfg.PairCipher = pAd->StaCfg.WepStatus;
1557 pAd->StaCfg.GroupCipher = pAd->StaCfg.WepStatus;
1558 pAd->StaCfg.OrigWepStatus = pAd->StaCfg.WepStatus;
1559 pAd->StaCfg.bMixCipher = FALSE;
1560
1561 //RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
1562 DBGPRINT(RT_DEBUG_TRACE, ("%s::(EncrypType=%d)\n", __func__, pAd->StaCfg.WepStatus));
1563 }
1564 }
1565
1566 {
1567 if(RTMPGetKeyParameter("WPAPSK", tmpbuf, 512, pBuffer, FALSE))
1568 {
1569 int ret = TRUE;
1570
1571 tmpbuf[strlen(tmpbuf)] = '\0'; // make STA can process .$^& for WPAPSK input
1572
1573 if ((pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPAPSK) &&
1574 (pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPA2PSK) &&
1575 (pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPANone)
1576 )
1577 {
1578 ret = FALSE;
1579 }
1580 else
1581 {
1582 ret = RT_CfgSetWPAPSKKey(pAd, tmpbuf, (PUCHAR)pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, pAd->StaCfg.PMK);
1583 }
1584
1585 if (ret == TRUE)
1586 {
1587 RTMPZeroMemory(pAd->StaCfg.WpaPassPhrase, 64);
1588 RTMPMoveMemory(pAd->StaCfg.WpaPassPhrase, tmpbuf, strlen(tmpbuf));
1589 pAd->StaCfg.WpaPassPhraseLen= strlen(tmpbuf);
1590
1591 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
1592 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
1593 {
1594 // Start STA supplicant state machine
1595 pAd->StaCfg.WpaState = SS_START;
1596 }
1597 else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
1598 {
1599 pAd->StaCfg.WpaState = SS_NOTUSE;
1600 }
1601 DBGPRINT(RT_DEBUG_TRACE, ("%s::(WPAPSK=%s)\n", __func__, tmpbuf));
1602 }
1603 }
1604 }
1605
1606 //DefaultKeyID, KeyType, KeyStr
1607 rtmp_read_key_parms_from_file(pAd, tmpbuf, pBuffer);
1608
1609
1610 //HSCounter
1611 /*if(RTMPGetKeyParameter("HSCounter", tmpbuf, 10, pBuffer, TRUE))
1612 {
1613 switch (simple_strtol(tmpbuf, 0, 10))
1614 {
1615 case 1: //Enable
1616 pAd->CommonCfg.bEnableHSCounter = TRUE;
1617 break;
1618 case 0: //Disable
1619 default:
1620 pAd->CommonCfg.bEnableHSCounter = FALSE;
1621 break;
1622 }
1623 DBGPRINT(RT_DEBUG_TRACE, "HSCounter=%d\n", pAd->CommonCfg.bEnableHSCounter);
1624 }*/
1625
1626 HTParametersHook(pAd, tmpbuf, pBuffer);
1627
1628 {
1629 //PSMode
1630 if (RTMPGetKeyParameter("PSMode", tmpbuf, 10, pBuffer, TRUE))
1631 {
1632 if (pAd->StaCfg.BssType == BSS_INFRA)
1633 {
1634 if ((strcmp(tmpbuf, "MAX_PSP") == 0) || (strcmp(tmpbuf, "max_psp") == 0))
1635 {
1636 // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
1637 // to exclude certain situations.
1638 // MlmeSetPsm(pAd, PWR_SAVE);
1639 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
1640 if (pAd->StaCfg.bWindowsACCAMEnable == FALSE)
1641 pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeMAX_PSP;
1642 pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeMAX_PSP;
1643 pAd->StaCfg.DefaultListenCount = 5;
1644 }
1645 else if ((strcmp(tmpbuf, "Fast_PSP") == 0) || (strcmp(tmpbuf, "fast_psp") == 0)
1646 || (strcmp(tmpbuf, "FAST_PSP") == 0))
1647 {
1648 // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
1649 // to exclude certain situations.
1650 // RTMP_SET_PSM_BIT(pAd, PWR_SAVE);
1651 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
1652 if (pAd->StaCfg.bWindowsACCAMEnable == FALSE)
1653 pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeFast_PSP;
1654 pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeFast_PSP;
1655 pAd->StaCfg.DefaultListenCount = 3;
1656 }
1657 else if ((strcmp(tmpbuf, "Legacy_PSP") == 0) || (strcmp(tmpbuf, "legacy_psp") == 0)
1658 || (strcmp(tmpbuf, "LEGACY_PSP") == 0))
1659 {
1660 // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
1661 // to exclude certain situations.
1662 // RTMP_SET_PSM_BIT(pAd, PWR_SAVE);
1663 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
1664 if (pAd->StaCfg.bWindowsACCAMEnable == FALSE)
1665 pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeLegacy_PSP;
1666 pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeLegacy_PSP;
1667 pAd->StaCfg.DefaultListenCount = 3;
1668 }
1669 else
1670 { //Default Ndis802_11PowerModeCAM
1671 // clear PSM bit immediately
1672 RTMP_SET_PSM_BIT(pAd, PWR_ACTIVE);
1673 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
1674 if (pAd->StaCfg.bWindowsACCAMEnable == FALSE)
1675 pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeCAM;
1676 pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeCAM;
1677 }
1678 DBGPRINT(RT_DEBUG_TRACE, ("PSMode=%ld\n", pAd->StaCfg.WindowsPowerMode));
1679 }
1680 }
1681 // AutoRoaming by RSSI
1682 if (RTMPGetKeyParameter("AutoRoaming", tmpbuf, 32, pBuffer, TRUE))
1683 {
1684 if (simple_strtol(tmpbuf, 0, 10) == 0)
1685 pAd->StaCfg.bAutoRoaming = FALSE;
1686 else
1687 pAd->StaCfg.bAutoRoaming = TRUE;
1688
1689 DBGPRINT(RT_DEBUG_TRACE, ("AutoRoaming=%d\n", pAd->StaCfg.bAutoRoaming));
1690 }
1691 // RoamThreshold
1692 if (RTMPGetKeyParameter("RoamThreshold", tmpbuf, 32, pBuffer, TRUE))
1693 {
1694 long lInfo = simple_strtol(tmpbuf, 0, 10);
1695
1696 if (lInfo > 90 || lInfo < 60)
1697 pAd->StaCfg.dBmToRoam = -70;
1698 else
1699 pAd->StaCfg.dBmToRoam = (CHAR)(-1)*lInfo;
1700
1701 DBGPRINT(RT_DEBUG_TRACE, ("RoamThreshold=%d dBm\n", pAd->StaCfg.dBmToRoam));
1702 }
1703
1704 if(RTMPGetKeyParameter("TGnWifiTest", tmpbuf, 10, pBuffer, TRUE))
1705 {
1706 if(simple_strtol(tmpbuf, 0, 10) == 0)
1707 pAd->StaCfg.bTGnWifiTest = FALSE;
1708 else
1709 pAd->StaCfg.bTGnWifiTest = TRUE;
1710 DBGPRINT(RT_DEBUG_TRACE, ("TGnWifiTest=%d\n", pAd->StaCfg.bTGnWifiTest));
1711 }
1712
1713 // Beacon Lost Time
1714 if (RTMPGetKeyParameter("BeaconLostTime", tmpbuf, 32, pBuffer, TRUE))
1715 {
1716 ULONG lInfo = (ULONG)simple_strtol(tmpbuf, 0, 10);
1717
1718 if ((lInfo != 0) && (lInfo <= 60))
1719 pAd->StaCfg.BeaconLostTime = (lInfo * OS_HZ);
1720 DBGPRINT(RT_DEBUG_TRACE, ("BeaconLostTime=%ld \n", pAd->StaCfg.BeaconLostTime));
1721 }
1722
1723
1724 }
1725
1726
1727
1728
1729 }while(0);
1730
1731
1732 kfree(tmpbuf);
1733
1734 return NDIS_STATUS_SUCCESS;
1735
1736}
diff --git a/drivers/staging/rt2860/common/cmm_sanity.c b/drivers/staging/rt2860/common/cmm_sanity.c
index 85855f7f38c..457b6d8a3ce 100644
--- a/drivers/staging/rt2860/common/cmm_sanity.c
+++ b/drivers/staging/rt2860/common/cmm_sanity.c
@@ -283,8 +283,8 @@ BOOLEAN PeerBeaconAndProbeRspSanity(
283 OUT USHORT *LengthVIE, 283 OUT USHORT *LengthVIE,
284 OUT PNDIS_802_11_VARIABLE_IEs pVIE) 284 OUT PNDIS_802_11_VARIABLE_IEs pVIE)
285{ 285{
286 CHAR *Ptr; 286 UCHAR *Ptr;
287 CHAR TimLen; 287 UCHAR TimLen;
288 PFRAME_802_11 pFrame; 288 PFRAME_802_11 pFrame;
289 PEID_STRUCT pEid; 289 PEID_STRUCT pEid;
290 UCHAR SubType; 290 UCHAR SubType;
@@ -529,10 +529,9 @@ BOOLEAN PeerBeaconAndProbeRspSanity(
529 case IE_TIM: 529 case IE_TIM:
530 if(INFRA_ON(pAd) && SubType == SUBTYPE_BEACON) 530 if(INFRA_ON(pAd) && SubType == SUBTYPE_BEACON)
531 { 531 {
532 GetTimBit((PUCHAR)pEid, pAd->StaActive.Aid, &TimLen, pBcastFlag, pDtimCount, pDtimPeriod, pMessageToMe); 532 GetTimBit((PCHAR)pEid, pAd->StaActive.Aid, &TimLen, pBcastFlag, pDtimCount, pDtimPeriod, pMessageToMe);
533 } 533 }
534 break; 534 break;
535
536 case IE_CHANNEL_SWITCH_ANNOUNCEMENT: 535 case IE_CHANNEL_SWITCH_ANNOUNCEMENT:
537 if(pEid->Len == 3) 536 if(pEid->Len == 3)
538 { 537 {
@@ -545,6 +544,26 @@ BOOLEAN PeerBeaconAndProbeRspSanity(
545 // Wifi WMM use the same IE vale, need to parse that too 544 // Wifi WMM use the same IE vale, need to parse that too
546 // case IE_WPA: 545 // case IE_WPA:
547 case IE_VENDOR_SPECIFIC: 546 case IE_VENDOR_SPECIFIC:
547 // Check Broadcom/Atheros 802.11n OUI version, for HT Capability IE.
548 // This HT IE is before IEEE draft set HT IE value.2006-09-28 by Jan.
549 /*if (NdisEqualMemory(pEid->Octet, BROADCOM_OUI, 3) && (pEid->Len >= 4))
550 {
551 if ((pEid->Octet[3] == OUI_BROADCOM_HT) && (pEid->Len >= 30))
552 {
553 {
554 NdisMoveMemory(pHtCapability, &pEid->Octet[4], sizeof(HT_CAPABILITY_IE));
555 *pHtCapabilityLen = SIZE_HT_CAP_IE; // Nnow we only support 26 bytes.
556 }
557 }
558 if ((pEid->Octet[3] == OUI_BROADCOM_HT) && (pEid->Len >= 26))
559 {
560 {
561 NdisMoveMemory(AddHtInfo, &pEid->Octet[4], sizeof(ADD_HT_INFO_IE));
562 *AddHtInfoLen = SIZE_ADD_HT_INFO_IE; // Nnow we only support 26 bytes.
563 }
564 }
565 }
566 */
548 // Check the OUI version, filter out non-standard usage 567 // Check the OUI version, filter out non-standard usage
549 if (NdisEqualMemory(pEid->Octet, RALINK_OUI, 3) && (pEid->Len == 7)) 568 if (NdisEqualMemory(pEid->Octet, RALINK_OUI, 3) && (pEid->Len == 7))
550 { 569 {
@@ -638,6 +657,8 @@ BOOLEAN PeerBeaconAndProbeRspSanity(
638 pEdcaParm->Cwmax[QID_AC_VO] = CW_MAX_IN_BITS-1; 657 pEdcaParm->Cwmax[QID_AC_VO] = CW_MAX_IN_BITS-1;
639 pEdcaParm->Txop[QID_AC_VO] = 48; // AC_VO: 48*32us ~= 1.5ms 658 pEdcaParm->Txop[QID_AC_VO] = 48; // AC_VO: 48*32us ~= 1.5ms
640 } 659 }
660
661
641 break; 662 break;
642 663
643 case IE_EXT_SUPP_RATES: 664 case IE_EXT_SUPP_RATES:
@@ -718,7 +739,7 @@ BOOLEAN PeerBeaconAndProbeRspSanity(
718 739
719 if (Sanity != 0x7) 740 if (Sanity != 0x7)
720 { 741 {
721 DBGPRINT(RT_DEBUG_WARN, ("PeerBeaconAndProbeRspSanity - missing field, Sanity=0x%02x\n", Sanity)); 742 DBGPRINT(RT_DEBUG_LOUD, ("PeerBeaconAndProbeRspSanity - missing field, Sanity=0x%02x\n", Sanity));
722 return FALSE; 743 return FALSE;
723 } 744 }
724 else 745 else
@@ -755,8 +776,6 @@ BOOLEAN MlmeScanReqSanity(
755 776
756 if ((*pBssType == BSS_INFRA || *pBssType == BSS_ADHOC || *pBssType == BSS_ANY) 777 if ((*pBssType == BSS_INFRA || *pBssType == BSS_ADHOC || *pBssType == BSS_ANY)
757 && (*pScanType == SCAN_ACTIVE || *pScanType == SCAN_PASSIVE 778 && (*pScanType == SCAN_ACTIVE || *pScanType == SCAN_PASSIVE
758 || *pScanType == SCAN_CISCO_PASSIVE || *pScanType == SCAN_CISCO_ACTIVE
759 || *pScanType == SCAN_CISCO_CHANNEL_LOAD || *pScanType == SCAN_CISCO_NOISE
760 )) 779 ))
761 { 780 {
762 return TRUE; 781 return TRUE;
@@ -837,8 +856,7 @@ BOOLEAN PeerAuthSanity(
837 NdisMoveMemory(pSeq, &pFrame->Octet[2], 2); 856 NdisMoveMemory(pSeq, &pFrame->Octet[2], 2);
838 NdisMoveMemory(pStatus, &pFrame->Octet[4], 2); 857 NdisMoveMemory(pStatus, &pFrame->Octet[4], 2);
839 858
840 if ((*pAlg == Ndis802_11AuthModeOpen) 859 if (*pAlg == AUTH_MODE_OPEN)
841 )
842 { 860 {
843 if (*pSeq == 1 || *pSeq == 2) 861 if (*pSeq == 1 || *pSeq == 2)
844 { 862 {
@@ -850,7 +868,7 @@ BOOLEAN PeerAuthSanity(
850 return FALSE; 868 return FALSE;
851 } 869 }
852 } 870 }
853 else if (*pAlg == Ndis802_11AuthModeShared) 871 else if (*pAlg == AUTH_MODE_KEY)
854 { 872 {
855 if (*pSeq == 1 || *pSeq == 4) 873 if (*pSeq == 1 || *pSeq == 4)
856 { 874 {
@@ -897,7 +915,7 @@ BOOLEAN MlmeAuthReqSanity(
897 *pTimeout = pInfo->Timeout; 915 *pTimeout = pInfo->Timeout;
898 *pAlg = pInfo->Alg; 916 *pAlg = pInfo->Alg;
899 917
900 if (((*pAlg == Ndis802_11AuthModeShared) ||(*pAlg == Ndis802_11AuthModeOpen) 918 if (((*pAlg == AUTH_MODE_KEY) ||(*pAlg == AUTH_MODE_OPEN)
901 ) && 919 ) &&
902 ((*pAddr & 0x01) == 0)) 920 ((*pAddr & 0x01) == 0))
903 { 921 {
@@ -1052,3 +1070,196 @@ NDIS_802_11_NETWORK_TYPE NetworkTypeInUseSanity(
1052 1070
1053 return NetWorkType; 1071 return NetWorkType;
1054} 1072}
1073
1074/*
1075 ==========================================================================
1076 Description:
1077 Check the validity of the received EAPoL frame
1078 Return:
1079 TRUE if all parameters are OK,
1080 FALSE otherwise
1081 ==========================================================================
1082 */
1083BOOLEAN PeerWpaMessageSanity(
1084 IN PRTMP_ADAPTER pAd,
1085 IN PEAPOL_PACKET pMsg,
1086 IN ULONG MsgLen,
1087 IN UCHAR MsgType,
1088 IN MAC_TABLE_ENTRY *pEntry)
1089{
1090 UCHAR mic[LEN_KEY_DESC_MIC], digest[80], KEYDATA[MAX_LEN_OF_RSNIE];
1091 BOOLEAN bReplayDiff = FALSE;
1092 BOOLEAN bWPA2 = FALSE;
1093 KEY_INFO EapolKeyInfo;
1094 UCHAR GroupKeyIndex = 0;
1095
1096
1097 NdisZeroMemory(mic, sizeof(mic));
1098 NdisZeroMemory(digest, sizeof(digest));
1099 NdisZeroMemory(KEYDATA, sizeof(KEYDATA));
1100 NdisZeroMemory((PUCHAR)&EapolKeyInfo, sizeof(EapolKeyInfo));
1101
1102 NdisMoveMemory((PUCHAR)&EapolKeyInfo, (PUCHAR)&pMsg->KeyDesc.KeyInfo, sizeof(KEY_INFO));
1103
1104 *((USHORT *)&EapolKeyInfo) = cpu2le16(*((USHORT *)&EapolKeyInfo));
1105
1106 // Choose WPA2 or not
1107 if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) || (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK))
1108 bWPA2 = TRUE;
1109
1110 // 0. Check MsgType
1111 if ((MsgType > EAPOL_GROUP_MSG_2) || (MsgType < EAPOL_PAIR_MSG_1))
1112 {
1113 DBGPRINT(RT_DEBUG_ERROR, ("The message type is invalid(%d)! \n", MsgType));
1114 return FALSE;
1115 }
1116
1117 // 1. Replay counter check
1118 if (MsgType == EAPOL_PAIR_MSG_1 || MsgType == EAPOL_PAIR_MSG_3 || MsgType == EAPOL_GROUP_MSG_1) // For supplicant
1119 {
1120 // First validate replay counter, only accept message with larger replay counter.
1121 // Let equal pass, some AP start with all zero replay counter
1122 UCHAR ZeroReplay[LEN_KEY_DESC_REPLAY];
1123
1124 NdisZeroMemory(ZeroReplay, LEN_KEY_DESC_REPLAY);
1125 if ((RTMPCompareMemory(pMsg->KeyDesc.ReplayCounter, pEntry->R_Counter, LEN_KEY_DESC_REPLAY) != 1) &&
1126 (RTMPCompareMemory(pMsg->KeyDesc.ReplayCounter, ZeroReplay, LEN_KEY_DESC_REPLAY) != 0))
1127 {
1128 bReplayDiff = TRUE;
1129 }
1130 }
1131 else if (MsgType == EAPOL_PAIR_MSG_2 || MsgType == EAPOL_PAIR_MSG_4 || MsgType == EAPOL_GROUP_MSG_2) // For authenticator
1132 {
1133 // check Replay Counter coresponds to MSG from authenticator, otherwise discard
1134 if (!NdisEqualMemory(pMsg->KeyDesc.ReplayCounter, pEntry->R_Counter, LEN_KEY_DESC_REPLAY))
1135 {
1136 bReplayDiff = TRUE;
1137 }
1138 }
1139
1140 // Replay Counter different condition
1141 if (bReplayDiff)
1142 {
1143 // send wireless event - for replay counter different
1144 if (pAd->CommonCfg.bWirelessEvent)
1145 RTMPSendWirelessEvent(pAd, IW_REPLAY_COUNTER_DIFF_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0);
1146
1147 if (MsgType < EAPOL_GROUP_MSG_1)
1148 {
1149 DBGPRINT(RT_DEBUG_ERROR, ("Replay Counter Different in pairwise msg %d of 4-way handshake!\n", MsgType));
1150 }
1151 else
1152 {
1153 DBGPRINT(RT_DEBUG_ERROR, ("Replay Counter Different in group msg %d of 2-way handshake!\n", (MsgType - EAPOL_PAIR_MSG_4)));
1154 }
1155
1156 hex_dump("Receive replay counter ", pMsg->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
1157 hex_dump("Current replay counter ", pEntry->R_Counter, LEN_KEY_DESC_REPLAY);
1158 return FALSE;
1159 }
1160
1161 // 2. Verify MIC except Pairwise Msg1
1162 if (MsgType != EAPOL_PAIR_MSG_1)
1163 {
1164 UCHAR rcvd_mic[LEN_KEY_DESC_MIC];
1165
1166 // Record the received MIC for check later
1167 NdisMoveMemory(rcvd_mic, pMsg->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
1168 NdisZeroMemory(pMsg->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
1169
1170 if (EapolKeyInfo.KeyDescVer == DESC_TYPE_TKIP) // TKIP
1171 {
1172 HMAC_MD5(pEntry->PTK, LEN_EAP_MICK, (PUCHAR)pMsg, MsgLen, mic, MD5_DIGEST_SIZE);
1173 }
1174 else if (EapolKeyInfo.KeyDescVer == DESC_TYPE_AES) // AES
1175 {
1176 HMAC_SHA1(pEntry->PTK, LEN_EAP_MICK, (PUCHAR)pMsg, MsgLen, digest, SHA1_DIGEST_SIZE);
1177 NdisMoveMemory(mic, digest, LEN_KEY_DESC_MIC);
1178 }
1179
1180 if (!NdisEqualMemory(rcvd_mic, mic, LEN_KEY_DESC_MIC))
1181 {
1182 // send wireless event - for MIC different
1183 if (pAd->CommonCfg.bWirelessEvent)
1184 RTMPSendWirelessEvent(pAd, IW_MIC_DIFF_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0);
1185
1186 if (MsgType < EAPOL_GROUP_MSG_1)
1187 {
1188 DBGPRINT(RT_DEBUG_ERROR, ("MIC Different in pairwise msg %d of 4-way handshake!\n", MsgType));
1189 }
1190 else
1191 {
1192 DBGPRINT(RT_DEBUG_ERROR, ("MIC Different in group msg %d of 2-way handshake!\n", (MsgType - EAPOL_PAIR_MSG_4)));
1193 }
1194
1195 hex_dump("Received MIC", rcvd_mic, LEN_KEY_DESC_MIC);
1196 hex_dump("Desired MIC", mic, LEN_KEY_DESC_MIC);
1197
1198 return FALSE;
1199 }
1200 }
1201
1202 // 1. Decrypt the Key Data field if GTK is included.
1203 // 2. Extract the context of the Key Data field if it exist.
1204 // The field in pairwise_msg_2_WPA1(WPA2) & pairwise_msg_3_WPA1 is clear.
1205 // The field in group_msg_1_WPA1(WPA2) & pairwise_msg_3_WPA2 is encrypted.
1206 if (CONV_ARRARY_TO_UINT16(pMsg->KeyDesc.KeyDataLen) > 0)
1207 {
1208 // Decrypt this field
1209 if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2) || (MsgType == EAPOL_GROUP_MSG_1))
1210 {
1211 if(
1212 (EapolKeyInfo.KeyDescVer == DESC_TYPE_AES))
1213 {
1214 // AES
1215 AES_GTK_KEY_UNWRAP(&pEntry->PTK[16], KEYDATA,
1216 CONV_ARRARY_TO_UINT16(pMsg->KeyDesc.KeyDataLen),
1217 pMsg->KeyDesc.KeyData);
1218 }
1219 else
1220 {
1221 INT i;
1222 UCHAR Key[32];
1223 // Decrypt TKIP GTK
1224 // Construct 32 bytes RC4 Key
1225 NdisMoveMemory(Key, pMsg->KeyDesc.KeyIv, 16);
1226 NdisMoveMemory(&Key[16], &pEntry->PTK[16], 16);
1227 ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, Key, 32);
1228 //discard first 256 bytes
1229 for(i = 0; i < 256; i++)
1230 ARCFOUR_BYTE(&pAd->PrivateInfo.WEPCONTEXT);
1231 // Decrypt GTK. Becareful, there is no ICV to check the result is correct or not
1232 ARCFOUR_DECRYPT(&pAd->PrivateInfo.WEPCONTEXT, KEYDATA,
1233 pMsg->KeyDesc.KeyData,
1234 CONV_ARRARY_TO_UINT16(pMsg->KeyDesc.KeyDataLen));
1235 }
1236
1237 if (!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1))
1238 GroupKeyIndex = EapolKeyInfo.KeyIndex;
1239
1240 }
1241 else if ((MsgType == EAPOL_PAIR_MSG_2) || (MsgType == EAPOL_PAIR_MSG_3 && !bWPA2))
1242 {
1243 NdisMoveMemory(KEYDATA, pMsg->KeyDesc.KeyData, CONV_ARRARY_TO_UINT16(pMsg->KeyDesc.KeyDataLen));
1244 }
1245 else
1246 {
1247
1248 return TRUE;
1249 }
1250
1251 // Parse Key Data field to
1252 // 1. verify RSN IE for pairwise_msg_2_WPA1(WPA2) ,pairwise_msg_3_WPA1(WPA2)
1253 // 2. verify KDE format for pairwise_msg_3_WPA2, group_msg_1_WPA2
1254 // 3. update shared key for pairwise_msg_3_WPA2, group_msg_1_WPA1(WPA2)
1255 if (!RTMPParseEapolKeyData(pAd, KEYDATA,
1256 CONV_ARRARY_TO_UINT16(pMsg->KeyDesc.KeyDataLen),
1257 GroupKeyIndex, MsgType, bWPA2, pEntry))
1258 {
1259 return FALSE;
1260 }
1261 }
1262
1263 return TRUE;
1264
1265}
diff --git a/drivers/staging/rt2860/common/cmm_sync.c b/drivers/staging/rt2860/common/cmm_sync.c
index a6e1b6ddfe5..4cb507dbeca 100644
--- a/drivers/staging/rt2860/common/cmm_sync.c
+++ b/drivers/staging/rt2860/common/cmm_sync.c
@@ -25,7 +25,7 @@
25 ************************************************************************* 25 *************************************************************************
26 26
27 Module Name: 27 Module Name:
28 sync.c 28 cmm_sync.c
29 29
30 Abstract: 30 Abstract:
31 31
@@ -64,11 +64,16 @@ UCHAR A_BAND_REGION_3_CHANNEL_LIST[]={52, 56, 60, 64, 149, 153, 157, 161};
64UCHAR A_BAND_REGION_4_CHANNEL_LIST[]={149, 153, 157, 161, 165}; 64UCHAR A_BAND_REGION_4_CHANNEL_LIST[]={149, 153, 157, 161, 165};
65UCHAR A_BAND_REGION_5_CHANNEL_LIST[]={149, 153, 157, 161}; 65UCHAR A_BAND_REGION_5_CHANNEL_LIST[]={149, 153, 157, 161};
66UCHAR A_BAND_REGION_6_CHANNEL_LIST[]={36, 40, 44, 48}; 66UCHAR A_BAND_REGION_6_CHANNEL_LIST[]={36, 40, 44, 48};
67UCHAR A_BAND_REGION_7_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165}; 67UCHAR A_BAND_REGION_7_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165, 169, 173};
68UCHAR A_BAND_REGION_8_CHANNEL_LIST[]={52, 56, 60, 64}; 68UCHAR A_BAND_REGION_8_CHANNEL_LIST[]={52, 56, 60, 64};
69UCHAR A_BAND_REGION_9_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165}; 69UCHAR A_BAND_REGION_9_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165};
70UCHAR A_BAND_REGION_10_CHANNEL_LIST[]={36, 40, 44, 48, 149, 153, 157, 161, 165}; 70UCHAR A_BAND_REGION_10_CHANNEL_LIST[]={36, 40, 44, 48, 149, 153, 157, 161, 165};
71UCHAR A_BAND_REGION_11_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 149, 153, 157, 161}; 71UCHAR A_BAND_REGION_11_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 149, 153, 157, 161};
72UCHAR A_BAND_REGION_12_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140};
73UCHAR A_BAND_REGION_13_CHANNEL_LIST[]={52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161};
74UCHAR A_BAND_REGION_14_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165};
75UCHAR A_BAND_REGION_15_CHANNEL_LIST[]={149, 153, 157, 161, 165, 169, 173};
76
72 77
73//BaSizeArray follows the 802.11n definition as MaxRxFactor. 2^(13+factor) bytes. When factor =0, it's about Ba buffer size =8. 78//BaSizeArray follows the 802.11n definition as MaxRxFactor. 2^(13+factor) bytes. When factor =0, it's about Ba buffer size =8.
74UCHAR BaSizeArray[4] = {8,16,32,64}; 79UCHAR BaSizeArray[4] = {8,16,32,64};
@@ -200,7 +205,22 @@ VOID BuildChannelList(
200 num = sizeof(A_BAND_REGION_11_CHANNEL_LIST)/sizeof(UCHAR); 205 num = sizeof(A_BAND_REGION_11_CHANNEL_LIST)/sizeof(UCHAR);
201 pChannelList = A_BAND_REGION_11_CHANNEL_LIST; 206 pChannelList = A_BAND_REGION_11_CHANNEL_LIST;
202 break; 207 break;
203 208 case REGION_12_A_BAND:
209 num = sizeof(A_BAND_REGION_12_CHANNEL_LIST)/sizeof(UCHAR);
210 pChannelList = A_BAND_REGION_12_CHANNEL_LIST;
211 break;
212 case REGION_13_A_BAND:
213 num = sizeof(A_BAND_REGION_13_CHANNEL_LIST)/sizeof(UCHAR);
214 pChannelList = A_BAND_REGION_13_CHANNEL_LIST;
215 break;
216 case REGION_14_A_BAND:
217 num = sizeof(A_BAND_REGION_14_CHANNEL_LIST)/sizeof(UCHAR);
218 pChannelList = A_BAND_REGION_14_CHANNEL_LIST;
219 break;
220 case REGION_15_A_BAND:
221 num = sizeof(A_BAND_REGION_15_CHANNEL_LIST)/sizeof(UCHAR);
222 pChannelList = A_BAND_REGION_15_CHANNEL_LIST;
223 break;
204 default: // Error. should never happen 224 default: // Error. should never happen
205 DBGPRINT(RT_DEBUG_WARN,("countryregion=%d not support", pAd->CommonCfg.CountryRegionForABand)); 225 DBGPRINT(RT_DEBUG_WARN,("countryregion=%d not support", pAd->CommonCfg.CountryRegionForABand));
206 break; 226 break;
@@ -383,8 +403,11 @@ VOID ScanNextChannel(
383 PHEADER_802_11 pHdr80211; 403 PHEADER_802_11 pHdr80211;
384 UINT ScanTimeIn5gChannel = SHORT_CHANNEL_TIME; 404 UINT ScanTimeIn5gChannel = SHORT_CHANNEL_TIME;
385 405
406 {
386 if (MONITOR_ON(pAd)) 407 if (MONITOR_ON(pAd))
387 return; 408 return;
409 }
410
388 411
389 if (pAd->MlmeAux.Channel == 0) 412 if (pAd->MlmeAux.Channel == 0)
390 { 413 {
@@ -409,6 +432,19 @@ VOID ScanNextChannel(
409 } 432 }
410 433
411 { 434 {
435#ifdef RT2860
436 /*
437 If all peer Ad-hoc clients leave, driver would do LinkDown and LinkUp.
438 In LinkUp, CommonCfg.Ssid would copy SSID from MlmeAux.
439 To prevent SSID is zero or wrong in Beacon, need to recover MlmeAux.SSID here.
440 */
441 if (ADHOC_ON(pAd))
442 {
443 NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
444 pAd->MlmeAux.SsidLen = pAd->CommonCfg.SsidLen;
445 NdisMoveMemory(pAd->MlmeAux.Ssid, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen);
446 }
447#endif // RT2860 //
412 // 448 //
413 // To prevent data lost. 449 // To prevent data lost.
414 // Send an NULL data with turned PSM bit on to current associated AP before SCAN progress. 450 // Send an NULL data with turned PSM bit on to current associated AP before SCAN progress.
@@ -438,29 +474,26 @@ VOID ScanNextChannel(
438 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status); 474 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status);
439 } 475 }
440 476
477
441 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS); 478 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
442 } 479 }
443#ifdef RT2870 480#ifdef RTMP_MAC_USB
444 else if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST) && (pAd->OpMode == OPMODE_STA)) 481 else if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST) && (pAd->OpMode == OPMODE_STA))
445 { 482 {
446 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE; 483 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
447 MlmeCntlConfirm(pAd, MT2_SCAN_CONF, MLME_FAIL_NO_RESOURCE); 484 MlmeCntlConfirm(pAd, MT2_SCAN_CONF, MLME_FAIL_NO_RESOURCE);
448 } 485 }
449#endif // RT2870 // 486#endif // RTMP_MAC_USB //
450 else 487 else
451 { 488 {
452 { 489 {
453 // BBP and RF are not accessible in PS mode, we has to wake them up first 490 // BBP and RF are not accessible in PS mode, we has to wake them up first
454 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) 491 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
455#ifdef RT2860
456 AsicForceWakeup(pAd, FROM_TX);
457#endif
458#ifdef RT2870
459 AsicForceWakeup(pAd, TRUE); 492 AsicForceWakeup(pAd, TRUE);
460#endif 493
461 // leave PSM during scanning. otherwise we may lost ProbeRsp & BEACON 494 // leave PSM during scanning. otherwise we may lost ProbeRsp & BEACON
462 if (pAd->StaCfg.Psm == PWR_SAVE) 495 if (pAd->StaCfg.Psm == PWR_SAVE)
463 MlmeSetPsmBit(pAd, PWR_ACTIVE); 496 RTMP_SET_PSM_BIT(pAd, PWR_ACTIVE);
464 } 497 }
465 498
466 AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, TRUE); 499 AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, TRUE);
@@ -487,16 +520,6 @@ VOID ScanNextChannel(
487 // Chnage the channel scan time for CISCO stuff based on its IAPP announcement 520 // Chnage the channel scan time for CISCO stuff based on its IAPP announcement
488 if (ScanType == FAST_SCAN_ACTIVE) 521 if (ScanType == FAST_SCAN_ACTIVE)
489 RTMPSetTimer(&pAd->MlmeAux.ScanTimer, FAST_ACTIVE_SCAN_TIME); 522 RTMPSetTimer(&pAd->MlmeAux.ScanTimer, FAST_ACTIVE_SCAN_TIME);
490 else if (((ScanType == SCAN_CISCO_ACTIVE) ||
491 (ScanType == SCAN_CISCO_PASSIVE) ||
492 (ScanType == SCAN_CISCO_CHANNEL_LOAD) ||
493 (ScanType == SCAN_CISCO_NOISE)) && (pAd->OpMode == OPMODE_STA))
494 {
495 if (pAd->StaCfg.CCXScanTime < 25)
496 RTMPSetTimer(&pAd->MlmeAux.ScanTimer, pAd->StaCfg.CCXScanTime * 2);
497 else
498 RTMPSetTimer(&pAd->MlmeAux.ScanTimer, pAd->StaCfg.CCXScanTime);
499 }
500 else // must be SCAN_PASSIVE or SCAN_ACTIVE 523 else // must be SCAN_PASSIVE or SCAN_ACTIVE
501 { 524 {
502 if ((pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED) 525 if ((pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED)
@@ -512,8 +535,9 @@ VOID ScanNextChannel(
512 RTMPSetTimer(&pAd->MlmeAux.ScanTimer, MAX_CHANNEL_TIME); 535 RTMPSetTimer(&pAd->MlmeAux.ScanTimer, MAX_CHANNEL_TIME);
513 } 536 }
514 537
515 if ((ScanType == SCAN_ACTIVE) || (ScanType == FAST_SCAN_ACTIVE) || 538 if ((ScanType == SCAN_ACTIVE)
516 (ScanType == SCAN_CISCO_ACTIVE)) 539 || (ScanType == FAST_SCAN_ACTIVE)
540 )
517 { 541 {
518 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory 542 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
519 if (NStatus != NDIS_STATUS_SUCCESS) 543 if (NStatus != NDIS_STATUS_SUCCESS)
diff --git a/drivers/staging/rt2860/common/rtmp_tkip.c b/drivers/staging/rt2860/common/cmm_tkip.c
index 4a7fda69f9b..20423e16e0c 100644
--- a/drivers/staging/rt2860/common/rtmp_tkip.c
+++ b/drivers/staging/rt2860/common/cmm_tkip.c
@@ -25,7 +25,7 @@
25 ************************************************************************* 25 *************************************************************************
26 26
27 Module Name: 27 Module Name:
28 rtmp_tkip.c 28 cmm_tkip.c
29 29
30 Abstract: 30 Abstract:
31 31
@@ -35,7 +35,7 @@
35 Paul Wu 02-25-02 Initial 35 Paul Wu 02-25-02 Initial
36*/ 36*/
37 37
38#include "../rt_config.h" 38#include "../rt_config.h"
39 39
40// Rotation functions on 32 bit values 40// Rotation functions on 32 bit values
41#define ROL32( A, n ) \ 41#define ROL32( A, n ) \
@@ -114,74 +114,6 @@ UINT Tkip_Sbox_Upper[256] =
114 0x82,0x29,0x5A,0x1E,0x7B,0xA8,0x6D,0x2C 114 0x82,0x29,0x5A,0x1E,0x7B,0xA8,0x6D,0x2C
115}; 115};
116 116
117/*****************************/
118/******** SBOX Table *********/
119/*****************************/
120
121UCHAR SboxTable[256] =
122{
123 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
124 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
125 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
126 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
127 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
128 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
129 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
130 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
131 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
132 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
133 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
134 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
135 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
136 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
137 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
138 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
139 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
140 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
141 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
142 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
143 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
144 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
145 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
146 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
147 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
148 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
149 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
150 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
151 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
152 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
153 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
154 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
155};
156
157VOID xor_32(
158 IN PUCHAR a,
159 IN PUCHAR b,
160 OUT PUCHAR out);
161
162VOID xor_128(
163 IN PUCHAR a,
164 IN PUCHAR b,
165 OUT PUCHAR out);
166
167VOID next_key(
168 IN PUCHAR key,
169 IN INT round);
170
171VOID byte_sub(
172 IN PUCHAR in,
173 OUT PUCHAR out);
174
175VOID shift_row(
176 IN PUCHAR in,
177 OUT PUCHAR out);
178
179VOID mix_column(
180 IN PUCHAR in,
181 OUT PUCHAR out);
182
183UCHAR RTMPCkipSbox(
184 IN UCHAR a);
185// 117//
186// Expanded IV for TKIP function. 118// Expanded IV for TKIP function.
187// 119//
@@ -330,7 +262,7 @@ VOID RTMPTkipSetMICKey(
330*/ 262*/
331VOID RTMPTkipAppendByte( 263VOID RTMPTkipAppendByte(
332 IN PTKIP_KEY_INFO pTkip, 264 IN PTKIP_KEY_INFO pTkip,
333 IN UCHAR uChar) 265 IN UCHAR uChar)
334{ 266{
335 // Append the byte to our word-sized buffer 267 // Append the byte to our word-sized buffer
336 pTkip->M |= (uChar << (8* pTkip->nBytesInM)); 268 pTkip->M |= (uChar << (8* pTkip->nBytesInM));
@@ -464,6 +396,7 @@ VOID RTMPInitTkipEngine(
464 tkipIv.IV16.field.rc2 = *pTSC; 396 tkipIv.IV16.field.rc2 = *pTSC;
465 tkipIv.IV16.field.CONTROL.field.ExtIV = 1; // 0: non-extended IV, 1: an extended IV 397 tkipIv.IV16.field.CONTROL.field.ExtIV = 1; // 0: non-extended IV, 1: an extended IV
466 tkipIv.IV16.field.CONTROL.field.KeyID = KeyId; 398 tkipIv.IV16.field.CONTROL.field.KeyID = KeyId;
399// tkipIv.IV32 = *(PULONG)(pTSC + 2);
467 NdisMoveMemory(&tkipIv.IV32, (pTSC + 2), 4); // Copy IV 400 NdisMoveMemory(&tkipIv.IV32, (pTSC + 2), 4); // Copy IV
468 401
469 *pIV16 = tkipIv.IV16.word; 402 *pIV16 = tkipIv.IV16.word;
@@ -581,75 +514,6 @@ BOOLEAN RTMPTkipCompareMICValue(
581 ======================================================================== 514 ========================================================================
582 515
583 Routine Description: 516 Routine Description:
584 Compare MIC value of received MSDU
585
586 Arguments:
587 pAd Pointer to our adapter
588 pLLC LLC header
589 pSrc Pointer to the received Plain text data
590 pDA Pointer to DA address
591 pSA Pointer to SA address
592 pMICKey pointer to MIC Key
593 Len the length of the received plain text data exclude MIC value
594
595 Return Value:
596 TRUE MIC value matched
597 FALSE MIC value mismatched
598
599 IRQL = DISPATCH_LEVEL
600
601 Note:
602
603 ========================================================================
604*/
605BOOLEAN RTMPTkipCompareMICValueWithLLC(
606 IN PRTMP_ADAPTER pAd,
607 IN PUCHAR pLLC,
608 IN PUCHAR pSrc,
609 IN PUCHAR pDA,
610 IN PUCHAR pSA,
611 IN PUCHAR pMICKey,
612 IN UINT Len)
613{
614 UCHAR OldMic[8];
615 ULONG Priority = 0;
616
617 // Init MIC value calculation
618 RTMPTkipSetMICKey(&pAd->PrivateInfo.Rx, pMICKey);
619 // DA
620 RTMPTkipAppend(&pAd->PrivateInfo.Rx, pDA, MAC_ADDR_LEN);
621 // SA
622 RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSA, MAC_ADDR_LEN);
623 // Priority + 3 bytes of 0
624 RTMPTkipAppend(&pAd->PrivateInfo.Rx, (PUCHAR)&Priority, 4);
625
626 // Start with LLC header
627 RTMPTkipAppend(&pAd->PrivateInfo.Rx, pLLC, 8);
628
629 // Calculate MIC value from plain text data
630 RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSrc, Len);
631
632 // Get MIC valude from received frame
633 NdisMoveMemory(OldMic, pSrc + Len, 8);
634
635 // Get MIC value from decrypted plain data
636 RTMPTkipGetMIC(&pAd->PrivateInfo.Rx);
637
638 // Move MIC value from MSDU, this steps should move to data path.
639 // Since the MIC value might cross MPDUs.
640 if(!NdisEqualMemory(pAd->PrivateInfo.Rx.MIC, OldMic, 8))
641 {
642 DBGPRINT_RAW(RT_DEBUG_ERROR, ("RTMPTkipCompareMICValueWithLLC(): TKIP MIC Error !\n")); //MIC error.
643
644
645 return (FALSE);
646 }
647 return (TRUE);
648}
649/*
650 ========================================================================
651
652 Routine Description:
653 Copy frame from waiting queue into relative ring buffer and set 517 Copy frame from waiting queue into relative ring buffer and set
654 appropriate ASIC register to kick hardware transmit function 518 appropriate ASIC register to kick hardware transmit function
655 519
@@ -865,209 +729,6 @@ VOID RTMPTkipMixKey(
865} 729}
866 730
867 731
868/************************************************/
869/* construct_mic_header1() */
870/* Builds the first MIC header block from */
871/* header fields. */
872/************************************************/
873
874void construct_mic_header1(
875 unsigned char *mic_header1,
876 int header_length,
877 unsigned char *mpdu)
878{
879 mic_header1[0] = (unsigned char)((header_length - 2) / 256);
880 mic_header1[1] = (unsigned char)((header_length - 2) % 256);
881 mic_header1[2] = mpdu[0] & 0xcf; /* Mute CF poll & CF ack bits */
882 mic_header1[3] = mpdu[1] & 0xc7; /* Mute retry, more data and pwr mgt bits */
883 mic_header1[4] = mpdu[4]; /* A1 */
884 mic_header1[5] = mpdu[5];
885 mic_header1[6] = mpdu[6];
886 mic_header1[7] = mpdu[7];
887 mic_header1[8] = mpdu[8];
888 mic_header1[9] = mpdu[9];
889 mic_header1[10] = mpdu[10]; /* A2 */
890 mic_header1[11] = mpdu[11];
891 mic_header1[12] = mpdu[12];
892 mic_header1[13] = mpdu[13];
893 mic_header1[14] = mpdu[14];
894 mic_header1[15] = mpdu[15];
895}
896
897/************************************************/
898/* construct_mic_header2() */
899/* Builds the last MIC header block from */
900/* header fields. */
901/************************************************/
902
903void construct_mic_header2(
904 unsigned char *mic_header2,
905 unsigned char *mpdu,
906 int a4_exists,
907 int qc_exists)
908{
909 int i;
910
911 for (i = 0; i<16; i++) mic_header2[i]=0x00;
912
913 mic_header2[0] = mpdu[16]; /* A3 */
914 mic_header2[1] = mpdu[17];
915 mic_header2[2] = mpdu[18];
916 mic_header2[3] = mpdu[19];
917 mic_header2[4] = mpdu[20];
918 mic_header2[5] = mpdu[21];
919
920 // In Sequence Control field, mute sequence numer bits (12-bit)
921 mic_header2[6] = mpdu[22] & 0x0f; /* SC */
922 mic_header2[7] = 0x00; /* mpdu[23]; */
923
924 if ((!qc_exists) & a4_exists)
925 {
926 for (i=0;i<6;i++) mic_header2[8+i] = mpdu[24+i]; /* A4 */
927
928 }
929
930 if (qc_exists && (!a4_exists))
931 {
932 mic_header2[8] = mpdu[24] & 0x0f; /* mute bits 15 - 4 */
933 mic_header2[9] = mpdu[25] & 0x00;
934 }
935
936 if (qc_exists && a4_exists)
937 {
938 for (i=0;i<6;i++) mic_header2[8+i] = mpdu[24+i]; /* A4 */
939
940 mic_header2[14] = mpdu[30] & 0x0f;
941 mic_header2[15] = mpdu[31] & 0x00;
942 }
943}
944
945
946/************************************************/
947/* construct_mic_iv() */
948/* Builds the MIC IV from header fields and PN */
949/************************************************/
950
951void construct_mic_iv(
952 unsigned char *mic_iv,
953 int qc_exists,
954 int a4_exists,
955 unsigned char *mpdu,
956 unsigned int payload_length,
957 unsigned char *pn_vector)
958{
959 int i;
960
961 mic_iv[0] = 0x59;
962 if (qc_exists && a4_exists)
963 mic_iv[1] = mpdu[30] & 0x0f; /* QoS_TC */
964 if (qc_exists && !a4_exists)
965 mic_iv[1] = mpdu[24] & 0x0f; /* mute bits 7-4 */
966 if (!qc_exists)
967 mic_iv[1] = 0x00;
968 for (i = 2; i < 8; i++)
969 mic_iv[i] = mpdu[i + 8]; /* mic_iv[2:7] = A2[0:5] = mpdu[10:15] */
970#ifdef CONSISTENT_PN_ORDER
971 for (i = 8; i < 14; i++)
972 mic_iv[i] = pn_vector[i - 8]; /* mic_iv[8:13] = PN[0:5] */
973#else
974 for (i = 8; i < 14; i++)
975 mic_iv[i] = pn_vector[13 - i]; /* mic_iv[8:13] = PN[5:0] */
976#endif
977 i = (payload_length / 256);
978 i = (payload_length % 256);
979 mic_iv[14] = (unsigned char) (payload_length / 256);
980 mic_iv[15] = (unsigned char) (payload_length % 256);
981
982}
983
984
985
986/************************************/
987/* bitwise_xor() */
988/* A 128 bit, bitwise exclusive or */
989/************************************/
990
991void bitwise_xor(unsigned char *ina, unsigned char *inb, unsigned char *out)
992{
993 int i;
994 for (i=0; i<16; i++)
995 {
996 out[i] = ina[i] ^ inb[i];
997 }
998}
999
1000
1001void aes128k128d(unsigned char *key, unsigned char *data, unsigned char *ciphertext)
1002{
1003 int round;
1004 int i;
1005 unsigned char intermediatea[16];
1006 unsigned char intermediateb[16];
1007 unsigned char round_key[16];
1008
1009 for(i=0; i<16; i++) round_key[i] = key[i];
1010
1011 for (round = 0; round < 11; round++)
1012 {
1013 if (round == 0)
1014 {
1015 xor_128(round_key, data, ciphertext);
1016 next_key(round_key, round);
1017 }
1018 else if (round == 10)
1019 {
1020 byte_sub(ciphertext, intermediatea);
1021 shift_row(intermediatea, intermediateb);
1022 xor_128(intermediateb, round_key, ciphertext);
1023 }
1024 else /* 1 - 9 */
1025 {
1026 byte_sub(ciphertext, intermediatea);
1027 shift_row(intermediatea, intermediateb);
1028 mix_column(&intermediateb[0], &intermediatea[0]);
1029 mix_column(&intermediateb[4], &intermediatea[4]);
1030 mix_column(&intermediateb[8], &intermediatea[8]);
1031 mix_column(&intermediateb[12], &intermediatea[12]);
1032 xor_128(intermediatea, round_key, ciphertext);
1033 next_key(round_key, round);
1034 }
1035 }
1036
1037}
1038
1039void construct_ctr_preload(
1040 unsigned char *ctr_preload,
1041 int a4_exists,
1042 int qc_exists,
1043 unsigned char *mpdu,
1044 unsigned char *pn_vector,
1045 int c)
1046{
1047
1048 int i = 0;
1049 for (i=0; i<16; i++) ctr_preload[i] = 0x00;
1050 i = 0;
1051
1052 ctr_preload[0] = 0x01; /* flag */
1053 if (qc_exists && a4_exists) ctr_preload[1] = mpdu[30] & 0x0f; /* QoC_Control */
1054 if (qc_exists && !a4_exists) ctr_preload[1] = mpdu[24] & 0x0f;
1055
1056 for (i = 2; i < 8; i++)
1057 ctr_preload[i] = mpdu[i + 8]; /* ctr_preload[2:7] = A2[0:5] = mpdu[10:15] */
1058#ifdef CONSISTENT_PN_ORDER
1059 for (i = 8; i < 14; i++)
1060 ctr_preload[i] = pn_vector[i - 8]; /* ctr_preload[8:13] = PN[0:5] */
1061#else
1062 for (i = 8; i < 14; i++)
1063 ctr_preload[i] = pn_vector[13 - i]; /* ctr_preload[8:13] = PN[5:0] */
1064#endif
1065 ctr_preload[14] = (unsigned char) (c / 256); // Ctr
1066 ctr_preload[15] = (unsigned char) (c % 256);
1067
1068}
1069
1070
1071// 732//
1072// TRUE: Success! 733// TRUE: Success!
1073// FALSE: Decrypt Error! 734// FALSE: Decrypt Error!
@@ -1102,12 +763,13 @@ BOOLEAN RTMPSoftDecryptTKIP(
1102 ULONG pnh;/* Most significant 32 bits of PN */ 763 ULONG pnh;/* Most significant 32 bits of PN */
1103 UINT num_blocks; 764 UINT num_blocks;
1104 UINT payload_remainder; 765 UINT payload_remainder;
1105 ARCFOURCONTEXT ArcFourContext; 766 ARCFOURCONTEXT ArcFourContext;
1106 UINT crc32 = 0; 767 UINT crc32 = 0;
1107 UINT trailfcs = 0; 768 UINT trailfcs = 0;
1108 UCHAR MIC[8]; 769 UCHAR MIC[8];
1109 UCHAR TrailMIC[8]; 770 UCHAR TrailMIC[8];
1110 771
772
1111 fc0 = *pData; 773 fc0 = *pData;
1112 fc1 = *(pData + 1); 774 fc1 = *(pData + 1);
1113 775
@@ -1211,376 +873,10 @@ BOOLEAN RTMPSoftDecryptTKIP(
1211 if (!NdisEqualMemory(MIC, TrailMIC, 8)) 873 if (!NdisEqualMemory(MIC, TrailMIC, 8))
1212 { 874 {
1213 DBGPRINT(RT_DEBUG_ERROR, ("RTMPSoftDecryptTKIP, WEP Data MIC Error !\n")); //MIC error. 875 DBGPRINT(RT_DEBUG_ERROR, ("RTMPSoftDecryptTKIP, WEP Data MIC Error !\n")); //MIC error.
876 //RTMPReportMicError(pAd, &pWpaKey[KeyID]); // marked by AlbertY @ 20060630
1214 return (FALSE); 877 return (FALSE);
1215 } 878 }
1216 879
880 //DBGPRINT(RT_DEBUG_TRACE, "RTMPSoftDecryptTKIP Decript done!!\n");
1217 return TRUE; 881 return TRUE;
1218} 882}
1219
1220
1221
1222
1223BOOLEAN RTMPSoftDecryptAES(
1224 IN PRTMP_ADAPTER pAd,
1225 IN PUCHAR pData,
1226 IN ULONG DataByteCnt,
1227 IN PCIPHER_KEY pWpaKey)
1228{
1229 UCHAR KeyID;
1230 UINT HeaderLen;
1231 UCHAR PN[6];
1232 UINT payload_len;
1233 UINT num_blocks;
1234 UINT payload_remainder;
1235 USHORT fc;
1236 UCHAR fc0;
1237 UCHAR fc1;
1238 UINT frame_type;
1239 UINT frame_subtype;
1240 UINT from_ds;
1241 UINT to_ds;
1242 INT a4_exists;
1243 INT qc_exists;
1244 UCHAR aes_out[16];
1245 int payload_index;
1246 UINT i;
1247 UCHAR ctr_preload[16];
1248 UCHAR chain_buffer[16];
1249 UCHAR padded_buffer[16];
1250 UCHAR mic_iv[16];
1251 UCHAR mic_header1[16];
1252 UCHAR mic_header2[16];
1253 UCHAR MIC[8];
1254 UCHAR TrailMIC[8];
1255
1256 fc0 = *pData;
1257 fc1 = *(pData + 1);
1258
1259 fc = *((PUSHORT)pData);
1260
1261 frame_type = ((fc0 >> 2) & 0x03);
1262 frame_subtype = ((fc0 >> 4) & 0x0f);
1263
1264 from_ds = (fc1 & 0x2) >> 1;
1265 to_ds = (fc1 & 0x1);
1266
1267 a4_exists = (from_ds & to_ds);
1268 qc_exists = ((frame_subtype == 0x08) || /* Assumed QoS subtypes */
1269 (frame_subtype == 0x09) || /* Likely to change. */
1270 (frame_subtype == 0x0a) ||
1271 (frame_subtype == 0x0b)
1272 );
1273
1274 HeaderLen = 24;
1275 if (a4_exists)
1276 HeaderLen += 6;
1277
1278 KeyID = *((PUCHAR)(pData+ HeaderLen + 3));
1279 KeyID = KeyID >> 6;
1280
1281 if (pWpaKey[KeyID].KeyLen == 0)
1282 {
1283 DBGPRINT(RT_DEBUG_TRACE, ("RTMPSoftDecryptAES failed!(KeyID[%d] Length can not be 0)\n", KeyID));
1284 return FALSE;
1285 }
1286
1287 PN[0] = *(pData+ HeaderLen);
1288 PN[1] = *(pData+ HeaderLen + 1);
1289 PN[2] = *(pData+ HeaderLen + 4);
1290 PN[3] = *(pData+ HeaderLen + 5);
1291 PN[4] = *(pData+ HeaderLen + 6);
1292 PN[5] = *(pData+ HeaderLen + 7);
1293
1294 payload_len = DataByteCnt - HeaderLen - 8 - 8; // 8 bytes for CCMP header , 8 bytes for MIC
1295 payload_remainder = (payload_len) % 16;
1296 num_blocks = (payload_len) / 16;
1297
1298
1299
1300 // Find start of payload
1301 payload_index = HeaderLen + 8; //IV+EIV
1302
1303 for (i=0; i< num_blocks; i++)
1304 {
1305 construct_ctr_preload(ctr_preload,
1306 a4_exists,
1307 qc_exists,
1308 pData,
1309 PN,
1310 i+1 );
1311
1312 aes128k128d(pWpaKey[KeyID].Key, ctr_preload, aes_out);
1313
1314 bitwise_xor(aes_out, pData + payload_index, chain_buffer);
1315 NdisMoveMemory(pData + payload_index - 8, chain_buffer, 16);
1316 payload_index += 16;
1317 }
1318
1319 //
1320 // If there is a short final block, then pad it
1321 // encrypt it and copy the unpadded part back
1322 //
1323 if (payload_remainder > 0)
1324 {
1325 construct_ctr_preload(ctr_preload,
1326 a4_exists,
1327 qc_exists,
1328 pData,
1329 PN,
1330 num_blocks + 1);
1331
1332 NdisZeroMemory(padded_buffer, 16);
1333 NdisMoveMemory(padded_buffer, pData + payload_index, payload_remainder);
1334
1335 aes128k128d(pWpaKey[KeyID].Key, ctr_preload, aes_out);
1336
1337 bitwise_xor(aes_out, padded_buffer, chain_buffer);
1338 NdisMoveMemory(pData + payload_index - 8, chain_buffer, payload_remainder);
1339 payload_index += payload_remainder;
1340 }
1341
1342 //
1343 // Descrypt the MIC
1344 //
1345 construct_ctr_preload(ctr_preload,
1346 a4_exists,
1347 qc_exists,
1348 pData,
1349 PN,
1350 0);
1351 NdisZeroMemory(padded_buffer, 16);
1352 NdisMoveMemory(padded_buffer, pData + payload_index, 8);
1353
1354 aes128k128d(pWpaKey[KeyID].Key, ctr_preload, aes_out);
1355
1356 bitwise_xor(aes_out, padded_buffer, chain_buffer);
1357
1358 NdisMoveMemory(TrailMIC, chain_buffer, 8);
1359
1360 //
1361 // Calculate MIC
1362 //
1363
1364 //Force the protected frame bit on
1365 *(pData + 1) = *(pData + 1) | 0x40;
1366
1367 // Find start of payload
1368 // Because the CCMP header has been removed
1369 payload_index = HeaderLen;
1370
1371 construct_mic_iv(
1372 mic_iv,
1373 qc_exists,
1374 a4_exists,
1375 pData,
1376 payload_len,
1377 PN);
1378
1379 construct_mic_header1(
1380 mic_header1,
1381 HeaderLen,
1382 pData);
1383
1384 construct_mic_header2(
1385 mic_header2,
1386 pData,
1387 a4_exists,
1388 qc_exists);
1389
1390 aes128k128d(pWpaKey[KeyID].Key, mic_iv, aes_out);
1391 bitwise_xor(aes_out, mic_header1, chain_buffer);
1392 aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
1393 bitwise_xor(aes_out, mic_header2, chain_buffer);
1394 aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
1395
1396 // iterate through each 16 byte payload block
1397 for (i = 0; i < num_blocks; i++)
1398 {
1399 bitwise_xor(aes_out, pData + payload_index, chain_buffer);
1400 payload_index += 16;
1401 aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
1402 }
1403
1404 // Add on the final payload block if it needs padding
1405 if (payload_remainder > 0)
1406 {
1407 NdisZeroMemory(padded_buffer, 16);
1408 NdisMoveMemory(padded_buffer, pData + payload_index, payload_remainder);
1409
1410 bitwise_xor(aes_out, padded_buffer, chain_buffer);
1411 aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
1412 }
1413 // aes_out contains padded mic, discard most significant
1414 // 8 bytes to generate 64 bit MIC
1415 for (i = 0 ; i < 8; i++) MIC[i] = aes_out[i];
1416
1417 if (!NdisEqualMemory(MIC, TrailMIC, 8))
1418 {
1419 DBGPRINT(RT_DEBUG_ERROR, ("RTMPSoftDecryptAES, MIC Error !\n")); //MIC error.
1420 return FALSE;
1421 }
1422
1423 return TRUE;
1424}
1425
1426/****************************************/
1427/* aes128k128d() */
1428/* Performs a 128 bit AES encrypt with */
1429/* 128 bit data. */
1430/****************************************/
1431VOID xor_128(
1432 IN PUCHAR a,
1433 IN PUCHAR b,
1434 OUT PUCHAR out)
1435{
1436 INT i;
1437
1438 for (i=0;i<16; i++)
1439 {
1440 out[i] = a[i] ^ b[i];
1441 }
1442}
1443
1444VOID next_key(
1445 IN PUCHAR key,
1446 IN INT round)
1447{
1448 UCHAR rcon;
1449 UCHAR sbox_key[4];
1450 UCHAR rcon_table[12] =
1451 {
1452 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
1453 0x1b, 0x36, 0x36, 0x36
1454 };
1455
1456 sbox_key[0] = RTMPCkipSbox(key[13]);
1457 sbox_key[1] = RTMPCkipSbox(key[14]);
1458 sbox_key[2] = RTMPCkipSbox(key[15]);
1459 sbox_key[3] = RTMPCkipSbox(key[12]);
1460
1461 rcon = rcon_table[round];
1462
1463 xor_32(&key[0], sbox_key, &key[0]);
1464 key[0] = key[0] ^ rcon;
1465
1466 xor_32(&key[4], &key[0], &key[4]);
1467 xor_32(&key[8], &key[4], &key[8]);
1468 xor_32(&key[12], &key[8], &key[12]);
1469}
1470
1471VOID xor_32(
1472 IN PUCHAR a,
1473 IN PUCHAR b,
1474 OUT PUCHAR out)
1475{
1476 INT i;
1477
1478 for (i=0;i<4; i++)
1479 {
1480 out[i] = a[i] ^ b[i];
1481 }
1482}
1483
1484VOID byte_sub(
1485 IN PUCHAR in,
1486 OUT PUCHAR out)
1487{
1488 INT i;
1489
1490 for (i=0; i< 16; i++)
1491 {
1492 out[i] = RTMPCkipSbox(in[i]);
1493 }
1494}
1495
1496UCHAR RTMPCkipSbox(
1497 IN UCHAR a)
1498{
1499 return SboxTable[(int)a];
1500}
1501
1502VOID shift_row(
1503 IN PUCHAR in,
1504 OUT PUCHAR out)
1505{
1506 out[0] = in[0];
1507 out[1] = in[5];
1508 out[2] = in[10];
1509 out[3] = in[15];
1510 out[4] = in[4];
1511 out[5] = in[9];
1512 out[6] = in[14];
1513 out[7] = in[3];
1514 out[8] = in[8];
1515 out[9] = in[13];
1516 out[10] = in[2];
1517 out[11] = in[7];
1518 out[12] = in[12];
1519 out[13] = in[1];
1520 out[14] = in[6];
1521 out[15] = in[11];
1522}
1523
1524VOID mix_column(
1525 IN PUCHAR in,
1526 OUT PUCHAR out)
1527{
1528 INT i;
1529 UCHAR add1b[4];
1530 UCHAR add1bf7[4];
1531 UCHAR rotl[4];
1532 UCHAR swap_halfs[4];
1533 UCHAR andf7[4];
1534 UCHAR rotr[4];
1535 UCHAR temp[4];
1536 UCHAR tempb[4];
1537
1538 for (i=0 ; i<4; i++)
1539 {
1540 if ((in[i] & 0x80)== 0x80)
1541 add1b[i] = 0x1b;
1542 else
1543 add1b[i] = 0x00;
1544 }
1545
1546 swap_halfs[0] = in[2]; /* Swap halfs */
1547 swap_halfs[1] = in[3];
1548 swap_halfs[2] = in[0];
1549 swap_halfs[3] = in[1];
1550
1551 rotl[0] = in[3]; /* Rotate left 8 bits */
1552 rotl[1] = in[0];
1553 rotl[2] = in[1];
1554 rotl[3] = in[2];
1555
1556 andf7[0] = in[0] & 0x7f;
1557 andf7[1] = in[1] & 0x7f;
1558 andf7[2] = in[2] & 0x7f;
1559 andf7[3] = in[3] & 0x7f;
1560
1561 for (i = 3; i>0; i--) /* logical shift left 1 bit */
1562 {
1563 andf7[i] = andf7[i] << 1;
1564 if ((andf7[i-1] & 0x80) == 0x80)
1565 {
1566 andf7[i] = (andf7[i] | 0x01);
1567 }
1568 }
1569 andf7[0] = andf7[0] << 1;
1570 andf7[0] = andf7[0] & 0xfe;
1571
1572 xor_32(add1b, andf7, add1bf7);
1573
1574 xor_32(in, add1bf7, rotr);
1575
1576 temp[0] = rotr[0]; /* Rotate right 8 bits */
1577 rotr[0] = rotr[1];
1578 rotr[1] = rotr[2];
1579 rotr[2] = rotr[3];
1580 rotr[3] = temp[0];
1581
1582 xor_32(add1bf7, rotr, temp);
1583 xor_32(swap_halfs, rotl,tempb);
1584 xor_32(temp, tempb, out);
1585}
1586
diff --git a/drivers/staging/rt2860/common/rtmp_wep.c b/drivers/staging/rt2860/common/cmm_wep.c
index 8e833e7011b..b13858d0a74 100644
--- a/drivers/staging/rt2860/common/rtmp_wep.c
+++ b/drivers/staging/rt2860/common/cmm_wep.c
@@ -35,7 +35,7 @@
35 Paul Wu 10-28-02 Initial 35 Paul Wu 10-28-02 Initial
36*/ 36*/
37 37
38#include "../rt_config.h" 38#include "../rt_config.h"
39 39
40UINT FCSTAB_32[256] = 40UINT FCSTAB_32[256] =
41{ 41{
@@ -106,6 +106,15 @@ UINT FCSTAB_32[256] =
106}; 106};
107 107
108/* 108/*
109UCHAR WEPKEY[] = {
110 //IV
111 0x00, 0x11, 0x22,
112 //WEP KEY
113 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC
114 };
115 */
116
117/*
109 ======================================================================== 118 ========================================================================
110 119
111 Routine Description: 120 Routine Description:
@@ -144,12 +153,6 @@ VOID RTMPInitWepEngine(
144 153
145 pAd->PrivateInfo.FCSCRC32 = PPPINITFCS32; //Init crc32. 154 pAd->PrivateInfo.FCSCRC32 = PPPINITFCS32; //Init crc32.
146 155
147 if (pAd->StaCfg.bCkipOn && (pAd->StaCfg.CkipFlag & 0x10) && (pAd->OpMode == OPMODE_STA))
148 {
149 ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, pKey, KeyLen); //INIT SBOX, KEYLEN+3(IV)
150 NdisMoveMemory(pDest, pKey, 3); //Append Init Vector
151 }
152 else
153 { 156 {
154 NdisMoveMemory(WEPKEY + 3, pKey, KeyLen); 157 NdisMoveMemory(WEPKEY + 3, pKey, KeyLen);
155 158
@@ -215,7 +218,7 @@ VOID RTMPEncryptData(
215 ======================================================================== 218 ========================================================================
216*/ 219*/
217BOOLEAN RTMPSoftDecryptWEP( 220BOOLEAN RTMPSoftDecryptWEP(
218 IN PRTMP_ADAPTER pAd, 221 IN PRTMP_ADAPTER pAd,
219 IN PUCHAR pData, 222 IN PUCHAR pData,
220 IN ULONG DataByteCnt, 223 IN ULONG DataByteCnt,
221 IN PCIPHER_KEY pGroupKey) 224 IN PCIPHER_KEY pGroupKey)
@@ -229,7 +232,7 @@ BOOLEAN RTMPSoftDecryptWEP(
229 //WEP KEY 232 //WEP KEY
230 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC 233 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC
231 }; 234 };
232 UCHAR *pPayload = (UCHAR *)pData + LENGTH_802_11; 235 UCHAR *pPayload = (UCHAR *)pData + LENGTH_802_11;
233 ULONG payload_len = DataByteCnt - LENGTH_802_11; 236 ULONG payload_len = DataByteCnt - LENGTH_802_11;
234 237
235 NdisMoveMemory(WEPKEY, pPayload, 3); //Get WEP IV 238 NdisMoveMemory(WEPKEY, pPayload, 3); //Get WEP IV
@@ -494,4 +497,3 @@ VOID RTMPSetICV(
494 497
495 ARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, pDest, (PUCHAR) &pAd->PrivateInfo.FCSCRC32, 4); 498 ARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, pDest, (PUCHAR) &pAd->PrivateInfo.FCSCRC32, 4);
496} 499}
497
diff --git a/drivers/staging/rt2860/common/cmm_wpa.c b/drivers/staging/rt2860/common/cmm_wpa.c
index 2de29fde2c4..5af78b84118 100644
--- a/drivers/staging/rt2860/common/cmm_wpa.c
+++ b/drivers/staging/rt2860/common/cmm_wpa.c
@@ -52,9 +52,1209 @@ UCHAR OUI_WPA2_CCMP[4] = {0x00, 0x0F, 0xAC, 0x04};
52UCHAR OUI_WPA2_8021X_AKM[4] = {0x00, 0x0F, 0xAC, 0x01}; 52UCHAR OUI_WPA2_8021X_AKM[4] = {0x00, 0x0F, 0xAC, 0x01};
53UCHAR OUI_WPA2_PSK_AKM[4] = {0x00, 0x0F, 0xAC, 0x02}; 53UCHAR OUI_WPA2_PSK_AKM[4] = {0x00, 0x0F, 0xAC, 0x02};
54UCHAR OUI_WPA2_WEP104[4] = {0x00, 0x0F, 0xAC, 0x05}; 54UCHAR OUI_WPA2_WEP104[4] = {0x00, 0x0F, 0xAC, 0x05};
55// MSA OUI 55
56UCHAR OUI_MSA_8021X_AKM[4] = {0x00, 0x0F, 0xAC, 0x05}; // Not yet final - IEEE 802.11s-D1.06 56
57UCHAR OUI_MSA_PSK_AKM[4] = {0x00, 0x0F, 0xAC, 0x06}; // Not yet final - IEEE 802.11s-D1.06 57
58static VOID ConstructEapolKeyData(
59 IN PMAC_TABLE_ENTRY pEntry,
60 IN UCHAR GroupKeyWepStatus,
61 IN UCHAR keyDescVer,
62 IN UCHAR MsgType,
63 IN UCHAR DefaultKeyIdx,
64 IN UCHAR *GTK,
65 IN UCHAR *RSNIE,
66 IN UCHAR RSNIE_LEN,
67 OUT PEAPOL_PACKET pMsg);
68
69static VOID CalculateMIC(
70 IN UCHAR KeyDescVer,
71 IN UCHAR *PTK,
72 OUT PEAPOL_PACKET pMsg);
73
74static VOID WpaEAPPacketAction(
75 IN PRTMP_ADAPTER pAd,
76 IN MLME_QUEUE_ELEM *Elem);
77
78static VOID WpaEAPOLASFAlertAction(
79 IN PRTMP_ADAPTER pAd,
80 IN MLME_QUEUE_ELEM *Elem);
81
82static VOID WpaEAPOLLogoffAction(
83 IN PRTMP_ADAPTER pAd,
84 IN MLME_QUEUE_ELEM *Elem);
85
86static VOID WpaEAPOLStartAction(
87 IN PRTMP_ADAPTER pAd,
88 IN MLME_QUEUE_ELEM *Elem);
89
90static VOID WpaEAPOLKeyAction(
91 IN PRTMP_ADAPTER pAd,
92 IN MLME_QUEUE_ELEM *Elem);
93
94/*
95 ==========================================================================
96 Description:
97 association state machine init, including state transition and timer init
98 Parameters:
99 S - pointer to the association state machine
100 ==========================================================================
101 */
102VOID WpaStateMachineInit(
103 IN PRTMP_ADAPTER pAd,
104 IN STATE_MACHINE *S,
105 OUT STATE_MACHINE_FUNC Trans[])
106{
107 StateMachineInit(S, (STATE_MACHINE_FUNC *)Trans, MAX_WPA_PTK_STATE, MAX_WPA_MSG, (STATE_MACHINE_FUNC)Drop, WPA_PTK, WPA_MACHINE_BASE);
108
109 StateMachineSetAction(S, WPA_PTK, MT2_EAPPacket, (STATE_MACHINE_FUNC)WpaEAPPacketAction);
110 StateMachineSetAction(S, WPA_PTK, MT2_EAPOLStart, (STATE_MACHINE_FUNC)WpaEAPOLStartAction);
111 StateMachineSetAction(S, WPA_PTK, MT2_EAPOLLogoff, (STATE_MACHINE_FUNC)WpaEAPOLLogoffAction);
112 StateMachineSetAction(S, WPA_PTK, MT2_EAPOLKey, (STATE_MACHINE_FUNC)WpaEAPOLKeyAction);
113 StateMachineSetAction(S, WPA_PTK, MT2_EAPOLASFAlert, (STATE_MACHINE_FUNC)WpaEAPOLASFAlertAction);
114}
115
116/*
117 ==========================================================================
118 Description:
119 this is state machine function.
120 When receiving EAP packets which is for 802.1x authentication use.
121 Not use in PSK case
122 Return:
123 ==========================================================================
124*/
125VOID WpaEAPPacketAction(
126 IN PRTMP_ADAPTER pAd,
127 IN MLME_QUEUE_ELEM *Elem)
128{
129}
130
131VOID WpaEAPOLASFAlertAction(
132 IN PRTMP_ADAPTER pAd,
133 IN MLME_QUEUE_ELEM *Elem)
134{
135}
136
137VOID WpaEAPOLLogoffAction(
138 IN PRTMP_ADAPTER pAd,
139 IN MLME_QUEUE_ELEM *Elem)
140{
141}
142
143/*
144 ==========================================================================
145 Description:
146 Start 4-way HS when rcv EAPOL_START which may create by our driver in assoc.c
147 Return:
148 ==========================================================================
149*/
150VOID WpaEAPOLStartAction(
151 IN PRTMP_ADAPTER pAd,
152 IN MLME_QUEUE_ELEM *Elem)
153{
154 MAC_TABLE_ENTRY *pEntry;
155 PHEADER_802_11 pHeader;
156
157 DBGPRINT(RT_DEBUG_TRACE, ("WpaEAPOLStartAction ===> \n"));
158
159 pHeader = (PHEADER_802_11)Elem->Msg;
160
161 //For normaol PSK, we enqueue an EAPOL-Start command to trigger the process.
162 if (Elem->MsgLen == 6)
163 pEntry = MacTableLookup(pAd, Elem->Msg);
164 else
165 {
166 pEntry = MacTableLookup(pAd, pHeader->Addr2);
167 }
168
169 if (pEntry)
170 {
171 DBGPRINT(RT_DEBUG_TRACE, (" PortSecured(%d), WpaState(%d), AuthMode(%d), PMKID_CacheIdx(%d) \n", pEntry->PortSecured, pEntry->WpaState, pEntry->AuthMode, pEntry->PMKID_CacheIdx));
172
173 if ((pEntry->PortSecured == WPA_802_1X_PORT_NOT_SECURED)
174 && (pEntry->WpaState < AS_PTKSTART)
175 && ((pEntry->AuthMode == Ndis802_11AuthModeWPAPSK) || (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK) || ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) && (pEntry->PMKID_CacheIdx != ENTRY_NOT_FOUND))))
176 {
177 pEntry->PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
178 pEntry->WpaState = AS_INITPSK;
179 pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED;
180 NdisZeroMemory(pEntry->R_Counter, sizeof(pEntry->R_Counter));
181 pEntry->ReTryCounter = PEER_MSG1_RETRY_TIMER_CTR;
182
183 WPAStart4WayHS(pAd, pEntry, PEER_MSG1_RETRY_EXEC_INTV);
184 }
185 }
186}
187
188/*
189 ==========================================================================
190 Description:
191 This is state machine function.
192 When receiving EAPOL packets which is for 802.1x key management.
193 Use both in WPA, and WPAPSK case.
194 In this function, further dispatch to different functions according to the received packet. 3 categories are :
195 1. normal 4-way pairwisekey and 2-way groupkey handshake
196 2. MIC error (Countermeasures attack) report packet from STA.
197 3. Request for pairwise/group key update from STA
198 Return:
199 ==========================================================================
200*/
201VOID WpaEAPOLKeyAction(
202 IN PRTMP_ADAPTER pAd,
203 IN MLME_QUEUE_ELEM *Elem)
204{
205 MAC_TABLE_ENTRY *pEntry;
206 PHEADER_802_11 pHeader;
207 PEAPOL_PACKET pEapol_packet;
208 KEY_INFO peerKeyInfo;
209
210 DBGPRINT(RT_DEBUG_TRACE, ("WpaEAPOLKeyAction ===>\n"));
211
212 pHeader = (PHEADER_802_11)Elem->Msg;
213 pEapol_packet = (PEAPOL_PACKET)&Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
214
215 NdisZeroMemory((PUCHAR)&peerKeyInfo, sizeof(peerKeyInfo));
216 NdisMoveMemory((PUCHAR)&peerKeyInfo, (PUCHAR)&pEapol_packet->KeyDesc.KeyInfo, sizeof(KEY_INFO));
217
218 hex_dump("Received Eapol frame", (unsigned char *)pEapol_packet, (Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H));
219
220 *((USHORT *)&peerKeyInfo) = cpu2le16(*((USHORT *)&peerKeyInfo));
221
222 do
223 {
224 pEntry = MacTableLookup(pAd, pHeader->Addr2);
225
226 if (!pEntry || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli)))
227 break;
228
229 if (pEntry->AuthMode < Ndis802_11AuthModeWPA)
230 break;
231
232 DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPoL-Key frame from STA %02X-%02X-%02X-%02X-%02X-%02X\n", PRINT_MAC(pEntry->Addr)));
233
234 if (((pEapol_packet->ProVer != EAPOL_VER) && (pEapol_packet->ProVer != EAPOL_VER2)) ||
235 ((pEapol_packet->KeyDesc.Type != WPA1_KEY_DESC) && (pEapol_packet->KeyDesc.Type != WPA2_KEY_DESC)))
236 {
237 DBGPRINT(RT_DEBUG_ERROR, ("Key descripter does not match with WPA rule\n"));
238 break;
239 }
240
241 // The value 1 shall be used for all EAPOL-Key frames to and from a STA when
242 // neither the group nor pairwise ciphers are CCMP for Key Descriptor 1.
243 if ((pEntry->WepStatus == Ndis802_11Encryption2Enabled) && (peerKeyInfo.KeyDescVer != DESC_TYPE_TKIP))
244 {
245 DBGPRINT(RT_DEBUG_ERROR, ("Key descripter version not match(TKIP) \n"));
246 break;
247 }
248 // The value 2 shall be used for all EAPOL-Key frames to and from a STA when
249 // either the pairwise or the group cipher is AES-CCMP for Key Descriptor 2.
250 else if ((pEntry->WepStatus == Ndis802_11Encryption3Enabled) && (peerKeyInfo.KeyDescVer != DESC_TYPE_AES))
251 {
252 DBGPRINT(RT_DEBUG_ERROR, ("Key descripter version not match(AES) \n"));
253 break;
254 }
255
256 // Check if this STA is in class 3 state and the WPA state is started
257 if ((pEntry->Sst == SST_ASSOC) && (pEntry->WpaState >= AS_INITPSK))
258 {
259 // Check the Key Ack (bit 7) of the Key Information to determine the Authenticator
260 // or not.
261 // An EAPOL-Key frame that is sent by the Supplicant in response to an EAPOL-
262 // Key frame from the Authenticator must not have the Ack bit set.
263 if (peerKeyInfo.KeyAck == 1)
264 {
265 // The frame is snet by Authenticator.
266 // So the Supplicant side shall handle this.
267
268 if ((peerKeyInfo.Secure == 0) && (peerKeyInfo.Request == 0) &&
269 (peerKeyInfo.Error == 0) && (peerKeyInfo.KeyType == PAIRWISEKEY))
270 {
271 // Process 1. the message 1 of 4-way HS in WPA or WPA2
272 // EAPOL-Key(0,0,1,0,P,0,0,ANonce,0,DataKD_M1)
273 // 2. the message 3 of 4-way HS in WPA
274 // EAPOL-Key(0,1,1,1,P,0,KeyRSC,ANonce,MIC,DataKD_M3)
275 if (peerKeyInfo.KeyMic == 0)
276 PeerPairMsg1Action(pAd, pEntry, Elem);
277 else
278 PeerPairMsg3Action(pAd, pEntry, Elem);
279 }
280 else if ((peerKeyInfo.Secure == 1) &&
281 (peerKeyInfo.KeyMic == 1) &&
282 (peerKeyInfo.Request == 0) &&
283 (peerKeyInfo.Error == 0))
284 {
285 // Process 1. the message 3 of 4-way HS in WPA2
286 // EAPOL-Key(1,1,1,1,P,0,KeyRSC,ANonce,MIC,DataKD_M3)
287 // 2. the message 1 of group KS in WPA or WPA2
288 // EAPOL-Key(1,1,1,0,G,0,Key RSC,0, MIC,GTK[N])
289 if (peerKeyInfo.KeyType == PAIRWISEKEY)
290 PeerPairMsg3Action(pAd, pEntry, Elem);
291 else
292 PeerGroupMsg1Action(pAd, pEntry, Elem);
293 }
294 }
295 else
296 {
297 // The frame is snet by Supplicant.
298 // So the Authenticator side shall handle this.
299 if ((peerKeyInfo.Request == 0) &&
300 (peerKeyInfo.Error == 0) &&
301 (peerKeyInfo.KeyMic == 1))
302 {
303 if (peerKeyInfo.Secure == 0 && peerKeyInfo.KeyType == PAIRWISEKEY)
304 {
305 // EAPOL-Key(0,1,0,0,P,0,0,SNonce,MIC,Data)
306 // Process 1. message 2 of 4-way HS in WPA or WPA2
307 // 2. message 4 of 4-way HS in WPA
308 if (CONV_ARRARY_TO_UINT16(pEapol_packet->KeyDesc.KeyDataLen) == 0)
309 {
310 PeerPairMsg4Action(pAd, pEntry, Elem);
311 }
312 else
313 {
314 PeerPairMsg2Action(pAd, pEntry, Elem);
315 }
316 }
317 else if (peerKeyInfo.Secure == 1 && peerKeyInfo.KeyType == PAIRWISEKEY)
318 {
319 // EAPOL-Key(1,1,0,0,P,0,0,0,MIC,0)
320 // Process message 4 of 4-way HS in WPA2
321 PeerPairMsg4Action(pAd, pEntry, Elem);
322 }
323 else if (peerKeyInfo.Secure == 1 && peerKeyInfo.KeyType == GROUPKEY)
324 {
325 // EAPOL-Key(1,1,0,0,G,0,0,0,MIC,0)
326 // Process message 2 of Group key HS in WPA or WPA2
327 PeerGroupMsg2Action(pAd, pEntry, &Elem->Msg[LENGTH_802_11], (Elem->MsgLen - LENGTH_802_11));
328 }
329 }
330 }
331 }
332 }while(FALSE);
333}
334
335/*
336 ========================================================================
337
338 Routine Description:
339 Copy frame from waiting queue into relative ring buffer and set
340 appropriate ASIC register to kick hardware encryption before really
341 sent out to air.
342
343 Arguments:
344 pAd Pointer to our adapter
345 PNDIS_PACKET Pointer to outgoing Ndis frame
346 NumberOfFrag Number of fragment required
347
348 Return Value:
349 None
350
351 Note:
352
353 ========================================================================
354*/
355VOID RTMPToWirelessSta(
356 IN PRTMP_ADAPTER pAd,
357 IN PMAC_TABLE_ENTRY pEntry,
358 IN PUCHAR pHeader802_3,
359 IN UINT HdrLen,
360 IN PUCHAR pData,
361 IN UINT DataLen,
362 IN BOOLEAN bClearFrame)
363{
364 PNDIS_PACKET pPacket;
365 NDIS_STATUS Status;
366
367 if ((!pEntry) || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli)))
368 return;
369
370 do {
371 // build a NDIS packet
372 Status = RTMPAllocateNdisPacket(pAd, &pPacket, pHeader802_3, HdrLen, pData, DataLen);
373 if (Status != NDIS_STATUS_SUCCESS)
374 break;
375
376
377 if (bClearFrame)
378 RTMP_SET_PACKET_CLEAR_EAP_FRAME(pPacket, 1);
379 else
380 RTMP_SET_PACKET_CLEAR_EAP_FRAME(pPacket, 0);
381 {
382 RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
383
384 RTMP_SET_PACKET_NET_DEVICE_MBSSID(pPacket, MAIN_MBSSID); // set a default value
385 if(pEntry->apidx != 0)
386 RTMP_SET_PACKET_NET_DEVICE_MBSSID(pPacket, pEntry->apidx);
387
388 RTMP_SET_PACKET_WCID(pPacket, (UCHAR)pEntry->Aid);
389 RTMP_SET_PACKET_MOREDATA(pPacket, FALSE);
390 }
391
392 {
393 // send out the packet
394 Status = STASendPacket(pAd, pPacket);
395 if (Status == NDIS_STATUS_SUCCESS)
396 {
397 UCHAR Index;
398
399 // Dequeue one frame from TxSwQueue0..3 queue and process it
400 // There are three place calling dequeue for TX ring.
401 // 1. Here, right after queueing the frame.
402 // 2. At the end of TxRingTxDone service routine.
403 // 3. Upon NDIS call RTMPSendPackets
404 if((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) &&
405 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)))
406 {
407 for(Index = 0; Index < 5; Index ++)
408 if(pAd->TxSwQueue[Index].Number > 0)
409 RTMPDeQueuePacket(pAd, FALSE, Index, MAX_TX_PROCESS);
410 }
411 }
412 }
413
414 } while (FALSE);
415}
416
417/*
418 ==========================================================================
419 Description:
420 This is a function to initilize 4-way handshake
421
422 Return:
423
424 ==========================================================================
425*/
426VOID WPAStart4WayHS(
427 IN PRTMP_ADAPTER pAd,
428 IN MAC_TABLE_ENTRY *pEntry,
429 IN ULONG TimeInterval)
430{
431 UCHAR Header802_3[14];
432 EAPOL_PACKET EAPOLPKT;
433 PUINT8 pBssid = NULL;
434 UCHAR group_cipher = Ndis802_11WEPDisabled;
435
436 DBGPRINT(RT_DEBUG_TRACE, ("===> WPAStart4WayHS\n"));
437
438 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_HALT_IN_PROGRESS))
439 {
440 DBGPRINT(RT_DEBUG_ERROR, ("[ERROR]WPAStart4WayHS : The interface is closed...\n"));
441 return;
442 }
443
444
445 if (pBssid == NULL)
446 {
447 DBGPRINT(RT_DEBUG_ERROR, ("[ERROR]WPAStart4WayHS : No corresponding Authenticator.\n"));
448 return;
449 }
450
451 // Check the status
452 if ((pEntry->WpaState > AS_PTKSTART) || (pEntry->WpaState < AS_INITPMK))
453 {
454 DBGPRINT(RT_DEBUG_ERROR, ("[ERROR]WPAStart4WayHS : Not expect calling\n"));
455 return;
456 }
457
458
459 // Increment replay counter by 1
460 ADD_ONE_To_64BIT_VAR(pEntry->R_Counter);
461
462 // Randomly generate ANonce
463 GenRandom(pAd, (UCHAR *)pBssid, pEntry->ANonce);
464
465 // Construct EAPoL message - Pairwise Msg 1
466 // EAPOL-Key(0,0,1,0,P,0,0,ANonce,0,DataKD_M1)
467 NdisZeroMemory(&EAPOLPKT, sizeof(EAPOL_PACKET));
468 ConstructEapolMsg(pEntry,
469 group_cipher,
470 EAPOL_PAIR_MSG_1,
471 0, // Default key index
472 pEntry->ANonce,
473 NULL, // TxRSC
474 NULL, // GTK
475 NULL, // RSNIE
476 0, // RSNIE length
477 &EAPOLPKT);
478
479
480 // Make outgoing frame
481 MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pBssid, EAPOL);
482 RTMPToWirelessSta(pAd, pEntry, Header802_3,
483 LENGTH_802_3, (PUCHAR)&EAPOLPKT,
484 CONV_ARRARY_TO_UINT16(EAPOLPKT.Body_Len) + 4,
485 (pEntry->PortSecured == WPA_802_1X_PORT_SECURED) ? FALSE : TRUE);
486
487 // Trigger Retry Timer
488 RTMPModTimer(&pEntry->RetryTimer, TimeInterval);
489
490 // Update State
491 pEntry->WpaState = AS_PTKSTART;
492
493 DBGPRINT(RT_DEBUG_TRACE, ("<=== WPAStart4WayHS: send Msg1 of 4-way \n"));
494
495}
496
497/*
498 ========================================================================
499
500 Routine Description:
501 Process Pairwise key Msg-1 of 4-way handshaking and send Msg-2
502
503 Arguments:
504 pAd Pointer to our adapter
505 Elem Message body
506
507 Return Value:
508 None
509
510 Note:
511
512 ========================================================================
513*/
514VOID PeerPairMsg1Action(
515 IN PRTMP_ADAPTER pAd,
516 IN MAC_TABLE_ENTRY *pEntry,
517 IN MLME_QUEUE_ELEM *Elem)
518{
519 UCHAR PTK[80];
520 UCHAR Header802_3[14];
521 PEAPOL_PACKET pMsg1;
522 UINT MsgLen;
523 EAPOL_PACKET EAPOLPKT;
524 PUINT8 pCurrentAddr = NULL;
525 PUINT8 pmk_ptr = NULL;
526 UCHAR group_cipher = Ndis802_11WEPDisabled;
527 PUINT8 rsnie_ptr = NULL;
528 UCHAR rsnie_len = 0;
529
530 DBGPRINT(RT_DEBUG_TRACE, ("===> PeerPairMsg1Action \n"));
531
532 if ((!pEntry) || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli)))
533 return;
534
535 if (Elem->MsgLen < (LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H + sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE - 2))
536 return;
537
538 {
539 pCurrentAddr = pAd->CurrentAddress;
540 pmk_ptr = pAd->StaCfg.PMK;
541 group_cipher = pAd->StaCfg.GroupCipher;
542 rsnie_ptr = pAd->StaCfg.RSN_IE;
543 rsnie_len = pAd->StaCfg.RSNIE_Len;
544 }
545
546 // Store the received frame
547 pMsg1 = (PEAPOL_PACKET) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
548 MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H;
549
550 // Sanity Check peer Pairwise message 1 - Replay Counter
551 if (PeerWpaMessageSanity(pAd, pMsg1, MsgLen, EAPOL_PAIR_MSG_1, pEntry) == FALSE)
552 return;
553
554 // Store Replay counter, it will use to verify message 3 and construct message 2
555 NdisMoveMemory(pEntry->R_Counter, pMsg1->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
556
557 // Store ANonce
558 NdisMoveMemory(pEntry->ANonce, pMsg1->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE);
559
560 // Generate random SNonce
561 GenRandom(pAd, (UCHAR *)pCurrentAddr, pEntry->SNonce);
562
563 {
564 // Calculate PTK(ANonce, SNonce)
565 WpaDerivePTK(pAd,
566 pmk_ptr,
567 pEntry->ANonce,
568 pEntry->Addr,
569 pEntry->SNonce,
570 pCurrentAddr,
571 PTK,
572 LEN_PTK);
573
574 // Save key to PTK entry
575 NdisMoveMemory(pEntry->PTK, PTK, LEN_PTK);
576 }
577
578 // Update WpaState
579 pEntry->WpaState = AS_PTKINIT_NEGOTIATING;
580
581 // Construct EAPoL message - Pairwise Msg 2
582 // EAPOL-Key(0,1,0,0,P,0,0,SNonce,MIC,DataKD_M2)
583 NdisZeroMemory(&EAPOLPKT, sizeof(EAPOL_PACKET));
584 ConstructEapolMsg(pEntry,
585 group_cipher,
586 EAPOL_PAIR_MSG_2,
587 0, // DefaultKeyIdx
588 pEntry->SNonce,
589 NULL, // TxRsc
590 NULL, // GTK
591 (UCHAR *)rsnie_ptr,
592 rsnie_len,
593 &EAPOLPKT);
594
595 // Make outgoing frame
596 MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pCurrentAddr, EAPOL);
597
598 RTMPToWirelessSta(pAd, pEntry,
599 Header802_3, sizeof(Header802_3), (PUCHAR)&EAPOLPKT,
600 CONV_ARRARY_TO_UINT16(EAPOLPKT.Body_Len) + 4, TRUE);
601
602 DBGPRINT(RT_DEBUG_TRACE, ("<=== PeerPairMsg1Action: send Msg2 of 4-way \n"));
603}
604
605
606/*
607 ==========================================================================
608 Description:
609 When receiving the second packet of 4-way pairwisekey handshake.
610 Return:
611 ==========================================================================
612*/
613VOID PeerPairMsg2Action(
614 IN PRTMP_ADAPTER pAd,
615 IN MAC_TABLE_ENTRY *pEntry,
616 IN MLME_QUEUE_ELEM *Elem)
617{
618 UCHAR PTK[80];
619 BOOLEAN Cancelled;
620 PHEADER_802_11 pHeader;
621 EAPOL_PACKET EAPOLPKT;
622 PEAPOL_PACKET pMsg2;
623 UINT MsgLen;
624 UCHAR Header802_3[LENGTH_802_3];
625 UCHAR TxTsc[6];
626 PUINT8 pBssid = NULL;
627 PUINT8 pmk_ptr = NULL;
628 PUINT8 gtk_ptr = NULL;
629 UCHAR default_key = 0;
630 UCHAR group_cipher = Ndis802_11WEPDisabled;
631 PUINT8 rsnie_ptr = NULL;
632 UCHAR rsnie_len = 0;
633
634 DBGPRINT(RT_DEBUG_TRACE, ("===> PeerPairMsg2Action \n"));
635
636 if ((!pEntry) || (!pEntry->ValidAsCLI))
637 return;
638
639 if (Elem->MsgLen < (LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H + sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE - 2))
640 return;
641
642 // check Entry in valid State
643 if (pEntry->WpaState < AS_PTKSTART)
644 return;
645
646
647
648 // pointer to 802.11 header
649 pHeader = (PHEADER_802_11)Elem->Msg;
650
651 // skip 802.11_header(24-byte) and LLC_header(8)
652 pMsg2 = (PEAPOL_PACKET)&Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
653 MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H;
654
655 // Store SNonce
656 NdisMoveMemory(pEntry->SNonce, pMsg2->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE);
657
658 {
659 // Derive PTK
660 WpaDerivePTK(pAd,
661 (UCHAR *)pmk_ptr,
662 pEntry->ANonce, // ANONCE
663 (UCHAR *)pBssid,
664 pEntry->SNonce, // SNONCE
665 pEntry->Addr,
666 PTK,
667 LEN_PTK);
668
669 NdisMoveMemory(pEntry->PTK, PTK, LEN_PTK);
670 }
671
672 // Sanity Check peer Pairwise message 2 - Replay Counter, MIC, RSNIE
673 if (PeerWpaMessageSanity(pAd, pMsg2, MsgLen, EAPOL_PAIR_MSG_2, pEntry) == FALSE)
674 return;
675
676 do
677 {
678 // delete retry timer
679 RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled);
680
681 // Change state
682 pEntry->WpaState = AS_PTKINIT_NEGOTIATING;
683
684 // Increment replay counter by 1
685 ADD_ONE_To_64BIT_VAR(pEntry->R_Counter);
686
687 // Construct EAPoL message - Pairwise Msg 3
688 NdisZeroMemory(&EAPOLPKT, sizeof(EAPOL_PACKET));
689 ConstructEapolMsg(pEntry,
690 group_cipher,
691 EAPOL_PAIR_MSG_3,
692 default_key,
693 pEntry->ANonce,
694 TxTsc,
695 (UCHAR *)gtk_ptr,
696 (UCHAR *)rsnie_ptr,
697 rsnie_len,
698 &EAPOLPKT);
699
700 // Make outgoing frame
701 MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pBssid, EAPOL);
702 RTMPToWirelessSta(pAd, pEntry, Header802_3, LENGTH_802_3,
703 (PUCHAR)&EAPOLPKT,
704 CONV_ARRARY_TO_UINT16(EAPOLPKT.Body_Len) + 4,
705 (pEntry->PortSecured == WPA_802_1X_PORT_SECURED) ? FALSE : TRUE);
706
707 pEntry->ReTryCounter = PEER_MSG3_RETRY_TIMER_CTR;
708 RTMPSetTimer(&pEntry->RetryTimer, PEER_MSG3_RETRY_EXEC_INTV);
709
710 // Update State
711 pEntry->WpaState = AS_PTKINIT_NEGOTIATING;
712 }while(FALSE);
713
714 DBGPRINT(RT_DEBUG_TRACE, ("<=== PeerPairMsg2Action: send Msg3 of 4-way \n"));
715}
716
717/*
718 ========================================================================
719
720 Routine Description:
721 Process Pairwise key Msg 3 of 4-way handshaking and send Msg 4
722
723 Arguments:
724 pAd Pointer to our adapter
725 Elem Message body
726
727 Return Value:
728 None
729
730 Note:
731
732 ========================================================================
733*/
734VOID PeerPairMsg3Action(
735 IN PRTMP_ADAPTER pAd,
736 IN MAC_TABLE_ENTRY *pEntry,
737 IN MLME_QUEUE_ELEM *Elem)
738{
739 PHEADER_802_11 pHeader;
740 UCHAR Header802_3[14];
741 EAPOL_PACKET EAPOLPKT;
742 PEAPOL_PACKET pMsg3;
743 UINT MsgLen;
744 PUINT8 pCurrentAddr = NULL;
745 UCHAR group_cipher = Ndis802_11WEPDisabled;
746
747 DBGPRINT(RT_DEBUG_TRACE, ("===> PeerPairMsg3Action \n"));
748
749 if ((!pEntry) || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli)))
750 return;
751
752 if (Elem->MsgLen < (LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H + sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE - 2))
753 return;
754
755 {
756 pCurrentAddr = pAd->CurrentAddress;
757 group_cipher = pAd->StaCfg.GroupCipher;
758
759 }
760
761 // Record 802.11 header & the received EAPOL packet Msg3
762 pHeader = (PHEADER_802_11) Elem->Msg;
763 pMsg3 = (PEAPOL_PACKET) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
764 MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H;
765
766 // Sanity Check peer Pairwise message 3 - Replay Counter, MIC, RSNIE
767 if (PeerWpaMessageSanity(pAd, pMsg3, MsgLen, EAPOL_PAIR_MSG_3, pEntry) == FALSE)
768 return;
769
770 // Save Replay counter, it will use construct message 4
771 NdisMoveMemory(pEntry->R_Counter, pMsg3->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
772
773 // Double check ANonce
774 if (!NdisEqualMemory(pEntry->ANonce, pMsg3->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE))
775 {
776 return;
777 }
778
779 // Construct EAPoL message - Pairwise Msg 4
780 NdisZeroMemory(&EAPOLPKT, sizeof(EAPOL_PACKET));
781 ConstructEapolMsg(pEntry,
782 group_cipher,
783 EAPOL_PAIR_MSG_4,
784 0, // group key index not used in message 4
785 NULL, // Nonce not used in message 4
786 NULL, // TxRSC not used in message 4
787 NULL, // GTK not used in message 4
788 NULL, // RSN IE not used in message 4
789 0,
790 &EAPOLPKT);
791
792 // Update WpaState
793 pEntry->WpaState = AS_PTKINITDONE;
794
795 // Update pairwise key
796 {
797 PCIPHER_KEY pSharedKey;
798
799 pSharedKey = &pAd->SharedKey[BSS0][0];
800
801 NdisMoveMemory(pAd->StaCfg.PTK, pEntry->PTK, LEN_PTK);
802
803 // Prepare pair-wise key information into shared key table
804 NdisZeroMemory(pSharedKey, sizeof(CIPHER_KEY));
805 pSharedKey->KeyLen = LEN_TKIP_EK;
806 NdisMoveMemory(pSharedKey->Key, &pAd->StaCfg.PTK[32], LEN_TKIP_EK);
807 NdisMoveMemory(pSharedKey->RxMic, &pAd->StaCfg.PTK[48], LEN_TKIP_RXMICK);
808 NdisMoveMemory(pSharedKey->TxMic, &pAd->StaCfg.PTK[48+LEN_TKIP_RXMICK], LEN_TKIP_TXMICK);
809
810 // Decide its ChiperAlg
811 if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
812 pSharedKey->CipherAlg = CIPHER_TKIP;
813 else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
814 pSharedKey->CipherAlg = CIPHER_AES;
815 else
816 pSharedKey->CipherAlg = CIPHER_NONE;
817
818 // Update these related information to MAC_TABLE_ENTRY
819 pEntry = &pAd->MacTab.Content[BSSID_WCID];
820 NdisMoveMemory(pEntry->PairwiseKey.Key, &pAd->StaCfg.PTK[32], LEN_TKIP_EK);
821 NdisMoveMemory(pEntry->PairwiseKey.RxMic, &pAd->StaCfg.PTK[48], LEN_TKIP_RXMICK);
822 NdisMoveMemory(pEntry->PairwiseKey.TxMic, &pAd->StaCfg.PTK[48+LEN_TKIP_RXMICK], LEN_TKIP_TXMICK);
823 pEntry->PairwiseKey.CipherAlg = pSharedKey->CipherAlg;
824
825 // Update pairwise key information to ASIC Shared Key Table
826 AsicAddSharedKeyEntry(pAd,
827 BSS0,
828 0,
829 pSharedKey->CipherAlg,
830 pSharedKey->Key,
831 pSharedKey->TxMic,
832 pSharedKey->RxMic);
833
834 // Update ASIC WCID attribute table and IVEIV table
835 RTMPAddWcidAttributeEntry(pAd,
836 BSS0,
837 0,
838 pSharedKey->CipherAlg,
839 pEntry);
840
841 }
842
843 // open 802.1x port control and privacy filter
844 if (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK ||
845 pEntry->AuthMode == Ndis802_11AuthModeWPA2)
846 {
847 pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
848 pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
849
850 STA_PORT_SECURED(pAd);
851 // Indicate Connected for GUI
852 pAd->IndicateMediaState = NdisMediaStateConnected;
853 DBGPRINT(RT_DEBUG_TRACE, ("PeerPairMsg3Action: AuthMode(%s) PairwiseCipher(%s) GroupCipher(%s) \n",
854 GetAuthMode(pEntry->AuthMode),
855 GetEncryptType(pEntry->WepStatus),
856 GetEncryptType(group_cipher)));
857 }
858 else
859 {
860 }
861
862 // Init 802.3 header and send out
863 MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pCurrentAddr, EAPOL);
864 RTMPToWirelessSta(pAd, pEntry,
865 Header802_3, sizeof(Header802_3),
866 (PUCHAR)&EAPOLPKT,
867 CONV_ARRARY_TO_UINT16(EAPOLPKT.Body_Len) + 4, TRUE);
868
869 DBGPRINT(RT_DEBUG_TRACE, ("<=== PeerPairMsg3Action: send Msg4 of 4-way \n"));
870}
871
872/*
873 ==========================================================================
874 Description:
875 When receiving the last packet of 4-way pairwisekey handshake.
876 Initilize 2-way groupkey handshake following.
877 Return:
878 ==========================================================================
879*/
880VOID PeerPairMsg4Action(
881 IN PRTMP_ADAPTER pAd,
882 IN MAC_TABLE_ENTRY *pEntry,
883 IN MLME_QUEUE_ELEM *Elem)
884{
885 PEAPOL_PACKET pMsg4;
886 PHEADER_802_11 pHeader;
887 UINT MsgLen;
888 BOOLEAN Cancelled;
889 UCHAR group_cipher = Ndis802_11WEPDisabled;
890
891 DBGPRINT(RT_DEBUG_TRACE, ("===> PeerPairMsg4Action\n"));
892
893 do
894 {
895 if ((!pEntry) || (!pEntry->ValidAsCLI))
896 break;
897
898 if (Elem->MsgLen < (LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H + sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE - 2 ) )
899 break;
900
901 if (pEntry->WpaState < AS_PTKINIT_NEGOTIATING)
902 break;
903
904
905 // pointer to 802.11 header
906 pHeader = (PHEADER_802_11)Elem->Msg;
907
908 // skip 802.11_header(24-byte) and LLC_header(8)
909 pMsg4 = (PEAPOL_PACKET)&Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
910 MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H;
911
912 // Sanity Check peer Pairwise message 4 - Replay Counter, MIC
913 if (PeerWpaMessageSanity(pAd, pMsg4, MsgLen, EAPOL_PAIR_MSG_4, pEntry) == FALSE)
914 break;
915
916 // 3. uses the MLME.SETKEYS.request to configure PTK into MAC
917 NdisZeroMemory(&pEntry->PairwiseKey, sizeof(CIPHER_KEY));
918
919 // reset IVEIV in Asic
920 AsicUpdateWCIDIVEIV(pAd, pEntry->Aid, 1, 0);
921
922 pEntry->PairwiseKey.KeyLen = LEN_TKIP_EK;
923 NdisMoveMemory(pEntry->PairwiseKey.Key, &pEntry->PTK[32], LEN_TKIP_EK);
924 NdisMoveMemory(pEntry->PairwiseKey.RxMic, &pEntry->PTK[TKIP_AP_RXMICK_OFFSET], LEN_TKIP_RXMICK);
925 NdisMoveMemory(pEntry->PairwiseKey.TxMic, &pEntry->PTK[TKIP_AP_TXMICK_OFFSET], LEN_TKIP_TXMICK);
926
927 // Set pairwise key to Asic
928 {
929 pEntry->PairwiseKey.CipherAlg = CIPHER_NONE;
930 if (pEntry->WepStatus == Ndis802_11Encryption2Enabled)
931 pEntry->PairwiseKey.CipherAlg = CIPHER_TKIP;
932 else if (pEntry->WepStatus == Ndis802_11Encryption3Enabled)
933 pEntry->PairwiseKey.CipherAlg = CIPHER_AES;
934
935 // Add Pair-wise key to Asic
936 AsicAddPairwiseKeyEntry(
937 pAd,
938 pEntry->Addr,
939 (UCHAR)pEntry->Aid,
940 &pEntry->PairwiseKey);
941
942 // update WCID attribute table and IVEIV table for this entry
943 RTMPAddWcidAttributeEntry(
944 pAd,
945 pEntry->apidx,
946 0,
947 pEntry->PairwiseKey.CipherAlg,
948 pEntry);
949 }
950
951 // 4. upgrade state
952 pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
953 pEntry->WpaState = AS_PTKINITDONE;
954 pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
955
956
957 if (pEntry->AuthMode == Ndis802_11AuthModeWPA2 ||
958 pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK)
959 {
960 pEntry->GTKState = REKEY_ESTABLISHED;
961 RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled);
962
963
964 // send wireless event - for set key done WPA2
965 if (pAd->CommonCfg.bWirelessEvent)
966 RTMPSendWirelessEvent(pAd, IW_SET_KEY_DONE_WPA2_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0);
967
968 DBGPRINT(RT_DEBUG_OFF, ("AP SETKEYS DONE - WPA2, AuthMode(%d)=%s, WepStatus(%d)=%s, GroupWepStatus(%d)=%s\n\n",
969 pEntry->AuthMode, GetAuthMode(pEntry->AuthMode),
970 pEntry->WepStatus, GetEncryptType(pEntry->WepStatus),
971 group_cipher,
972 GetEncryptType(group_cipher)));
973 }
974 else
975 {
976 // 5. init Group 2-way handshake if necessary.
977 WPAStart2WayGroupHS(pAd, pEntry);
978
979 pEntry->ReTryCounter = GROUP_MSG1_RETRY_TIMER_CTR;
980 RTMPModTimer(&pEntry->RetryTimer, PEER_MSG3_RETRY_EXEC_INTV);
981 }
982 }while(FALSE);
983
984}
985
986/*
987 ==========================================================================
988 Description:
989 This is a function to send the first packet of 2-way groupkey handshake
990 Return:
991
992 ==========================================================================
993*/
994VOID WPAStart2WayGroupHS(
995 IN PRTMP_ADAPTER pAd,
996 IN MAC_TABLE_ENTRY *pEntry)
997{
998 UCHAR Header802_3[14];
999 UCHAR TxTsc[6];
1000 EAPOL_PACKET EAPOLPKT;
1001 UCHAR group_cipher = Ndis802_11WEPDisabled;
1002 UCHAR default_key = 0;
1003 PUINT8 gnonce_ptr = NULL;
1004 PUINT8 gtk_ptr = NULL;
1005 PUINT8 pBssid = NULL;
1006
1007 DBGPRINT(RT_DEBUG_TRACE, ("===> WPAStart2WayGroupHS\n"));
1008
1009 if ((!pEntry) || (!pEntry->ValidAsCLI))
1010 return;
1011
1012
1013 do
1014 {
1015 // Increment replay counter by 1
1016 ADD_ONE_To_64BIT_VAR(pEntry->R_Counter);
1017
1018 // Construct EAPoL message - Group Msg 1
1019 NdisZeroMemory(&EAPOLPKT, sizeof(EAPOL_PACKET));
1020 ConstructEapolMsg(pEntry,
1021 group_cipher,
1022 EAPOL_GROUP_MSG_1,
1023 default_key,
1024 (UCHAR *)gnonce_ptr,
1025 TxTsc,
1026 (UCHAR *)gtk_ptr,
1027 NULL,
1028 0,
1029 &EAPOLPKT);
1030
1031 // Make outgoing frame
1032 MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pBssid, EAPOL);
1033 RTMPToWirelessSta(pAd, pEntry,
1034 Header802_3, LENGTH_802_3,
1035 (PUCHAR)&EAPOLPKT,
1036 CONV_ARRARY_TO_UINT16(EAPOLPKT.Body_Len) + 4, FALSE);
1037
1038
1039
1040 }while (FALSE);
1041
1042 DBGPRINT(RT_DEBUG_TRACE, ("<=== WPAStart2WayGroupHS : send out Group Message 1 \n"));
1043
1044 return;
1045}
1046
1047/*
1048 ========================================================================
1049
1050 Routine Description:
1051 Process Group key 2-way handshaking
1052
1053 Arguments:
1054 pAd Pointer to our adapter
1055 Elem Message body
1056
1057 Return Value:
1058 None
1059
1060 Note:
1061
1062 ========================================================================
1063*/
1064VOID PeerGroupMsg1Action(
1065 IN PRTMP_ADAPTER pAd,
1066 IN MAC_TABLE_ENTRY *pEntry,
1067 IN MLME_QUEUE_ELEM *Elem)
1068{
1069 UCHAR Header802_3[14];
1070 EAPOL_PACKET EAPOLPKT;
1071 PEAPOL_PACKET pGroup;
1072 UINT MsgLen;
1073 BOOLEAN Cancelled;
1074 UCHAR default_key = 0;
1075 UCHAR group_cipher = Ndis802_11WEPDisabled;
1076 PUINT8 pCurrentAddr = NULL;
1077
1078 DBGPRINT(RT_DEBUG_TRACE, ("===> PeerGroupMsg1Action \n"));
1079
1080 if ((!pEntry) || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli)))
1081 return;
1082
1083 {
1084 pCurrentAddr = pAd->CurrentAddress;
1085 group_cipher = pAd->StaCfg.GroupCipher;
1086 default_key = pAd->StaCfg.DefaultKeyId;
1087 }
1088
1089 // Process Group Message 1 frame. skip 802.11 header(24) & LLC_SNAP header(8)
1090 pGroup = (PEAPOL_PACKET) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
1091 MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H;
1092
1093 // Sanity Check peer group message 1 - Replay Counter, MIC, RSNIE
1094 if (PeerWpaMessageSanity(pAd, pGroup, MsgLen, EAPOL_GROUP_MSG_1, pEntry) == FALSE)
1095 return;
1096
1097 // delete retry timer
1098 RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled);
1099
1100 // Save Replay counter, it will use to construct message 2
1101 NdisMoveMemory(pEntry->R_Counter, pGroup->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
1102
1103 // Construct EAPoL message - Group Msg 2
1104 NdisZeroMemory(&EAPOLPKT, sizeof(EAPOL_PACKET));
1105 ConstructEapolMsg(pEntry,
1106 group_cipher,
1107 EAPOL_GROUP_MSG_2,
1108 default_key,
1109 NULL, // Nonce not used
1110 NULL, // TxRSC not used
1111 NULL, // GTK not used
1112 NULL, // RSN IE not used
1113 0,
1114 &EAPOLPKT);
1115
1116 // open 802.1x port control and privacy filter
1117 pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
1118 pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
1119
1120 STA_PORT_SECURED(pAd);
1121 // Indicate Connected for GUI
1122 pAd->IndicateMediaState = NdisMediaStateConnected;
1123
1124 DBGPRINT(RT_DEBUG_TRACE, ("PeerGroupMsg1Action: AuthMode(%s) PairwiseCipher(%s) GroupCipher(%s) \n",
1125 GetAuthMode(pEntry->AuthMode),
1126 GetEncryptType(pEntry->WepStatus),
1127 GetEncryptType(group_cipher)));
1128
1129 // init header and Fill Packet and send Msg 2 to authenticator
1130 MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pCurrentAddr, EAPOL);
1131 RTMPToWirelessSta(pAd, pEntry,
1132 Header802_3, sizeof(Header802_3),
1133 (PUCHAR)&EAPOLPKT,
1134 CONV_ARRARY_TO_UINT16(EAPOLPKT.Body_Len) + 4, FALSE);
1135
1136 DBGPRINT(RT_DEBUG_TRACE, ("<=== PeerGroupMsg1Action: sned group message 2\n"));
1137}
1138
1139/*
1140 ==========================================================================
1141 Description:
1142 When receiving the last packet of 2-way groupkey handshake.
1143 Return:
1144 ==========================================================================
1145*/
1146VOID PeerGroupMsg2Action(
1147 IN PRTMP_ADAPTER pAd,
1148 IN MAC_TABLE_ENTRY *pEntry,
1149 IN VOID *Msg,
1150 IN UINT MsgLen)
1151{
1152 UINT Len;
1153 PUCHAR pData;
1154 BOOLEAN Cancelled;
1155 PEAPOL_PACKET pMsg2;
1156 UCHAR group_cipher = Ndis802_11WEPDisabled;
1157
1158 DBGPRINT(RT_DEBUG_TRACE, ("===> PeerGroupMsg2Action \n"));
1159
1160 do
1161 {
1162 if ((!pEntry) || (!pEntry->ValidAsCLI))
1163 break;
1164
1165 if (MsgLen < (LENGTH_802_1_H + LENGTH_EAPOL_H + sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE - 2))
1166 break;
1167
1168 if (pEntry->WpaState != AS_PTKINITDONE)
1169 break;
1170
1171
1172 pData = (PUCHAR)Msg;
1173 pMsg2 = (PEAPOL_PACKET) (pData + LENGTH_802_1_H);
1174 Len = MsgLen - LENGTH_802_1_H;
1175
1176 // Sanity Check peer group message 2 - Replay Counter, MIC
1177 if (PeerWpaMessageSanity(pAd, pMsg2, Len, EAPOL_GROUP_MSG_2, pEntry) == FALSE)
1178 break;
1179
1180 // 3. upgrade state
1181
1182 RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled);
1183 pEntry->GTKState = REKEY_ESTABLISHED;
1184
1185 if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) || (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK))
1186 {
1187 // send wireless event - for set key done WPA2
1188 if (pAd->CommonCfg.bWirelessEvent)
1189 RTMPSendWirelessEvent(pAd, IW_SET_KEY_DONE_WPA2_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0);
1190
1191 DBGPRINT(RT_DEBUG_OFF, ("AP SETKEYS DONE - WPA2, AuthMode(%d)=%s, WepStatus(%d)=%s, GroupWepStatus(%d)=%s\n\n",
1192 pEntry->AuthMode, GetAuthMode(pEntry->AuthMode),
1193 pEntry->WepStatus, GetEncryptType(pEntry->WepStatus),
1194 group_cipher, GetEncryptType(group_cipher)));
1195 }
1196 else
1197 {
1198 // send wireless event - for set key done WPA
1199 if (pAd->CommonCfg.bWirelessEvent)
1200 RTMPSendWirelessEvent(pAd, IW_SET_KEY_DONE_WPA1_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0);
1201
1202 DBGPRINT(RT_DEBUG_OFF, ("AP SETKEYS DONE - WPA1, AuthMode(%d)=%s, WepStatus(%d)=%s, GroupWepStatus(%d)=%s\n\n",
1203 pEntry->AuthMode, GetAuthMode(pEntry->AuthMode),
1204 pEntry->WepStatus, GetEncryptType(pEntry->WepStatus),
1205 group_cipher, GetEncryptType(group_cipher)));
1206 }
1207 }while(FALSE);
1208}
1209
1210/*
1211 ========================================================================
1212
1213 Routine Description:
1214 Classify WPA EAP message type
1215
1216 Arguments:
1217 EAPType Value of EAP message type
1218 MsgType Internal Message definition for MLME state machine
1219
1220 Return Value:
1221 TRUE Found appropriate message type
1222 FALSE No appropriate message type
1223
1224 IRQL = DISPATCH_LEVEL
1225
1226 Note:
1227 All these constants are defined in wpa.h
1228 For supplicant, there is only EAPOL Key message avaliable
1229
1230 ========================================================================
1231*/
1232BOOLEAN WpaMsgTypeSubst(
1233 IN UCHAR EAPType,
1234 OUT INT *MsgType)
1235{
1236 switch (EAPType)
1237 {
1238 case EAPPacket:
1239 *MsgType = MT2_EAPPacket;
1240 break;
1241 case EAPOLStart:
1242 *MsgType = MT2_EAPOLStart;
1243 break;
1244 case EAPOLLogoff:
1245 *MsgType = MT2_EAPOLLogoff;
1246 break;
1247 case EAPOLKey:
1248 *MsgType = MT2_EAPOLKey;
1249 break;
1250 case EAPOLASFAlert:
1251 *MsgType = MT2_EAPOLASFAlert;
1252 break;
1253 default:
1254 return FALSE;
1255 }
1256 return TRUE;
1257}
58 1258
59/* 1259/*
60 ======================================================================== 1260 ========================================================================
@@ -126,7 +1326,7 @@ VOID PRF(
126 // Then concatenate to last result 1326 // Then concatenate to last result
127 for (i = 0; i < (len + 19) / 20; i++) 1327 for (i = 0; i < (len + 19) / 20; i++)
128 { 1328 {
129 HMAC_SHA1(input, total_len, key, key_len, &output[currentindex]); 1329 HMAC_SHA1(key, key_len, input, total_len, &output[currentindex], SHA1_DIGEST_SIZE);
130 currentindex += 20; 1330 currentindex += 20;
131 1331
132 // update the last octet 1332 // update the last octet
@@ -136,6 +1336,61 @@ VOID PRF(
136} 1336}
137 1337
138/* 1338/*
1339* F(P, S, c, i) = U1 xor U2 xor ... Uc
1340* U1 = PRF(P, S || Int(i))
1341* U2 = PRF(P, U1)
1342* Uc = PRF(P, Uc-1)
1343*/
1344
1345static void F(char *password, unsigned char *ssid, int ssidlength, int iterations, int count, unsigned char *output)
1346{
1347 unsigned char digest[36], digest1[SHA1_DIGEST_SIZE];
1348 int i, j;
1349
1350 /* U1 = PRF(P, S || int(i)) */
1351 memcpy(digest, ssid, ssidlength);
1352 digest[ssidlength] = (unsigned char)((count>>24) & 0xff);
1353 digest[ssidlength+1] = (unsigned char)((count>>16) & 0xff);
1354 digest[ssidlength+2] = (unsigned char)((count>>8) & 0xff);
1355 digest[ssidlength+3] = (unsigned char)(count & 0xff);
1356 HMAC_SHA1((unsigned char*) password, (int) strlen(password), digest, ssidlength+4, digest1, SHA1_DIGEST_SIZE); // for WPA update
1357
1358 /* output = U1 */
1359 memcpy(output, digest1, SHA1_DIGEST_SIZE);
1360
1361 for (i = 1; i < iterations; i++)
1362 {
1363 /* Un = PRF(P, Un-1) */
1364 HMAC_SHA1((unsigned char*) password, (int) strlen(password), digest1, SHA1_DIGEST_SIZE, digest, SHA1_DIGEST_SIZE); // for WPA update
1365 memcpy(digest1, digest, SHA1_DIGEST_SIZE);
1366
1367 /* output = output xor Un */
1368 for (j = 0; j < SHA1_DIGEST_SIZE; j++)
1369 {
1370 output[j] ^= digest[j];
1371 }
1372 }
1373}
1374
1375/*
1376* password - ascii string up to 63 characters in length
1377* ssid - octet string up to 32 octets
1378* ssidlength - length of ssid in octets
1379* output must be 40 octets in length and outputs 256 bits of key
1380*/
1381int PasswordHash(PSTRING password, PUCHAR ssid, INT ssidlength, PUCHAR output)
1382{
1383 if ((strlen(password) > 63) || (ssidlength > 32))
1384 return 0;
1385
1386 F(password, ssid, ssidlength, 4096, 1, output);
1387 F(password, ssid, ssidlength, 4096, 2, &output[SHA1_DIGEST_SIZE]);
1388 return 1;
1389}
1390
1391
1392
1393/*
139 ======================================================================== 1394 ========================================================================
140 1395
141 Routine Description: 1396 Routine Description:
@@ -143,7 +1398,7 @@ VOID PRF(
143 It shall be called by 4-way handshake processing. 1398 It shall be called by 4-way handshake processing.
144 1399
145 Arguments: 1400 Arguments:
146 pAd - pointer to our pAdapter context 1401 pAd - pointer to our pAdapter context
147 PMK - pointer to PMK 1402 PMK - pointer to PMK
148 ANonce - pointer to ANonce 1403 ANonce - pointer to ANonce
149 AA - pointer to Authenticator Address 1404 AA - pointer to Authenticator Address
@@ -159,7 +1414,7 @@ VOID PRF(
159 1414
160 ======================================================================== 1415 ========================================================================
161*/ 1416*/
162VOID WpaCountPTK( 1417VOID WpaDerivePTK(
163 IN PRTMP_ADAPTER pAd, 1418 IN PRTMP_ADAPTER pAd,
164 IN UCHAR *PMK, 1419 IN UCHAR *PMK,
165 IN UCHAR *ANonce, 1420 IN UCHAR *ANonce,
@@ -290,8 +1545,8 @@ VOID GenRandom(
290 1545
291 Arguments: 1546 Arguments:
292 pAd - pointer to our pAdapter context 1547 pAd - pointer to our pAdapter context
293 ElementID - indicate the WPA1 or WPA2 1548 ElementID - indicate the WPA1 or WPA2
294 WepStatus - indicate the encryption type 1549 WepStatus - indicate the encryption type
295 bMixCipher - a boolean to indicate the pairwise cipher and group 1550 bMixCipher - a boolean to indicate the pairwise cipher and group
296 cipher are the same or not 1551 cipher are the same or not
297 1552
@@ -301,7 +1556,7 @@ VOID GenRandom(
301 1556
302 ======================================================================== 1557 ========================================================================
303*/ 1558*/
304static VOID RTMPInsertRsnIeCipher( 1559static VOID RTMPMakeRsnIeCipher(
305 IN PRTMP_ADAPTER pAd, 1560 IN PRTMP_ADAPTER pAd,
306 IN UCHAR ElementID, 1561 IN UCHAR ElementID,
307 IN UINT WepStatus, 1562 IN UINT WepStatus,
@@ -324,7 +1579,7 @@ static VOID RTMPInsertRsnIeCipher(
324 1579
325 switch (WepStatus) 1580 switch (WepStatus)
326 { 1581 {
327 // TKIP mode 1582 // TKIP mode
328 case Ndis802_11Encryption2Enabled: 1583 case Ndis802_11Encryption2Enabled:
329 NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4); 1584 NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4);
330 pRsnie_cipher->ucount = 1; 1585 pRsnie_cipher->ucount = 1;
@@ -351,11 +1606,11 @@ static VOID RTMPInsertRsnIeCipher(
351 // Insert WPA2 TKIP as the first pairwise cipher 1606 // Insert WPA2 TKIP as the first pairwise cipher
352 if (MIX_CIPHER_WPA2_TKIP_ON(FlexibleCipher)) 1607 if (MIX_CIPHER_WPA2_TKIP_ON(FlexibleCipher))
353 { 1608 {
354 NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_TKIP, 4); 1609 NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_TKIP, 4);
355 // Insert WPA2 AES as the secondary pairwise cipher 1610 // Insert WPA2 AES as the secondary pairwise cipher
356 if (MIX_CIPHER_WPA2_AES_ON(FlexibleCipher)) 1611 if (MIX_CIPHER_WPA2_AES_ON(FlexibleCipher))
357 { 1612 {
358 NdisMoveMemory(pRsnie_cipher->ucast[0].oui + 4, OUI_WPA2_CCMP, 4); 1613 NdisMoveMemory(pRsnie_cipher->ucast[0].oui + 4, OUI_WPA2_CCMP, 4);
359 PairwiseCnt = 2; 1614 PairwiseCnt = 2;
360 } 1615 }
361 } 1616 }
@@ -374,7 +1629,7 @@ static VOID RTMPInsertRsnIeCipher(
374 (pAd->StaCfg.GroupCipher != Ndis802_11Encryption2Enabled) && 1629 (pAd->StaCfg.GroupCipher != Ndis802_11Encryption2Enabled) &&
375 (pAd->StaCfg.GroupCipher != Ndis802_11Encryption3Enabled)) 1630 (pAd->StaCfg.GroupCipher != Ndis802_11Encryption3Enabled))
376 { 1631 {
377 UINT GroupCipher = pAd->StaCfg.GroupCipher; 1632 UINT GroupCipher = pAd->StaCfg.GroupCipher;
378 switch(GroupCipher) 1633 switch(GroupCipher)
379 { 1634 {
380 case Ndis802_11GroupWEP40Enabled: 1635 case Ndis802_11GroupWEP40Enabled:
@@ -427,11 +1682,11 @@ static VOID RTMPInsertRsnIeCipher(
427 // Insert WPA TKIP as the first pairwise cipher 1682 // Insert WPA TKIP as the first pairwise cipher
428 if (MIX_CIPHER_WPA_TKIP_ON(FlexibleCipher)) 1683 if (MIX_CIPHER_WPA_TKIP_ON(FlexibleCipher))
429 { 1684 {
430 NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_TKIP, 4); 1685 NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_TKIP, 4);
431 // Insert WPA AES as the secondary pairwise cipher 1686 // Insert WPA AES as the secondary pairwise cipher
432 if (MIX_CIPHER_WPA_AES_ON(FlexibleCipher)) 1687 if (MIX_CIPHER_WPA_AES_ON(FlexibleCipher))
433 { 1688 {
434 NdisMoveMemory(pRsnie_cipher->ucast[0].oui + 4, OUI_WPA_CCMP, 4); 1689 NdisMoveMemory(pRsnie_cipher->ucast[0].oui + 4, OUI_WPA_CCMP, 4);
435 PairwiseCnt = 2; 1690 PairwiseCnt = 2;
436 } 1691 }
437 } 1692 }
@@ -450,7 +1705,7 @@ static VOID RTMPInsertRsnIeCipher(
450 (pAd->StaCfg.GroupCipher != Ndis802_11Encryption2Enabled) && 1705 (pAd->StaCfg.GroupCipher != Ndis802_11Encryption2Enabled) &&
451 (pAd->StaCfg.GroupCipher != Ndis802_11Encryption3Enabled)) 1706 (pAd->StaCfg.GroupCipher != Ndis802_11Encryption3Enabled))
452 { 1707 {
453 UINT GroupCipher = pAd->StaCfg.GroupCipher; 1708 UINT GroupCipher = pAd->StaCfg.GroupCipher;
454 switch(GroupCipher) 1709 switch(GroupCipher)
455 { 1710 {
456 case Ndis802_11GroupWEP40Enabled: 1711 case Ndis802_11GroupWEP40Enabled:
@@ -477,8 +1732,8 @@ static VOID RTMPInsertRsnIeCipher(
477 1732
478 Arguments: 1733 Arguments:
479 pAd - pointer to our pAdapter context 1734 pAd - pointer to our pAdapter context
480 ElementID - indicate the WPA1 or WPA2 1735 ElementID - indicate the WPA1 or WPA2
481 AuthMode - indicate the authentication mode 1736 AuthMode - indicate the authentication mode
482 apidx - indicate the interface index 1737 apidx - indicate the interface index
483 1738
484 Return Value: 1739 Return Value:
@@ -487,7 +1742,7 @@ static VOID RTMPInsertRsnIeCipher(
487 1742
488 ======================================================================== 1743 ========================================================================
489*/ 1744*/
490static VOID RTMPInsertRsnIeAKM( 1745static VOID RTMPMakeRsnIeAKM(
491 IN PRTMP_ADAPTER pAd, 1746 IN PRTMP_ADAPTER pAd,
492 IN UCHAR ElementID, 1747 IN UCHAR ElementID,
493 IN UINT AuthMode, 1748 IN UINT AuthMode,
@@ -496,25 +1751,29 @@ static VOID RTMPInsertRsnIeAKM(
496 OUT UCHAR *rsn_len) 1751 OUT UCHAR *rsn_len)
497{ 1752{
498 RSNIE_AUTH *pRsnie_auth; 1753 RSNIE_AUTH *pRsnie_auth;
1754 UCHAR AkmCnt = 1; // default as 1
499 1755
500 pRsnie_auth = (RSNIE_AUTH*)(pRsnIe + (*rsn_len)); 1756 pRsnie_auth = (RSNIE_AUTH*)(pRsnIe + (*rsn_len));
501 1757
502 // decide WPA2 or WPA1 1758 // decide WPA2 or WPA1
503 if (ElementID == Wpa2Ie) 1759 if (ElementID == Wpa2Ie)
504 { 1760 {
1761
505 switch (AuthMode) 1762 switch (AuthMode)
506 { 1763 {
507 case Ndis802_11AuthModeWPA2: 1764 case Ndis802_11AuthModeWPA2:
508 case Ndis802_11AuthModeWPA1WPA2: 1765 case Ndis802_11AuthModeWPA1WPA2:
509 pRsnie_auth->acount = 1; 1766 NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA2_8021X_AKM, 4);
510 NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA2_8021X_AKM, 4);
511 break; 1767 break;
512 1768
513 case Ndis802_11AuthModeWPA2PSK: 1769 case Ndis802_11AuthModeWPA2PSK:
514 case Ndis802_11AuthModeWPA1PSKWPA2PSK: 1770 case Ndis802_11AuthModeWPA1PSKWPA2PSK:
515 pRsnie_auth->acount = 1; 1771 NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA2_PSK_AKM, 4);
516 NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA2_PSK_AKM, 4);
517 break; 1772 break;
1773 default:
1774 AkmCnt = 0;
1775 break;
1776
518 } 1777 }
519 } 1778 }
520 else 1779 else
@@ -523,26 +1782,28 @@ static VOID RTMPInsertRsnIeAKM(
523 { 1782 {
524 case Ndis802_11AuthModeWPA: 1783 case Ndis802_11AuthModeWPA:
525 case Ndis802_11AuthModeWPA1WPA2: 1784 case Ndis802_11AuthModeWPA1WPA2:
526 pRsnie_auth->acount = 1;
527 NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA_8021X_AKM, 4); 1785 NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA_8021X_AKM, 4);
528 break; 1786 break;
529 1787
530 case Ndis802_11AuthModeWPAPSK: 1788 case Ndis802_11AuthModeWPAPSK:
531 case Ndis802_11AuthModeWPA1PSKWPA2PSK: 1789 case Ndis802_11AuthModeWPA1PSKWPA2PSK:
532 pRsnie_auth->acount = 1;
533 NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA_PSK_AKM, 4); 1790 NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA_PSK_AKM, 4);
534 break; 1791 break;
535 1792
536 case Ndis802_11AuthModeWPANone: 1793 case Ndis802_11AuthModeWPANone:
537 pRsnie_auth->acount = 1;
538 NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA_NONE_AKM, 4); 1794 NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA_NONE_AKM, 4);
539 break; 1795 break;
1796 default:
1797 AkmCnt = 0;
1798 break;
540 } 1799 }
541 } 1800 }
542 1801
1802 pRsnie_auth->acount = AkmCnt;
543 pRsnie_auth->acount = cpu2le16(pRsnie_auth->acount); 1803 pRsnie_auth->acount = cpu2le16(pRsnie_auth->acount);
544 1804
545 (*rsn_len) += sizeof(RSNIE_AUTH); // update current RSNIE length 1805 // update current RSNIE length
1806 (*rsn_len) += (sizeof(RSNIE_AUTH) + (4 * (AkmCnt - 1)));
546 1807
547} 1808}
548 1809
@@ -555,7 +1816,7 @@ static VOID RTMPInsertRsnIeAKM(
555 1816
556 Arguments: 1817 Arguments:
557 pAd - pointer to our pAdapter context 1818 pAd - pointer to our pAdapter context
558 ElementID - indicate the WPA1 or WPA2 1819 ElementID - indicate the WPA1 or WPA2
559 apidx - indicate the interface index 1820 apidx - indicate the interface index
560 1821
561 Return Value: 1822 Return Value:
@@ -564,7 +1825,7 @@ static VOID RTMPInsertRsnIeAKM(
564 1825
565 ======================================================================== 1826 ========================================================================
566*/ 1827*/
567static VOID RTMPInsertRsnIeCap( 1828static VOID RTMPMakeRsnIeCap(
568 IN PRTMP_ADAPTER pAd, 1829 IN PRTMP_ADAPTER pAd,
569 IN UCHAR ElementID, 1830 IN UCHAR ElementID,
570 IN UCHAR apidx, 1831 IN UCHAR apidx,
@@ -595,8 +1856,8 @@ static VOID RTMPInsertRsnIeCap(
595 1856
596 Arguments: 1857 Arguments:
597 pAd - pointer to our pAdapter context 1858 pAd - pointer to our pAdapter context
598 AuthMode - indicate the authentication mode 1859 AuthMode - indicate the authentication mode
599 WepStatus - indicate the encryption type 1860 WepStatus - indicate the encryption type
600 apidx - indicate the interface index 1861 apidx - indicate the interface index
601 1862
602 Return Value: 1863 Return Value:
@@ -612,7 +1873,7 @@ VOID RTMPMakeRSNIE(
612 IN UCHAR apidx) 1873 IN UCHAR apidx)
613{ 1874{
614 PUCHAR pRsnIe = NULL; // primary RSNIE 1875 PUCHAR pRsnIe = NULL; // primary RSNIE
615 UCHAR *rsnielen_cur_p = 0; // the length of the primary RSNIE 1876 UCHAR *rsnielen_cur_p = 0; // the length of the primary RSNIE
616 UCHAR *rsnielen_ex_cur_p = 0; // the length of the secondary RSNIE 1877 UCHAR *rsnielen_ex_cur_p = 0; // the length of the secondary RSNIE
617 UCHAR PrimaryRsnie; 1878 UCHAR PrimaryRsnie;
618 BOOLEAN bMixCipher = FALSE; // indicate the pairwise and group cipher are different 1879 BOOLEAN bMixCipher = FALSE; // indicate the pairwise and group cipher are different
@@ -667,13 +1928,13 @@ VOID RTMPMakeRSNIE(
667 { 1928 {
668 // Build the primary RSNIE 1929 // Build the primary RSNIE
669 // 1. insert cipher suite 1930 // 1. insert cipher suite
670 RTMPInsertRsnIeCipher(pAd, PrimaryRsnie, WepStatus, bMixCipher, FlexibleCipher, pRsnIe, &p_offset); 1931 RTMPMakeRsnIeCipher(pAd, PrimaryRsnie, WepStatus, bMixCipher, FlexibleCipher, pRsnIe, &p_offset);
671 1932
672 // 2. insert AKM 1933 // 2. insert AKM
673 RTMPInsertRsnIeAKM(pAd, PrimaryRsnie, AuthMode, apidx, pRsnIe, &p_offset); 1934 RTMPMakeRsnIeAKM(pAd, PrimaryRsnie, AuthMode, apidx, pRsnIe, &p_offset);
674 1935
675 // 3. insert capability 1936 // 3. insert capability
676 RTMPInsertRsnIeCap(pAd, PrimaryRsnie, apidx, pRsnIe, &p_offset); 1937 RTMPMakeRsnIeCap(pAd, PrimaryRsnie, apidx, pRsnIe, &p_offset);
677 } 1938 }
678 1939
679 // 4. update the RSNIE length 1940 // 4. update the RSNIE length
@@ -693,12 +1954,12 @@ VOID RTMPMakeRSNIE(
693 pAd - pointer to our pAdapter context 1954 pAd - pointer to our pAdapter context
694 pEntry - pointer to active entry 1955 pEntry - pointer to active entry
695 pData - the received frame 1956 pData - the received frame
696 DataByteCount - the received frame's length 1957 DataByteCount - the received frame's length
697 FromWhichBSSID - indicate the interface index 1958 FromWhichBSSID - indicate the interface index
698 1959
699 Return: 1960 Return:
700 TRUE - This frame is EAP frame 1961 TRUE - This frame is EAP frame
701 FALSE - otherwise 1962 FALSE - otherwise
702 ========================================================================== 1963 ==========================================================================
703*/ 1964*/
704BOOLEAN RTMPCheckWPAframe( 1965BOOLEAN RTMPCheckWPAframe(
@@ -741,7 +2002,7 @@ BOOLEAN RTMPCheckWPAframe(
741 DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL-Start frame, TYPE = 1 \n")); 2002 DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL-Start frame, TYPE = 1 \n"));
742 if (pEntry->EnqueueEapolStartTimerRunning != EAPOL_START_DISABLE) 2003 if (pEntry->EnqueueEapolStartTimerRunning != EAPOL_START_DISABLE)
743 { 2004 {
744 DBGPRINT(RT_DEBUG_TRACE, ("Cancel the EnqueueEapolStartTimerRunning \n")); 2005 DBGPRINT(RT_DEBUG_TRACE, ("Cancel the EnqueueEapolStartTimerRunning \n"));
745 RTMPCancelTimer(&pEntry->EnqueueStartForPSKTimer, &Cancelled); 2006 RTMPCancelTimer(&pEntry->EnqueueStartForPSKTimer, &Cancelled);
746 pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE; 2007 pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE;
747 } 2008 }
@@ -764,73 +2025,1088 @@ BOOLEAN RTMPCheckWPAframe(
764} 2025}
765 2026
766/* 2027/*
2028 ==========================================================================
2029 Description:
2030 Report the EAP message type
2031
2032 Arguments:
2033 msg - EAPOL_PAIR_MSG_1
2034 EAPOL_PAIR_MSG_2
2035 EAPOL_PAIR_MSG_3
2036 EAPOL_PAIR_MSG_4
2037 EAPOL_GROUP_MSG_1
2038 EAPOL_GROUP_MSG_2
2039
2040 Return:
2041 message type string
2042
2043 ==========================================================================
2044*/
2045PSTRING GetEapolMsgType(CHAR msg)
2046{
2047 if(msg == EAPOL_PAIR_MSG_1)
2048 return "Pairwise Message 1";
2049 else if(msg == EAPOL_PAIR_MSG_2)
2050 return "Pairwise Message 2";
2051 else if(msg == EAPOL_PAIR_MSG_3)
2052 return "Pairwise Message 3";
2053 else if(msg == EAPOL_PAIR_MSG_4)
2054 return "Pairwise Message 4";
2055 else if(msg == EAPOL_GROUP_MSG_1)
2056 return "Group Message 1";
2057 else if(msg == EAPOL_GROUP_MSG_2)
2058 return "Group Message 2";
2059 else
2060 return "Invalid Message";
2061}
2062
2063
2064/*
2065 ========================================================================
2066
2067 Routine Description:
2068 Check Sanity RSN IE of EAPoL message
2069
2070 Arguments:
2071
2072 Return Value:
2073
2074
2075 ========================================================================
2076*/
2077BOOLEAN RTMPCheckRSNIE(
2078 IN PRTMP_ADAPTER pAd,
2079 IN PUCHAR pData,
2080 IN UCHAR DataLen,
2081 IN MAC_TABLE_ENTRY *pEntry,
2082 OUT UCHAR *Offset)
2083{
2084 PUCHAR pVIE;
2085 UCHAR len;
2086 PEID_STRUCT pEid;
2087 BOOLEAN result = FALSE;
2088
2089 pVIE = pData;
2090 len = DataLen;
2091 *Offset = 0;
2092
2093 while (len > sizeof(RSNIE2))
2094 {
2095 pEid = (PEID_STRUCT) pVIE;
2096 // WPA RSN IE
2097 if ((pEid->Eid == IE_WPA) && (NdisEqualMemory(pEid->Octet, WPA_OUI, 4)))
2098 {
2099 if ((pEntry->AuthMode == Ndis802_11AuthModeWPA || pEntry->AuthMode == Ndis802_11AuthModeWPAPSK) &&
2100 (NdisEqualMemory(pVIE, pEntry->RSN_IE, pEntry->RSNIE_Len)) &&
2101 (pEntry->RSNIE_Len == (pEid->Len + 2)))
2102 {
2103 result = TRUE;
2104 }
2105
2106 *Offset += (pEid->Len + 2);
2107 }
2108 // WPA2 RSN IE
2109 else if ((pEid->Eid == IE_RSN) && (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3)))
2110 {
2111 if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2 || pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK) &&
2112 (pEid->Eid == pEntry->RSN_IE[0]) &&
2113 ((pEid->Len + 2) >= pEntry->RSNIE_Len) &&
2114 (NdisEqualMemory(pEid->Octet, &pEntry->RSN_IE[2], pEntry->RSNIE_Len - 2)))
2115 {
2116
2117 result = TRUE;
2118 }
2119
2120 *Offset += (pEid->Len + 2);
2121 }
2122 else
2123 {
2124 break;
2125 }
2126
2127 pVIE += (pEid->Len + 2);
2128 len -= (pEid->Len + 2);
2129 }
2130
2131
2132 return result;
2133
2134}
2135
2136/*
767 ======================================================================== 2137 ========================================================================
768 2138
769 Routine Description: 2139 Routine Description:
770 Misc function to decrypt AES body 2140 Parse KEYDATA field. KEYDATA[] May contain 2 RSN IE and optionally GTK.
2141 GTK is encaptulated in KDE format at p.83 802.11i D10
771 2142
772 Arguments: 2143 Arguments:
773 2144
774 Return Value: 2145 Return Value:
775 2146
776 Note: 2147 Note:
777 This function references to RFC 3394 for aes key unwrap algorithm. 2148 802.11i D10
778 2149
779 ======================================================================== 2150 ========================================================================
780*/ 2151*/
781VOID AES_GTK_KEY_UNWRAP( 2152BOOLEAN RTMPParseEapolKeyData(
782 IN UCHAR *key, 2153 IN PRTMP_ADAPTER pAd,
783 OUT UCHAR *plaintext, 2154 IN PUCHAR pKeyData,
784 IN UCHAR c_len, 2155 IN UCHAR KeyDataLen,
785 IN UCHAR *ciphertext) 2156 IN UCHAR GroupKeyIndex,
2157 IN UCHAR MsgType,
2158 IN BOOLEAN bWPA2,
2159 IN MAC_TABLE_ENTRY *pEntry)
2160{
2161 PKDE_ENCAP pKDE = NULL;
2162 PUCHAR pMyKeyData = pKeyData;
2163 UCHAR KeyDataLength = KeyDataLen;
2164 UCHAR GTKLEN = 0;
2165 UCHAR DefaultIdx = 0;
2166 UCHAR skip_offset;
2167
2168 // Verify The RSN IE contained in pairewise_msg_2 && pairewise_msg_3 and skip it
2169 if (MsgType == EAPOL_PAIR_MSG_2 || MsgType == EAPOL_PAIR_MSG_3)
2170 {
2171 // Check RSN IE whether it is WPA2/WPA2PSK
2172 if (!RTMPCheckRSNIE(pAd, pKeyData, KeyDataLen, pEntry, &skip_offset))
2173 {
2174 // send wireless event - for RSN IE different
2175 if (pAd->CommonCfg.bWirelessEvent)
2176 RTMPSendWirelessEvent(pAd, IW_RSNIE_DIFF_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0);
2177
2178 DBGPRINT(RT_DEBUG_ERROR, ("RSN_IE Different in msg %d of 4-way handshake!\n", MsgType));
2179 hex_dump("Receive RSN_IE ", pKeyData, KeyDataLen);
2180 hex_dump("Desired RSN_IE ", pEntry->RSN_IE, pEntry->RSNIE_Len);
786 2181
2182 return FALSE;
2183 }
2184 else
2185 {
2186 if (bWPA2 && MsgType == EAPOL_PAIR_MSG_3)
2187 {
2188 WpaShowAllsuite(pMyKeyData, skip_offset);
2189
2190 // skip RSN IE
2191 pMyKeyData += skip_offset;
2192 KeyDataLength -= skip_offset;
2193 DBGPRINT(RT_DEBUG_TRACE, ("RTMPParseEapolKeyData ==> WPA2/WPA2PSK RSN IE matched in Msg 3, Length(%d) \n", skip_offset));
2194 }
2195 else
2196 return TRUE;
2197 }
2198 }
2199
2200 DBGPRINT(RT_DEBUG_TRACE,("RTMPParseEapolKeyData ==> KeyDataLength %d without RSN_IE \n", KeyDataLength));
2201 //hex_dump("remain data", pMyKeyData, KeyDataLength);
2202
2203
2204 // Parse EKD format in pairwise_msg_3_WPA2 && group_msg_1_WPA2
2205 if (bWPA2 && (MsgType == EAPOL_PAIR_MSG_3 || MsgType == EAPOL_GROUP_MSG_1))
2206 {
2207 if (KeyDataLength >= 8) // KDE format exclude GTK length
2208 {
2209 pKDE = (PKDE_ENCAP) pMyKeyData;
2210
2211
2212 DefaultIdx = pKDE->GTKEncap.Kid;
2213
2214 // Sanity check - KED length
2215 if (KeyDataLength < (pKDE->Len + 2))
2216 {
2217 DBGPRINT(RT_DEBUG_ERROR, ("ERROR: The len from KDE is too short \n"));
2218 return FALSE;
2219 }
2220
2221 // Get GTK length - refer to IEEE 802.11i-2004 p.82
2222 GTKLEN = pKDE->Len -6;
2223 if (GTKLEN < LEN_AES_KEY)
2224 {
2225 DBGPRINT(RT_DEBUG_ERROR, ("ERROR: GTK Key length is too short (%d) \n", GTKLEN));
2226 return FALSE;
2227 }
2228
2229 }
2230 else
2231 {
2232 DBGPRINT(RT_DEBUG_ERROR, ("ERROR: KDE format length is too short \n"));
2233 return FALSE;
2234 }
2235
2236 DBGPRINT(RT_DEBUG_TRACE, ("GTK in KDE format ,DefaultKeyID=%d, KeyLen=%d \n", DefaultIdx, GTKLEN));
2237 // skip it
2238 pMyKeyData += 8;
2239 KeyDataLength -= 8;
2240
2241 }
2242 else if (!bWPA2 && MsgType == EAPOL_GROUP_MSG_1)
2243 {
2244 DefaultIdx = GroupKeyIndex;
2245 DBGPRINT(RT_DEBUG_TRACE, ("GTK DefaultKeyID=%d \n", DefaultIdx));
2246 }
2247
2248 // Sanity check - shared key index must be 1 ~ 3
2249 if (DefaultIdx < 1 || DefaultIdx > 3)
2250 {
2251 DBGPRINT(RT_DEBUG_ERROR, ("ERROR: GTK Key index(%d) is invalid in %s %s \n", DefaultIdx, ((bWPA2) ? "WPA2" : "WPA"), GetEapolMsgType(MsgType)));
2252 return FALSE;
2253 }
2254
2255 {
2256 PCIPHER_KEY pSharedKey;
2257
2258 // set key material, TxMic and RxMic
2259 NdisMoveMemory(pAd->StaCfg.GTK, pMyKeyData, 32);
2260 pAd->StaCfg.DefaultKeyId = DefaultIdx;
2261
2262 pSharedKey = &pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId];
2263
2264 // Prepare pair-wise key information into shared key table
2265 NdisZeroMemory(pSharedKey, sizeof(CIPHER_KEY));
2266 pSharedKey->KeyLen = LEN_TKIP_EK;
2267 NdisMoveMemory(pSharedKey->Key, pAd->StaCfg.GTK, LEN_TKIP_EK);
2268 NdisMoveMemory(pSharedKey->RxMic, &pAd->StaCfg.GTK[16], LEN_TKIP_RXMICK);
2269 NdisMoveMemory(pSharedKey->TxMic, &pAd->StaCfg.GTK[24], LEN_TKIP_TXMICK);
2270
2271 // Update Shared Key CipherAlg
2272 pSharedKey->CipherAlg = CIPHER_NONE;
2273 if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
2274 pSharedKey->CipherAlg = CIPHER_TKIP;
2275 else if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)
2276 pSharedKey->CipherAlg = CIPHER_AES;
2277 else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP40Enabled)
2278 pSharedKey->CipherAlg = CIPHER_WEP64;
2279 else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP104Enabled)
2280 pSharedKey->CipherAlg = CIPHER_WEP128;
2281
2282
2283 // Update group key information to ASIC Shared Key Table
2284 AsicAddSharedKeyEntry(pAd,
2285 BSS0,
2286 pAd->StaCfg.DefaultKeyId,
2287 pSharedKey->CipherAlg,
2288 pSharedKey->Key,
2289 pSharedKey->TxMic,
2290 pSharedKey->RxMic);
2291
2292 // Update ASIC WCID attribute table and IVEIV table
2293 RTMPAddWcidAttributeEntry(pAd,
2294 BSS0,
2295 pAd->StaCfg.DefaultKeyId,
2296 pSharedKey->CipherAlg,
2297 NULL);
2298 }
2299
2300 return TRUE;
2301
2302}
2303
2304
2305/*
2306 ========================================================================
2307
2308 Routine Description:
2309 Construct EAPoL message for WPA handshaking
2310 Its format is below,
2311
2312 +--------------------+
2313 | Protocol Version | 1 octet
2314 +--------------------+
2315 | Protocol Type | 1 octet
2316 +--------------------+
2317 | Body Length | 2 octets
2318 +--------------------+
2319 | Descriptor Type | 1 octet
2320 +--------------------+
2321 | Key Information | 2 octets
2322 +--------------------+
2323 | Key Length | 1 octet
2324 +--------------------+
2325 | Key Repaly Counter | 8 octets
2326 +--------------------+
2327 | Key Nonce | 32 octets
2328 +--------------------+
2329 | Key IV | 16 octets
2330 +--------------------+
2331 | Key RSC | 8 octets
2332 +--------------------+
2333 | Key ID or Reserved | 8 octets
2334 +--------------------+
2335 | Key MIC | 16 octets
2336 +--------------------+
2337 | Key Data Length | 2 octets
2338 +--------------------+
2339 | Key Data | n octets
2340 +--------------------+
2341
2342
2343 Arguments:
2344 pAd Pointer to our adapter
2345
2346 Return Value:
2347 None
2348
2349 Note:
2350
2351 ========================================================================
2352*/
2353VOID ConstructEapolMsg(
2354 IN PMAC_TABLE_ENTRY pEntry,
2355 IN UCHAR GroupKeyWepStatus,
2356 IN UCHAR MsgType,
2357 IN UCHAR DefaultKeyIdx,
2358 IN UCHAR *KeyNonce,
2359 IN UCHAR *TxRSC,
2360 IN UCHAR *GTK,
2361 IN UCHAR *RSNIE,
2362 IN UCHAR RSNIE_Len,
2363 OUT PEAPOL_PACKET pMsg)
787{ 2364{
788 UCHAR A[8], BIN[16], BOUT[16]; 2365 BOOLEAN bWPA2 = FALSE;
789 UCHAR xor; 2366 UCHAR KeyDescVer;
790 INT i, j; 2367
791 aes_context aesctx; 2368 // Choose WPA2 or not
792 UCHAR *R; 2369 if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) ||
793 INT num_blocks = c_len/8; // unit:64bits 2370 (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK))
2371 bWPA2 = TRUE;
2372
2373 // Init Packet and Fill header
2374 pMsg->ProVer = EAPOL_VER;
2375 pMsg->ProType = EAPOLKey;
2376
2377 // Default 95 bytes, the EAPoL-Key descriptor exclude Key-data field
2378 SET_UINT16_TO_ARRARY(pMsg->Body_Len, LEN_EAPOL_KEY_MSG);
2379
2380 // Fill in EAPoL descriptor
2381 if (bWPA2)
2382 pMsg->KeyDesc.Type = WPA2_KEY_DESC;
2383 else
2384 pMsg->KeyDesc.Type = WPA1_KEY_DESC;
2385
2386 // Key Descriptor Version (bits 0-2) specifies the key descriptor version type
2387 {
2388 // Fill in Key information, refer to IEEE Std 802.11i-2004 page 78
2389 // When either the pairwise or the group cipher is AES, the DESC_TYPE_AES(2) shall be used.
2390 KeyDescVer = (((pEntry->WepStatus == Ndis802_11Encryption3Enabled) ||
2391 (GroupKeyWepStatus == Ndis802_11Encryption3Enabled)) ? (DESC_TYPE_AES) : (DESC_TYPE_TKIP));
2392 }
2393
2394 pMsg->KeyDesc.KeyInfo.KeyDescVer = KeyDescVer;
2395
2396 // Specify Key Type as Group(0) or Pairwise(1)
2397 if (MsgType >= EAPOL_GROUP_MSG_1)
2398 pMsg->KeyDesc.KeyInfo.KeyType = GROUPKEY;
2399 else
2400 pMsg->KeyDesc.KeyInfo.KeyType = PAIRWISEKEY;
2401
2402 // Specify Key Index, only group_msg1_WPA1
2403 if (!bWPA2 && (MsgType >= EAPOL_GROUP_MSG_1))
2404 pMsg->KeyDesc.KeyInfo.KeyIndex = DefaultKeyIdx;
2405
2406 if (MsgType == EAPOL_PAIR_MSG_3)
2407 pMsg->KeyDesc.KeyInfo.Install = 1;
2408
2409 if ((MsgType == EAPOL_PAIR_MSG_1) || (MsgType == EAPOL_PAIR_MSG_3) || (MsgType == EAPOL_GROUP_MSG_1))
2410 pMsg->KeyDesc.KeyInfo.KeyAck = 1;
2411
2412 if (MsgType != EAPOL_PAIR_MSG_1)
2413 pMsg->KeyDesc.KeyInfo.KeyMic = 1;
2414
2415 if ((bWPA2 && (MsgType >= EAPOL_PAIR_MSG_3)) ||
2416 (!bWPA2 && (MsgType >= EAPOL_GROUP_MSG_1)))
2417 {
2418 pMsg->KeyDesc.KeyInfo.Secure = 1;
2419 }
2420
2421 if (bWPA2 && ((MsgType == EAPOL_PAIR_MSG_3) ||
2422 (MsgType == EAPOL_GROUP_MSG_1)))
2423 {
2424 pMsg->KeyDesc.KeyInfo.EKD_DL = 1;
2425 }
2426
2427 // key Information element has done.
2428 *(USHORT *)(&pMsg->KeyDesc.KeyInfo) = cpu2le16(*(USHORT *)(&pMsg->KeyDesc.KeyInfo));
2429
2430 // Fill in Key Length
2431 {
2432 if (MsgType >= EAPOL_GROUP_MSG_1)
2433 {
2434 // the length of group key cipher
2435 pMsg->KeyDesc.KeyLength[1] = ((GroupKeyWepStatus == Ndis802_11Encryption2Enabled) ? TKIP_GTK_LENGTH : LEN_AES_KEY);
2436 }
2437 else
2438 {
2439 // the length of pairwise key cipher
2440 pMsg->KeyDesc.KeyLength[1] = ((pEntry->WepStatus == Ndis802_11Encryption2Enabled) ? LEN_TKIP_KEY : LEN_AES_KEY);
2441 }
2442 }
2443
2444 // Fill in replay counter
2445 NdisMoveMemory(pMsg->KeyDesc.ReplayCounter, pEntry->R_Counter, LEN_KEY_DESC_REPLAY);
2446
2447 // Fill Key Nonce field
2448 // ANonce : pairwise_msg1 & pairwise_msg3
2449 // SNonce : pairwise_msg2
2450 // GNonce : group_msg1_wpa1
2451 if ((MsgType <= EAPOL_PAIR_MSG_3) || ((!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1))))
2452 NdisMoveMemory(pMsg->KeyDesc.KeyNonce, KeyNonce, LEN_KEY_DESC_NONCE);
2453
2454 // Fill key IV - WPA2 as 0, WPA1 as random
2455 if (!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1))
2456 {
2457 // Suggest IV be random number plus some number,
2458 NdisMoveMemory(pMsg->KeyDesc.KeyIv, &KeyNonce[16], LEN_KEY_DESC_IV);
2459 pMsg->KeyDesc.KeyIv[15] += 2;
2460 }
2461
2462 // Fill Key RSC field
2463 // It contains the RSC for the GTK being installed.
2464 if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2) || (MsgType == EAPOL_GROUP_MSG_1))
2465 {
2466 NdisMoveMemory(pMsg->KeyDesc.KeyRsc, TxRSC, 6);
2467 }
2468
2469 // Clear Key MIC field for MIC calculation later
2470 NdisZeroMemory(pMsg->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
2471
2472 ConstructEapolKeyData(pEntry,
2473 GroupKeyWepStatus,
2474 KeyDescVer,
2475 MsgType,
2476 DefaultKeyIdx,
2477 GTK,
2478 RSNIE,
2479 RSNIE_Len,
2480 pMsg);
2481
2482 // Calculate MIC and fill in KeyMic Field except Pairwise Msg 1.
2483 if (MsgType != EAPOL_PAIR_MSG_1)
2484 {
2485 CalculateMIC(KeyDescVer, pEntry->PTK, pMsg);
2486 }
2487
2488 DBGPRINT(RT_DEBUG_TRACE, ("===> ConstructEapolMsg for %s %s\n", ((bWPA2) ? "WPA2" : "WPA"), GetEapolMsgType(MsgType)));
2489 DBGPRINT(RT_DEBUG_TRACE, (" Body length = %d \n", CONV_ARRARY_TO_UINT16(pMsg->Body_Len)));
2490 DBGPRINT(RT_DEBUG_TRACE, (" Key length = %d \n", CONV_ARRARY_TO_UINT16(pMsg->KeyDesc.KeyLength)));
2491
2492
2493}
2494
2495/*
2496 ========================================================================
2497
2498 Routine Description:
2499 Construct the Key Data field of EAPoL message
2500
2501 Arguments:
2502 pAd Pointer to our adapter
2503 Elem Message body
2504
2505 Return Value:
2506 None
2507
2508 Note:
2509
2510 ========================================================================
2511*/
2512VOID ConstructEapolKeyData(
2513 IN PMAC_TABLE_ENTRY pEntry,
2514 IN UCHAR GroupKeyWepStatus,
2515 IN UCHAR keyDescVer,
2516 IN UCHAR MsgType,
2517 IN UCHAR DefaultKeyIdx,
2518 IN UCHAR *GTK,
2519 IN UCHAR *RSNIE,
2520 IN UCHAR RSNIE_LEN,
2521 OUT PEAPOL_PACKET pMsg)
2522{
2523 UCHAR *mpool, *Key_Data, *Rc4GTK;
2524 UCHAR ekey[(LEN_KEY_DESC_IV+LEN_EAP_EK)];
2525 ULONG data_offset;
2526 BOOLEAN bWPA2Capable = FALSE;
2527 PRTMP_ADAPTER pAd = pEntry->pAd;
2528 BOOLEAN GTK_Included = FALSE;
2529
2530 // Choose WPA2 or not
2531 if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) ||
2532 (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK))
2533 bWPA2Capable = TRUE;
2534
2535 if (MsgType == EAPOL_PAIR_MSG_1 ||
2536 MsgType == EAPOL_PAIR_MSG_4 ||
2537 MsgType == EAPOL_GROUP_MSG_2)
2538 return;
2539
2540 // allocate memory pool
2541 os_alloc_mem(NULL, (PUCHAR *)&mpool, 1500);
2542
2543 if (mpool == NULL)
2544 return;
2545
2546 /* Rc4GTK Len = 512 */
2547 Rc4GTK = (UCHAR *) ROUND_UP(mpool, 4);
2548 /* Key_Data Len = 512 */
2549 Key_Data = (UCHAR *) ROUND_UP(Rc4GTK + 512, 4);
2550
2551 NdisZeroMemory(Key_Data, 512);
2552 SET_UINT16_TO_ARRARY(pMsg->KeyDesc.KeyDataLen, 0);
2553 data_offset = 0;
2554
2555 // Encapsulate RSNIE in pairwise_msg2 & pairwise_msg3
2556 if (RSNIE_LEN && ((MsgType == EAPOL_PAIR_MSG_2) || (MsgType == EAPOL_PAIR_MSG_3)))
2557 {
2558 PUINT8 pmkid_ptr = NULL;
2559 UINT8 pmkid_len = 0;
2560
2561
2562 RTMPInsertRSNIE(&Key_Data[data_offset],
2563 &data_offset,
2564 RSNIE,
2565 RSNIE_LEN,
2566 pmkid_ptr,
2567 pmkid_len);
2568 }
2569
2570
2571 // Encapsulate KDE format in pairwise_msg3_WPA2 & group_msg1_WPA2
2572 if (bWPA2Capable && ((MsgType == EAPOL_PAIR_MSG_3) || (MsgType == EAPOL_GROUP_MSG_1)))
2573 {
2574 // Key Data Encapsulation (KDE) format - 802.11i-2004 Figure-43w and Table-20h
2575 Key_Data[data_offset + 0] = 0xDD;
794 2576
2577 if (GroupKeyWepStatus == Ndis802_11Encryption3Enabled)
2578 {
2579 Key_Data[data_offset + 1] = 0x16;// 4+2+16(OUI+DataType+DataField)
2580 }
2581 else
2582 {
2583 Key_Data[data_offset + 1] = 0x26;// 4+2+32(OUI+DataType+DataField)
2584 }
2585
2586 Key_Data[data_offset + 2] = 0x00;
2587 Key_Data[data_offset + 3] = 0x0F;
2588 Key_Data[data_offset + 4] = 0xAC;
2589 Key_Data[data_offset + 5] = 0x01;
2590
2591 // GTK KDE format - 802.11i-2004 Figure-43x
2592 Key_Data[data_offset + 6] = (DefaultKeyIdx & 0x03);
2593 Key_Data[data_offset + 7] = 0x00; // Reserved Byte
2594
2595 data_offset += 8;
2596 }
2597
2598
2599 // Encapsulate GTK
2600 // Only for pairwise_msg3_WPA2 and group_msg1
2601 if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2Capable) || (MsgType == EAPOL_GROUP_MSG_1))
2602 {
2603 // Fill in GTK
2604 if (GroupKeyWepStatus == Ndis802_11Encryption3Enabled)
2605 {
2606 NdisMoveMemory(&Key_Data[data_offset], GTK, LEN_AES_KEY);
2607 data_offset += LEN_AES_KEY;
2608 }
2609 else
2610 {
2611 NdisMoveMemory(&Key_Data[data_offset], GTK, TKIP_GTK_LENGTH);
2612 data_offset += TKIP_GTK_LENGTH;
2613 }
2614
2615 GTK_Included = TRUE;
2616 }
2617
2618
2619 // This whole key-data field shall be encrypted if a GTK is included.
2620 // Encrypt the data material in key data field with KEK
2621 if (GTK_Included)
2622 {
2623 //hex_dump("GTK_Included", Key_Data, data_offset);
2624
2625 if (
2626 (keyDescVer == DESC_TYPE_AES))
2627 {
2628 UCHAR remainder = 0;
2629 UCHAR pad_len = 0;
2630
2631 // Key Descriptor Version 2 or 3: AES key wrap, defined in IETF RFC 3394,
2632 // shall be used to encrypt the Key Data field using the KEK field from
2633 // the derived PTK.
2634
2635 // If the Key Data field uses the NIST AES key wrap, then the Key Data field
2636 // shall be padded before encrypting if the key data length is less than 16
2637 // octets or if it is not a multiple of 8. The padding consists of appending
2638 // a single octet 0xdd followed by zero or more 0x00 octets.
2639 if ((remainder = data_offset & 0x07) != 0)
2640 {
2641 INT i;
2642
2643 pad_len = (8 - remainder);
2644 Key_Data[data_offset] = 0xDD;
2645 for (i = 1; i < pad_len; i++)
2646 Key_Data[data_offset + i] = 0;
2647
2648 data_offset += pad_len;
2649 }
2650
2651 AES_GTK_KEY_WRAP(&pEntry->PTK[16], Key_Data, data_offset, Rc4GTK);
2652 // AES wrap function will grow 8 bytes in length
2653 data_offset += 8;
2654 }
2655 else
2656 {
2657 /* Key Descriptor Version 1: ARC4 is used to encrypt the Key Data field
2658 using the KEK field from the derived PTK. */
2659
2660 // PREPARE Encrypted "Key DATA" field. (Encrypt GTK with RC4, usinf PTK[16]->[31] as Key, IV-field as IV)
2661 // put TxTsc in Key RSC field
2662 pAd->PrivateInfo.FCSCRC32 = PPPINITFCS32; //Init crc32.
2663
2664 // ekey is the contanetion of IV-field, and PTK[16]->PTK[31]
2665 NdisMoveMemory(ekey, pMsg->KeyDesc.KeyIv, LEN_KEY_DESC_IV);
2666 NdisMoveMemory(&ekey[LEN_KEY_DESC_IV], &pEntry->PTK[16], LEN_EAP_EK);
2667 ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, ekey, sizeof(ekey)); //INIT SBOX, KEYLEN+3(IV)
2668 pAd->PrivateInfo.FCSCRC32 = RTMP_CALC_FCS32(pAd->PrivateInfo.FCSCRC32, Key_Data, data_offset);
2669 WPAARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, Rc4GTK, Key_Data, data_offset);
2670 }
2671
2672 NdisMoveMemory(pMsg->KeyDesc.KeyData, Rc4GTK, data_offset);
2673 }
2674 else
2675 {
2676 NdisMoveMemory(pMsg->KeyDesc.KeyData, Key_Data, data_offset);
2677 }
2678
2679 // Update key data length field and total body length
2680 SET_UINT16_TO_ARRARY(pMsg->KeyDesc.KeyDataLen, data_offset);
2681 INC_UINT16_TO_ARRARY(pMsg->Body_Len, data_offset);
2682
2683 os_free_mem(NULL, mpool);
2684
2685}
2686
2687/*
2688 ========================================================================
2689
2690 Routine Description:
2691 Calcaulate MIC. It is used during 4-ways handsharking.
2692
2693 Arguments:
2694 pAd - pointer to our pAdapter context
2695 PeerWepStatus - indicate the encryption type
2696
2697 Return Value:
2698
2699 Note:
2700
2701 ========================================================================
2702*/
2703static VOID CalculateMIC(
2704 IN UCHAR KeyDescVer,
2705 IN UCHAR *PTK,
2706 OUT PEAPOL_PACKET pMsg)
2707{
2708 UCHAR *OutBuffer;
2709 ULONG FrameLen = 0;
2710 UCHAR mic[LEN_KEY_DESC_MIC];
2711 UCHAR digest[80];
795 2712
796 os_alloc_mem(NULL, (PUCHAR *)&R, 512); 2713 // allocate memory for MIC calculation
2714 os_alloc_mem(NULL, (PUCHAR *)&OutBuffer, 512);
797 2715
798 if (R == NULL) 2716 if (OutBuffer == NULL)
799 { 2717 {
800 DBGPRINT(RT_DEBUG_ERROR, ("!!!AES_GTK_KEY_UNWRAP: no memory!!!\n")); 2718 DBGPRINT(RT_DEBUG_ERROR, ("!!!CalculateMIC: no memory!!!\n"));
801 return; 2719 return;
802 } /* End of if */ 2720 }
2721
2722 // make a frame for calculating MIC.
2723 MakeOutgoingFrame(OutBuffer, &FrameLen,
2724 CONV_ARRARY_TO_UINT16(pMsg->Body_Len) + 4, pMsg,
2725 END_OF_ARGS);
803 2726
804 // Initialize 2727 NdisZeroMemory(mic, sizeof(mic));
805 NdisMoveMemory(A, ciphertext, 8); 2728
806 //Input plaintext 2729 // Calculate MIC
807 for(i = 0; i < (c_len-8); i++) 2730 if (KeyDescVer == DESC_TYPE_AES)
2731 {
2732 HMAC_SHA1(PTK, LEN_EAP_MICK, OutBuffer, FrameLen, digest, SHA1_DIGEST_SIZE);
2733 NdisMoveMemory(mic, digest, LEN_KEY_DESC_MIC);
2734 }
2735 else
808 { 2736 {
809 R[ i] = ciphertext[i + 8]; 2737 HMAC_MD5(PTK, LEN_EAP_MICK, OutBuffer, FrameLen, mic, MD5_DIGEST_SIZE);
810 } 2738 }
811 2739
812 rtmp_aes_set_key(&aesctx, key, 128); 2740 // store the calculated MIC
2741 NdisMoveMemory(pMsg->KeyDesc.KeyMic, mic, LEN_KEY_DESC_MIC);
813 2742
814 for(j = 5; j >= 0; j--) 2743 os_free_mem(NULL, OutBuffer);
2744}
2745
2746/*
2747 ========================================================================
2748
2749 Routine Description:
2750 Some received frames can't decrypt by Asic, so decrypt them by software.
2751
2752 Arguments:
2753 pAd - pointer to our pAdapter context
2754 PeerWepStatus - indicate the encryption type
2755
2756 Return Value:
2757 NDIS_STATUS_SUCCESS - decryption successful
2758 NDIS_STATUS_FAILURE - decryption failure
2759
2760 ========================================================================
2761*/
2762NDIS_STATUS RTMPSoftDecryptBroadCastData(
2763 IN PRTMP_ADAPTER pAd,
2764 IN RX_BLK *pRxBlk,
2765 IN NDIS_802_11_ENCRYPTION_STATUS GroupCipher,
2766 IN PCIPHER_KEY pShard_key)
2767{
2768 PRXWI_STRUC pRxWI = pRxBlk->pRxWI;
2769
2770
2771
2772 // handle WEP decryption
2773 if (GroupCipher == Ndis802_11Encryption1Enabled)
815 { 2774 {
816 for(i = (num_blocks-1); i > 0; i--) 2775 if (RTMPSoftDecryptWEP(pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount, pShard_key))
817 { 2776 {
818 xor = (num_blocks -1 )* j + i; 2777
819 NdisMoveMemory(BIN, A, 8); 2778 //Minus IV[4] & ICV[4]
820 BIN[7] = A[7] ^ xor; 2779 pRxWI->MPDUtotalByteCount -= 8;
821 NdisMoveMemory(&BIN[8], &R[(i-1)*8], 8);
822 rtmp_aes_decrypt(&aesctx, BIN, BOUT);
823 NdisMoveMemory(A, &BOUT[0], 8);
824 NdisMoveMemory(&R[(i-1)*8], &BOUT[8], 8);
825 } 2780 }
2781 else
2782 {
2783 DBGPRINT(RT_DEBUG_ERROR, ("ERROR : Software decrypt WEP data fails.\n"));
2784 // give up this frame
2785 return NDIS_STATUS_FAILURE;
2786 }
2787 }
2788 // handle TKIP decryption
2789 else if (GroupCipher == Ndis802_11Encryption2Enabled)
2790 {
2791 if (RTMPSoftDecryptTKIP(pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount, 0, pShard_key))
2792 {
2793
2794 //Minus 8 bytes MIC, 8 bytes IV/EIV, 4 bytes ICV
2795 pRxWI->MPDUtotalByteCount -= 20;
2796 }
2797 else
2798 {
2799 DBGPRINT(RT_DEBUG_ERROR, ("ERROR : RTMPSoftDecryptTKIP Failed\n"));
2800 // give up this frame
2801 return NDIS_STATUS_FAILURE;
2802 }
826 } 2803 }
2804 // handle AES decryption
2805 else if (GroupCipher == Ndis802_11Encryption3Enabled)
2806 {
2807 if (RTMPSoftDecryptAES(pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount , pShard_key))
2808 {
827 2809
828 // OUTPUT 2810 //8 bytes MIC, 8 bytes IV/EIV (CCMP Header)
829 for(i = 0; i < c_len; i++) 2811 pRxWI->MPDUtotalByteCount -= 16;
2812 }
2813 else
2814 {
2815 DBGPRINT(RT_DEBUG_ERROR, ("ERROR : RTMPSoftDecryptAES Failed\n"));
2816 // give up this frame
2817 return NDIS_STATUS_FAILURE;
2818 }
2819 }
2820 else
830 { 2821 {
831 plaintext[i] = R[i]; 2822 // give up this frame
2823 return NDIS_STATUS_FAILURE;
832 } 2824 }
833 2825
2826 return NDIS_STATUS_SUCCESS;
2827
2828}
2829
2830
2831PUINT8 GetSuiteFromRSNIE(
2832 IN PUINT8 rsnie,
2833 IN UINT rsnie_len,
2834 IN UINT8 type,
2835 OUT UINT8 *count)
2836{
2837 PEID_STRUCT pEid;
2838 INT len;
2839 PUINT8 pBuf;
2840 INT offset = 0;
2841 PRSNIE_AUTH pAkm;
2842 UINT16 acount;
2843 BOOLEAN isWPA2 = FALSE;
2844
2845 pEid = (PEID_STRUCT)rsnie;
2846 len = rsnie_len - 2; // exclude IE and length
2847 pBuf = (PUINT8)&pEid->Octet[0];
2848
2849
2850
2851 // set default value
2852 *count = 0;
2853
2854 // Check length
2855 if ((len <= 0) || (pEid->Len != len))
2856 {
2857 DBGPRINT_ERR(("%s : The length is invalid\n", __func__));
2858 return NULL;
2859 }
2860
2861 // Check WPA or WPA2
2862 if (pEid->Eid == IE_WPA)
2863 {
2864 PRSNIE pRsnie = (PRSNIE)pBuf;
2865 UINT16 ucount;
2866
2867 if (len < sizeof(RSNIE))
2868 {
2869 DBGPRINT_ERR(("%s : The length is too short for WPA\n", __func__));
2870 return NULL;
2871 }
2872
2873 // Get the count of pairwise cipher
2874 ucount = cpu2le16(pRsnie->ucount);
2875 if (ucount > 2)
2876 {
2877 DBGPRINT_ERR(("%s : The count(%d) of pairwise cipher is invlaid\n",
2878 __func__, ucount));
2879 return NULL;
2880 }
2881
2882 // Get the group cipher
2883 if (type == GROUP_SUITE)
2884 {
2885 *count = 1;
2886 return pRsnie->mcast;
2887 }
2888 // Get the pairwise cipher suite
2889 else if (type == PAIRWISE_SUITE)
2890 {
2891 DBGPRINT(RT_DEBUG_TRACE, ("%s : The count of pairwise cipher is %d\n",
2892 __func__, ucount));
2893 *count = ucount;
2894 return pRsnie->ucast[0].oui;
2895 }
2896
2897 offset = sizeof(RSNIE) + (4 * (ucount - 1));
2898
2899 }
2900 else if (pEid->Eid == IE_RSN)
2901 {
2902 PRSNIE2 pRsnie = (PRSNIE2)pBuf;
2903 UINT16 ucount;
2904
2905 isWPA2 = TRUE;
2906
2907 if (len < sizeof(RSNIE2))
2908 {
2909 DBGPRINT_ERR(("%s : The length is too short for WPA2\n", __func__));
2910 return NULL;
2911 }
2912
2913 // Get the count of pairwise cipher
2914 ucount = cpu2le16(pRsnie->ucount);
2915 if (ucount > 2)
2916 {
2917 DBGPRINT_ERR(("%s : The count(%d) of pairwise cipher is invlaid\n",
2918 __func__, ucount));
2919 return NULL;
2920 }
2921
2922 // Get the group cipher
2923 if (type == GROUP_SUITE)
2924 {
2925 *count = 1;
2926 return pRsnie->mcast;
2927 }
2928 // Get the pairwise cipher suite
2929 else if (type == PAIRWISE_SUITE)
2930 {
2931 DBGPRINT(RT_DEBUG_TRACE, ("%s : The count of pairwise cipher is %d\n",
2932 __func__, ucount));
2933 *count = ucount;
2934 return pRsnie->ucast[0].oui;
2935 }
2936
2937 offset = sizeof(RSNIE2) + (4 * (ucount - 1));
2938
2939 }
2940 else
2941 {
2942 DBGPRINT_ERR(("%s : Unknown IE (%d)\n", __func__, pEid->Eid));
2943 return NULL;
2944 }
2945
2946 // skip group cipher and pairwise cipher suite
2947 pBuf += offset;
2948 len -= offset;
2949
2950 if (len < sizeof(RSNIE_AUTH))
2951 {
2952 DBGPRINT_ERR(("%s : The length of RSNIE is too short\n", __func__));
2953 return NULL;
2954 }
2955
2956 // pointer to AKM count
2957 pAkm = (PRSNIE_AUTH)pBuf;
2958
2959 // Get the count of pairwise cipher
2960 acount = cpu2le16(pAkm->acount);
2961 if (acount > 2)
2962 {
2963 DBGPRINT_ERR(("%s : The count(%d) of AKM is invlaid\n",
2964 __func__, acount));
2965 return NULL;
2966 }
2967
2968 // Get the AKM suite
2969 if (type == AKM_SUITE)
2970 {
2971 DBGPRINT(RT_DEBUG_TRACE, ("%s : The count of AKM is %d\n",
2972 __func__, acount));
2973 *count = acount;
2974 return pAkm->auth[0].oui;
2975 }
2976 offset = sizeof(RSNIE_AUTH) + (4 * (acount - 1));
2977
2978 pBuf += offset;
2979 len -= offset;
2980
2981 // The remaining length must larger than (RSN-Capability(2) + PMKID-Count(2) + PMKID(16~))
2982 if (len >= (sizeof(RSN_CAPABILITIES) + 2 + LEN_PMKID))
2983 {
2984 // Skip RSN capability and PMKID-Count
2985 pBuf += (sizeof(RSN_CAPABILITIES) + 2);
2986 len -= (sizeof(RSN_CAPABILITIES) + 2);
2987
2988 // Get PMKID
2989 if (type == PMKID_LIST)
2990 {
2991 *count = 1;
2992 return pBuf;
2993 }
2994 }
2995 else
2996 {
2997 DBGPRINT_ERR(("%s : it can't get any more information beyond AKM \n", __func__));
2998 return NULL;
2999 }
3000
3001 *count = 0;
3002 //DBGPRINT_ERR(("%s : The type(%d) doesn't support \n", __func__, type));
3003 return NULL;
3004
3005}
3006
3007VOID WpaShowAllsuite(
3008 IN PUINT8 rsnie,
3009 IN UINT rsnie_len)
3010{
3011 PUINT8 pSuite = NULL;
3012 UINT8 count;
3013
3014 hex_dump("RSNIE", rsnie, rsnie_len);
3015
3016 // group cipher
3017 if ((pSuite = GetSuiteFromRSNIE(rsnie, rsnie_len, GROUP_SUITE, &count)) != NULL)
3018 {
3019 hex_dump("group cipher", pSuite, 4*count);
3020 }
3021
3022 // pairwise cipher
3023 if ((pSuite = GetSuiteFromRSNIE(rsnie, rsnie_len, PAIRWISE_SUITE, &count)) != NULL)
3024 {
3025 hex_dump("pairwise cipher", pSuite, 4*count);
3026 }
3027
3028 // AKM
3029 if ((pSuite = GetSuiteFromRSNIE(rsnie, rsnie_len, AKM_SUITE, &count)) != NULL)
3030 {
3031 hex_dump("AKM suite", pSuite, 4*count);
3032 }
3033
3034 // PMKID
3035 if ((pSuite = GetSuiteFromRSNIE(rsnie, rsnie_len, PMKID_LIST, &count)) != NULL)
3036 {
3037 hex_dump("PMKID", pSuite, LEN_PMKID);
3038 }
3039
3040}
3041
3042VOID RTMPInsertRSNIE(
3043 IN PUCHAR pFrameBuf,
3044 OUT PULONG pFrameLen,
3045 IN PUINT8 rsnie_ptr,
3046 IN UINT8 rsnie_len,
3047 IN PUINT8 pmkid_ptr,
3048 IN UINT8 pmkid_len)
3049{
3050 PUCHAR pTmpBuf;
3051 ULONG TempLen = 0;
3052 UINT8 extra_len = 0;
3053 UINT16 pmk_count = 0;
3054 UCHAR ie_num;
3055 UINT8 total_len = 0;
3056 UCHAR WPA2_OUI[3]={0x00,0x0F,0xAC};
3057
3058 pTmpBuf = pFrameBuf;
3059
3060 /* PMKID-List Must larger than 0 and the multiple of 16. */
3061 if (pmkid_len > 0 && ((pmkid_len & 0x0f) == 0))
3062 {
3063 extra_len = sizeof(UINT16) + pmkid_len;
3064
3065 pmk_count = (pmkid_len >> 4);
3066 pmk_count = cpu2le16(pmk_count);
3067 }
3068 else
3069 {
3070 DBGPRINT(RT_DEBUG_WARN, ("%s : The length is PMKID-List is invalid (%d), so don't insert it.\n",
3071 __func__, pmkid_len));
3072 }
3073
3074 if (rsnie_len != 0)
3075 {
3076 ie_num = IE_WPA;
3077 total_len = rsnie_len;
3078
3079 if (NdisEqualMemory(rsnie_ptr + 2, WPA2_OUI, sizeof(WPA2_OUI)))
3080 {
3081 ie_num = IE_RSN;
3082 total_len += extra_len;
3083 }
3084
3085 /* construct RSNIE body */
3086 MakeOutgoingFrame(pTmpBuf, &TempLen,
3087 1, &ie_num,
3088 1, &total_len,
3089 rsnie_len, rsnie_ptr,
3090 END_OF_ARGS);
3091
3092 pTmpBuf += TempLen;
3093 *pFrameLen = *pFrameLen + TempLen;
3094
3095 if (ie_num == IE_RSN)
3096 {
3097 /* Insert PMKID-List field */
3098 if (extra_len > 0)
3099 {
3100 MakeOutgoingFrame(pTmpBuf, &TempLen,
3101 2, &pmk_count,
3102 pmkid_len, pmkid_ptr,
3103 END_OF_ARGS);
3104
3105 pTmpBuf += TempLen;
3106 *pFrameLen = *pFrameLen + TempLen;
3107 }
3108 }
3109 }
834 3110
835 os_free_mem(NULL, R); 3111 return;
836} 3112}
diff --git a/drivers/staging/rt2860/common/crypt_hmac.c b/drivers/staging/rt2860/common/crypt_hmac.c
new file mode 100644
index 00000000000..02701a5e328
--- /dev/null
+++ b/drivers/staging/rt2860/common/crypt_hmac.c
@@ -0,0 +1,194 @@
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
30#ifdef HMAC_SHA1_SUPPORT
31/*
32========================================================================
33Routine Description:
34 HMAC using SHA1 hash function
35
36Arguments:
37 key Secret key
38 key_len The length of the key in bytes
39 message Message context
40 message_len The length of message in bytes
41 macLen Request the length of message authentication code
42
43Return Value:
44 mac Message authentication code
45
46Note:
47 None
48========================================================================
49*/
50VOID HMAC_SHA1 (
51 IN const UINT8 Key[],
52 IN UINT KeyLen,
53 IN const UINT8 Message[],
54 IN UINT MessageLen,
55 OUT UINT8 MAC[],
56 IN UINT MACLen)
57{
58 SHA1_CTX_STRUC sha_ctx1;
59 SHA1_CTX_STRUC sha_ctx2;
60 UINT8 K0[SHA1_BLOCK_SIZE];
61 UINT8 Digest[SHA1_DIGEST_SIZE];
62 UINT index;
63
64 NdisZeroMemory(&sha_ctx1, sizeof(SHA1_CTX_STRUC));
65 NdisZeroMemory(&sha_ctx2, sizeof(SHA1_CTX_STRUC));
66 /*
67 * If the length of K = B(Block size): K0 = K.
68 * If the length of K > B: hash K to obtain an L byte string,
69 * then append (B-L) zeros to create a B-byte string K0 (i.e., K0 = H(K) || 00...00).
70 * If the length of K < B: append zeros to the end of K to create a B-byte string K0
71 */
72 NdisZeroMemory(K0, SHA1_BLOCK_SIZE);
73 if (KeyLen <= SHA1_BLOCK_SIZE)
74 NdisMoveMemory(K0, Key, KeyLen);
75 else
76 RT_SHA1(Key, KeyLen, K0);
77 /* End of if */
78
79 /* Exclusive-Or K0 with ipad */
80 /* ipad: Inner pad; the byte x¡¦36¡¦ repeated B times. */
81 for (index = 0; index < SHA1_BLOCK_SIZE; index++)
82 K0[index] ^= 0x36;
83 /* End of for */
84
85 RT_SHA1_Init(&sha_ctx1);
86 /* H(K0^ipad) */
87 SHA1_Append(&sha_ctx1, K0, sizeof(K0));
88 /* H((K0^ipad)||text) */
89 SHA1_Append(&sha_ctx1, Message, MessageLen);
90 SHA1_End(&sha_ctx1, Digest);
91
92 /* Exclusive-Or K0 with opad and remove ipad */
93 /* opad: Outer pad; the byte x¡¦5c¡¦ repeated B times. */
94 for (index = 0; index < SHA1_BLOCK_SIZE; index++)
95 K0[index] ^= 0x36^0x5c;
96 /* End of for */
97
98 RT_SHA1_Init(&sha_ctx2);
99 /* H(K0^opad) */
100 SHA1_Append(&sha_ctx2, K0, sizeof(K0));
101 /* H( (K0^opad) || H((K0^ipad)||text) ) */
102 SHA1_Append(&sha_ctx2, Digest, SHA1_DIGEST_SIZE);
103 SHA1_End(&sha_ctx2, Digest);
104
105 if (MACLen > SHA1_DIGEST_SIZE)
106 NdisMoveMemory(MAC, Digest, SHA1_DIGEST_SIZE);
107 else
108 NdisMoveMemory(MAC, Digest, MACLen);
109} /* End of HMAC_SHA1 */
110#endif /* HMAC_SHA1_SUPPORT */
111
112#ifdef HMAC_MD5_SUPPORT
113/*
114========================================================================
115Routine Description:
116 HMAC using MD5 hash function
117
118Arguments:
119 key Secret key
120 key_len The length of the key in bytes
121 message Message context
122 message_len The length of message in bytes
123 macLen Request the length of message authentication code
124
125Return Value:
126 mac Message authentication code
127
128Note:
129 None
130========================================================================
131*/
132VOID HMAC_MD5(
133 IN const UINT8 Key[],
134 IN UINT KeyLen,
135 IN const UINT8 Message[],
136 IN UINT MessageLen,
137 OUT UINT8 MAC[],
138 IN UINT MACLen)
139{
140 MD5_CTX_STRUC md5_ctx1;
141 MD5_CTX_STRUC md5_ctx2;
142 UINT8 K0[MD5_BLOCK_SIZE];
143 UINT8 Digest[MD5_DIGEST_SIZE];
144 UINT index;
145
146 NdisZeroMemory(&md5_ctx1, sizeof(MD5_CTX_STRUC));
147 NdisZeroMemory(&md5_ctx2, sizeof(MD5_CTX_STRUC));
148 /*
149 * If the length of K = B(Block size): K0 = K.
150 * If the length of K > B: hash K to obtain an L byte string,
151 * then append (B-L) zeros to create a B-byte string K0 (i.e., K0 = H(K) || 00...00).
152 * If the length of K < B: append zeros to the end of K to create a B-byte string K0
153 */
154 NdisZeroMemory(K0, MD5_BLOCK_SIZE);
155 if (KeyLen <= MD5_BLOCK_SIZE) {
156 NdisMoveMemory(K0, Key, KeyLen);
157 } else {
158 RT_MD5(Key, KeyLen, K0);
159 }
160
161 /* Exclusive-Or K0 with ipad */
162 /* ipad: Inner pad; the byte x¡¦36¡¦ repeated B times. */
163 for (index = 0; index < MD5_BLOCK_SIZE; index++)
164 K0[index] ^= 0x36;
165 /* End of for */
166
167 MD5_Init(&md5_ctx1);
168 /* H(K0^ipad) */
169 MD5_Append(&md5_ctx1, K0, sizeof(K0));
170 /* H((K0^ipad)||text) */
171 MD5_Append(&md5_ctx1, Message, MessageLen);
172 MD5_End(&md5_ctx1, Digest);
173
174 /* Exclusive-Or K0 with opad and remove ipad */
175 /* opad: Outer pad; the byte x¡¦5c¡¦ repeated B times. */
176 for (index = 0; index < MD5_BLOCK_SIZE; index++)
177 K0[index] ^= 0x36^0x5c;
178 /* End of for */
179
180 MD5_Init(&md5_ctx2);
181 /* H(K0^opad) */
182 MD5_Append(&md5_ctx2, K0, sizeof(K0));
183 /* H( (K0^opad) || H((K0^ipad)||text) ) */
184 MD5_Append(&md5_ctx2, Digest, MD5_DIGEST_SIZE);
185 MD5_End(&md5_ctx2, Digest);
186
187 if (MACLen > MD5_DIGEST_SIZE)
188 NdisMoveMemory(MAC, Digest, MD5_DIGEST_SIZE);
189 else
190 NdisMoveMemory(MAC, Digest, MACLen);
191} /* End of HMAC_SHA256 */
192#endif /* HMAC_MD5_SUPPORT */
193
194/* End of crypt_hmac.c */
diff --git a/drivers/staging/rt2860/common/crypt_md5.c b/drivers/staging/rt2860/common/crypt_md5.c
new file mode 100644
index 00000000000..7c9ecfa8e5a
--- /dev/null
+++ b/drivers/staging/rt2860/common/crypt_md5.c
@@ -0,0 +1,352 @@
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) + (UINT32)(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) + (UINT32)(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) + (UINT32)(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) + (UINT32)(ac); \
58 (a) = ROTL32((a),(s)); \
59 (a) += (b); \
60}
61static const UINT32 MD5_DefaultHashValue[4] = {
62 0x67452301UL, 0xefcdab89UL, 0x98badcfeUL, 0x10325476UL
63};
64#endif /* MD5_SUPPORT */
65
66
67#ifdef MD5_SUPPORT
68/*
69========================================================================
70Routine Description:
71 Initial Md5_CTX_STRUC
72
73Arguments:
74 pMD5_CTX Pointer to Md5_CTX_STRUC
75
76Return Value:
77 None
78
79Note:
80 None
81========================================================================
82*/
83VOID MD5_Init (
84 IN MD5_CTX_STRUC *pMD5_CTX)
85{
86 NdisMoveMemory(pMD5_CTX->HashValue, MD5_DefaultHashValue,
87 sizeof(MD5_DefaultHashValue));
88 NdisZeroMemory(pMD5_CTX->Block, MD5_BLOCK_SIZE);
89 pMD5_CTX->BlockLen = 0;
90 pMD5_CTX->MessageLen = 0;
91} /* End of MD5_Init */
92
93
94/*
95========================================================================
96Routine Description:
97 MD5 computation for one block (512 bits)
98
99Arguments:
100 pMD5_CTX Pointer to Md5_CTX_STRUC
101
102Return Value:
103 None
104
105Note:
106 T[i] := floor(abs(sin(i + 1)) * (2 pow 32)), i is number of round
107========================================================================
108*/
109VOID MD5_Hash (
110 IN MD5_CTX_STRUC *pMD5_CTX)
111{
112 UINT32 X_i;
113 UINT32 X[16];
114 UINT32 a,b,c,d;
115
116 /* Prepare the message schedule, {X_i} */
117 NdisMoveMemory(X, pMD5_CTX->Block, MD5_BLOCK_SIZE);
118 for (X_i = 0; X_i < 16; X_i++)
119 X[X_i] = cpu2le32(X[X_i]); /* Endian Swap */
120 /* End of for */
121
122 /* MD5 hash computation */
123 /* Initialize the working variables */
124 a = pMD5_CTX->HashValue[0];
125 b = pMD5_CTX->HashValue[1];
126 c = pMD5_CTX->HashValue[2];
127 d = pMD5_CTX->HashValue[3];
128
129 /*
130 * Round 1
131 * Let [abcd k s i] denote the operation
132 * a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s)
133 */
134 ROUND1(a, b, c, d, X[ 0], 7, 0xd76aa478); /* 1 */
135 ROUND1(d, a, b, c, X[ 1], 12, 0xe8c7b756); /* 2 */
136 ROUND1(c, d, a, b, X[ 2], 17, 0x242070db); /* 3 */
137 ROUND1(b, c, d, a, X[ 3], 22, 0xc1bdceee); /* 4 */
138 ROUND1(a, b, c, d, X[ 4], 7, 0xf57c0faf); /* 5 */
139 ROUND1(d, a, b, c, X[ 5], 12, 0x4787c62a); /* 6 */
140 ROUND1(c, d, a, b, X[ 6], 17, 0xa8304613); /* 7 */
141 ROUND1(b, c, d, a, X[ 7], 22, 0xfd469501); /* 8 */
142 ROUND1(a, b, c, d, X[ 8], 7, 0x698098d8); /* 9 */
143 ROUND1(d, a, b, c, X[ 9], 12, 0x8b44f7af); /* 10 */
144 ROUND1(c, d, a, b, X[10], 17, 0xffff5bb1); /* 11 */
145 ROUND1(b, c, d, a, X[11], 22, 0x895cd7be); /* 12 */
146 ROUND1(a, b, c, d, X[12], 7, 0x6b901122); /* 13 */
147 ROUND1(d, a, b, c, X[13], 12, 0xfd987193); /* 14 */
148 ROUND1(c, d, a, b, X[14], 17, 0xa679438e); /* 15 */
149 ROUND1(b, c, d, a, X[15], 22, 0x49b40821); /* 16 */
150
151 /*
152 * Round 2
153 * Let [abcd k s i] denote the operation
154 * a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s)
155 */
156 ROUND2(a, b, c, d, X[ 1], 5, 0xf61e2562); /* 17 */
157 ROUND2(d, a, b, c, X[ 6], 9, 0xc040b340); /* 18 */
158 ROUND2(c, d, a, b, X[11], 14, 0x265e5a51); /* 19 */
159 ROUND2(b, c, d, a, X[ 0], 20, 0xe9b6c7aa); /* 20 */
160 ROUND2(a, b, c, d, X[ 5], 5, 0xd62f105d); /* 21 */
161 ROUND2(d, a, b, c, X[10], 9, 0x2441453); /* 22 */
162 ROUND2(c, d, a, b, X[15], 14, 0xd8a1e681); /* 23 */
163 ROUND2(b, c, d, a, X[ 4], 20, 0xe7d3fbc8); /* 24 */
164 ROUND2(a, b, c, d, X[ 9], 5, 0x21e1cde6); /* 25 */
165 ROUND2(d, a, b, c, X[14], 9, 0xc33707d6); /* 26 */
166 ROUND2(c, d, a, b, X[ 3], 14, 0xf4d50d87); /* 27 */
167 ROUND2(b, c, d, a, X[ 8], 20, 0x455a14ed); /* 28 */
168 ROUND2(a, b, c, d, X[13], 5, 0xa9e3e905); /* 29 */
169 ROUND2(d, a, b, c, X[ 2], 9, 0xfcefa3f8); /* 30 */
170 ROUND2(c, d, a, b, X[ 7], 14, 0x676f02d9); /* 31 */
171 ROUND2(b, c, d, a, X[12], 20, 0x8d2a4c8a); /* 32 */
172
173 /*
174 * Round 3
175 * Let [abcd k s t] denote the operation
176 * a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s)
177 */
178 ROUND3(a, b, c, d, X[ 5], 4, 0xfffa3942); /* 33 */
179 ROUND3(d, a, b, c, X[ 8], 11, 0x8771f681); /* 34 */
180 ROUND3(c, d, a, b, X[11], 16, 0x6d9d6122); /* 35 */
181 ROUND3(b, c, d, a, X[14], 23, 0xfde5380c); /* 36 */
182 ROUND3(a, b, c, d, X[ 1], 4, 0xa4beea44); /* 37 */
183 ROUND3(d, a, b, c, X[ 4], 11, 0x4bdecfa9); /* 38 */
184 ROUND3(c, d, a, b, X[ 7], 16, 0xf6bb4b60); /* 39 */
185 ROUND3(b, c, d, a, X[10], 23, 0xbebfbc70); /* 40 */
186 ROUND3(a, b, c, d, X[13], 4, 0x289b7ec6); /* 41 */
187 ROUND3(d, a, b, c, X[ 0], 11, 0xeaa127fa); /* 42 */
188 ROUND3(c, d, a, b, X[ 3], 16, 0xd4ef3085); /* 43 */
189 ROUND3(b, c, d, a, X[ 6], 23, 0x4881d05); /* 44 */
190 ROUND3(a, b, c, d, X[ 9], 4, 0xd9d4d039); /* 45 */
191 ROUND3(d, a, b, c, X[12], 11, 0xe6db99e5); /* 46 */
192 ROUND3(c, d, a, b, X[15], 16, 0x1fa27cf8); /* 47 */
193 ROUND3(b, c, d, a, X[ 2], 23, 0xc4ac5665); /* 48 */
194
195 /*
196 * Round 4
197 * Let [abcd k s t] denote the operation
198 * a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s)
199 */
200 ROUND4(a, b, c, d, X[ 0], 6, 0xf4292244); /* 49 */
201 ROUND4(d, a, b, c, X[ 7], 10, 0x432aff97); /* 50 */
202 ROUND4(c, d, a, b, X[14], 15, 0xab9423a7); /* 51 */
203 ROUND4(b, c, d, a, X[ 5], 21, 0xfc93a039); /* 52 */
204 ROUND4(a, b, c, d, X[12], 6, 0x655b59c3); /* 53 */
205 ROUND4(d, a, b, c, X[ 3], 10, 0x8f0ccc92); /* 54 */
206 ROUND4(c, d, a, b, X[10], 15, 0xffeff47d); /* 55 */
207 ROUND4(b, c, d, a, X[ 1], 21, 0x85845dd1); /* 56 */
208 ROUND4(a, b, c, d, X[ 8], 6, 0x6fa87e4f); /* 57 */
209 ROUND4(d, a, b, c, X[15], 10, 0xfe2ce6e0); /* 58 */
210 ROUND4(c, d, a, b, X[ 6], 15, 0xa3014314); /* 59 */
211 ROUND4(b, c, d, a, X[13], 21, 0x4e0811a1); /* 60 */
212 ROUND4(a, b, c, d, X[ 4], 6, 0xf7537e82); /* 61 */
213 ROUND4(d, a, b, c, X[11], 10, 0xbd3af235); /* 62 */
214 ROUND4(c, d, a, b, X[ 2], 15, 0x2ad7d2bb); /* 63 */
215 ROUND4(b, c, d, a, X[ 9], 21, 0xeb86d391); /* 64 */
216
217 /* Compute the i^th intermediate hash value H^(i) */
218 pMD5_CTX->HashValue[0] += a;
219 pMD5_CTX->HashValue[1] += b;
220 pMD5_CTX->HashValue[2] += c;
221 pMD5_CTX->HashValue[3] += d;
222
223 NdisZeroMemory(pMD5_CTX->Block, MD5_BLOCK_SIZE);
224 pMD5_CTX->BlockLen = 0;
225} /* End of MD5_Hash */
226
227
228/*
229========================================================================
230Routine Description:
231 The message is appended to block. If block size > 64 bytes, the MD5_Hash
232will be called.
233
234Arguments:
235 pMD5_CTX Pointer to MD5_CTX_STRUC
236 message Message context
237 messageLen The length of message in bytes
238
239Return Value:
240 None
241
242Note:
243 None
244========================================================================
245*/
246VOID MD5_Append (
247 IN MD5_CTX_STRUC *pMD5_CTX,
248 IN const UINT8 Message[],
249 IN UINT MessageLen)
250{
251 UINT appendLen = 0;
252 UINT diffLen = 0;
253
254 while (appendLen != MessageLen) {
255 diffLen = MessageLen - appendLen;
256 if ((pMD5_CTX->BlockLen + diffLen) < MD5_BLOCK_SIZE) {
257 NdisMoveMemory(pMD5_CTX->Block + pMD5_CTX->BlockLen,
258 Message + appendLen, diffLen);
259 pMD5_CTX->BlockLen += diffLen;
260 appendLen += diffLen;
261 }
262 else
263 {
264 NdisMoveMemory(pMD5_CTX->Block + pMD5_CTX->BlockLen,
265 Message + appendLen, MD5_BLOCK_SIZE - pMD5_CTX->BlockLen);
266 appendLen += (MD5_BLOCK_SIZE - pMD5_CTX->BlockLen);
267 pMD5_CTX->BlockLen = MD5_BLOCK_SIZE;
268 MD5_Hash(pMD5_CTX);
269 } /* End of if */
270 } /* End of while */
271 pMD5_CTX->MessageLen += MessageLen;
272} /* End of MD5_Append */
273
274
275/*
276========================================================================
277Routine Description:
278 1. Append bit 1 to end of the message
279 2. Append the length of message in rightmost 64 bits
280 3. Transform the Hash Value to digest message
281
282Arguments:
283 pMD5_CTX Pointer to MD5_CTX_STRUC
284
285Return Value:
286 digestMessage Digest message
287
288Note:
289 None
290========================================================================
291*/
292VOID MD5_End (
293 IN MD5_CTX_STRUC *pMD5_CTX,
294 OUT UINT8 DigestMessage[])
295{
296 UINT index;
297 UINT64 message_length_bits;
298
299 /* append 1 bits to end of the message */
300 NdisFillMemory(pMD5_CTX->Block + pMD5_CTX->BlockLen, 1, 0x80);
301
302 /* 55 = 64 - 8 - 1: append 1 bit(1 byte) and message length (8 bytes) */
303 if (pMD5_CTX->BlockLen > 55)
304 MD5_Hash(pMD5_CTX);
305 /* End of if */
306
307 /* Append the length of message in rightmost 64 bits */
308 message_length_bits = pMD5_CTX->MessageLen*8;
309 message_length_bits = cpu2le64(message_length_bits);
310 NdisMoveMemory(&pMD5_CTX->Block[56], &message_length_bits, 8);
311 MD5_Hash(pMD5_CTX);
312
313 /* Return message digest, transform the UINT32 hash value to bytes */
314 for (index = 0; index < 4;index++)
315 pMD5_CTX->HashValue[index] = cpu2le32(pMD5_CTX->HashValue[index]);
316 /* End of for */
317 NdisMoveMemory(DigestMessage, pMD5_CTX->HashValue, MD5_DIGEST_SIZE);
318} /* End of MD5_End */
319
320
321/*
322========================================================================
323Routine Description:
324 MD5 algorithm
325
326Arguments:
327 message Message context
328 messageLen The length of message in bytes
329
330Return Value:
331 digestMessage Digest message
332
333Note:
334 None
335========================================================================
336*/
337VOID RT_MD5 (
338 IN const UINT8 Message[],
339 IN UINT MessageLen,
340 OUT UINT8 DigestMessage[])
341{
342 MD5_CTX_STRUC md5_ctx;
343
344 NdisZeroMemory(&md5_ctx, sizeof(MD5_CTX_STRUC));
345 MD5_Init(&md5_ctx);
346 MD5_Append(&md5_ctx, Message, MessageLen);
347 MD5_End(&md5_ctx, DigestMessage);
348} /* End of RT_MD5 */
349
350#endif /* MD5_SUPPORT */
351
352/* End of crypt_md5.c */
diff --git a/drivers/staging/rt2860/common/crypt_sha2.c b/drivers/staging/rt2860/common/crypt_sha2.c
new file mode 100644
index 00000000000..cb3f7c27b62
--- /dev/null
+++ b/drivers/staging/rt2860/common/crypt_sha2.c
@@ -0,0 +1,535 @@
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 UINT32 SHA1_K[4] = {
45 0x5a827999UL, 0x6ed9eba1UL, 0x8f1bbcdcUL, 0xca62c1d6UL
46};
47static const UINT32 SHA1_DefaultHashValue[5] = {
48 0x67452301UL, 0xefcdab89UL, 0x98badcfeUL, 0x10325476UL, 0xc3d2e1f0UL
49};
50#endif /* SHA1_SUPPORT */
51
52
53#ifdef SHA256_SUPPORT
54/* SHA256 functions */
55#define Zsigma_256_0(x) (ROTR32(x,2) ^ ROTR32(x,13) ^ ROTR32(x,22))
56#define Zsigma_256_1(x) (ROTR32(x,6) ^ ROTR32(x,11) ^ ROTR32(x,25))
57#define Sigma_256_0(x) (ROTR32(x,7) ^ ROTR32(x,18) ^ SHR(x,3))
58#define Sigma_256_1(x) (ROTR32(x,17) ^ ROTR32(x,19) ^ SHR(x,10))
59/* SHA256 constants */
60static const UINT32 SHA256_K[64] = {
61 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
62 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
63 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,
64 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL,
65 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
66 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,
67 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL,
68 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL,
69 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL,
70 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
71 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL,
72 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,
73 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL,
74 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL,
75 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
76 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
77};
78static const UINT32 SHA256_DefaultHashValue[8] = {
79 0x6a09e667UL, 0xbb67ae85UL, 0x3c6ef372UL, 0xa54ff53aUL,
80 0x510e527fUL, 0x9b05688cUL, 0x1f83d9abUL, 0x5be0cd19UL
81};
82#endif /* SHA256_SUPPORT */
83
84
85#ifdef SHA1_SUPPORT
86/*
87========================================================================
88Routine Description:
89 Initial SHA1_CTX_STRUC
90
91Arguments:
92 pSHA_CTX Pointer to SHA1_CTX_STRUC
93
94Return Value:
95 None
96
97Note:
98 None
99========================================================================
100*/
101VOID RT_SHA1_Init (
102 IN SHA1_CTX_STRUC *pSHA_CTX)
103{
104 NdisMoveMemory(pSHA_CTX->HashValue, SHA1_DefaultHashValue,
105 sizeof(SHA1_DefaultHashValue));
106 NdisZeroMemory(pSHA_CTX->Block, SHA1_BLOCK_SIZE);
107 pSHA_CTX->MessageLen = 0;
108 pSHA_CTX->BlockLen = 0;
109} /* End of RT_SHA1_Init */
110
111
112/*
113========================================================================
114Routine Description:
115 SHA1 computation for one block (512 bits)
116
117Arguments:
118 pSHA_CTX Pointer to SHA1_CTX_STRUC
119
120Return Value:
121 None
122
123Note:
124 None
125========================================================================
126*/
127VOID SHA1_Hash (
128 IN SHA1_CTX_STRUC *pSHA_CTX)
129{
130 UINT32 W_i,t,s;
131 UINT32 W[16];
132 UINT32 a,b,c,d,e,T,f_t = 0;
133
134 /* Prepare the message schedule, {W_i}, 0 < t < 15 */
135 NdisMoveMemory(W, pSHA_CTX->Block, SHA1_BLOCK_SIZE);
136 for (W_i = 0; W_i < 16; W_i++)
137 W[W_i] = cpu2be32(W[W_i]); /* Endian Swap */
138 /* End of for */
139
140 /* SHA256 hash computation */
141 /* Initialize the working variables */
142 a = pSHA_CTX->HashValue[0];
143 b = pSHA_CTX->HashValue[1];
144 c = pSHA_CTX->HashValue[2];
145 d = pSHA_CTX->HashValue[3];
146 e = pSHA_CTX->HashValue[4];
147
148 /* 80 rounds */
149 for (t = 0;t < 80;t++) {
150 s = t & SHA1_MASK;
151 if (t > 15) { /* Prepare the message schedule, {W_i}, 16 < t < 79 */
152 W[s] = (W[(s+13) & SHA1_MASK]) ^ (W[(s+8) & SHA1_MASK]) ^ (W[(s+2) & SHA1_MASK]) ^ W[s];
153 W[s] = ROTL32(W[s],1);
154 } /* End of if */
155 switch (t / 20) {
156 case 0:
157 f_t = Ch(b,c,d);
158 break;
159 case 1:
160 f_t = Parity(b,c,d);
161 break;
162 case 2:
163 f_t = Maj(b,c,d);
164 break;
165 case 3:
166 f_t = Parity(b,c,d);
167 break;
168 } /* End of switch */
169 T = ROTL32(a,5) + f_t + e + SHA1_K[t / 20] + W[s];
170 e = d;
171 d = c;
172 c = ROTL32(b,30);
173 b = a;
174 a = T;
175 } /* End of for */
176
177 /* Compute the i^th intermediate hash value H^(i) */
178 pSHA_CTX->HashValue[0] += a;
179 pSHA_CTX->HashValue[1] += b;
180 pSHA_CTX->HashValue[2] += c;
181 pSHA_CTX->HashValue[3] += d;
182 pSHA_CTX->HashValue[4] += e;
183
184 NdisZeroMemory(pSHA_CTX->Block, SHA1_BLOCK_SIZE);
185 pSHA_CTX->BlockLen = 0;
186} /* End of SHA1_Hash */
187
188
189/*
190========================================================================
191Routine Description:
192 The message is appended to block. If block size > 64 bytes, the SHA1_Hash
193will be called.
194
195Arguments:
196 pSHA_CTX Pointer to SHA1_CTX_STRUC
197 message Message context
198 messageLen The length of message in bytes
199
200Return Value:
201 None
202
203Note:
204 None
205========================================================================
206*/
207VOID SHA1_Append (
208 IN SHA1_CTX_STRUC *pSHA_CTX,
209 IN const UINT8 Message[],
210 IN UINT MessageLen)
211{
212 UINT appendLen = 0;
213 UINT diffLen = 0;
214
215 while (appendLen != MessageLen) {
216 diffLen = MessageLen - appendLen;
217 if ((pSHA_CTX->BlockLen + diffLen) < SHA1_BLOCK_SIZE) {
218 NdisMoveMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen,
219 Message + appendLen, diffLen);
220 pSHA_CTX->BlockLen += diffLen;
221 appendLen += diffLen;
222 }
223 else
224 {
225 NdisMoveMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen,
226 Message + appendLen, SHA1_BLOCK_SIZE - pSHA_CTX->BlockLen);
227 appendLen += (SHA1_BLOCK_SIZE - pSHA_CTX->BlockLen);
228 pSHA_CTX->BlockLen = SHA1_BLOCK_SIZE;
229 SHA1_Hash(pSHA_CTX);
230 } /* End of if */
231 } /* End of while */
232 pSHA_CTX->MessageLen += MessageLen;
233} /* End of SHA1_Append */
234
235
236/*
237========================================================================
238Routine Description:
239 1. Append bit 1 to end of the message
240 2. Append the length of message in rightmost 64 bits
241 3. Transform the Hash Value to digest message
242
243Arguments:
244 pSHA_CTX Pointer to SHA1_CTX_STRUC
245
246Return Value:
247 digestMessage Digest message
248
249Note:
250 None
251========================================================================
252*/
253VOID SHA1_End (
254 IN SHA1_CTX_STRUC *pSHA_CTX,
255 OUT UINT8 DigestMessage[])
256{
257 UINT index;
258 UINT64 message_length_bits;
259
260 /* Append bit 1 to end of the message */
261 NdisFillMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen, 1, 0x80);
262
263 /* 55 = 64 - 8 - 1: append 1 bit(1 byte) and message length (8 bytes) */
264 if (pSHA_CTX->BlockLen > 55)
265 SHA1_Hash(pSHA_CTX);
266 /* End of if */
267
268 /* Append the length of message in rightmost 64 bits */
269 message_length_bits = pSHA_CTX->MessageLen*8;
270 message_length_bits = cpu2be64(message_length_bits);
271 NdisMoveMemory(&pSHA_CTX->Block[56], &message_length_bits, 8);
272 SHA1_Hash(pSHA_CTX);
273
274 /* Return message digest, transform the UINT32 hash value to bytes */
275 for (index = 0; index < 5;index++)
276 pSHA_CTX->HashValue[index] = cpu2be32(pSHA_CTX->HashValue[index]);
277 /* End of for */
278 NdisMoveMemory(DigestMessage, pSHA_CTX->HashValue, SHA1_DIGEST_SIZE);
279} /* End of SHA1_End */
280
281
282/*
283========================================================================
284Routine Description:
285 SHA1 algorithm
286
287Arguments:
288 message Message context
289 messageLen The length of message in bytes
290
291Return Value:
292 digestMessage Digest message
293
294Note:
295 None
296========================================================================
297*/
298VOID RT_SHA1 (
299 IN const UINT8 Message[],
300 IN UINT MessageLen,
301 OUT UINT8 DigestMessage[])
302{
303
304 SHA1_CTX_STRUC sha_ctx;
305
306 NdisZeroMemory(&sha_ctx, sizeof(SHA1_CTX_STRUC));
307 RT_SHA1_Init(&sha_ctx);
308 SHA1_Append(&sha_ctx, Message, MessageLen);
309 SHA1_End(&sha_ctx, DigestMessage);
310} /* End of RT_SHA1 */
311#endif /* SHA1_SUPPORT */
312
313
314#ifdef SHA256_SUPPORT
315/*
316========================================================================
317Routine Description:
318 Initial SHA256_CTX_STRUC
319
320Arguments:
321 pSHA_CTX Pointer to SHA256_CTX_STRUC
322
323Return Value:
324 None
325
326Note:
327 None
328========================================================================
329*/
330VOID SHA256_Init (
331 IN SHA256_CTX_STRUC *pSHA_CTX)
332{
333 NdisMoveMemory(pSHA_CTX->HashValue, SHA256_DefaultHashValue,
334 sizeof(SHA256_DefaultHashValue));
335 NdisZeroMemory(pSHA_CTX->Block, SHA256_BLOCK_SIZE);
336 pSHA_CTX->MessageLen = 0;
337 pSHA_CTX->BlockLen = 0;
338} /* End of SHA256_Init */
339
340
341/*
342========================================================================
343Routine Description:
344 SHA256 computation for one block (512 bits)
345
346Arguments:
347 pSHA_CTX Pointer to SHA256_CTX_STRUC
348
349Return Value:
350 None
351
352Note:
353 None
354========================================================================
355*/
356VOID SHA256_Hash (
357 IN SHA256_CTX_STRUC *pSHA_CTX)
358{
359 UINT32 W_i,t;
360 UINT32 W[64];
361 UINT32 a,b,c,d,e,f,g,h,T1,T2;
362
363 /* Prepare the message schedule, {W_i}, 0 < t < 15 */
364 NdisMoveMemory(W, pSHA_CTX->Block, SHA256_BLOCK_SIZE);
365 for (W_i = 0; W_i < 16; W_i++)
366 W[W_i] = cpu2be32(W[W_i]); /* Endian Swap */
367 /* End of for */
368
369 /* SHA256 hash computation */
370 /* Initialize the working variables */
371 a = pSHA_CTX->HashValue[0];
372 b = pSHA_CTX->HashValue[1];
373 c = pSHA_CTX->HashValue[2];
374 d = pSHA_CTX->HashValue[3];
375 e = pSHA_CTX->HashValue[4];
376 f = pSHA_CTX->HashValue[5];
377 g = pSHA_CTX->HashValue[6];
378 h = pSHA_CTX->HashValue[7];
379
380 /* 64 rounds */
381 for (t = 0;t < 64;t++) {
382 if (t > 15) /* Prepare the message schedule, {W_i}, 16 < t < 63 */
383 W[t] = Sigma_256_1(W[t-2]) + W[t-7] + Sigma_256_0(W[t-15]) + W[t-16];
384 /* End of if */
385 T1 = h + Zsigma_256_1(e) + Ch(e,f,g) + SHA256_K[t] + W[t];
386 T2 = Zsigma_256_0(a) + Maj(a,b,c);
387 h = g;
388 g = f;
389 f = e;
390 e = d + T1;
391 d = c;
392 c = b;
393 b = a;
394 a = T1 + T2;
395 } /* End of for */
396
397 /* Compute the i^th intermediate hash value H^(i) */
398 pSHA_CTX->HashValue[0] += a;
399 pSHA_CTX->HashValue[1] += b;
400 pSHA_CTX->HashValue[2] += c;
401 pSHA_CTX->HashValue[3] += d;
402 pSHA_CTX->HashValue[4] += e;
403 pSHA_CTX->HashValue[5] += f;
404 pSHA_CTX->HashValue[6] += g;
405 pSHA_CTX->HashValue[7] += h;
406
407 NdisZeroMemory(pSHA_CTX->Block, SHA256_BLOCK_SIZE);
408 pSHA_CTX->BlockLen = 0;
409} /* End of SHA256_Hash */
410
411
412/*
413========================================================================
414Routine Description:
415 The message is appended to block. If block size > 64 bytes, the SHA256_Hash
416will be called.
417
418Arguments:
419 pSHA_CTX Pointer to SHA256_CTX_STRUC
420 message Message context
421 messageLen The length of message in bytes
422
423Return Value:
424 None
425
426Note:
427 None
428========================================================================
429*/
430VOID SHA256_Append (
431 IN SHA256_CTX_STRUC *pSHA_CTX,
432 IN const UINT8 Message[],
433 IN UINT MessageLen)
434{
435 UINT appendLen = 0;
436 UINT diffLen = 0;
437
438 while (appendLen != MessageLen) {
439 diffLen = MessageLen - appendLen;
440 if ((pSHA_CTX->BlockLen + diffLen) < SHA256_BLOCK_SIZE) {
441 NdisMoveMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen,
442 Message + appendLen, diffLen);
443 pSHA_CTX->BlockLen += diffLen;
444 appendLen += diffLen;
445 }
446 else
447 {
448 NdisMoveMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen,
449 Message + appendLen, SHA256_BLOCK_SIZE - pSHA_CTX->BlockLen);
450 appendLen += (SHA256_BLOCK_SIZE - pSHA_CTX->BlockLen);
451 pSHA_CTX->BlockLen = SHA256_BLOCK_SIZE;
452 SHA256_Hash(pSHA_CTX);
453 } /* End of if */
454 } /* End of while */
455 pSHA_CTX->MessageLen += MessageLen;
456} /* End of SHA256_Append */
457
458
459/*
460========================================================================
461Routine Description:
462 1. Append bit 1 to end of the message
463 2. Append the length of message in rightmost 64 bits
464 3. Transform the Hash Value to digest message
465
466Arguments:
467 pSHA_CTX Pointer to SHA256_CTX_STRUC
468
469Return Value:
470 digestMessage Digest message
471
472Note:
473 None
474========================================================================
475*/
476VOID SHA256_End (
477 IN SHA256_CTX_STRUC *pSHA_CTX,
478 OUT UINT8 DigestMessage[])
479{
480 UINT index;
481 UINT64 message_length_bits;
482
483 /* Append bit 1 to end of the message */
484 NdisFillMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen, 1, 0x80);
485
486 /* 55 = 64 - 8 - 1: append 1 bit(1 byte) and message length (8 bytes) */
487 if (pSHA_CTX->BlockLen > 55)
488 SHA256_Hash(pSHA_CTX);
489 /* End of if */
490
491 /* Append the length of message in rightmost 64 bits */
492 message_length_bits = pSHA_CTX->MessageLen*8;
493 message_length_bits = cpu2be64(message_length_bits);
494 NdisMoveMemory(&pSHA_CTX->Block[56], &message_length_bits, 8);
495 SHA256_Hash(pSHA_CTX);
496
497 /* Return message digest, transform the UINT32 hash value to bytes */
498 for (index = 0; index < 8;index++)
499 pSHA_CTX->HashValue[index] = cpu2be32(pSHA_CTX->HashValue[index]);
500 /* End of for */
501 NdisMoveMemory(DigestMessage, pSHA_CTX->HashValue, SHA256_DIGEST_SIZE);
502} /* End of SHA256_End */
503
504
505/*
506========================================================================
507Routine Description:
508 SHA256 algorithm
509
510Arguments:
511 message Message context
512 messageLen The length of message in bytes
513
514Return Value:
515 digestMessage Digest message
516
517Note:
518 None
519========================================================================
520*/
521VOID RT_SHA256 (
522 IN const UINT8 Message[],
523 IN UINT MessageLen,
524 OUT UINT8 DigestMessage[])
525{
526 SHA256_CTX_STRUC sha_ctx;
527
528 NdisZeroMemory(&sha_ctx, sizeof(SHA256_CTX_STRUC));
529 SHA256_Init(&sha_ctx);
530 SHA256_Append(&sha_ctx, Message, MessageLen);
531 SHA256_End(&sha_ctx, DigestMessage);
532} /* End of RT_SHA256 */
533#endif /* SHA256_SUPPORT */
534
535/* End of crypt_sha2.c */
diff --git a/drivers/staging/rt2860/common/dfs.c b/drivers/staging/rt2860/common/dfs.c
index 23330f2661d..7b3890f631e 100644
--- a/drivers/staging/rt2860/common/dfs.c
+++ b/drivers/staging/rt2860/common/dfs.c
@@ -33,7 +33,6 @@
33 Revision History: 33 Revision History:
34 Who When What 34 Who When What
35 -------- ---------- ---------------------------------------------- 35 -------- ---------- ----------------------------------------------
36 Fonchi 03-12-2007 created
37*/ 36*/
38 37
39#include "../rt_config.h" 38#include "../rt_config.h"
@@ -46,10 +45,15 @@ typedef struct _RADAR_DURATION_TABLE
46} RADAR_DURATION_TABLE, *PRADAR_DURATION_TABLE; 45} RADAR_DURATION_TABLE, *PRADAR_DURATION_TABLE;
47 46
48 47
49static UCHAR RdIdleTimeTable[MAX_RD_REGION][4] = 48
49UCHAR RdIdleTimeTable[MAX_RD_REGION][4] =
50{ 50{
51 {9, 250, 250, 250}, // CE 51 {9, 250, 250, 250}, // CE
52#ifdef DFS_FCC_BW40_FIX
53 {1, 250, 250, 250}, // FCC
54#else
52 {4, 250, 250, 250}, // FCC 55 {4, 250, 250, 250}, // FCC
56#endif
53 {4, 250, 250, 250}, // JAP 57 {4, 250, 250, 250}, // JAP
54 {15, 250, 250, 250}, // JAP_W53 58 {15, 250, 250, 250}, // JAP_W53
55 {4, 250, 250, 250} // JAP_W56 59 {4, 250, 250, 250} // JAP_W56
@@ -80,11 +84,32 @@ VOID BbpRadarDetectionStart(
80 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 124, 0x28); 84 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 124, 0x28);
81 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 125, 0xff); 85 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 125, 0xff);
82 86
87#ifdef MERGE_ARCH_TEAM
88 if ((pAd->CommonCfg.RadarDetect.RDDurRegion == JAP) || (pAd->CommonCfg.RadarDetect.RDDurRegion == JAP_W53) || (pAd->CommonCfg.RadarDetect.RDDurRegion == JAP_W56))
89 {
90 pAd->CommonCfg.RadarDetect.RDDurRegion = JAP;
91 pAd->CommonCfg.RadarDetect.RDDurRegion = JapRadarType(pAd);
92 if (pAd->CommonCfg.RadarDetect.RDDurRegion == JAP_W56)
93 {
94 pAd->CommonCfg.RadarDetect.DfsSessionTime = 13;
95 }
96 else if (pAd->CommonCfg.RadarDetect.RDDurRegion == JAP_W53)
97 {
98 pAd->CommonCfg.RadarDetect.DfsSessionTime = 15;
99 }
100 }
101#endif // MERGE_ARCH_TEAM //
102
83 RadarPeriod = ((UINT)RdIdleTimeTable[pAd->CommonCfg.RadarDetect.RDDurRegion][0] + (UINT)pAd->CommonCfg.RadarDetect.DfsSessionTime) < 250 ? 103 RadarPeriod = ((UINT)RdIdleTimeTable[pAd->CommonCfg.RadarDetect.RDDurRegion][0] + (UINT)pAd->CommonCfg.RadarDetect.DfsSessionTime) < 250 ?
84 (RdIdleTimeTable[pAd->CommonCfg.RadarDetect.RDDurRegion][0] + pAd->CommonCfg.RadarDetect.DfsSessionTime) : 250; 104 (RdIdleTimeTable[pAd->CommonCfg.RadarDetect.RDDurRegion][0] + pAd->CommonCfg.RadarDetect.DfsSessionTime) : 250;
85 105
106#ifdef MERGE_ARCH_TEAM
107
108
109#else // Original RT28xx source code.
86 RTMP_IO_WRITE8(pAd, 0x7020, 0x1d); 110 RTMP_IO_WRITE8(pAd, 0x7020, 0x1d);
87 RTMP_IO_WRITE8(pAd, 0x7021, 0x40); 111 RTMP_IO_WRITE8(pAd, 0x7021, 0x40);
112#endif // MERGE_ARCH_TEAM //
88 113
89 RadarDetectionStart(pAd, 0, RadarPeriod); 114 RadarDetectionStart(pAd, 0, RadarPeriod);
90 return; 115 return;
@@ -143,6 +168,17 @@ VOID RadarDetectionStart(
143 CtsProtect = 0x03; 168 CtsProtect = 0x03;
144 break; 169 break;
145 170
171 case JAP:
172 {
173 UCHAR RDDurRegion;
174 RDDurRegion = JapRadarType(pAd);
175 if (RDDurRegion == JAP_W56)
176 CtsProtect = 0x03;
177 else
178 CtsProtect = 0x02;
179 break;
180 }
181
146 case CE: 182 case CE:
147 case JAP_W53: 183 case JAP_W53:
148 default: 184 default:
@@ -210,7 +246,6 @@ BOOLEAN RadarChannelCheck(
210 IN PRTMP_ADAPTER pAd, 246 IN PRTMP_ADAPTER pAd,
211 IN UCHAR Ch) 247 IN UCHAR Ch)
212{ 248{
213#if 1
214 INT i; 249 INT i;
215 BOOLEAN result = FALSE; 250 BOOLEAN result = FALSE;
216 251
@@ -224,23 +259,6 @@ BOOLEAN RadarChannelCheck(
224 } 259 }
225 260
226 return result; 261 return result;
227#else
228 INT i;
229 UCHAR Channel[15]={52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140};
230
231 for (i=0; i<15; i++)
232 {
233 if (Ch == Channel[i])
234 {
235 break;
236 }
237 }
238
239 if (i != 15)
240 return TRUE;
241 else
242 return FALSE;
243#endif
244} 262}
245 263
246ULONG JapRadarType( 264ULONG JapRadarType(
@@ -399,11 +417,11 @@ VOID RadarDetectPeriodic(
399*/ 417*/
400INT Set_ChMovingTime_Proc( 418INT Set_ChMovingTime_Proc(
401 IN PRTMP_ADAPTER pAd, 419 IN PRTMP_ADAPTER pAd,
402 IN PUCHAR arg) 420 IN PSTRING arg)
403{ 421{
404 UINT8 Value; 422 UINT8 Value;
405 423
406 Value = simple_strtol(arg, 0, 10); 424 Value = (UINT8) simple_strtol(arg, 0, 10);
407 425
408 pAd->CommonCfg.RadarDetect.ChMovingTime = Value; 426 pAd->CommonCfg.RadarDetect.ChMovingTime = Value;
409 427
@@ -415,11 +433,11 @@ INT Set_ChMovingTime_Proc(
415 433
416INT Set_LongPulseRadarTh_Proc( 434INT Set_LongPulseRadarTh_Proc(
417 IN PRTMP_ADAPTER pAd, 435 IN PRTMP_ADAPTER pAd,
418 IN PUCHAR arg) 436 IN PSTRING arg)
419{ 437{
420 UINT8 Value; 438 UINT8 Value;
421 439
422 Value = simple_strtol(arg, 0, 10) > 10 ? 10 : simple_strtol(arg, 0, 10); 440 Value = (UINT8) simple_strtol(arg, 0, 10) > 10 ? 10 : simple_strtol(arg, 0, 10);
423 441
424 pAd->CommonCfg.RadarDetect.LongPulseRadarTh = Value; 442 pAd->CommonCfg.RadarDetect.LongPulseRadarTh = Value;
425 443
diff --git a/drivers/staging/rt2860/common/ee_efuse.c b/drivers/staging/rt2860/common/ee_efuse.c
new file mode 100644
index 00000000000..f52224441d2
--- /dev/null
+++ b/drivers/staging/rt2860/common/ee_efuse.c
@@ -0,0 +1,1525 @@
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
39#include "../rt_config.h"
40
41
42
43#define EFUSE_USAGE_MAP_START 0x2d0
44#define EFUSE_USAGE_MAP_END 0x2fc
45#define EFUSE_USAGE_MAP_SIZE 45
46
47
48
49#define EFUSE_EEPROM_DEFULT_FILE "RT30xxEEPROM.bin"
50#define MAX_EEPROM_BIN_FILE_SIZE 1024
51
52
53
54#define EFUSE_TAG 0x2fe
55
56typedef union _EFUSE_CTRL_STRUC {
57 struct {
58 UINT32 EFSROM_AOUT:6;
59 UINT32 EFSROM_MODE:2;
60 UINT32 EFSROM_LDO_OFF_TIME:6;
61 UINT32 EFSROM_LDO_ON_TIME:2;
62 UINT32 EFSROM_AIN:10;
63 UINT32 RESERVED:4;
64 UINT32 EFSROM_KICK:1;
65 UINT32 SEL_EFUSE:1;
66 } field;
67 UINT32 word;
68} EFUSE_CTRL_STRUC, *PEFUSE_CTRL_STRUC;
69
70static UCHAR eFuseReadRegisters(
71 IN PRTMP_ADAPTER pAd,
72 IN USHORT Offset,
73 IN USHORT Length,
74 OUT USHORT* pData);
75
76static VOID eFuseReadPhysical(
77 IN PRTMP_ADAPTER pAd,
78 IN PUSHORT lpInBuffer,
79 IN ULONG nInBufferSize,
80 OUT PUSHORT lpOutBuffer,
81 IN ULONG nOutBufferSize);
82
83static VOID eFusePhysicalWriteRegisters(
84 IN PRTMP_ADAPTER pAd,
85 IN USHORT Offset,
86 IN USHORT Length,
87 OUT USHORT* pData);
88
89static NTSTATUS eFuseWriteRegisters(
90 IN PRTMP_ADAPTER pAd,
91 IN USHORT Offset,
92 IN USHORT Length,
93 IN USHORT* pData);
94
95static VOID eFuseWritePhysical(
96 IN PRTMP_ADAPTER pAd,
97 PUSHORT lpInBuffer,
98 ULONG nInBufferSize,
99 PUCHAR lpOutBuffer,
100 ULONG nOutBufferSize);
101
102
103static NTSTATUS eFuseWriteRegistersFromBin(
104 IN PRTMP_ADAPTER pAd,
105 IN USHORT Offset,
106 IN USHORT Length,
107 IN USHORT* pData);
108
109
110/*
111========================================================================
112
113 Routine Description:
114
115 Arguments:
116
117 Return Value:
118
119 Note:
120
121========================================================================
122*/
123UCHAR eFuseReadRegisters(
124 IN PRTMP_ADAPTER pAd,
125 IN USHORT Offset,
126 IN USHORT Length,
127 OUT USHORT* pData)
128{
129 EFUSE_CTRL_STRUC eFuseCtrlStruc;
130 int i;
131 USHORT efuseDataOffset;
132 UINT32 data;
133
134 RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
135
136 //Step0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
137 //Use the eeprom logical address and covert to address to block number
138 eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
139
140 //Step1. Write EFSROM_MODE (0x580, bit7:bit6) to 0.
141 eFuseCtrlStruc.field.EFSROM_MODE = 0;
142
143 //Step2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.
144 eFuseCtrlStruc.field.EFSROM_KICK = 1;
145
146 NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
147 RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
148
149 //Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.
150 i = 0;
151 while(i < 500)
152 {
153 //rtmp.HwMemoryReadDword(EFUSE_CTRL, (DWORD *) &eFuseCtrlStruc, 4);
154 RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
155 if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
156 {
157 break;
158 }
159 RTMPusecDelay(2);
160 i++;
161 }
162
163 //if EFSROM_AOUT is not found in physical address, write 0xffff
164 if (eFuseCtrlStruc.field.EFSROM_AOUT == 0x3f)
165 {
166 for(i=0; i<Length/2; i++)
167 *(pData+2*i) = 0xffff;
168 }
169 else
170 {
171 //Step4. Read 16-byte of data from EFUSE_DATA0-3 (0x590-0x59C)
172 efuseDataOffset = EFUSE_DATA3 - (Offset & 0xC);
173 //data hold 4 bytes data.
174 //In RTMP_IO_READ32 will automatically execute 32-bytes swapping
175 RTMP_IO_READ32(pAd, efuseDataOffset, &data);
176 //Decide the upper 2 bytes or the bottom 2 bytes.
177 // Little-endian S | S Big-endian
178 // addr 3 2 1 0 | 0 1 2 3
179 // Ori-V D C B A | A B C D
180 //After swapping
181 // D C B A | D C B A
182 //Return 2-bytes
183 //The return byte statrs from S. Therefore, the little-endian will return BA, the Big-endian will return DC.
184 //For returning the bottom 2 bytes, the Big-endian should shift right 2-bytes.
185 data = data >> (8*(Offset & 0x3));
186
187 NdisMoveMemory(pData, &data, Length);
188 }
189
190 return (UCHAR) eFuseCtrlStruc.field.EFSROM_AOUT;
191
192}
193
194/*
195========================================================================
196
197 Routine Description:
198
199 Arguments:
200
201 Return Value:
202
203 Note:
204
205========================================================================
206*/
207VOID eFusePhysicalReadRegisters(
208 IN PRTMP_ADAPTER pAd,
209 IN USHORT Offset,
210 IN USHORT Length,
211 OUT USHORT* pData)
212{
213 EFUSE_CTRL_STRUC eFuseCtrlStruc;
214 int i;
215 USHORT efuseDataOffset;
216 UINT32 data;
217
218 RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
219
220 //Step0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
221 eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
222
223 //Step1. Write EFSROM_MODE (0x580, bit7:bit6) to 1.
224 //Read in physical view
225 eFuseCtrlStruc.field.EFSROM_MODE = 1;
226
227 //Step2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.
228 eFuseCtrlStruc.field.EFSROM_KICK = 1;
229
230 NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
231 RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
232
233 //Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.
234 i = 0;
235 while(i < 500)
236 {
237 RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
238 if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
239 break;
240 RTMPusecDelay(2);
241 i++;
242 }
243
244 //Step4. Read 16-byte of data from EFUSE_DATA0-3 (0x59C-0x590)
245 //Because the size of each EFUSE_DATA is 4 Bytes, the size of address of each is 2 bits.
246 //The previous 2 bits is the EFUSE_DATA number, the last 2 bits is used to decide which bytes
247 //Decide which EFUSE_DATA to read
248 //590:F E D C
249 //594:B A 9 8
250 //598:7 6 5 4
251 //59C:3 2 1 0
252 efuseDataOffset = EFUSE_DATA3 - (Offset & 0xC) ;
253
254 RTMP_IO_READ32(pAd, efuseDataOffset, &data);
255
256 data = data >> (8*(Offset & 0x3));
257
258 NdisMoveMemory(pData, &data, Length);
259
260}
261
262/*
263========================================================================
264
265 Routine Description:
266
267 Arguments:
268
269 Return Value:
270
271 Note:
272
273========================================================================
274*/
275static VOID eFuseReadPhysical(
276 IN PRTMP_ADAPTER pAd,
277 IN PUSHORT lpInBuffer,
278 IN ULONG nInBufferSize,
279 OUT PUSHORT lpOutBuffer,
280 IN ULONG nOutBufferSize
281)
282{
283 USHORT* pInBuf = (USHORT*)lpInBuffer;
284 USHORT* pOutBuf = (USHORT*)lpOutBuffer;
285
286 USHORT Offset = pInBuf[0]; //addr
287 USHORT Length = pInBuf[1]; //length
288 int i;
289
290 for(i=0; i<Length; i+=2)
291 {
292 eFusePhysicalReadRegisters(pAd,Offset+i, 2, &pOutBuf[i/2]);
293 }
294}
295
296/*
297========================================================================
298
299 Routine Description:
300
301 Arguments:
302
303 Return Value:
304
305 Note:
306
307========================================================================
308*/
309NTSTATUS eFuseRead(
310 IN PRTMP_ADAPTER pAd,
311 IN USHORT Offset,
312 OUT PUCHAR pData,
313 IN USHORT Length)
314{
315 USHORT* pOutBuf = (USHORT*)pData;
316 NTSTATUS Status = STATUS_SUCCESS;
317 UCHAR EFSROM_AOUT;
318 int i;
319
320 for(i=0; i<Length; i+=2)
321 {
322 EFSROM_AOUT = eFuseReadRegisters(pAd, Offset+i, 2, &pOutBuf[i/2]);
323 }
324 return Status;
325}
326
327/*
328========================================================================
329
330 Routine Description:
331
332 Arguments:
333
334 Return Value:
335
336 Note:
337
338========================================================================
339*/
340static VOID eFusePhysicalWriteRegisters(
341 IN PRTMP_ADAPTER pAd,
342 IN USHORT Offset,
343 IN USHORT Length,
344 OUT USHORT* pData)
345{
346 EFUSE_CTRL_STRUC eFuseCtrlStruc;
347 int i;
348 USHORT efuseDataOffset;
349 UINT32 data, eFuseDataBuffer[4];
350
351 //Step0. Write 16-byte of data to EFUSE_DATA0-3 (0x590-0x59C), where EFUSE_DATA0 is the LSB DW, EFUSE_DATA3 is the MSB DW.
352
353 /////////////////////////////////////////////////////////////////
354 //read current values of 16-byte block
355 RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
356
357 //Step0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
358 eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
359
360 //Step1. Write EFSROM_MODE (0x580, bit7:bit6) to 1.
361 eFuseCtrlStruc.field.EFSROM_MODE = 1;
362
363 //Step2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.
364 eFuseCtrlStruc.field.EFSROM_KICK = 1;
365
366 NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
367 RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
368
369 //Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.
370 i = 0;
371 while(i < 500)
372 {
373 RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
374
375 if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
376 break;
377 RTMPusecDelay(2);
378 i++;
379 }
380
381 //Step4. Read 16-byte of data from EFUSE_DATA0-3 (0x59C-0x590)
382 efuseDataOffset = EFUSE_DATA3;
383 for(i=0; i< 4; i++)
384 {
385 RTMP_IO_READ32(pAd, efuseDataOffset, (PUINT32) &eFuseDataBuffer[i]);
386 efuseDataOffset -= 4;
387 }
388
389 //Update the value, the offset is multiple of 2, length is 2
390 efuseDataOffset = (Offset & 0xc) >> 2;
391 data = pData[0] & 0xffff;
392 //The offset should be 0x***10 or 0x***00
393 if((Offset % 4) != 0)
394 {
395 eFuseDataBuffer[efuseDataOffset] = (eFuseDataBuffer[efuseDataOffset] & 0xffff) | (data << 16);
396 }
397 else
398 {
399 eFuseDataBuffer[efuseDataOffset] = (eFuseDataBuffer[efuseDataOffset] & 0xffff0000) | data;
400 }
401
402 efuseDataOffset = EFUSE_DATA3;
403 for(i=0; i< 4; i++)
404 {
405 RTMP_IO_WRITE32(pAd, efuseDataOffset, eFuseDataBuffer[i]);
406 efuseDataOffset -= 4;
407 }
408 /////////////////////////////////////////////////////////////////
409
410 //Step1. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
411
412 RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
413
414 eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
415
416 //Step2. Write EFSROM_MODE (0x580, bit7:bit6) to 3.
417 eFuseCtrlStruc.field.EFSROM_MODE = 3;
418
419 //Step3. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical write procedure.
420 eFuseCtrlStruc.field.EFSROM_KICK = 1;
421
422 NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
423 RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
424
425 //Step4. Polling EFSROM_KICK(0x580, bit30) until it become 0 again. It¡¦s done.
426 i = 0;
427
428 while(i < 500)
429 {
430 RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
431
432 if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
433 break;
434
435 RTMPusecDelay(2);
436 i++;
437 }
438}
439
440/*
441========================================================================
442
443 Routine Description:
444
445 Arguments:
446
447 Return Value:
448
449 Note:
450
451========================================================================
452*/
453static NTSTATUS eFuseWriteRegisters(
454 IN PRTMP_ADAPTER pAd,
455 IN USHORT Offset,
456 IN USHORT Length,
457 IN USHORT* pData)
458{
459 USHORT i,Loop=0;
460 USHORT eFuseData;
461 USHORT LogicalAddress, BlkNum = 0xffff;
462 UCHAR EFSROM_AOUT;
463
464 USHORT addr,tmpaddr, InBuf[3], tmpOffset;
465 USHORT buffer[8];
466 BOOLEAN bWriteSuccess = TRUE;
467
468 DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters Offset=%x, pData=%x\n", Offset, *pData));
469
470 //Step 0. find the entry in the mapping table
471 //The address of EEPROM is 2-bytes alignment.
472 //The last bit is used for alignment, so it must be 0.
473 tmpOffset = Offset & 0xfffe;
474 EFSROM_AOUT = eFuseReadRegisters(pAd, tmpOffset, 2, &eFuseData);
475
476 if( EFSROM_AOUT == 0x3f)
477 { //find available logical address pointer
478 //the logical address does not exist, find an empty one
479 //from the first address of block 45=16*45=0x2d0 to the last address of block 47
480 //==>48*16-3(reserved)=2FC
481 for (i=EFUSE_USAGE_MAP_START; i<=EFUSE_USAGE_MAP_END; i+=2)
482 {
483 //Retrive the logical block nubmer form each logical address pointer
484 //It will access two logical address pointer each time.
485 eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
486 if( (LogicalAddress & 0xff) == 0)
487 {//Not used logical address pointer
488 BlkNum = i-EFUSE_USAGE_MAP_START;
489 break;
490 }
491 else if(( (LogicalAddress >> 8) & 0xff) == 0)
492 {//Not used logical address pointer
493 if (i != EFUSE_USAGE_MAP_END)
494 {
495 BlkNum = i-EFUSE_USAGE_MAP_START+1;
496 }
497 break;
498 }
499 }
500 }
501 else
502 {
503 BlkNum = EFSROM_AOUT;
504 }
505
506 DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters BlkNum = %d \n", BlkNum));
507
508 if(BlkNum == 0xffff)
509 {
510 DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters: out of free E-fuse space!!!\n"));
511 return FALSE;
512 }
513
514 //Step 1. Save data of this block which is pointed by the avaible logical address pointer
515 // read and save the original block data
516 for(i =0; i<8; i++)
517 {
518 addr = BlkNum * 0x10 ;
519
520 InBuf[0] = addr+2*i;
521 InBuf[1] = 2;
522 InBuf[2] = 0x0;
523
524 eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
525
526 buffer[i] = InBuf[2];
527 }
528
529 //Step 2. Update the data in buffer, and write the data to Efuse
530 buffer[ (Offset >> 1) % 8] = pData[0];
531
532 do
533 { Loop++;
534 //Step 3. Write the data to Efuse
535 if(!bWriteSuccess)
536 {
537 for(i =0; i<8; i++)
538 {
539 addr = BlkNum * 0x10 ;
540
541 InBuf[0] = addr+2*i;
542 InBuf[1] = 2;
543 InBuf[2] = buffer[i];
544
545 eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 2);
546 }
547 }
548 else
549 {
550 addr = BlkNum * 0x10 ;
551
552 InBuf[0] = addr+(Offset % 16);
553 InBuf[1] = 2;
554 InBuf[2] = pData[0];
555
556 eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 2);
557 }
558
559 //Step 4. Write mapping table
560 addr = EFUSE_USAGE_MAP_START+BlkNum;
561
562 tmpaddr = addr;
563
564 if(addr % 2 != 0)
565 addr = addr -1;
566 InBuf[0] = addr;
567 InBuf[1] = 2;
568
569 //convert the address from 10 to 8 bit ( bit7, 6 = parity and bit5 ~ 0 = bit9~4), and write to logical map entry
570 tmpOffset = Offset;
571 tmpOffset >>= 4;
572 tmpOffset |= ((~((tmpOffset & 0x01) ^ ( tmpOffset >> 1 & 0x01) ^ (tmpOffset >> 2 & 0x01) ^ (tmpOffset >> 3 & 0x01))) << 6) & 0x40;
573 tmpOffset |= ((~( (tmpOffset >> 2 & 0x01) ^ (tmpOffset >> 3 & 0x01) ^ (tmpOffset >> 4 & 0x01) ^ ( tmpOffset >> 5 & 0x01))) << 7) & 0x80;
574
575 // write the logical address
576 if(tmpaddr%2 != 0)
577 InBuf[2] = tmpOffset<<8;
578 else
579 InBuf[2] = tmpOffset;
580
581 eFuseWritePhysical(pAd,&InBuf[0], 6, NULL, 0);
582
583 //Step 5. Compare data if not the same, invalidate the mapping entry, then re-write the data until E-fuse is exhausted
584 bWriteSuccess = TRUE;
585 for(i =0; i<8; i++)
586 {
587 addr = BlkNum * 0x10 ;
588
589 InBuf[0] = addr+2*i;
590 InBuf[1] = 2;
591 InBuf[2] = 0x0;
592
593 eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
594
595 if(buffer[i] != InBuf[2])
596 {
597 bWriteSuccess = FALSE;
598 break;
599 }
600 }
601
602 //Step 6. invlidate mapping entry and find a free mapping entry if not succeed
603 if (!bWriteSuccess)
604 {
605 DBGPRINT(RT_DEBUG_TRACE, ("Not bWriteSuccess BlkNum = %d\n", BlkNum));
606
607 // the offset of current mapping entry
608 addr = EFUSE_USAGE_MAP_START+BlkNum;
609
610 //find a new mapping entry
611 BlkNum = 0xffff;
612 for (i=EFUSE_USAGE_MAP_START; i<=EFUSE_USAGE_MAP_END; i+=2)
613 {
614 eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
615 if( (LogicalAddress & 0xff) == 0)
616 {
617 BlkNum = i-EFUSE_USAGE_MAP_START;
618 break;
619 }
620 else if(( (LogicalAddress >> 8) & 0xff) == 0)
621 {
622 if (i != EFUSE_USAGE_MAP_END)
623 {
624 BlkNum = i+1-EFUSE_USAGE_MAP_START;
625 }
626 break;
627 }
628 }
629 DBGPRINT(RT_DEBUG_TRACE, ("Not bWriteSuccess new BlkNum = %d\n", BlkNum));
630 if(BlkNum == 0xffff)
631 {
632 DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters: out of free E-fuse space!!!\n"));
633 return FALSE;
634 }
635
636 //invalidate the original mapping entry if new entry is not found
637 tmpaddr = addr;
638
639 if(addr % 2 != 0)
640 addr = addr -1;
641 InBuf[0] = addr;
642 InBuf[1] = 2;
643
644 eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
645
646 // write the logical address
647 if(tmpaddr%2 != 0)
648 {
649 // Invalidate the high byte
650 for (i=8; i<15; i++)
651 {
652 if( ( (InBuf[2] >> i) & 0x01) == 0)
653 {
654 InBuf[2] |= (0x1 <<i);
655 break;
656 }
657 }
658 }
659 else
660 {
661 // invalidate the low byte
662 for (i=0; i<8; i++)
663 {
664 if( ( (InBuf[2] >> i) & 0x01) == 0)
665 {
666 InBuf[2] |= (0x1 <<i);
667 break;
668 }
669 }
670 }
671 eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 0);
672 }
673 }
674 while (!bWriteSuccess&&Loop<2);
675 if(!bWriteSuccess)
676 DBGPRINT(RT_DEBUG_ERROR,("Efsue Write Failed!!\n"));
677 return TRUE;
678}
679
680
681/*
682========================================================================
683
684 Routine Description:
685
686 Arguments:
687
688 Return Value:
689
690 Note:
691
692========================================================================
693*/
694static VOID eFuseWritePhysical(
695 IN PRTMP_ADAPTER pAd,
696 PUSHORT lpInBuffer,
697 ULONG nInBufferSize,
698 PUCHAR lpOutBuffer,
699 ULONG nOutBufferSize
700)
701{
702 USHORT* pInBuf = (USHORT*)lpInBuffer;
703 int i;
704 //USHORT* pOutBuf = (USHORT*)ioBuffer;
705 USHORT Offset = pInBuf[0]; // addr
706 USHORT Length = pInBuf[1]; // length
707 USHORT* pValueX = &pInBuf[2]; // value ...
708
709 DBGPRINT(RT_DEBUG_TRACE, ("eFuseWritePhysical Offset=0x%x, length=%d\n", Offset, Length));
710
711 {
712 // Little-endian S | S Big-endian
713 // addr 3 2 1 0 | 0 1 2 3
714 // Ori-V D C B A | A B C D
715 // After swapping
716 // D C B A | D C B A
717 // Both the little and big-endian use the same sequence to write data.
718 // Therefore, we only need swap data when read the data.
719 for (i=0; i<Length; i+=2)
720 {
721 eFusePhysicalWriteRegisters(pAd, Offset+i, 2, &pValueX[i/2]);
722 }
723 }
724}
725
726
727/*
728========================================================================
729
730 Routine Description:
731
732 Arguments:
733
734 Return Value:
735
736 Note:
737
738========================================================================
739*/
740NTSTATUS eFuseWrite(
741 IN PRTMP_ADAPTER pAd,
742 IN USHORT Offset,
743 IN PUCHAR pData,
744 IN USHORT length)
745{
746 int i;
747 USHORT* pValueX = (PUSHORT) pData; //value ...
748
749 // The input value=3070 will be stored as following
750 // Little-endian S | S Big-endian
751 // addr 1 0 | 0 1
752 // Ori-V 30 70 | 30 70
753 // After swapping
754 // 30 70 | 70 30
755 // Casting
756 // 3070 | 7030 (x)
757 // The swapping should be removed for big-endian
758 for(i=0; i<length; i+=2)
759 {
760 eFuseWriteRegisters(pAd, Offset+i, 2, &pValueX[i/2]);
761 }
762
763 return TRUE;
764}
765
766
767
768
769/*
770========================================================================
771
772 Routine Description:
773
774 Arguments:
775
776 Return Value:
777
778 Note:
779
780========================================================================
781*/
782INT set_eFuseGetFreeBlockCount_Proc(
783 IN PRTMP_ADAPTER pAd,
784 IN PSTRING arg)
785{
786 USHORT i;
787 USHORT LogicalAddress;
788 USHORT efusefreenum=0;
789 if(!pAd->bUseEfuse)
790 return FALSE;
791 for (i = EFUSE_USAGE_MAP_START; i <= EFUSE_USAGE_MAP_END; i+=2)
792 {
793 eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
794 if( (LogicalAddress & 0xff) == 0)
795 {
796 efusefreenum= (UCHAR) (EFUSE_USAGE_MAP_END-i+1);
797 break;
798 }
799 else if(( (LogicalAddress >> 8) & 0xff) == 0)
800 {
801 efusefreenum = (UCHAR) (EFUSE_USAGE_MAP_END-i);
802 break;
803 }
804
805 if(i == EFUSE_USAGE_MAP_END)
806 efusefreenum = 0;
807 }
808 printk("efuseFreeNumber is %d\n",efusefreenum);
809 return TRUE;
810}
811
812
813INT set_eFusedump_Proc(
814 IN PRTMP_ADAPTER pAd,
815 IN PSTRING arg)
816{
817USHORT InBuf[3];
818 INT i=0;
819 if(!pAd->bUseEfuse)
820 return FALSE;
821 for(i =0; i<EFUSE_USAGE_MAP_END/2; i++)
822 {
823 InBuf[0] = 2*i;
824 InBuf[1] = 2;
825 InBuf[2] = 0x0;
826
827 eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
828 if(i%4==0)
829 printk("\nBlock %x:",i/8);
830 printk("%04x ",InBuf[2]);
831 }
832 return TRUE;
833}
834
835
836INT set_eFuseLoadFromBin_Proc(
837 IN PRTMP_ADAPTER pAd,
838 IN PSTRING arg)
839{
840 PSTRING src;
841 RTMP_OS_FD srcf;
842 RTMP_OS_FS_INFO osfsInfo;
843 INT retval, memSize;
844 PSTRING buffer, memPtr;
845 INT i = 0,j=0,k=1;
846 USHORT *PDATA;
847 USHORT DATA;
848
849 memSize = 128 + MAX_EEPROM_BIN_FILE_SIZE + sizeof(USHORT) * 8;
850 memPtr = kmalloc(memSize, MEM_ALLOC_FLAG);
851 if (memPtr == NULL)
852 return FALSE;
853
854 NdisZeroMemory(memPtr, memSize);
855 src = memPtr; // kmalloc(128, MEM_ALLOC_FLAG);
856 buffer = src + 128; // kmalloc(MAX_EEPROM_BIN_FILE_SIZE, MEM_ALLOC_FLAG);
857 PDATA = (USHORT*)(buffer + MAX_EEPROM_BIN_FILE_SIZE); // kmalloc(sizeof(USHORT)*8,MEM_ALLOC_FLAG);
858
859 if(strlen(arg)>0)
860 NdisMoveMemory(src, arg, strlen(arg));
861 else
862 NdisMoveMemory(src, EFUSE_EEPROM_DEFULT_FILE, strlen(EFUSE_EEPROM_DEFULT_FILE));
863 DBGPRINT(RT_DEBUG_TRACE, ("FileName=%s\n",src));
864
865 RtmpOSFSInfoChange(&osfsInfo, TRUE);
866
867 srcf = RtmpOSFileOpen(src, O_RDONLY, 0);
868 if (IS_FILE_OPEN_ERR(srcf))
869 {
870 DBGPRINT(RT_DEBUG_ERROR, ("--> Error opening file %s\n", src));
871 retval = FALSE;
872 goto recoverFS;
873 }
874 else
875 {
876 // The object must have a read method
877 while(RtmpOSFileRead(srcf, &buffer[i], 1)==1)
878 {
879 i++;
880 if(i>MAX_EEPROM_BIN_FILE_SIZE)
881 {
882 DBGPRINT(RT_DEBUG_ERROR, ("--> Error reading file %s, file size too large[>%d]\n", src, MAX_EEPROM_BIN_FILE_SIZE));
883 retval = FALSE;
884 goto closeFile;
885 }
886 }
887
888 retval = RtmpOSFileClose(srcf);
889 if (retval)
890 DBGPRINT(RT_DEBUG_TRACE, ("--> Error closing file %s\n", src));
891 }
892
893
894 RtmpOSFSInfoChange(&osfsInfo, FALSE);
895
896 for(j=0;j<i;j++)
897 {
898 DBGPRINT(RT_DEBUG_TRACE, ("%02X ",buffer[j]&0xff));
899 if((j+1)%2==0)
900 PDATA[j/2%8]=((buffer[j]<<8)&0xff00)|(buffer[j-1]&0xff);
901 if(j%16==0)
902 {
903 k=buffer[j];
904 }
905 else
906 {
907 k&=buffer[j];
908 if((j+1)%16==0)
909 {
910 DBGPRINT(RT_DEBUG_TRACE, (" result=%02X,blk=%02x\n",k,j/16));
911 if(k!=0xff)
912 eFuseWriteRegistersFromBin(pAd,(USHORT)j-15, 16, PDATA);
913 else
914 {
915 if(eFuseReadRegisters(pAd,j, 2,(PUSHORT)&DATA)!=0x3f)
916 eFuseWriteRegistersFromBin(pAd,(USHORT)j-15, 16, PDATA);
917 }
918 /*
919 for(l=0;l<8;l++)
920 printk("%04x ",PDATA[l]);
921 printk("\n");
922 */
923 NdisZeroMemory(PDATA,16);
924 }
925 }
926 }
927
928 return TRUE;
929
930closeFile:
931 if (srcf)
932 RtmpOSFileClose(srcf);
933
934recoverFS:
935 RtmpOSFSInfoChange(&osfsInfo, FALSE);
936
937
938 if (memPtr)
939 kfree(memPtr);
940
941 return retval;
942}
943
944
945static NTSTATUS eFuseWriteRegistersFromBin(
946 IN PRTMP_ADAPTER pAd,
947 IN USHORT Offset,
948 IN USHORT Length,
949 IN USHORT* pData)
950{
951 USHORT i;
952 USHORT eFuseData;
953 USHORT LogicalAddress, BlkNum = 0xffff;
954 UCHAR EFSROM_AOUT,Loop=0;
955 EFUSE_CTRL_STRUC eFuseCtrlStruc;
956 USHORT efuseDataOffset;
957 UINT32 data,tempbuffer;
958 USHORT addr,tmpaddr, InBuf[3], tmpOffset;
959 UINT32 buffer[4];
960 BOOLEAN bWriteSuccess = TRUE;
961 BOOLEAN bNotWrite=TRUE;
962 BOOLEAN bAllocateNewBlk=TRUE;
963
964 DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin Offset=%x, pData=%04x:%04x:%04x:%04x\n", Offset, *pData,*(pData+1),*(pData+2),*(pData+3)));
965
966 do
967 {
968 //Step 0. find the entry in the mapping table
969 //The address of EEPROM is 2-bytes alignment.
970 //The last bit is used for alignment, so it must be 0.
971 Loop++;
972 tmpOffset = Offset & 0xfffe;
973 EFSROM_AOUT = eFuseReadRegisters(pAd, tmpOffset, 2, &eFuseData);
974
975 if( EFSROM_AOUT == 0x3f)
976 { //find available logical address pointer
977 //the logical address does not exist, find an empty one
978 //from the first address of block 45=16*45=0x2d0 to the last address of block 47
979 //==>48*16-3(reserved)=2FC
980 bAllocateNewBlk=TRUE;
981 for (i=EFUSE_USAGE_MAP_START; i<=EFUSE_USAGE_MAP_END; i+=2)
982 {
983 //Retrive the logical block nubmer form each logical address pointer
984 //It will access two logical address pointer each time.
985 eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
986 if( (LogicalAddress & 0xff) == 0)
987 {//Not used logical address pointer
988 BlkNum = i-EFUSE_USAGE_MAP_START;
989 break;
990 }
991 else if(( (LogicalAddress >> 8) & 0xff) == 0)
992 {//Not used logical address pointer
993 if (i != EFUSE_USAGE_MAP_END)
994 {
995 BlkNum = i-EFUSE_USAGE_MAP_START+1;
996 }
997 break;
998 }
999 }
1000 }
1001 else
1002 {
1003 bAllocateNewBlk=FALSE;
1004 BlkNum = EFSROM_AOUT;
1005 }
1006
1007 DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters BlkNum = %d \n", BlkNum));
1008
1009 if(BlkNum == 0xffff)
1010 {
1011 DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters: out of free E-fuse space!!!\n"));
1012 return FALSE;
1013 }
1014 //Step 1.1.0
1015 //If the block is not existing in mapping table, create one
1016 //and write down the 16-bytes data to the new block
1017 if(bAllocateNewBlk)
1018 {
1019 DBGPRINT(RT_DEBUG_TRACE, ("Allocate New Blk\n"));
1020 efuseDataOffset = EFUSE_DATA3;
1021 for(i=0; i< 4; i++)
1022 {
1023 DBGPRINT(RT_DEBUG_TRACE, ("Allocate New Blk, Data%d=%04x%04x\n",3-i,pData[2*i+1],pData[2*i]));
1024 tempbuffer=((pData[2*i+1]<<16)&0xffff0000)|pData[2*i];
1025
1026
1027 RTMP_IO_WRITE32(pAd, efuseDataOffset,tempbuffer);
1028 efuseDataOffset -= 4;
1029
1030 }
1031 /////////////////////////////////////////////////////////////////
1032
1033 //Step1.1.1. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
1034 RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
1035 eFuseCtrlStruc.field.EFSROM_AIN = BlkNum* 0x10 ;
1036
1037 //Step1.1.2. Write EFSROM_MODE (0x580, bit7:bit6) to 3.
1038 eFuseCtrlStruc.field.EFSROM_MODE = 3;
1039
1040 //Step1.1.3. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical write procedure.
1041 eFuseCtrlStruc.field.EFSROM_KICK = 1;
1042
1043 NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
1044
1045 RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
1046
1047 //Step1.1.4. Polling EFSROM_KICK(0x580, bit30) until it become 0 again. It¡¦s done.
1048 i = 0;
1049 while(i < 100)
1050 {
1051 RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
1052
1053 if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
1054 break;
1055
1056 RTMPusecDelay(2);
1057 i++;
1058 }
1059
1060 }
1061 else
1062 { //Step1.2.
1063 //If the same logical number is existing, check if the writting data and the data
1064 //saving in this block are the same.
1065 /////////////////////////////////////////////////////////////////
1066 //read current values of 16-byte block
1067 RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
1068
1069 //Step1.2.0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
1070 eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
1071
1072 //Step1.2.1. Write EFSROM_MODE (0x580, bit7:bit6) to 1.
1073 eFuseCtrlStruc.field.EFSROM_MODE = 0;
1074
1075 //Step1.2.2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.
1076 eFuseCtrlStruc.field.EFSROM_KICK = 1;
1077
1078 NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
1079 RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
1080
1081 //Step1.2.3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.
1082 i = 0;
1083 while(i < 500)
1084 {
1085 RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
1086
1087 if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
1088 break;
1089 RTMPusecDelay(2);
1090 i++;
1091 }
1092
1093 //Step1.2.4. Read 16-byte of data from EFUSE_DATA0-3 (0x59C-0x590)
1094 efuseDataOffset = EFUSE_DATA3;
1095 for(i=0; i< 4; i++)
1096 {
1097 RTMP_IO_READ32(pAd, efuseDataOffset, (PUINT32) &buffer[i]);
1098 efuseDataOffset -= 4;
1099 }
1100 //Step1.2.5. Check if the data of efuse and the writing data are the same.
1101 for(i =0; i<4; i++)
1102 {
1103 tempbuffer=((pData[2*i+1]<<16)&0xffff0000)|pData[2*i];
1104 DBGPRINT(RT_DEBUG_TRACE, ("buffer[%d]=%x,pData[%d]=%x,pData[%d]=%x,tempbuffer=%x\n",i,buffer[i],2*i,pData[2*i],2*i+1,pData[2*i+1],tempbuffer));
1105
1106 if(((buffer[i]&0xffff0000)==(pData[2*i+1]<<16))&&((buffer[i]&0xffff)==pData[2*i]))
1107 bNotWrite&=TRUE;
1108 else
1109 {
1110 bNotWrite&=FALSE;
1111 break;
1112 }
1113 }
1114 if(!bNotWrite)
1115 {
1116 printk("The data is not the same\n");
1117
1118 for(i =0; i<8; i++)
1119 {
1120 addr = BlkNum * 0x10 ;
1121
1122 InBuf[0] = addr+2*i;
1123 InBuf[1] = 2;
1124 InBuf[2] = pData[i];
1125
1126 eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 2);
1127 }
1128
1129 }
1130 else
1131 return TRUE;
1132 }
1133
1134
1135
1136 //Step 2. Write mapping table
1137 addr = EFUSE_USAGE_MAP_START+BlkNum;
1138
1139 tmpaddr = addr;
1140
1141 if(addr % 2 != 0)
1142 addr = addr -1;
1143 InBuf[0] = addr;
1144 InBuf[1] = 2;
1145
1146 //convert the address from 10 to 8 bit ( bit7, 6 = parity and bit5 ~ 0 = bit9~4), and write to logical map entry
1147 tmpOffset = Offset;
1148 tmpOffset >>= 4;
1149 tmpOffset |= ((~((tmpOffset & 0x01) ^ ( tmpOffset >> 1 & 0x01) ^ (tmpOffset >> 2 & 0x01) ^ (tmpOffset >> 3 & 0x01))) << 6) & 0x40;
1150 tmpOffset |= ((~( (tmpOffset >> 2 & 0x01) ^ (tmpOffset >> 3 & 0x01) ^ (tmpOffset >> 4 & 0x01) ^ ( tmpOffset >> 5 & 0x01))) << 7) & 0x80;
1151
1152 // write the logical address
1153 if(tmpaddr%2 != 0)
1154 InBuf[2] = tmpOffset<<8;
1155 else
1156 InBuf[2] = tmpOffset;
1157
1158 eFuseWritePhysical(pAd,&InBuf[0], 6, NULL, 0);
1159
1160 //Step 3. Compare data if not the same, invalidate the mapping entry, then re-write the data until E-fuse is exhausted
1161 bWriteSuccess = TRUE;
1162 for(i =0; i<8; i++)
1163 {
1164 addr = BlkNum * 0x10 ;
1165
1166 InBuf[0] = addr+2*i;
1167 InBuf[1] = 2;
1168 InBuf[2] = 0x0;
1169
1170 eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
1171 DBGPRINT(RT_DEBUG_TRACE, ("addr=%x, buffer[i]=%x,InBuf[2]=%x\n",InBuf[0],pData[i],InBuf[2]));
1172 if(pData[i] != InBuf[2])
1173 {
1174 bWriteSuccess = FALSE;
1175 break;
1176 }
1177 }
1178
1179 //Step 4. invlidate mapping entry and find a free mapping entry if not succeed
1180
1181 if (!bWriteSuccess&&Loop<2)
1182 {
1183 DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin::Not bWriteSuccess BlkNum = %d\n", BlkNum));
1184
1185 // the offset of current mapping entry
1186 addr = EFUSE_USAGE_MAP_START+BlkNum;
1187
1188 //find a new mapping entry
1189 BlkNum = 0xffff;
1190 for (i=EFUSE_USAGE_MAP_START; i<=EFUSE_USAGE_MAP_END; i+=2)
1191 {
1192 eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
1193 if( (LogicalAddress & 0xff) == 0)
1194 {
1195 BlkNum = i-EFUSE_USAGE_MAP_START;
1196 break;
1197 }
1198 else if(( (LogicalAddress >> 8) & 0xff) == 0)
1199 {
1200 if (i != EFUSE_USAGE_MAP_END)
1201 {
1202 BlkNum = i+1-EFUSE_USAGE_MAP_START;
1203 }
1204 break;
1205 }
1206 }
1207 DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin::Not bWriteSuccess new BlkNum = %d\n", BlkNum));
1208 if(BlkNum == 0xffff)
1209 {
1210 DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin: out of free E-fuse space!!!\n"));
1211 return FALSE;
1212 }
1213
1214 //invalidate the original mapping entry if new entry is not found
1215 tmpaddr = addr;
1216
1217 if(addr % 2 != 0)
1218 addr = addr -1;
1219 InBuf[0] = addr;
1220 InBuf[1] = 2;
1221
1222 eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
1223
1224 // write the logical address
1225 if(tmpaddr%2 != 0)
1226 {
1227 // Invalidate the high byte
1228 for (i=8; i<15; i++)
1229 {
1230 if( ( (InBuf[2] >> i) & 0x01) == 0)
1231 {
1232 InBuf[2] |= (0x1 <<i);
1233 break;
1234 }
1235 }
1236 }
1237 else
1238 {
1239 // invalidate the low byte
1240 for (i=0; i<8; i++)
1241 {
1242 if( ( (InBuf[2] >> i) & 0x01) == 0)
1243 {
1244 InBuf[2] |= (0x1 <<i);
1245 break;
1246 }
1247 }
1248 }
1249 eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 0);
1250 }
1251
1252 }
1253 while(!bWriteSuccess&&Loop<2);
1254
1255 return TRUE;
1256}
1257
1258
1259int rtmp_ee_efuse_read16(
1260 IN RTMP_ADAPTER *pAd,
1261 IN USHORT Offset,
1262 OUT USHORT *pValue)
1263{
1264 if(pAd->bFroceEEPROMBuffer || pAd->bEEPROMFile)
1265 {
1266 DBGPRINT(RT_DEBUG_TRACE, ("Read from EEPROM Buffer\n"));
1267 NdisMoveMemory(pValue, &(pAd->EEPROMImage[Offset]), 2);
1268 }
1269 else
1270 eFuseReadRegisters(pAd, Offset, 2, pValue);
1271 return (*pValue);
1272}
1273
1274
1275int rtmp_ee_efuse_write16(
1276 IN RTMP_ADAPTER *pAd,
1277 IN USHORT Offset,
1278 IN USHORT data)
1279{
1280 if(pAd->bFroceEEPROMBuffer||pAd->bEEPROMFile)
1281 {
1282 DBGPRINT(RT_DEBUG_TRACE, ("Write to EEPROM Buffer\n"));
1283 NdisMoveMemory(&(pAd->EEPROMImage[Offset]), &data, 2);
1284 }
1285 else
1286 eFuseWriteRegisters(pAd, Offset, 2, &data);
1287 return 0;
1288}
1289
1290
1291int RtmpEfuseSupportCheck(
1292 IN RTMP_ADAPTER *pAd)
1293{
1294 USHORT value;
1295
1296 if (IS_RT30xx(pAd))
1297 {
1298 eFusePhysicalReadRegisters(pAd, EFUSE_TAG, 2, &value);
1299 pAd->EFuseTag = (value & 0xff);
1300 }
1301 return 0;
1302}
1303
1304INT set_eFuseBufferModeWriteBack_Proc(
1305 IN PRTMP_ADAPTER pAd,
1306 IN PSTRING arg)
1307{
1308 UINT Enable;
1309
1310
1311 if(strlen(arg)>0)
1312 {
1313 Enable= simple_strtol(arg, 0, 16);
1314 }
1315 else
1316 return FALSE;
1317 if(Enable==1)
1318 {
1319 DBGPRINT(RT_DEBUG_TRACE, ("set_eFuseBufferMode_Proc:: Call WRITEEEPROMBUF"));
1320 eFuseWriteEeeppromBuf(pAd);
1321 }
1322 else
1323 return FALSE;
1324 return TRUE;
1325}
1326
1327
1328/*
1329 ========================================================================
1330
1331 Routine Description:
1332 Load EEPROM from bin file for eFuse mode
1333
1334 Arguments:
1335 Adapter Pointer to our adapter
1336
1337 Return Value:
1338 NDIS_STATUS_SUCCESS firmware image load ok
1339 NDIS_STATUS_FAILURE image not found
1340
1341 IRQL = PASSIVE_LEVEL
1342
1343 ========================================================================
1344*/
1345INT eFuseLoadEEPROM(
1346 IN PRTMP_ADAPTER pAd)
1347{
1348 PSTRING src = NULL;
1349 INT retval;
1350 RTMP_OS_FD srcf;
1351 RTMP_OS_FS_INFO osFSInfo;
1352
1353
1354 src=EFUSE_BUFFER_PATH;
1355 DBGPRINT(RT_DEBUG_TRACE, ("FileName=%s\n",src));
1356
1357
1358 RtmpOSFSInfoChange(&osFSInfo, TRUE);
1359
1360 if (src && *src)
1361 {
1362 srcf = RtmpOSFileOpen(src, O_RDONLY, 0);
1363 if (IS_FILE_OPEN_ERR(srcf))
1364 {
1365 DBGPRINT(RT_DEBUG_ERROR, ("--> Error %ld opening %s\n", -PTR_ERR(srcf),src));
1366 return FALSE;
1367 }
1368 else
1369 {
1370
1371 memset(pAd->EEPROMImage, 0x00, MAX_EEPROM_BIN_FILE_SIZE);
1372
1373
1374 retval =RtmpOSFileRead(srcf, (PSTRING)pAd->EEPROMImage, MAX_EEPROM_BIN_FILE_SIZE);
1375 if (retval > 0)
1376 {
1377 RTMPSetProfileParameters(pAd, (PSTRING)pAd->EEPROMImage);
1378 retval = NDIS_STATUS_SUCCESS;
1379 }
1380 else
1381 DBGPRINT(RT_DEBUG_ERROR, ("Read file \"%s\" failed(errCode=%d)!\n", src, retval));
1382
1383 }
1384
1385
1386 }
1387 else
1388 {
1389 DBGPRINT(RT_DEBUG_ERROR, ("--> Error src or srcf is null\n"));
1390 return FALSE;
1391
1392 }
1393
1394 retval=RtmpOSFileClose(srcf);
1395
1396 if (retval)
1397 {
1398 DBGPRINT(RT_DEBUG_TRACE, ("--> Error %d closing %s\n", -retval, src));
1399 }
1400
1401
1402 RtmpOSFSInfoChange(&osFSInfo, FALSE);
1403
1404 return TRUE;
1405}
1406
1407INT eFuseWriteEeeppromBuf(
1408 IN PRTMP_ADAPTER pAd)
1409{
1410
1411 PSTRING src = NULL;
1412 INT retval;
1413 RTMP_OS_FD srcf;
1414 RTMP_OS_FS_INFO osFSInfo;
1415
1416
1417 src=EFUSE_BUFFER_PATH;
1418 DBGPRINT(RT_DEBUG_TRACE, ("FileName=%s\n",src));
1419
1420 RtmpOSFSInfoChange(&osFSInfo, TRUE);
1421
1422
1423
1424 if (src && *src)
1425 {
1426 srcf = RtmpOSFileOpen(src, O_WRONLY|O_CREAT, 0);
1427
1428 if (IS_FILE_OPEN_ERR(srcf))
1429 {
1430 DBGPRINT(RT_DEBUG_ERROR, ("--> Error %ld opening %s\n", -PTR_ERR(srcf),src));
1431 return FALSE;
1432 }
1433 else
1434 {
1435/*
1436 // The object must have a read method
1437 if (srcf->f_op && srcf->f_op->write)
1438 {
1439 // The object must have a read method
1440 srcf->f_op->write(srcf, pAd->EEPROMImage, 1024, &srcf->f_pos);
1441
1442 }
1443 else
1444 {
1445 DBGPRINT(RT_DEBUG_ERROR, ("--> Error!! System doest not support read function\n"));
1446 return FALSE;
1447 }
1448*/
1449
1450 RtmpOSFileWrite(srcf, (PSTRING)pAd->EEPROMImage,MAX_EEPROM_BIN_FILE_SIZE);
1451
1452 }
1453
1454
1455 }
1456 else
1457 {
1458 DBGPRINT(RT_DEBUG_ERROR, ("--> Error src or srcf is null\n"));
1459 return FALSE;
1460
1461 }
1462
1463 retval=RtmpOSFileClose(srcf);
1464
1465 if (retval)
1466 {
1467 DBGPRINT(RT_DEBUG_TRACE, ("--> Error %d closing %s\n", -retval, src));
1468 }
1469
1470 RtmpOSFSInfoChange(&osFSInfo, FALSE);
1471 return TRUE;
1472}
1473
1474
1475VOID eFuseGetFreeBlockCount(IN PRTMP_ADAPTER pAd,
1476 PUINT EfuseFreeBlock)
1477{
1478 USHORT i;
1479 USHORT LogicalAddress;
1480 if(!pAd->bUseEfuse)
1481 {
1482 DBGPRINT(RT_DEBUG_TRACE,("eFuseGetFreeBlockCount Only supports efuse Mode\n"));
1483 return ;
1484 }
1485 for (i = EFUSE_USAGE_MAP_START; i <= EFUSE_USAGE_MAP_END; i+=2)
1486 {
1487 eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
1488 if( (LogicalAddress & 0xff) == 0)
1489 {
1490 *EfuseFreeBlock= (UCHAR) (EFUSE_USAGE_MAP_END-i+1);
1491 break;
1492 }
1493 else if(( (LogicalAddress >> 8) & 0xff) == 0)
1494 {
1495 *EfuseFreeBlock = (UCHAR) (EFUSE_USAGE_MAP_END-i);
1496 break;
1497 }
1498
1499 if(i == EFUSE_USAGE_MAP_END)
1500 *EfuseFreeBlock = 0;
1501 }
1502 DBGPRINT(RT_DEBUG_TRACE,("eFuseGetFreeBlockCount is 0x%x\n",*EfuseFreeBlock));
1503}
1504
1505INT eFuse_init(
1506 IN PRTMP_ADAPTER pAd)
1507{
1508 UINT EfuseFreeBlock=0;
1509 DBGPRINT(RT_DEBUG_ERROR, ("NVM is Efuse and its size =%x[%x-%x] \n",EFUSE_USAGE_MAP_SIZE,EFUSE_USAGE_MAP_START,EFUSE_USAGE_MAP_END));
1510 eFuseGetFreeBlockCount(pAd, &EfuseFreeBlock);
1511 //If the used block of efuse is less than 5. We assume the default value
1512 // of this efuse is empty and change to the buffer mode in odrder to
1513 //bring up interfaces successfully.
1514 if(EfuseFreeBlock > (EFUSE_USAGE_MAP_END-5))
1515 {
1516 DBGPRINT(RT_DEBUG_ERROR, ("NVM is Efuse and the information is too less to bring up interface. Force to use EEPROM Buffer Mode\n"));
1517 pAd->bFroceEEPROMBuffer = TRUE;
1518 eFuseLoadEEPROM(pAd);
1519 }
1520 else
1521 pAd->bFroceEEPROMBuffer = FALSE;
1522 DBGPRINT(RT_DEBUG_TRACE, ("NVM is Efuse and force to use EEPROM Buffer Mode=%x\n",pAd->bFroceEEPROMBuffer));
1523
1524 return 0;
1525}
diff --git a/drivers/staging/rt2860/common/ee_prom.c b/drivers/staging/rt2860/common/ee_prom.c
new file mode 100644
index 00000000000..9ebff8b9e56
--- /dev/null
+++ b/drivers/staging/rt2860/common/ee_prom.c
@@ -0,0 +1,270 @@
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
39#include "../rt_config.h"
40
41
42
43// IRQL = PASSIVE_LEVEL
44static inline VOID RaiseClock(
45 IN PRTMP_ADAPTER pAd,
46 IN UINT32 *x)
47{
48 *x = *x | EESK;
49 RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x);
50 RTMPusecDelay(1); // Max frequency = 1MHz in Spec. definition
51}
52
53// IRQL = PASSIVE_LEVEL
54static inline VOID LowerClock(
55 IN PRTMP_ADAPTER pAd,
56 IN UINT32 *x)
57{
58 *x = *x & ~EESK;
59 RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x);
60 RTMPusecDelay(1);
61}
62
63// IRQL = PASSIVE_LEVEL
64static inline USHORT ShiftInBits(
65 IN PRTMP_ADAPTER pAd)
66{
67 UINT32 x,i;
68 USHORT data=0;
69
70 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
71
72 x &= ~( EEDO | EEDI);
73
74 for(i=0; i<16; i++)
75 {
76 data = data << 1;
77 RaiseClock(pAd, &x);
78
79 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
80 LowerClock(pAd, &x); //prevent read failed
81
82 x &= ~(EEDI);
83 if(x & EEDO)
84 data |= 1;
85 }
86
87 return data;
88}
89
90
91// IRQL = PASSIVE_LEVEL
92static inline VOID ShiftOutBits(
93 IN PRTMP_ADAPTER pAd,
94 IN USHORT data,
95 IN USHORT count)
96{
97 UINT32 x,mask;
98
99 mask = 0x01 << (count - 1);
100 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
101
102 x &= ~(EEDO | EEDI);
103
104 do
105 {
106 x &= ~EEDI;
107 if(data & mask) x |= EEDI;
108
109 RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
110
111 RaiseClock(pAd, &x);
112 LowerClock(pAd, &x);
113
114 mask = mask >> 1;
115 } while(mask);
116
117 x &= ~EEDI;
118 RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
119}
120
121
122// IRQL = PASSIVE_LEVEL
123static inline VOID EEpromCleanup(
124 IN PRTMP_ADAPTER pAd)
125{
126 UINT32 x;
127
128 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
129
130 x &= ~(EECS | EEDI);
131 RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
132
133 RaiseClock(pAd, &x);
134 LowerClock(pAd, &x);
135}
136
137
138static inline VOID EWEN(
139 IN PRTMP_ADAPTER pAd)
140{
141 UINT32 x;
142
143 // reset bits and set EECS
144 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
145 x &= ~(EEDI | EEDO | EESK);
146 x |= EECS;
147 RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
148
149 // kick a pulse
150 RaiseClock(pAd, &x);
151 LowerClock(pAd, &x);
152
153 // output the read_opcode and six pulse in that order
154 ShiftOutBits(pAd, EEPROM_EWEN_OPCODE, 5);
155 ShiftOutBits(pAd, 0, 6);
156
157 EEpromCleanup(pAd);
158}
159
160
161static inline VOID EWDS(
162 IN PRTMP_ADAPTER pAd)
163{
164 UINT32 x;
165
166 // reset bits and set EECS
167 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
168 x &= ~(EEDI | EEDO | EESK);
169 x |= EECS;
170 RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
171
172 // kick a pulse
173 RaiseClock(pAd, &x);
174 LowerClock(pAd, &x);
175
176 // output the read_opcode and six pulse in that order
177 ShiftOutBits(pAd, EEPROM_EWDS_OPCODE, 5);
178 ShiftOutBits(pAd, 0, 6);
179
180 EEpromCleanup(pAd);
181}
182
183
184// IRQL = PASSIVE_LEVEL
185int rtmp_ee_prom_read16(
186 IN PRTMP_ADAPTER pAd,
187 IN USHORT Offset,
188 OUT USHORT *pValue)
189{
190 UINT32 x;
191 USHORT data;
192
193
194 Offset /= 2;
195 // reset bits and set EECS
196 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
197 x &= ~(EEDI | EEDO | EESK);
198 x |= EECS;
199 RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
200
201 // patch can not access e-Fuse issue
202 if (!(IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)))
203 {
204 // kick a pulse
205 RaiseClock(pAd, &x);
206 LowerClock(pAd, &x);
207 }
208
209 // output the read_opcode and register number in that order
210 ShiftOutBits(pAd, EEPROM_READ_OPCODE, 3);
211 ShiftOutBits(pAd, Offset, pAd->EEPROMAddressNum);
212
213 // Now read the data (16 bits) in from the selected EEPROM word
214 data = ShiftInBits(pAd);
215
216 EEpromCleanup(pAd);
217
218
219 *pValue = data;
220
221 return NDIS_STATUS_SUCCESS;
222}
223
224
225int rtmp_ee_prom_write16(
226 IN PRTMP_ADAPTER pAd,
227 IN USHORT Offset,
228 IN USHORT Data)
229{
230 UINT32 x;
231
232
233 Offset /= 2;
234
235 EWEN(pAd);
236
237 // reset bits and set EECS
238 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
239 x &= ~(EEDI | EEDO | EESK);
240 x |= EECS;
241 RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
242
243 // patch can not access e-Fuse issue
244 if (!(IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)))
245 {
246 // kick a pulse
247 RaiseClock(pAd, &x);
248 LowerClock(pAd, &x);
249 }
250
251 // output the read_opcode ,register number and data in that order
252 ShiftOutBits(pAd, EEPROM_WRITE_OPCODE, 3);
253 ShiftOutBits(pAd, Offset, pAd->EEPROMAddressNum);
254 ShiftOutBits(pAd, Data, 16); // 16-bit access
255
256 // read DO status
257 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
258
259 EEpromCleanup(pAd);
260
261 RTMPusecDelay(10000); //delay for twp(MAX)=10ms
262
263 EWDS(pAd);
264
265 EEpromCleanup(pAd);
266
267
268 return NDIS_STATUS_SUCCESS;
269
270}
diff --git a/drivers/staging/rt2860/common/eeprom.c b/drivers/staging/rt2860/common/eeprom.c
index ffcb4ce1a03..03b8454bf74 100644
--- a/drivers/staging/rt2860/common/eeprom.c
+++ b/drivers/staging/rt2860/common/eeprom.c
@@ -36,1444 +36,68 @@
36*/ 36*/
37#include "../rt_config.h" 37#include "../rt_config.h"
38 38
39// IRQL = PASSIVE_LEVEL
40VOID RaiseClock(
41 IN PRTMP_ADAPTER pAd,
42 IN UINT32 *x)
43{
44 *x = *x | EESK;
45 RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x);
46 RTMPusecDelay(1); // Max frequency = 1MHz in Spec. definition
47}
48
49// IRQL = PASSIVE_LEVEL
50VOID LowerClock(
51 IN PRTMP_ADAPTER pAd,
52 IN UINT32 *x)
53{
54 *x = *x & ~EESK;
55 RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x);
56 RTMPusecDelay(1);
57}
58
59// IRQL = PASSIVE_LEVEL
60USHORT ShiftInBits(
61 IN PRTMP_ADAPTER pAd)
62{
63 UINT32 x,i;
64 USHORT data=0;
65
66 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
67
68 x &= ~( EEDO | EEDI);
69
70 for(i=0; i<16; i++)
71 {
72 data = data << 1;
73 RaiseClock(pAd, &x);
74
75 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
76
77 LowerClock(pAd, &x); /* prevent read failed */
78
79 x &= ~(EEDI);
80 if(x & EEDO)
81 data |= 1;
82 }
83
84 return data;
85}
86
87// IRQL = PASSIVE_LEVEL
88VOID ShiftOutBits(
89 IN PRTMP_ADAPTER pAd,
90 IN USHORT data,
91 IN USHORT count)
92{
93 UINT32 x,mask;
94
95 mask = 0x01 << (count - 1);
96 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
97
98 x &= ~(EEDO | EEDI);
99
100 do
101 {
102 x &= ~EEDI;
103 if(data & mask) x |= EEDI;
104
105 RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
106
107 RaiseClock(pAd, &x);
108 LowerClock(pAd, &x);
109
110 mask = mask >> 1;
111 } while(mask);
112
113 x &= ~EEDI;
114 RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
115}
116
117// IRQL = PASSIVE_LEVEL
118VOID EEpromCleanup(
119 IN PRTMP_ADAPTER pAd)
120{
121 UINT32 x;
122
123 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
124
125 x &= ~(EECS | EEDI);
126 RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
127
128 RaiseClock(pAd, &x);
129 LowerClock(pAd, &x);
130}
131
132VOID EWEN(
133 IN PRTMP_ADAPTER pAd)
134{
135 UINT32 x;
136
137 // reset bits and set EECS
138 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
139 x &= ~(EEDI | EEDO | EESK);
140 x |= EECS;
141 RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
142
143 // kick a pulse
144 RaiseClock(pAd, &x);
145 LowerClock(pAd, &x);
146
147 // output the read_opcode and six pulse in that order
148 ShiftOutBits(pAd, EEPROM_EWEN_OPCODE, 5);
149 ShiftOutBits(pAd, 0, 6);
150
151 EEpromCleanup(pAd);
152}
153
154VOID EWDS(
155 IN PRTMP_ADAPTER pAd)
156{
157 UINT32 x;
158
159 // reset bits and set EECS
160 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
161 x &= ~(EEDI | EEDO | EESK);
162 x |= EECS;
163 RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
164
165 // kick a pulse
166 RaiseClock(pAd, &x);
167 LowerClock(pAd, &x);
168
169 // output the read_opcode and six pulse in that order
170 ShiftOutBits(pAd, EEPROM_EWDS_OPCODE, 5);
171 ShiftOutBits(pAd, 0, 6);
172
173 EEpromCleanup(pAd);
174}
175
176// IRQL = PASSIVE_LEVEL
177USHORT RTMP_EEPROM_READ16(
178 IN PRTMP_ADAPTER pAd,
179 IN USHORT Offset)
180{
181 UINT32 x;
182 USHORT data;
183
184#ifdef RT2870
185 if (pAd->NicConfig2.field.AntDiversity)
186 {
187 pAd->EepromAccess = TRUE;
188 }
189#endif
190 Offset /= 2;
191 // reset bits and set EECS
192 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
193 x &= ~(EEDI | EEDO | EESK);
194 x |= EECS;
195 RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
196
197 // patch can not access e-Fuse issue
198 if (!IS_RT3090(pAd))
199 {
200 // kick a pulse
201 RaiseClock(pAd, &x);
202 LowerClock(pAd, &x);
203 }
204
205 // output the read_opcode and register number in that order
206 ShiftOutBits(pAd, EEPROM_READ_OPCODE, 3);
207 ShiftOutBits(pAd, Offset, pAd->EEPROMAddressNum);
208
209 // Now read the data (16 bits) in from the selected EEPROM word
210 data = ShiftInBits(pAd);
211
212 EEpromCleanup(pAd);
213
214#ifdef RT2870
215 // Antenna and EEPROM access are both using EESK pin,
216 // Therefor we should avoid accessing EESK at the same time
217 // Then restore antenna after EEPROM access
218 if ((pAd->NicConfig2.field.AntDiversity) || (pAd->RfIcType == RFIC_3020))
219 {
220 pAd->EepromAccess = FALSE;
221 AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
222 }
223#endif
224 return data;
225} //ReadEEprom
226
227VOID RTMP_EEPROM_WRITE16(
228 IN PRTMP_ADAPTER pAd,
229 IN USHORT Offset,
230 IN USHORT Data)
231{
232 UINT32 x;
233
234#ifdef RT2870
235 if (pAd->NicConfig2.field.AntDiversity)
236 {
237 pAd->EepromAccess = TRUE;
238 }
239#endif
240 Offset /= 2;
241
242 EWEN(pAd);
243
244 // reset bits and set EECS
245 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
246 x &= ~(EEDI | EEDO | EESK);
247 x |= EECS;
248 RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
249
250 // patch can not access e-Fuse issue
251 if (!IS_RT3090(pAd))
252 {
253 // kick a pulse
254 RaiseClock(pAd, &x);
255 LowerClock(pAd, &x);
256 }
257
258 // output the read_opcode ,register number and data in that order
259 ShiftOutBits(pAd, EEPROM_WRITE_OPCODE, 3);
260 ShiftOutBits(pAd, Offset, pAd->EEPROMAddressNum);
261 ShiftOutBits(pAd, Data, 16); // 16-bit access
262
263 // read DO status
264 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
265
266 EEpromCleanup(pAd);
267
268 RTMPusecDelay(10000); //delay for twp(MAX)=10ms
269
270 EWDS(pAd);
271
272 EEpromCleanup(pAd);
273
274#ifdef RT2870
275 // Antenna and EEPROM access are both using EESK pin,
276 // Therefor we should avoid accessing EESK at the same time
277 // Then restore antenna after EEPROM access
278 if ((pAd->NicConfig2.field.AntDiversity) || (pAd->RfIcType == RFIC_3020))
279 {
280 pAd->EepromAccess = FALSE;
281 AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
282 }
283#endif
284}
285
286#ifdef RT2870
287/*
288 ========================================================================
289
290 Routine Description:
291
292 Arguments:
293
294 Return Value:
295
296 IRQL =
297
298 Note:
299
300 ========================================================================
301*/
302UCHAR eFuseReadRegisters(
303 IN PRTMP_ADAPTER pAd,
304 IN USHORT Offset,
305 IN USHORT Length,
306 OUT USHORT* pData)
307{
308 EFUSE_CTRL_STRUC eFuseCtrlStruc;
309 int i;
310 USHORT efuseDataOffset;
311 UINT32 data;
312
313 RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
314
315 //Step0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
316 //Use the eeprom logical address and covert to address to block number
317 eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
318
319 //Step1. Write EFSROM_MODE (0x580, bit7:bit6) to 0.
320 eFuseCtrlStruc.field.EFSROM_MODE = 0;
321
322 //Step2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.
323 eFuseCtrlStruc.field.EFSROM_KICK = 1;
324 39
325 NdisMoveMemory(&data, &eFuseCtrlStruc, 4); 40INT RtmpChipOpsEepromHook(
326 RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data); 41 IN RTMP_ADAPTER *pAd,
327 42 IN INT infType)
328 //Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.
329 i = 0;
330 while(i < 100)
331 {
332 //rtmp.HwMemoryReadDword(EFUSE_CTRL, (DWORD *) &eFuseCtrlStruc, 4);
333 RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
334 if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
335 {
336 break;
337 }
338 RTMPusecDelay(2);
339 i++;
340 }
341
342 //if EFSROM_AOUT is not found in physical address, write 0xffff
343 if (eFuseCtrlStruc.field.EFSROM_AOUT == 0x3f)
344 {
345 for(i=0; i<Length/2; i++)
346 *(pData+2*i) = 0xffff;
347 }
348 else
349 {
350 //Step4. Read 16-byte of data from EFUSE_DATA0-3 (0x590-0x59C)
351 efuseDataOffset = EFUSE_DATA3 - (Offset & 0xC) ;
352 //data hold 4 bytes data.
353 //In RTMP_IO_READ32 will automatically execute 32-bytes swapping
354 RTMP_IO_READ32(pAd, efuseDataOffset, &data);
355 //Decide the upper 2 bytes or the bottom 2 bytes.
356 // Little-endian S | S Big-endian
357 // addr 3 2 1 0 | 0 1 2 3
358 // Ori-V D C B A | A B C D
359 //After swapping
360 // D C B A | D C B A
361 //Return 2-bytes
362 //The return byte statrs from S. Therefore, the little-endian will return BA, the Big-endian will return DC.
363 //For returning the bottom 2 bytes, the Big-endian should shift right 2-bytes.
364 data = data >> (8*(Offset & 0x3));
365
366 NdisMoveMemory(pData, &data, Length);
367 }
368
369 return (UCHAR) eFuseCtrlStruc.field.EFSROM_AOUT;
370
371}
372
373/*
374 ========================================================================
375
376 Routine Description:
377
378 Arguments:
379
380 Return Value:
381
382 IRQL =
383
384 Note:
385
386 ========================================================================
387*/
388VOID eFusePhysicalReadRegisters(
389 IN PRTMP_ADAPTER pAd,
390 IN USHORT Offset,
391 IN USHORT Length,
392 OUT USHORT* pData)
393{ 43{
394 EFUSE_CTRL_STRUC eFuseCtrlStruc; 44 RTMP_CHIP_OP *pChipOps = &pAd->chipOps;
395 int i; 45#ifdef RT30xx
396 USHORT efuseDataOffset; 46#ifdef RTMP_EFUSE_SUPPORT
397 UINT32 data; 47 UINT32 eFuseCtrl, MacCsr0;
398 48 int index;
399 RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
400
401 //Step0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
402 eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
403
404 //Step1. Write EFSROM_MODE (0x580, bit7:bit6) to 1.
405 //Read in physical view
406 eFuseCtrlStruc.field.EFSROM_MODE = 1;
407
408 //Step2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.
409 eFuseCtrlStruc.field.EFSROM_KICK = 1;
410
411 NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
412 RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
413
414 //Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.
415 i = 0;
416 while(i < 100)
417 {
418 RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
419 if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
420 break;
421 RTMPusecDelay(2);
422 i++;
423 }
424
425 //Step4. Read 16-byte of data from EFUSE_DATA0-3 (0x59C-0x590)
426 //Because the size of each EFUSE_DATA is 4 Bytes, the size of address of each is 2 bits.
427 //The previous 2 bits is the EFUSE_DATA number, the last 2 bits is used to decide which bytes
428 //Decide which EFUSE_DATA to read
429 //590:F E D C
430 //594:B A 9 8
431 //598:7 6 5 4
432 //59C:3 2 1 0
433 efuseDataOffset = EFUSE_DATA3 - (Offset & 0xC) ;
434
435 RTMP_IO_READ32(pAd, efuseDataOffset, &data);
436
437 data = data >> (8*(Offset & 0x3));
438
439 NdisMoveMemory(pData, &data, Length);
440
441}
442
443/*
444 ========================================================================
445
446 Routine Description:
447
448 Arguments:
449
450 Return Value:
451
452 IRQL =
453
454 Note:
455
456 ========================================================================
457*/
458VOID eFuseReadPhysical(
459 IN PRTMP_ADAPTER pAd,
460 IN PUSHORT lpInBuffer,
461 IN ULONG nInBufferSize,
462 OUT PUSHORT lpOutBuffer,
463 IN ULONG nOutBufferSize
464)
465{
466 USHORT* pInBuf = (USHORT*)lpInBuffer;
467 USHORT* pOutBuf = (USHORT*)lpOutBuffer;
468
469 USHORT Offset = pInBuf[0]; //addr
470 USHORT Length = pInBuf[1]; //length
471 int i;
472
473 for(i=0; i<Length; i+=2)
474 {
475 eFusePhysicalReadRegisters(pAd,Offset+i, 2, &pOutBuf[i/2]);
476 }
477}
478
479/*
480 ========================================================================
481
482 Routine Description:
483
484 Arguments:
485
486 Return Value:
487
488 IRQL =
489
490 Note:
491
492 ========================================================================
493*/
494NTSTATUS eFuseRead(
495 IN PRTMP_ADAPTER pAd,
496 IN USHORT Offset,
497 OUT PUCHAR pData,
498 IN USHORT Length)
499{
500 USHORT* pOutBuf = (USHORT*)pData;
501 NTSTATUS Status = STATUS_SUCCESS;
502 UCHAR EFSROM_AOUT;
503 int i;
504
505 for(i=0; i<Length; i+=2)
506 {
507 EFSROM_AOUT = eFuseReadRegisters(pAd, Offset+i, 2, &pOutBuf[i/2]);
508 }
509 return Status;
510}
511
512/*
513 ========================================================================
514
515 Routine Description:
516
517 Arguments:
518
519 Return Value:
520
521 IRQL =
522
523 Note:
524
525 ========================================================================
526*/
527VOID eFusePhysicalWriteRegisters(
528 IN PRTMP_ADAPTER pAd,
529 IN USHORT Offset,
530 IN USHORT Length,
531 OUT USHORT* pData)
532{
533 EFUSE_CTRL_STRUC eFuseCtrlStruc;
534 int i;
535 USHORT efuseDataOffset;
536 UINT32 data, eFuseDataBuffer[4];
537
538 //Step0. Write 16-byte of data to EFUSE_DATA0-3 (0x590-0x59C), where EFUSE_DATA0 is the LSB DW, EFUSE_DATA3 is the MSB DW.
539
540 /////////////////////////////////////////////////////////////////
541 //read current values of 16-byte block
542 RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
543
544 //Step0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
545 eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
546
547 //Step1. Write EFSROM_MODE (0x580, bit7:bit6) to 1.
548 eFuseCtrlStruc.field.EFSROM_MODE = 1;
549
550 //Step2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.
551 eFuseCtrlStruc.field.EFSROM_KICK = 1;
552
553 NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
554 RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
555
556 //Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.
557 i = 0;
558 while(i < 100)
559 {
560 RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
561
562 if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
563 break;
564 RTMPusecDelay(2);
565 i++;
566 }
567
568 //Step4. Read 16-byte of data from EFUSE_DATA0-3 (0x59C-0x590)
569 efuseDataOffset = EFUSE_DATA3;
570 for(i=0; i< 4; i++)
571 {
572 RTMP_IO_READ32(pAd, efuseDataOffset, (PUINT32) &eFuseDataBuffer[i]);
573 efuseDataOffset -= 4;
574 }
575
576 //Update the value, the offset is multiple of 2, length is 2
577 efuseDataOffset = (Offset & 0xc) >> 2;
578 data = pData[0] & 0xffff;
579 //The offset should be 0x***10 or 0x***00
580 if((Offset % 4) != 0)
581 {
582 eFuseDataBuffer[efuseDataOffset] = (eFuseDataBuffer[efuseDataOffset] & 0xffff) | (data << 16);
583 }
584 else
585 {
586 eFuseDataBuffer[efuseDataOffset] = (eFuseDataBuffer[efuseDataOffset] & 0xffff0000) | data;
587 }
588
589 efuseDataOffset = EFUSE_DATA3;
590 for(i=0; i< 4; i++)
591 {
592 RTMP_IO_WRITE32(pAd, efuseDataOffset, eFuseDataBuffer[i]);
593 efuseDataOffset -= 4;
594 }
595 /////////////////////////////////////////////////////////////////
596
597 //Step1. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
598 eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
599
600 //Step2. Write EFSROM_MODE (0x580, bit7:bit6) to 3.
601 eFuseCtrlStruc.field.EFSROM_MODE = 3;
602
603 //Step3. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical write procedure.
604 eFuseCtrlStruc.field.EFSROM_KICK = 1;
605
606 NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
607 RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
608
609 //Step4. Polling EFSROM_KICK(0x580, bit30) until it become 0 again. It��s done.
610 i = 0;
611 while(i < 100)
612 {
613 RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
614
615 if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
616 break;
617
618 RTMPusecDelay(2);
619 i++;
620 }
621}
622
623/*
624 ========================================================================
625
626 Routine Description:
627
628 Arguments:
629
630 Return Value:
631
632 IRQL =
633
634 Note:
635
636 ========================================================================
637*/
638NTSTATUS eFuseWriteRegisters(
639 IN PRTMP_ADAPTER pAd,
640 IN USHORT Offset,
641 IN USHORT Length,
642 IN USHORT* pData)
643{
644 USHORT i;
645 USHORT eFuseData;
646 USHORT LogicalAddress, BlkNum = 0xffff;
647 UCHAR EFSROM_AOUT;
648
649 USHORT addr,tmpaddr, InBuf[3], tmpOffset;
650 USHORT buffer[8];
651 BOOLEAN bWriteSuccess = TRUE;
652
653 DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters Offset=%x, pData=%x\n", Offset, *pData));
654
655 //Step 0. find the entry in the mapping table
656 //The address of EEPROM is 2-bytes alignment.
657 //The last bit is used for alignment, so it must be 0.
658 tmpOffset = Offset & 0xfffe;
659 EFSROM_AOUT = eFuseReadRegisters(pAd, tmpOffset, 2, &eFuseData);
660
661 if( EFSROM_AOUT == 0x3f)
662 { //find available logical address pointer
663 //the logical address does not exist, find an empty one
664 //from the first address of block 45=16*45=0x2d0 to the last address of block 47
665 //==>48*16-3(reserved)=2FC
666 for (i=EFUSE_USAGE_MAP_START; i<=EFUSE_USAGE_MAP_END; i+=2)
667 {
668 //Retrive the logical block nubmer form each logical address pointer
669 //It will access two logical address pointer each time.
670 eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
671 if( (LogicalAddress & 0xff) == 0)
672 {//Not used logical address pointer
673 BlkNum = i-EFUSE_USAGE_MAP_START;
674 break;
675 }
676 else if(( (LogicalAddress >> 8) & 0xff) == 0)
677 {//Not used logical address pointer
678 if (i != EFUSE_USAGE_MAP_END)
679 {
680 BlkNum = i-EFUSE_USAGE_MAP_START+1;
681 }
682 break;
683 }
684 }
685 }
686 else
687 {
688 BlkNum = EFSROM_AOUT;
689 }
690
691 DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters BlkNum = %d \n", BlkNum));
692
693 if(BlkNum == 0xffff)
694 {
695 DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters: out of free E-fuse space!!!\n"));
696 return FALSE;
697 }
698
699 //Step 1. Save data of this block which is pointed by the avaible logical address pointer
700 // read and save the original block data
701 for(i =0; i<8; i++)
702 {
703 addr = BlkNum * 0x10 ;
704
705 InBuf[0] = addr+2*i;
706 InBuf[1] = 2;
707 InBuf[2] = 0x0;
708
709 eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
710
711 buffer[i] = InBuf[2];
712 }
713
714 //Step 2. Update the data in buffer, and write the data to Efuse
715 buffer[ (Offset >> 1) % 8] = pData[0];
716 49
50 index = 0;
717 do 51 do
718 { 52 {
719 //Step 3. Write the data to Efuse 53 RTMP_IO_READ32(pAd, MAC_CSR0, &MacCsr0);
720 if(!bWriteSuccess) 54 pAd->MACVersion = MacCsr0;
721 {
722 for(i =0; i<8; i++)
723 {
724 addr = BlkNum * 0x10 ;
725
726 InBuf[0] = addr+2*i;
727 InBuf[1] = 2;
728 InBuf[2] = buffer[i];
729
730 eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 2);
731 }
732 }
733 else
734 {
735 addr = BlkNum * 0x10 ;
736
737 InBuf[0] = addr+(Offset % 16);
738 InBuf[1] = 2;
739 InBuf[2] = pData[0];
740
741 eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 2);
742 }
743
744 //Step 4. Write mapping table
745 addr = EFUSE_USAGE_MAP_START+BlkNum;
746
747 tmpaddr = addr;
748 55
749 if(addr % 2 != 0) 56 if ((pAd->MACVersion != 0x00) && (pAd->MACVersion != 0xFFFFFFFF))
750 addr = addr -1;
751 InBuf[0] = addr;
752 InBuf[1] = 2;
753
754 //convert the address from 10 to 8 bit ( bit7, 6 = parity and bit5 ~ 0 = bit9~4), and write to logical map entry
755 tmpOffset = Offset;
756 tmpOffset >>= 4;
757 tmpOffset |= ((~((tmpOffset & 0x01) ^ ( tmpOffset >> 1 & 0x01) ^ (tmpOffset >> 2 & 0x01) ^ (tmpOffset >> 3 & 0x01))) << 6) & 0x40;
758 tmpOffset |= ((~( (tmpOffset >> 2 & 0x01) ^ (tmpOffset >> 3 & 0x01) ^ (tmpOffset >> 4 & 0x01) ^ ( tmpOffset >> 5 & 0x01))) << 7) & 0x80;
759
760 // write the logical address
761 if(tmpaddr%2 != 0)
762 InBuf[2] = tmpOffset<<8;
763 else
764 InBuf[2] = tmpOffset;
765
766 eFuseWritePhysical(pAd,&InBuf[0], 6, NULL, 0);
767
768 //Step 5. Compare data if not the same, invalidate the mapping entry, then re-write the data until E-fuse is exhausted
769 bWriteSuccess = TRUE;
770 for(i =0; i<8; i++)
771 {
772 addr = BlkNum * 0x10 ;
773
774 InBuf[0] = addr+2*i;
775 InBuf[1] = 2;
776 InBuf[2] = 0x0;
777
778 eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
779
780 if(buffer[i] != InBuf[2])
781 {
782 bWriteSuccess = FALSE;
783 break;
784 }
785 }
786
787 //Step 6. invlidate mapping entry and find a free mapping entry if not succeed
788 if (!bWriteSuccess)
789 {
790 DBGPRINT(RT_DEBUG_TRACE, ("Not bWriteSuccess BlkNum = %d\n", BlkNum));
791
792 // the offset of current mapping entry
793 addr = EFUSE_USAGE_MAP_START+BlkNum;
794
795 //find a new mapping entry
796 BlkNum = 0xffff;
797 for (i=EFUSE_USAGE_MAP_START; i<=EFUSE_USAGE_MAP_END; i+=2)
798 {
799 eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
800 if( (LogicalAddress & 0xff) == 0)
801 {
802 BlkNum = i-EFUSE_USAGE_MAP_START;
803 break;
804 }
805 else if(( (LogicalAddress >> 8) & 0xff) == 0)
806 {
807 if (i != EFUSE_USAGE_MAP_END)
808 {
809 BlkNum = i+1-EFUSE_USAGE_MAP_START;
810 }
811 break;
812 }
813 }
814 DBGPRINT(RT_DEBUG_TRACE, ("Not bWriteSuccess new BlkNum = %d\n", BlkNum));
815 if(BlkNum == 0xffff)
816 {
817 DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters: out of free E-fuse space!!!\n"));
818 return FALSE;
819 }
820
821 //invalidate the original mapping entry if new entry is not found
822 tmpaddr = addr;
823
824 if(addr % 2 != 0)
825 addr = addr -1;
826 InBuf[0] = addr;
827 InBuf[1] = 2;
828
829 eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
830
831 // write the logical address
832 if(tmpaddr%2 != 0)
833 {
834 // Invalidate the high byte
835 for (i=8; i<15; i++)
836 {
837 if( ( (InBuf[2] >> i) & 0x01) == 0)
838 {
839 InBuf[2] |= (0x1 <<i);
840 break;
841 }
842 }
843 }
844 else
845 {
846 // invalidate the low byte
847 for (i=0; i<8; i++)
848 {
849 if( ( (InBuf[2] >> i) & 0x01) == 0)
850 {
851 InBuf[2] |= (0x1 <<i);
852 break;
853 }
854 }
855 }
856 eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 0);
857 }
858 }
859 while(!bWriteSuccess);
860
861 return TRUE;
862}
863
864/*
865 ========================================================================
866
867 Routine Description:
868
869 Arguments:
870
871 Return Value:
872
873 IRQL =
874
875 Note:
876
877 ========================================================================
878*/
879VOID eFuseWritePhysical(
880 IN PRTMP_ADAPTER pAd,
881 PUSHORT lpInBuffer,
882 ULONG nInBufferSize,
883 PUCHAR lpOutBuffer,
884 ULONG nOutBufferSize
885)
886{
887 USHORT* pInBuf = (USHORT*)lpInBuffer;
888 int i;
889 //USHORT* pOutBuf = (USHORT*)ioBuffer;
890
891 USHORT Offset = pInBuf[0]; //addr
892 USHORT Length = pInBuf[1]; //length
893 USHORT* pValueX = &pInBuf[2]; //value ...
894 // Little-endian S | S Big-endian
895 // addr 3 2 1 0 | 0 1 2 3
896 // Ori-V D C B A | A B C D
897 //After swapping
898 // D C B A | D C B A
899 //Both the little and big-endian use the same sequence to write data.
900 //Therefore, we only need swap data when read the data.
901 for(i=0; i<Length; i+=2)
902 {
903 eFusePhysicalWriteRegisters(pAd, Offset+i, 2, &pValueX[i/2]);
904 }
905}
906
907
908/*
909 ========================================================================
910
911 Routine Description:
912
913 Arguments:
914
915 Return Value:
916
917 IRQL =
918
919 Note:
920
921 ========================================================================
922*/
923NTSTATUS eFuseWrite(
924 IN PRTMP_ADAPTER pAd,
925 IN USHORT Offset,
926 IN PUCHAR pData,
927 IN USHORT length)
928{
929 int i;
930
931 USHORT* pValueX = (PUSHORT) pData; //value ...
932 //The input value=3070 will be stored as following
933 // Little-endian S | S Big-endian
934 // addr 1 0 | 0 1
935 // Ori-V 30 70 | 30 70
936 //After swapping
937 // 30 70 | 70 30
938 //Casting
939 // 3070 | 7030 (x)
940 //The swapping should be removed for big-endian
941 for(i=0; i<length; i+=2)
942 {
943 eFuseWriteRegisters(pAd, Offset+i, 2, &pValueX[i/2]);
944 }
945
946 return TRUE;
947}
948
949/*
950 ========================================================================
951
952 Routine Description:
953
954 Arguments:
955
956 Return Value:
957
958 IRQL =
959
960 Note:
961
962 ========================================================================
963*/
964INT set_eFuseGetFreeBlockCount_Proc(
965 IN PRTMP_ADAPTER pAd,
966 IN PUCHAR arg)
967{
968 USHORT i;
969 USHORT LogicalAddress;
970 USHORT efusefreenum=0;
971 if(!pAd->bUseEfuse)
972 return FALSE;
973 for (i = EFUSE_USAGE_MAP_START; i <= EFUSE_USAGE_MAP_END; i+=2)
974 {
975 eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
976 if( (LogicalAddress & 0xff) == 0)
977 {
978 efusefreenum= (UCHAR) (EFUSE_USAGE_MAP_END-i+1);
979 break;
980 }
981 else if(( (LogicalAddress >> 8) & 0xff) == 0)
982 {
983 efusefreenum = (UCHAR) (EFUSE_USAGE_MAP_END-i);
984 break;
985 }
986
987 if(i == EFUSE_USAGE_MAP_END)
988 efusefreenum = 0;
989 }
990 printk("efuseFreeNumber is %d\n",efusefreenum);
991 return TRUE;
992}
993INT set_eFusedump_Proc(
994 IN PRTMP_ADAPTER pAd,
995 IN PUCHAR arg)
996{
997USHORT InBuf[3];
998 INT i=0;
999 if(!pAd->bUseEfuse)
1000 return FALSE;
1001 for(i =0; i<EFUSE_USAGE_MAP_END/2; i++)
1002 {
1003 InBuf[0] = 2*i;
1004 InBuf[1] = 2;
1005 InBuf[2] = 0x0;
1006
1007 eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
1008 if(i%4==0)
1009 printk("\nBlock %x:",i/8);
1010 printk("%04x ",InBuf[2]);
1011 }
1012 return TRUE;
1013}
1014INT set_eFuseLoadFromBin_Proc(
1015 IN PRTMP_ADAPTER pAd,
1016 IN PUCHAR arg)
1017{
1018 CHAR *src;
1019 struct file *srcf;
1020 INT retval;
1021 mm_segment_t orgfs;
1022 UCHAR *buffer;
1023 UCHAR BinFileSize=0;
1024 INT i = 0,j=0,k=1;
1025 USHORT *PDATA;
1026 USHORT DATA;
1027 BinFileSize=strlen("RT30xxEEPROM.bin");
1028 src = kmalloc(128, MEM_ALLOC_FLAG);
1029 NdisZeroMemory(src, 128);
1030
1031 if(strlen(arg)>0)
1032 {
1033
1034 NdisMoveMemory(src, arg, strlen(arg));
1035 }
1036
1037 else
1038 {
1039
1040 NdisMoveMemory(src, "RT30xxEEPROM.bin", BinFileSize);
1041 }
1042
1043 DBGPRINT(RT_DEBUG_TRACE, ("FileName=%s\n",src));
1044 buffer = kmalloc(MAX_EEPROM_BIN_FILE_SIZE, MEM_ALLOC_FLAG);
1045
1046 if(buffer == NULL)
1047 {
1048 kfree(src);
1049 return FALSE;
1050}
1051 PDATA=kmalloc(sizeof(USHORT)*8,MEM_ALLOC_FLAG);
1052
1053 if(PDATA==NULL)
1054 {
1055 kfree(src);
1056
1057 kfree(buffer);
1058 return FALSE;
1059 }
1060
1061 orgfs = get_fs();
1062 set_fs(KERNEL_DS);
1063
1064 if (src && *src)
1065 {
1066 srcf = filp_open(src, O_RDONLY, 0);
1067 if (IS_ERR(srcf))
1068 {
1069 DBGPRINT(RT_DEBUG_ERROR, ("--> Error %ld opening %s\n", -PTR_ERR(srcf),src));
1070 return FALSE;
1071 }
1072 else
1073 {
1074 // The object must have a read method
1075 if (srcf->f_op && srcf->f_op->read)
1076 {
1077 memset(buffer, 0x00, MAX_EEPROM_BIN_FILE_SIZE);
1078 while(srcf->f_op->read(srcf, &buffer[i], 1, &srcf->f_pos)==1)
1079 {
1080 DBGPRINT(RT_DEBUG_TRACE, ("%02X ",buffer[i]));
1081 if((i+1)%8==0)
1082 DBGPRINT(RT_DEBUG_TRACE, ("\n"));
1083 i++;
1084 if(i>=MAX_EEPROM_BIN_FILE_SIZE)
1085 {
1086 DBGPRINT(RT_DEBUG_ERROR, ("--> Error %ld reading %s, The file is too large[1024]\n", -PTR_ERR(srcf),src));
1087 kfree(PDATA);
1088 kfree(buffer);
1089 kfree(src);
1090 return FALSE;
1091 }
1092 }
1093 }
1094 else
1095 {
1096 DBGPRINT(RT_DEBUG_ERROR, ("--> Error!! System doest not support read function\n"));
1097 kfree(PDATA);
1098 kfree(buffer);
1099 kfree(src);
1100 return FALSE;
1101 }
1102 }
1103
1104
1105 }
1106 else
1107 {
1108 DBGPRINT(RT_DEBUG_ERROR, ("--> Error src or srcf is null\n"));
1109 kfree(PDATA);
1110 kfree(buffer);
1111 return FALSE;
1112
1113 }
1114
1115
1116 retval=filp_close(srcf,NULL);
1117
1118 if (retval)
1119 {
1120 DBGPRINT(RT_DEBUG_TRACE, ("--> Error %d closing %s\n", -retval, src));
1121 }
1122 set_fs(orgfs);
1123
1124 for(j=0;j<i;j++)
1125 {
1126 DBGPRINT(RT_DEBUG_TRACE, ("%02X ",buffer[j]));
1127 if((j+1)%2==0)
1128 PDATA[j/2%8]=((buffer[j]<<8)&0xff00)|(buffer[j-1]&0xff);
1129 if(j%16==0)
1130 {
1131 k=buffer[j];
1132 }
1133 else
1134 {
1135 k&=buffer[j];
1136 if((j+1)%16==0)
1137 {
1138
1139 DBGPRINT(RT_DEBUG_TRACE, (" result=%02X,blk=%02x\n",k,j/16));
1140
1141 if(k!=0xff)
1142 eFuseWriteRegistersFromBin(pAd,(USHORT)j-15, 16, PDATA);
1143 else
1144 {
1145 if(eFuseReadRegisters(pAd,j, 2,(PUSHORT)&DATA)!=0x3f)
1146 eFuseWriteRegistersFromBin(pAd,(USHORT)j-15, 16, PDATA);
1147 }
1148 /*
1149 for(l=0;l<8;l++)
1150 printk("%04x ",PDATA[l]);
1151 printk("\n");
1152 */
1153 NdisZeroMemory(PDATA,16);
1154
1155
1156 }
1157 }
1158
1159
1160 }
1161
1162
1163 kfree(PDATA);
1164 kfree(buffer);
1165 kfree(src);
1166 return TRUE;
1167}
1168NTSTATUS eFuseWriteRegistersFromBin(
1169 IN PRTMP_ADAPTER pAd,
1170 IN USHORT Offset,
1171 IN USHORT Length,
1172 IN USHORT* pData)
1173{
1174 USHORT i;
1175 USHORT eFuseData;
1176 USHORT LogicalAddress, BlkNum = 0xffff;
1177 UCHAR EFSROM_AOUT,Loop=0;
1178 EFUSE_CTRL_STRUC eFuseCtrlStruc;
1179 USHORT efuseDataOffset;
1180 UINT32 data,tempbuffer;
1181 USHORT addr,tmpaddr, InBuf[3], tmpOffset;
1182 UINT32 buffer[4];
1183 BOOLEAN bWriteSuccess = TRUE;
1184 BOOLEAN bNotWrite=TRUE;
1185 BOOLEAN bAllocateNewBlk=TRUE;
1186
1187 DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin Offset=%x, pData=%04x:%04x:%04x:%04x\n", Offset, *pData,*(pData+1),*(pData+2),*(pData+3)));
1188
1189 do
1190 {
1191 //Step 0. find the entry in the mapping table
1192 //The address of EEPROM is 2-bytes alignment.
1193 //The last bit is used for alignment, so it must be 0.
1194 Loop++;
1195 tmpOffset = Offset & 0xfffe;
1196 EFSROM_AOUT = eFuseReadRegisters(pAd, tmpOffset, 2, &eFuseData);
1197
1198 if( EFSROM_AOUT == 0x3f)
1199 { //find available logical address pointer
1200 //the logical address does not exist, find an empty one
1201 //from the first address of block 45=16*45=0x2d0 to the last address of block 47
1202 //==>48*16-3(reserved)=2FC
1203 bAllocateNewBlk=TRUE;
1204 for (i=EFUSE_USAGE_MAP_START; i<=EFUSE_USAGE_MAP_END; i+=2)
1205 {
1206 //Retrive the logical block nubmer form each logical address pointer
1207 //It will access two logical address pointer each time.
1208 eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
1209 if( (LogicalAddress & 0xff) == 0)
1210 {//Not used logical address pointer
1211 BlkNum = i-EFUSE_USAGE_MAP_START;
1212 break;
1213 }
1214 else if(( (LogicalAddress >> 8) & 0xff) == 0)
1215 {//Not used logical address pointer
1216 if (i != EFUSE_USAGE_MAP_END)
1217 {
1218 BlkNum = i-EFUSE_USAGE_MAP_START+1;
1219 }
1220 break;
1221 }
1222 }
1223 }
1224 else
1225 {
1226 bAllocateNewBlk=FALSE;
1227 BlkNum = EFSROM_AOUT;
1228 }
1229
1230 DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters BlkNum = %d \n", BlkNum));
1231
1232 if(BlkNum == 0xffff)
1233 {
1234 DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters: out of free E-fuse space!!!\n"));
1235 return FALSE;
1236 }
1237 //Step 1.1.0
1238 //If the block is not existing in mapping table, create one
1239 //and write down the 16-bytes data to the new block
1240 if(bAllocateNewBlk)
1241 {
1242 DBGPRINT(RT_DEBUG_TRACE, ("Allocate New Blk\n"));
1243 efuseDataOffset = EFUSE_DATA3;
1244 for(i=0; i< 4; i++)
1245 {
1246 DBGPRINT(RT_DEBUG_TRACE, ("Allocate New Blk, Data%d=%04x%04x\n",3-i,pData[2*i+1],pData[2*i]));
1247 tempbuffer=((pData[2*i+1]<<16)&0xffff0000)|pData[2*i];
1248
1249
1250 RTMP_IO_WRITE32(pAd, efuseDataOffset,tempbuffer);
1251 efuseDataOffset -= 4;
1252
1253 }
1254 /////////////////////////////////////////////////////////////////
1255
1256 //Step1.1.1. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
1257 eFuseCtrlStruc.field.EFSROM_AIN = BlkNum* 0x10 ;
1258
1259 //Step1.1.2. Write EFSROM_MODE (0x580, bit7:bit6) to 3.
1260 eFuseCtrlStruc.field.EFSROM_MODE = 3;
1261
1262 //Step1.1.3. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical write procedure.
1263 eFuseCtrlStruc.field.EFSROM_KICK = 1;
1264
1265 NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
1266
1267 RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
1268
1269 //Step1.1.4. Polling EFSROM_KICK(0x580, bit30) until it become 0 again. It��s done.
1270 i = 0;
1271 while(i < 100)
1272 {
1273 RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
1274
1275 if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
1276 break; 57 break;
1277 58
1278 RTMPusecDelay(2); 59 RTMPusecDelay(10);
1279 i++; 60 } while (index++ < 100);
1280 }
1281 61
1282 } 62 pAd->bUseEfuse=FALSE;
1283 else 63 RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrl);
1284 { //Step1.2. 64 pAd->bUseEfuse = ( (eFuseCtrl & 0x80000000) == 0x80000000) ? 1 : 0;
1285 //If the same logical number is existing, check if the writting data and the data 65 if(pAd->bUseEfuse)
1286 //saving in this block are the same.
1287 /////////////////////////////////////////////////////////////////
1288 //read current values of 16-byte block
1289 RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
1290
1291 //Step1.2.0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
1292 eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
1293
1294 //Step1.2.1. Write EFSROM_MODE (0x580, bit7:bit6) to 1.
1295 eFuseCtrlStruc.field.EFSROM_MODE = 0;
1296
1297 //Step1.2.2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.
1298 eFuseCtrlStruc.field.EFSROM_KICK = 1;
1299
1300 NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
1301 RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
1302
1303 //Step1.2.3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.
1304 i = 0;
1305 while(i < 100)
1306 {
1307 RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
1308
1309 if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
1310 break;
1311 RTMPusecDelay(2);
1312 i++;
1313 }
1314
1315 //Step1.2.4. Read 16-byte of data from EFUSE_DATA0-3 (0x59C-0x590)
1316 efuseDataOffset = EFUSE_DATA3;
1317 for(i=0; i< 4; i++)
1318 {
1319 RTMP_IO_READ32(pAd, efuseDataOffset, (PUINT32) &buffer[i]);
1320 efuseDataOffset -= 4;
1321 }
1322 //Step1.2.5. Check if the data of efuse and the writing data are the same.
1323 for(i =0; i<4; i++)
1324 {
1325 tempbuffer=((pData[2*i+1]<<16)&0xffff0000)|pData[2*i];
1326 DBGPRINT(RT_DEBUG_TRACE, ("buffer[%d]=%x,pData[%d]=%x,pData[%d]=%x,tempbuffer=%x\n",i,buffer[i],2*i,pData[2*i],2*i+1,pData[2*i+1],tempbuffer));
1327
1328 if(((buffer[i]&0xffff0000)==(pData[2*i+1]<<16))&&((buffer[i]&0xffff)==pData[2*i]))
1329 bNotWrite&=TRUE;
1330 else
1331 { 66 {
1332 bNotWrite&=FALSE; 67 pChipOps->eeinit = eFuse_init;
1333 break; 68 pChipOps->eeread = rtmp_ee_efuse_read16;
1334 } 69 pChipOps->eewrite = rtmp_ee_efuse_write16;
1335 } 70 return 0 ;
1336 if(!bNotWrite)
1337 {
1338 printk("The data is not the same\n");
1339
1340 for(i =0; i<8; i++)
1341 {
1342 addr = BlkNum * 0x10 ;
1343
1344 InBuf[0] = addr+2*i;
1345 InBuf[1] = 2;
1346 InBuf[2] = pData[i];
1347
1348 eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 2);
1349 }
1350
1351 }
1352 else
1353 return TRUE;
1354 } 71 }
1355
1356
1357
1358 //Step 2. Write mapping table
1359 addr = EFUSE_USAGE_MAP_START+BlkNum;
1360
1361 tmpaddr = addr;
1362
1363 if(addr % 2 != 0)
1364 addr = addr -1;
1365 InBuf[0] = addr;
1366 InBuf[1] = 2;
1367
1368 //convert the address from 10 to 8 bit ( bit7, 6 = parity and bit5 ~ 0 = bit9~4), and write to logical map entry
1369 tmpOffset = Offset;
1370 tmpOffset >>= 4;
1371 tmpOffset |= ((~((tmpOffset & 0x01) ^ ( tmpOffset >> 1 & 0x01) ^ (tmpOffset >> 2 & 0x01) ^ (tmpOffset >> 3 & 0x01))) << 6) & 0x40;
1372 tmpOffset |= ((~( (tmpOffset >> 2 & 0x01) ^ (tmpOffset >> 3 & 0x01) ^ (tmpOffset >> 4 & 0x01) ^ ( tmpOffset >> 5 & 0x01))) << 7) & 0x80;
1373
1374 // write the logical address
1375 if(tmpaddr%2 != 0)
1376 InBuf[2] = tmpOffset<<8;
1377 else 72 else
1378 InBuf[2] = tmpOffset;
1379
1380 eFuseWritePhysical(pAd,&InBuf[0], 6, NULL, 0);
1381
1382 //Step 3. Compare data if not the same, invalidate the mapping entry, then re-write the data until E-fuse is exhausted
1383 bWriteSuccess = TRUE;
1384 for(i =0; i<8; i++)
1385 {
1386 addr = BlkNum * 0x10 ;
1387
1388 InBuf[0] = addr+2*i;
1389 InBuf[1] = 2;
1390 InBuf[2] = 0x0;
1391
1392 eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
1393 DBGPRINT(RT_DEBUG_TRACE, ("addr=%x, buffer[i]=%x,InBuf[2]=%x\n",InBuf[0],pData[i],InBuf[2]));
1394 if(pData[i] != InBuf[2])
1395 { 73 {
1396 bWriteSuccess = FALSE; 74 pAd->bFroceEEPROMBuffer = FALSE;
1397 break; 75 DBGPRINT(RT_DEBUG_TRACE, ("NVM is EEPROM\n"));
1398 } 76 }
1399 } 77#endif // RTMP_EFUSE_SUPPORT //
1400 78#endif // RT30xx //
1401 //Step 4. invlidate mapping entry and find a free mapping entry if not succeed
1402 79
1403 if (!bWriteSuccess&&Loop<2) 80 switch(infType)
1404 { 81 {
1405 DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin::Not bWriteSuccess BlkNum = %d\n", BlkNum)); 82#ifdef RTMP_PCI_SUPPORT
1406 83 case RTMP_DEV_INF_PCI:
1407 // the offset of current mapping entry 84 pChipOps->eeinit = NULL;
1408 addr = EFUSE_USAGE_MAP_START+BlkNum; 85 pChipOps->eeread = rtmp_ee_prom_read16;
1409 86 pChipOps->eewrite = rtmp_ee_prom_write16;
1410 //find a new mapping entry
1411 BlkNum = 0xffff;
1412 for (i=EFUSE_USAGE_MAP_START; i<=EFUSE_USAGE_MAP_END; i+=2)
1413 {
1414 eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
1415 if( (LogicalAddress & 0xff) == 0)
1416 {
1417 BlkNum = i-EFUSE_USAGE_MAP_START;
1418 break; 87 break;
1419 } 88#endif // RTMP_PCI_SUPPORT //
1420 else if(( (LogicalAddress >> 8) & 0xff) == 0) 89#ifdef RTMP_USB_SUPPORT
1421 { 90 case RTMP_DEV_INF_USB:
1422 if (i != EFUSE_USAGE_MAP_END) 91 pChipOps->eeinit = NULL;
1423 { 92 pChipOps->eeread = RTUSBReadEEPROM16;
1424 BlkNum = i+1-EFUSE_USAGE_MAP_START; 93 pChipOps->eewrite = RTUSBWriteEEPROM16;
1425 }
1426 break; 94 break;
1427 } 95#endif // RTMP_USB_SUPPORT //
1428 }
1429 DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin::Not bWriteSuccess new BlkNum = %d\n", BlkNum));
1430 if(BlkNum == 0xffff)
1431 {
1432 DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin: out of free E-fuse space!!!\n"));
1433 return FALSE;
1434 }
1435
1436 //invalidate the original mapping entry if new entry is not found
1437 tmpaddr = addr;
1438 96
1439 if(addr % 2 != 0) 97 default:
1440 addr = addr -1; 98 DBGPRINT(RT_DEBUG_ERROR, ("RtmpChipOpsEepromHook() failed!\n"));
1441 InBuf[0] = addr;
1442 InBuf[1] = 2;
1443
1444 eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
1445
1446 // write the logical address
1447 if(tmpaddr%2 != 0)
1448 {
1449 // Invalidate the high byte
1450 for (i=8; i<15; i++)
1451 {
1452 if( ( (InBuf[2] >> i) & 0x01) == 0)
1453 {
1454 InBuf[2] |= (0x1 <<i);
1455 break; 99 break;
1456 } 100 }
1457 }
1458 }
1459 else
1460 {
1461 // invalidate the low byte
1462 for (i=0; i<8; i++)
1463 {
1464 if( ( (InBuf[2] >> i) & 0x01) == 0)
1465 {
1466 InBuf[2] |= (0x1 <<i);
1467 break;
1468 }
1469 }
1470 }
1471 eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 0);
1472 }
1473
1474 }
1475 while(!bWriteSuccess&&Loop<2);
1476 101
1477 return TRUE; 102 return 0;
1478} 103}
1479#endif
diff --git a/drivers/staging/rt2860/common/firmware.h b/drivers/staging/rt2860/common/firmware.h
index e72996f42c0..e984725358d 100644
--- a/drivers/staging/rt2860/common/firmware.h
+++ b/drivers/staging/rt2860/common/firmware.h
@@ -43,7 +43,7 @@
43/* AUTO GEN PLEASE DO NOT MODIFY IT */ 43/* AUTO GEN PLEASE DO NOT MODIFY IT */
44 44
45 45
46UCHAR FirmwareImage [] = { 46UCHAR FirmwareImage_2860 [] = {
470x02, 0x03, 0x5e, 0x02, 0x02, 0xb1, 0x22, 0x22, 0xff, 0xff, 0xff, 0x02, 0x01, 0x82, 0xff, 0xff, 470x02, 0x03, 0x5e, 0x02, 0x02, 0xb1, 0x22, 0x22, 0xff, 0xff, 0xff, 0x02, 0x01, 0x82, 0xff, 0xff,
480xff, 0xff, 0xff, 0x02, 0x00, 0x1e, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02, 0x01, 0x33, 0xc0, 0xe0, 480xff, 0xff, 0xff, 0x02, 0x00, 0x1e, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02, 0x01, 0x33, 0xc0, 0xe0,
490xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x18, 0xc2, 0xaf, 0x30, 0x45, 0x03, 490xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x18, 0xc2, 0xaf, 0x30, 0x45, 0x03,
diff --git a/drivers/staging/rt2860/common/firmware_3070.h b/drivers/staging/rt2860/common/firmware_3070.h
new file mode 100644
index 00000000000..19569407f72
--- /dev/null
+++ b/drivers/staging/rt2860/common/firmware_3070.h
@@ -0,0 +1,517 @@
1/* AUTO GEN PLEASE DO NOT MODIFY IT */
2/* AUTO GEN PLEASE DO NOT MODIFY IT */
3
4
5UCHAR FirmwareImage_3070 [] = {
60xff, 0xff, 0xff, 0x02, 0x10, 0x28, 0x02, 0x10, 0x32, 0x02, 0x10, 0x78, 0x02, 0x13, 0x1f, 0x02,
70x13, 0x20, 0x02, 0x13, 0x3f, 0x02, 0x13, 0x44, 0x12, 0x13, 0x40, 0x22, 0x02, 0x17, 0xae, 0x02,
80x18, 0xd2, 0x02, 0x14, 0x3d, 0x02, 0x13, 0x78, 0x30, 0x05, 0x06, 0x20, 0x0d, 0x03, 0x12, 0x19,
90x95, 0x22, 0x90, 0x01, 0x8c, 0xe0, 0x30, 0xe3, 0x1b, 0xe5, 0x4c, 0x30, 0xe0, 0x04, 0x7f, 0x40,
100x80, 0x02, 0x7f, 0x00, 0x90, 0x10, 0x2f, 0xef, 0xf0, 0x90, 0x01, 0x8c, 0x74, 0x08, 0xf0, 0xe4,
110x90, 0x01, 0xa7, 0xf0, 0x90, 0x01, 0x8c, 0xe0, 0x30, 0xe0, 0x1c, 0x90, 0x01, 0x80, 0xe0, 0xb4,
120x02, 0x15, 0xa3, 0xe0, 0xb4, 0x01, 0x10, 0x90, 0x01, 0x84, 0xe0, 0xb4, 0x81, 0x09, 0x90, 0x01,
130x8c, 0x74, 0x01, 0xf0, 0x12, 0x0d, 0xc8, 0x22, 0x90, 0x04, 0x14, 0xe0, 0x20, 0xe7, 0x03, 0x02,
140x13, 0x1e, 0x90, 0x70, 0x12, 0xe0, 0xf5, 0x56, 0x90, 0x04, 0x04, 0xe0, 0x12, 0x0a, 0x9d, 0x10,
150xd9, 0x31, 0x10, 0xbd, 0x36, 0x11, 0x02, 0x50, 0x11, 0x39, 0x51, 0x11, 0x42, 0x52, 0x11, 0x42,
160x53, 0x11, 0x42, 0x54, 0x11, 0x83, 0x55, 0x11, 0xd2, 0x56, 0x12, 0x25, 0x70, 0x12, 0x50, 0x71,
170x12, 0x7e, 0x72, 0x12, 0xd5, 0x73, 0x12, 0xf6, 0x80, 0x00, 0x00, 0x13, 0x1e, 0x90, 0x70, 0x11,
180xe0, 0xf5, 0x3c, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe5, 0x56,
190xf4, 0x70, 0x03, 0x02, 0x13, 0x1e, 0x02, 0x13, 0x17, 0x20, 0x02, 0x03, 0x30, 0x03, 0x1d, 0x7d,
200x02, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13,
210xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0x1e, 0x02, 0x13, 0x17, 0x85, 0x56, 0x41, 0xd2,
220x02, 0x22, 0x90, 0x70, 0x10, 0xe0, 0x54, 0x7f, 0xff, 0xbf, 0x0a, 0x0d, 0x90, 0x70, 0x11, 0xe0,
230xb4, 0x08, 0x06, 0x75, 0x4e, 0x01, 0x75, 0x4f, 0x84, 0x90, 0x70, 0x10, 0xe0, 0x54, 0x7f, 0xff,
240xbf, 0x02, 0x12, 0x90, 0x70, 0x11, 0xe0, 0x64, 0x08, 0x60, 0x04, 0xe0, 0xb4, 0x20, 0x06, 0x75,
250x4e, 0x03, 0x75, 0x4f, 0x20, 0xe4, 0xf5, 0x27, 0x22, 0x90, 0x70, 0x11, 0xe0, 0x24, 0xff, 0x92,
260x47, 0x22, 0x90, 0x04, 0x04, 0xe0, 0x25, 0xe0, 0x24, 0x5d, 0xf5, 0x57, 0x90, 0x70, 0x10, 0xe0,
270xff, 0x74, 0x47, 0x25, 0x57, 0xf8, 0xc6, 0xef, 0xc6, 0x90, 0x70, 0x11, 0xe0, 0xff, 0x74, 0x48,
280x25, 0x57, 0xf8, 0xc6, 0xef, 0xc6, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14,
290x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0x1e,
300x02, 0x13, 0x17, 0xe5, 0x47, 0x64, 0x07, 0x60, 0x1d, 0xe5, 0x47, 0x64, 0x08, 0x60, 0x17, 0xe5,
310x47, 0x64, 0x09, 0x60, 0x11, 0xe5, 0x47, 0x64, 0x0a, 0x60, 0x0b, 0xe5, 0x47, 0x64, 0x0b, 0x60,
320x05, 0xe5, 0x47, 0xb4, 0x0c, 0x08, 0x90, 0x70, 0x11, 0xe0, 0x54, 0x0f, 0xf5, 0x3a, 0xe5, 0x47,
330xb4, 0x09, 0x08, 0xe5, 0x3a, 0xb4, 0x03, 0x03, 0xe4, 0xf5, 0x46, 0xe5, 0x47, 0xb4, 0x0a, 0x08,
340xe5, 0x3a, 0xb4, 0x01, 0x03, 0xe4, 0xf5, 0x46, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0xd2,
350x04, 0x22, 0x90, 0x70, 0x11, 0xe0, 0xf4, 0xff, 0x90, 0x70, 0x10, 0xe0, 0x5f, 0xff, 0x90, 0x70,
360x11, 0xe0, 0x55, 0x27, 0x4f, 0x90, 0x70, 0x18, 0xf0, 0x90, 0x70, 0x11, 0xe0, 0x90, 0x70, 0x19,
370xf0, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x30, 0x15, 0x03, 0xd2, 0x14, 0x22, 0x90, 0x70,
380x18, 0xe0, 0xf5, 0x27, 0x90, 0x02, 0x29, 0xe0, 0xff, 0x90, 0x70, 0x19, 0xe0, 0xfe, 0xef, 0x5e,
390x90, 0x02, 0x29, 0xf0, 0x30, 0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5, 0x27, 0xf4, 0xff, 0x90,
400x02, 0x28, 0xef, 0xf0, 0x22, 0x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0, 0xfd, 0xed,
410xf8, 0xe6, 0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0,
420xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0x1e, 0x02, 0x13, 0x17,
430x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0, 0xfd, 0xed, 0xf5, 0x82, 0x8e, 0x83, 0xe0,
440xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90,
450x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0x1e, 0x02, 0x13, 0x17, 0x90, 0x10,
460x00, 0xe0, 0xf5, 0x57, 0x90, 0x10, 0x02, 0xe0, 0xf5, 0x58, 0xa3, 0xe0, 0xf5, 0x59, 0xe5, 0x58,
470xb4, 0x70, 0x1e, 0xe5, 0x59, 0xb4, 0x30, 0x19, 0x90, 0x05, 0x08, 0xe0, 0x44, 0x01, 0xf0, 0xfd,
480x90, 0x05, 0x05, 0xe0, 0x54, 0xfb, 0xf0, 0x44, 0x04, 0xf0, 0xed, 0x54, 0xfe, 0x90, 0x05, 0x08,
490xf0, 0xe4, 0xf5, 0x4e, 0xf5, 0x4f, 0x75, 0x3a, 0xff, 0x75, 0x3c, 0xff, 0xad, 0x57, 0xaf, 0x56,
500x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56,
510xf4, 0x60, 0x4b, 0x80, 0x42, 0x90, 0x70, 0x10, 0xe0, 0x24, 0xff, 0x92, 0x93, 0xe4, 0xfd, 0xaf,
520x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5,
530x56, 0xf4, 0x60, 0x2a, 0x80, 0x21, 0x90, 0x70, 0x10, 0xe0, 0x24, 0xff, 0x92, 0x4a, 0xd2, 0x05,
540xad, 0x57, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70,
550x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x07, 0x90, 0x70, 0x25, 0xe0, 0x44, 0x01, 0xf0, 0x22, 0x22,
560xe5, 0x53, 0x70, 0x1a, 0x30, 0x60, 0x09, 0xb2, 0x4d, 0x30, 0x4d, 0x04, 0x05, 0x46, 0xc2, 0x04,
570xe5, 0x4f, 0x45, 0x4e, 0x60, 0x08, 0xe5, 0x4f, 0x15, 0x4f, 0x70, 0x02, 0x15, 0x4e, 0x22, 0x22,
580xc2, 0x42, 0xd3, 0x22, 0x30, 0x14, 0x30, 0x90, 0x70, 0x19, 0xe0, 0x55, 0x27, 0xff, 0x90, 0x70,
590x18, 0xe0, 0x4f, 0xf5, 0x27, 0x90, 0x02, 0x29, 0xe0, 0xff, 0x90, 0x70, 0x19, 0xe0, 0xfe, 0xef,
600x5e, 0x90, 0x02, 0x29, 0xf0, 0x30, 0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5, 0x27, 0xf4, 0xff,
610x90, 0x02, 0x28, 0xef, 0xf0, 0xc2, 0x14, 0x22, 0xc2, 0x4b, 0xc2, 0x4c, 0xe5, 0x44, 0x12, 0x0a,
620x9d, 0x13, 0x9a, 0x00, 0x14, 0x28, 0x04, 0x14, 0x24, 0x08, 0x14, 0x04, 0x10, 0x13, 0xae, 0x20,
630x13, 0xce, 0x60, 0x13, 0xdf, 0xa0, 0x00, 0x00, 0x14, 0x2a, 0x85, 0x48, 0x43, 0x85, 0x4a, 0x42,
640x85, 0x4c, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x60, 0x03, 0x02, 0x14, 0x2a, 0x80, 0x1b, 0xe5, 0x48,
650xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4a, 0xc4, 0x54, 0x0f, 0xf5, 0x42, 0xe5, 0x4c, 0xc4, 0x54,
660x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x61, 0x53, 0x43, 0x0f, 0x80, 0x5c, 0x85, 0x49,
670x43, 0x85, 0x4b, 0x42, 0x85, 0x4d, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x4d, 0x80, 0x1b, 0xe5,
680x49, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4b, 0xc4, 0x54, 0x0f, 0xf5, 0x42, 0xe5, 0x4d, 0xc4,
690x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x30, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x10,
700xf5, 0x43, 0x80, 0x26, 0xe5, 0x47, 0x64, 0x04, 0x60, 0x05, 0xe5, 0x47, 0xb4, 0x05, 0x06, 0x43,
710x5e, 0x04, 0x75, 0x42, 0x09, 0xe5, 0x47, 0xb4, 0x06, 0x10, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x30,
720xf5, 0x43, 0x80, 0x06, 0xd2, 0x4b, 0x80, 0x02, 0xd2, 0x4c, 0xe4, 0xf5, 0x25, 0xe5, 0x42, 0xc4,
730x54, 0xf0, 0xff, 0xe5, 0x43, 0x54, 0x0f, 0x4f, 0xf5, 0x5f, 0xd2, 0x60, 0x22, 0xd2, 0x15, 0xe5,
740x47, 0x24, 0xf5, 0x60, 0x0b, 0x24, 0xcb, 0x60, 0x07, 0x24, 0x40, 0x70, 0x06, 0xc2, 0x15, 0x22,
750x12, 0x17, 0x79, 0x12, 0x14, 0x5f, 0xc2, 0x15, 0xc2, 0xaf, 0xc2, 0x04, 0xd2, 0xaf, 0x22, 0xc2,
760xaf, 0x90, 0x04, 0x14, 0xe0, 0x54, 0x0e, 0x60, 0x04, 0xd2, 0x18, 0x80, 0x08, 0xe5, 0x4e, 0x45,
770x4f, 0x24, 0xff, 0x92, 0x18, 0xd2, 0xaf, 0x90, 0x04, 0x14, 0xe0, 0xa2, 0xe4, 0x92, 0x19, 0x74,
780x1e, 0xf0, 0xe5, 0x5f, 0x54, 0x0f, 0xf5, 0x2d, 0xe5, 0x25, 0x70, 0x13, 0x30, 0x18, 0x05, 0xe5,
790x5f, 0x20, 0xe5, 0x0b, 0x30, 0x19, 0x19, 0xe5, 0x5f, 0x54, 0x30, 0xff, 0xbf, 0x30, 0x11, 0xe5,
800x25, 0x70, 0x05, 0x75, 0x25, 0x0c, 0x80, 0x02, 0x15, 0x25, 0xd2, 0x6c, 0xd2, 0x6d, 0x80, 0x0f,
810xe5, 0x5f, 0x30, 0xe6, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x04, 0xd2, 0x6c, 0xc2, 0x6d, 0xe5,
820x47, 0x64, 0x03, 0x70, 0x21, 0x30, 0x4b, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x18, 0xe5, 0x25,
830x70, 0x03, 0x30, 0x4c, 0x11, 0xc2, 0x4c, 0xe5, 0x25, 0x70, 0x05, 0x75, 0x25, 0x07, 0x80, 0x02,
840x15, 0x25, 0xd2, 0x6c, 0xd2, 0x6d, 0xe5, 0x47, 0xb4, 0x09, 0x14, 0xe5, 0x44, 0x20, 0xe3, 0x0b,
850xe5, 0x3a, 0x64, 0x02, 0x60, 0x05, 0xe5, 0x3a, 0xb4, 0x03, 0x04, 0xc2, 0x6c, 0xd2, 0x6d, 0xe5,
860x47, 0xb4, 0x0a, 0x13, 0xe5, 0x3a, 0xb4, 0x01, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x08, 0xe5,
870x3a, 0x70, 0x04, 0xd2, 0x6c, 0xc2, 0x6d, 0x20, 0x69, 0x07, 0xe5, 0x5e, 0x20, 0xe0, 0x02, 0xb2,
880x68, 0x20, 0x6b, 0x07, 0xe5, 0x5e, 0x20, 0xe1, 0x02, 0xb2, 0x6a, 0x20, 0x6d, 0x07, 0xe5, 0x5e,
890x20, 0xe2, 0x02, 0xb2, 0x6c, 0x75, 0x2e, 0x40, 0x20, 0x69, 0x04, 0xa2, 0x68, 0x80, 0x26, 0x30,
900x68, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe2, 0x04, 0x7f, 0x01, 0x80,
910x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e,
920x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x73, 0x92, 0x72, 0x20, 0x6b, 0x04, 0xa2, 0x6a, 0x80, 0x26,
930x30, 0x6a, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe0, 0x04, 0x7f, 0x01,
940x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02,
950x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x75, 0x92, 0x74, 0x20, 0x6d, 0x04, 0xa2, 0x6c, 0x80,
960x26, 0xe5, 0x47, 0x64, 0x0a, 0x70, 0x22, 0x30, 0x6c, 0x06, 0xe5, 0x46, 0xa2, 0xe3, 0x80, 0x17,
970xe5, 0x3a, 0xb4, 0x01, 0x06, 0xe5, 0x46, 0xa2, 0xe3, 0x80, 0x34, 0xe5, 0x46, 0x20, 0xe4, 0x03,
980x30, 0xe5, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x80, 0x26, 0x30, 0x6c, 0x06, 0xe5, 0x46, 0xa2, 0xe2,
990x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe1, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54,
1000xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92,
1010x71, 0x92, 0x70, 0x90, 0x10, 0x00, 0xe0, 0x90, 0x10, 0x2c, 0xf0, 0x90, 0x10, 0x03, 0xe0, 0xc3,
1020x94, 0x30, 0x40, 0x14, 0xa2, 0x71, 0x92, 0x77, 0xa2, 0x70, 0x92, 0x76, 0xe5, 0x2e, 0x13, 0x13,
1030x54, 0x3f, 0xf5, 0x2e, 0xc2, 0x77, 0xd2, 0x76, 0x90, 0x10, 0x2f, 0xe5, 0x2e, 0xf0, 0xe5, 0x47,
1040x64, 0x06, 0x70, 0x39, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x43, 0xc4, 0x54, 0x0f,
1050x14, 0x60, 0x0c, 0x24, 0xfe, 0x60, 0x0c, 0x24, 0x03, 0x70, 0x13, 0xc2, 0x38, 0x80, 0x0f, 0xd2,
1060x38, 0x80, 0x0b, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x38, 0x30, 0x47,
1070x05, 0xaf, 0x27, 0x02, 0x17, 0x73, 0xe5, 0x27, 0xf4, 0xff, 0x02, 0x17, 0x73, 0xe5, 0x47, 0x64,
1080x07, 0x60, 0x0f, 0xe5, 0x47, 0x64, 0x08, 0x60, 0x09, 0xe5, 0x47, 0x64, 0x09, 0x60, 0x03, 0x02,
1090x16, 0xf2, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xfc, 0xf0, 0xe5, 0x3a, 0x14, 0x60, 0x22, 0x14, 0x60,
1100x25, 0x14, 0x60, 0x2d, 0x24, 0xfc, 0x60, 0x49, 0x24, 0xf9, 0x60, 0x14, 0x24, 0x0e, 0x70, 0x50,
1110xe5, 0x46, 0x13, 0x13, 0x54, 0x3f, 0x75, 0xf0, 0x03, 0x84, 0xe5, 0xf0, 0x24, 0xff, 0x80, 0x3a,
1120xd2, 0x39, 0xc2, 0x38, 0x80, 0x3e, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x1d, 0xc3, 0x80,
1130x1a, 0xe5, 0x46, 0x30, 0xe2, 0x0d, 0x54, 0x38, 0xc3, 0x94, 0x30, 0x50, 0x06, 0x7e, 0x00, 0x7f,
1140x01, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x00, 0xee, 0x4f, 0x24, 0xff, 0x92, 0x38, 0xc2, 0x39, 0x80,
1150x13, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x39, 0xc2, 0x38, 0x80, 0x04,
1160xc2, 0x38, 0xc2, 0x39, 0x30, 0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5, 0x27, 0xf4, 0xff, 0x02,
1170x17, 0x73, 0xe5, 0x47, 0x64, 0x0c, 0x60, 0x06, 0xe5, 0x47, 0x64, 0x0b, 0x70, 0x7a, 0x90, 0x02,
1180x29, 0xe0, 0x54, 0xfd, 0xf0, 0xe5, 0x3a, 0x14, 0x60, 0x20, 0x14, 0x60, 0x21, 0x14, 0x60, 0x2b,
1190x24, 0xfc, 0x60, 0x45, 0x24, 0xf9, 0x60, 0x12, 0x24, 0x0e, 0x70, 0x4a, 0xe5, 0x46, 0x13, 0x13,
1200x54, 0x3f, 0x75, 0xf0, 0x03, 0x84, 0xe5, 0xf0, 0x80, 0x29, 0xd2, 0x39, 0x80, 0x3a, 0xe5, 0x46,
1210x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x39, 0x80, 0x2d, 0xe5, 0x46, 0x30, 0xe2, 0x0d,
1220x54, 0x38, 0xc3, 0x94, 0x30, 0x50, 0x06, 0x7e, 0x00, 0x7f, 0x01, 0x80, 0x04, 0x7e, 0x00, 0x7f,
1230x00, 0xee, 0x4f, 0x24, 0xff, 0x92, 0x39, 0x80, 0x0f, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80,
1240x01, 0xc3, 0x92, 0x39, 0x80, 0x02, 0xc2, 0x39, 0x30, 0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5,
1250x27, 0xf4, 0xff, 0x90, 0x02, 0x28, 0xef, 0xf0, 0x22, 0xe5, 0x47, 0xb4, 0x0b, 0x10, 0x90, 0x02,
1260x29, 0xe0, 0x54, 0xeb, 0xf0, 0xe5, 0x27, 0x54, 0xeb, 0x45, 0x45, 0xf5, 0x27, 0x22, 0xe4, 0x90,
1270x02, 0x29, 0xf0, 0x30, 0x47, 0x04, 0xaf, 0x45, 0x80, 0x04, 0xe5, 0x45, 0xf4, 0xff, 0x90, 0x02,
1280x28, 0xef, 0xf0, 0x22, 0x8f, 0x50, 0xd2, 0x59, 0x22, 0x8f, 0x54, 0xd2, 0x58, 0x22, 0xe4, 0xf5,
1290x62, 0xc2, 0xaf, 0xe5, 0x51, 0x14, 0x60, 0x48, 0x14, 0x60, 0x66, 0x24, 0x02, 0x60, 0x03, 0x02,
1300x18, 0xb6, 0xd2, 0x59, 0x75, 0x55, 0x01, 0x90, 0x02, 0xa2, 0xe0, 0x54, 0x7f, 0xf0, 0xa3, 0xe0,
1310x20, 0xe7, 0x23, 0x90, 0x04, 0x34, 0xe0, 0xb4, 0x02, 0x1c, 0xa3, 0xe0, 0xb4, 0x02, 0x17, 0xa3,
1320xe0, 0xb4, 0x02, 0x12, 0x7f, 0x20, 0x12, 0x17, 0xa4, 0x90, 0x10, 0x04, 0xe0, 0x54, 0xf3, 0xf0,
1330x75, 0x51, 0x01, 0x02, 0x18, 0xb6, 0xe5, 0x50, 0x70, 0x06, 0x75, 0x62, 0x03, 0x02, 0x18, 0xb6,
1340x90, 0x12, 0x00, 0xe0, 0x54, 0x03, 0x70, 0x12, 0x7f, 0x20, 0x12, 0x17, 0xa4, 0x90, 0x02, 0xa2,
1350xe0, 0x54, 0xbf, 0xf0, 0x75, 0x51, 0x02, 0x02, 0x18, 0xb6, 0xe5, 0x50, 0x70, 0x03, 0x02, 0x18,
1360xb1, 0x90, 0x02, 0xa3, 0xe0, 0x30, 0xe6, 0x03, 0x02, 0x18, 0xad, 0x90, 0x04, 0x37, 0xe0, 0x64,
1370x22, 0x70, 0x7a, 0x90, 0x01, 0x8a, 0x74, 0x7e, 0xf0, 0x90, 0x01, 0x96, 0xf0, 0x90, 0x12, 0x04,
1380x74, 0x0a, 0xf0, 0xe5, 0x58, 0xb4, 0x72, 0x15, 0xe5, 0x59, 0xb4, 0x35, 0x10, 0xe4, 0x90, 0x05,
1390x00, 0xf0, 0xa3, 0x74, 0x08, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0x74, 0x03, 0xf0, 0x7f, 0x01, 0x12,
1400x0d, 0x2a, 0x90, 0x13, 0x28, 0xe0, 0x54, 0xf0, 0xf0, 0xa3, 0xe0, 0x54, 0xf0, 0xf0, 0xe5, 0x59,
1410xb4, 0x35, 0x14, 0xe5, 0x3c, 0xf4, 0x60, 0x06, 0xa3, 0xe0, 0x54, 0xf3, 0x80, 0x14, 0x90, 0x13,
1420x2a, 0xe0, 0x54, 0xfb, 0xf0, 0x80, 0x14, 0xe5, 0x3c, 0xf4, 0x90, 0x13, 0x2a, 0x60, 0x08, 0xe0,
1430x54, 0xf2, 0x45, 0x3c, 0xf0, 0x80, 0x04, 0xe0, 0x54, 0xfa, 0xf0, 0x90, 0x04, 0x01, 0xe0, 0x54,
1440xfd, 0xf0, 0x75, 0x62, 0x01, 0x75, 0x55, 0x02, 0xe4, 0xf5, 0x51, 0x80, 0x09, 0xe5, 0x50, 0x70,
1450x05, 0x75, 0x62, 0x03, 0xf5, 0x51, 0xe5, 0x62, 0x60, 0x15, 0xc2, 0x01, 0xe4, 0xf5, 0x51, 0xc2,
1460x59, 0xad, 0x62, 0xaf, 0x40, 0x12, 0x19, 0x61, 0xe5, 0x62, 0xb4, 0x03, 0x02, 0xd2, 0x03, 0xd2,
1470xaf, 0x22, 0xc2, 0xaf, 0x30, 0x01, 0x12, 0xe4, 0x90, 0x01, 0x96, 0xf0, 0xf5, 0x51, 0xc2, 0x59,
1480xc2, 0x01, 0x7d, 0x02, 0xaf, 0x40, 0x12, 0x19, 0x61, 0xe5, 0x52, 0x14, 0x60, 0x09, 0x04, 0x70,
1490x6d, 0x75, 0x52, 0x01, 0x75, 0x55, 0x03, 0x90, 0x04, 0x01, 0xe0, 0x44, 0x0e, 0xf0, 0x90, 0x13,
1500x28, 0xe0, 0x44, 0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x05, 0xf0, 0x90,
1510x12, 0x04, 0x74, 0x03, 0xf0, 0xe5, 0x58, 0xb4, 0x72, 0x16, 0xe5, 0x59, 0xb4, 0x35, 0x11, 0x90,
1520x05, 0x00, 0x74, 0xe2, 0xf0, 0xa3, 0x74, 0x08, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0x74, 0x03, 0xf0,
1530x7f, 0x01, 0x12, 0x0d, 0x2a, 0x90, 0x02, 0xa2, 0xe0, 0x44, 0xc0, 0xf0, 0x90, 0x10, 0x04, 0xe0,
1540x44, 0x0c, 0xf0, 0xe4, 0xf5, 0x52, 0xf5, 0x55, 0x30, 0x02, 0x09, 0xc2, 0x02, 0x7d, 0x01, 0xaf,
1550x41, 0x12, 0x19, 0x61, 0x30, 0x03, 0x02, 0xc2, 0x03, 0xe4, 0x90, 0x01, 0x96, 0xf0, 0xd2, 0xaf,
1560x22, 0xef, 0xf4, 0x60, 0x2d, 0xe4, 0xfe, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5,
1570x83, 0xe0, 0xb4, 0xff, 0x19, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xef,
1580xf0, 0x74, 0x1c, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xed, 0xf0, 0x22, 0x0e, 0xbe,
1590x04, 0xd5, 0x22, 0x22, 0x22, 0x90, 0x70, 0x2a, 0xe0, 0x30, 0xe1, 0x4d, 0xc2, 0xaf, 0x90, 0x70,
1600x28, 0xe0, 0x90, 0x10, 0x1c, 0xf0, 0x90, 0x70, 0x29, 0xe0, 0x90, 0x10, 0x1d, 0xf0, 0x90, 0x70,
1610x2a, 0xe0, 0x90, 0x10, 0x1e, 0xf0, 0x90, 0x10, 0x1c, 0xe0, 0xf5, 0x62, 0x90, 0x10, 0x1e, 0xe0,
1620x20, 0xe1, 0xf3, 0x90, 0x10, 0x1c, 0xe0, 0x90, 0x70, 0x28, 0xf0, 0x90, 0x10, 0x1d, 0xe0, 0x90,
1630x70, 0x29, 0xf0, 0x90, 0x10, 0x1e, 0xe0, 0x90, 0x70, 0x2a, 0xf0, 0x30, 0x4a, 0x07, 0x90, 0x70,
1640x24, 0xe0, 0x44, 0x01, 0xf0, 0xc2, 0x05, 0xd2, 0xaf, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00,
1650x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1660x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1670x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1680x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1690x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1700x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1710x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1720x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1730x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1740x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1750x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1760x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1770x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1780x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1790x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1800x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1810x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1820x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1830x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1840x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1850x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1860x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1870x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1880x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1890x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1900x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1910x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1920x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1930x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1940x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1950x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1960x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1970x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1980x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1990x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2000x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2010x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2020x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2030x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2040x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2050x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2060x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2070x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2080x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2090x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2100x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2110x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2120x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2130x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2140x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2150x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2160x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2170x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2180x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2190x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2200x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2210x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2220x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2230x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2240x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2250x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2260x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2270x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2280x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2290x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2300x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2310x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2320x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2330x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2340x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2350x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2360x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2370x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2380x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2390x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2400x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2410x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2420x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2430x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2440x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2450x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2460x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2470x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2480x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2490x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2500x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2510x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2520x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2530x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2540x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2550x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2560x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2570x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2580x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2590x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2600x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2610x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x7b, 0xc4,
2620xff, 0xff, 0xff, 0x02, 0x10, 0x28, 0x02, 0x10, 0x32, 0x02, 0x10, 0x78, 0x02, 0x13, 0x1f, 0x02,
2630x13, 0x20, 0x02, 0x13, 0x3f, 0x02, 0x13, 0x44, 0x12, 0x13, 0x40, 0x22, 0x02, 0x17, 0xae, 0x02,
2640x18, 0xd2, 0x02, 0x14, 0x3d, 0x02, 0x13, 0x78, 0x30, 0x05, 0x06, 0x20, 0x0d, 0x03, 0x12, 0x19,
2650x95, 0x22, 0x90, 0x01, 0x8c, 0xe0, 0x30, 0xe3, 0x1b, 0xe5, 0x4c, 0x30, 0xe0, 0x04, 0x7f, 0x40,
2660x80, 0x02, 0x7f, 0x00, 0x90, 0x10, 0x2f, 0xef, 0xf0, 0x90, 0x01, 0x8c, 0x74, 0x08, 0xf0, 0xe4,
2670x90, 0x01, 0xa7, 0xf0, 0x90, 0x01, 0x8c, 0xe0, 0x30, 0xe0, 0x1c, 0x90, 0x01, 0x80, 0xe0, 0xb4,
2680x02, 0x15, 0xa3, 0xe0, 0xb4, 0x01, 0x10, 0x90, 0x01, 0x84, 0xe0, 0xb4, 0x81, 0x09, 0x90, 0x01,
2690x8c, 0x74, 0x01, 0xf0, 0x12, 0x0d, 0xdd, 0x22, 0x90, 0x04, 0x14, 0xe0, 0x20, 0xe7, 0x03, 0x02,
2700x13, 0x1e, 0x90, 0x70, 0x12, 0xe0, 0xf5, 0x56, 0x90, 0x04, 0x04, 0xe0, 0x12, 0x0a, 0xb6, 0x10,
2710xd9, 0x31, 0x10, 0xbd, 0x36, 0x11, 0x02, 0x50, 0x11, 0x39, 0x51, 0x11, 0x42, 0x52, 0x11, 0x42,
2720x53, 0x11, 0x42, 0x54, 0x11, 0x83, 0x55, 0x11, 0xd2, 0x56, 0x12, 0x25, 0x70, 0x12, 0x50, 0x71,
2730x12, 0x7e, 0x72, 0x12, 0xd5, 0x73, 0x12, 0xf6, 0x80, 0x00, 0x00, 0x13, 0x1e, 0x90, 0x70, 0x11,
2740xe0, 0xf5, 0x3c, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe5, 0x56,
2750xf4, 0x70, 0x03, 0x02, 0x13, 0x1e, 0x02, 0x13, 0x17, 0x20, 0x02, 0x03, 0x30, 0x03, 0x1d, 0x7d,
2760x02, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13,
2770xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0x1e, 0x02, 0x13, 0x17, 0x85, 0x56, 0x41, 0xd2,
2780x02, 0x22, 0x90, 0x70, 0x10, 0xe0, 0x54, 0x7f, 0xff, 0xbf, 0x0a, 0x0d, 0x90, 0x70, 0x11, 0xe0,
2790xb4, 0x08, 0x06, 0x75, 0x4e, 0x01, 0x75, 0x4f, 0x84, 0x90, 0x70, 0x10, 0xe0, 0x54, 0x7f, 0xff,
2800xbf, 0x02, 0x12, 0x90, 0x70, 0x11, 0xe0, 0x64, 0x08, 0x60, 0x04, 0xe0, 0xb4, 0x20, 0x06, 0x75,
2810x4e, 0x03, 0x75, 0x4f, 0x20, 0xe4, 0xf5, 0x27, 0x22, 0x90, 0x70, 0x11, 0xe0, 0x24, 0xff, 0x92,
2820x47, 0x22, 0x90, 0x04, 0x04, 0xe0, 0x25, 0xe0, 0x24, 0x5d, 0xf5, 0x57, 0x90, 0x70, 0x10, 0xe0,
2830xff, 0x74, 0x47, 0x25, 0x57, 0xf8, 0xc6, 0xef, 0xc6, 0x90, 0x70, 0x11, 0xe0, 0xff, 0x74, 0x48,
2840x25, 0x57, 0xf8, 0xc6, 0xef, 0xc6, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14,
2850x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0x1e,
2860x02, 0x13, 0x17, 0xe5, 0x47, 0x64, 0x07, 0x60, 0x1d, 0xe5, 0x47, 0x64, 0x08, 0x60, 0x17, 0xe5,
2870x47, 0x64, 0x09, 0x60, 0x11, 0xe5, 0x47, 0x64, 0x0a, 0x60, 0x0b, 0xe5, 0x47, 0x64, 0x0b, 0x60,
2880x05, 0xe5, 0x47, 0xb4, 0x0c, 0x08, 0x90, 0x70, 0x11, 0xe0, 0x54, 0x0f, 0xf5, 0x3a, 0xe5, 0x47,
2890xb4, 0x09, 0x08, 0xe5, 0x3a, 0xb4, 0x03, 0x03, 0xe4, 0xf5, 0x46, 0xe5, 0x47, 0xb4, 0x0a, 0x08,
2900xe5, 0x3a, 0xb4, 0x01, 0x03, 0xe4, 0xf5, 0x46, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0xd2,
2910x04, 0x22, 0x90, 0x70, 0x11, 0xe0, 0xf4, 0xff, 0x90, 0x70, 0x10, 0xe0, 0x5f, 0xff, 0x90, 0x70,
2920x11, 0xe0, 0x55, 0x27, 0x4f, 0x90, 0x70, 0x18, 0xf0, 0x90, 0x70, 0x11, 0xe0, 0x90, 0x70, 0x19,
2930xf0, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x30, 0x15, 0x03, 0xd2, 0x14, 0x22, 0x90, 0x70,
2940x18, 0xe0, 0xf5, 0x27, 0x90, 0x02, 0x29, 0xe0, 0xff, 0x90, 0x70, 0x19, 0xe0, 0xfe, 0xef, 0x5e,
2950x90, 0x02, 0x29, 0xf0, 0x30, 0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5, 0x27, 0xf4, 0xff, 0x90,
2960x02, 0x28, 0xef, 0xf0, 0x22, 0x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0, 0xfd, 0xed,
2970xf8, 0xe6, 0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0,
2980xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0x1e, 0x02, 0x13, 0x17,
2990x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0, 0xfd, 0xed, 0xf5, 0x82, 0x8e, 0x83, 0xe0,
3000xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90,
3010x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0x1e, 0x02, 0x13, 0x17, 0x90, 0x10,
3020x00, 0xe0, 0xf5, 0x57, 0x90, 0x10, 0x02, 0xe0, 0xf5, 0x58, 0xa3, 0xe0, 0xf5, 0x59, 0xe5, 0x58,
3030xb4, 0x70, 0x1e, 0xe5, 0x59, 0xb4, 0x30, 0x19, 0x90, 0x05, 0x08, 0xe0, 0x44, 0x01, 0xf0, 0xfd,
3040x90, 0x05, 0x05, 0xe0, 0x54, 0xfb, 0xf0, 0x44, 0x04, 0xf0, 0xed, 0x54, 0xfe, 0x90, 0x05, 0x08,
3050xf0, 0xe4, 0xf5, 0x4e, 0xf5, 0x4f, 0x75, 0x3a, 0xff, 0x75, 0x3c, 0xff, 0xad, 0x57, 0xaf, 0x56,
3060x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56,
3070xf4, 0x60, 0x4b, 0x80, 0x42, 0x90, 0x70, 0x10, 0xe0, 0x24, 0xff, 0x92, 0x93, 0xe4, 0xfd, 0xaf,
3080x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5,
3090x56, 0xf4, 0x60, 0x2a, 0x80, 0x21, 0x90, 0x70, 0x10, 0xe0, 0x24, 0xff, 0x92, 0x4a, 0xd2, 0x05,
3100xad, 0x57, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70,
3110x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x07, 0x90, 0x70, 0x25, 0xe0, 0x44, 0x01, 0xf0, 0x22, 0x22,
3120xe5, 0x53, 0x70, 0x1a, 0x30, 0x60, 0x09, 0xb2, 0x4d, 0x30, 0x4d, 0x04, 0x05, 0x46, 0xc2, 0x04,
3130xe5, 0x4f, 0x45, 0x4e, 0x60, 0x08, 0xe5, 0x4f, 0x15, 0x4f, 0x70, 0x02, 0x15, 0x4e, 0x22, 0x22,
3140xc2, 0x42, 0xd3, 0x22, 0x30, 0x14, 0x30, 0x90, 0x70, 0x19, 0xe0, 0x55, 0x27, 0xff, 0x90, 0x70,
3150x18, 0xe0, 0x4f, 0xf5, 0x27, 0x90, 0x02, 0x29, 0xe0, 0xff, 0x90, 0x70, 0x19, 0xe0, 0xfe, 0xef,
3160x5e, 0x90, 0x02, 0x29, 0xf0, 0x30, 0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5, 0x27, 0xf4, 0xff,
3170x90, 0x02, 0x28, 0xef, 0xf0, 0xc2, 0x14, 0x22, 0xc2, 0x4b, 0xc2, 0x4c, 0xe5, 0x44, 0x12, 0x0a,
3180xb6, 0x13, 0x9a, 0x00, 0x14, 0x28, 0x04, 0x14, 0x24, 0x08, 0x14, 0x04, 0x10, 0x13, 0xae, 0x20,
3190x13, 0xce, 0x60, 0x13, 0xdf, 0xa0, 0x00, 0x00, 0x14, 0x2a, 0x85, 0x48, 0x43, 0x85, 0x4a, 0x42,
3200x85, 0x4c, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x60, 0x03, 0x02, 0x14, 0x2a, 0x80, 0x1b, 0xe5, 0x48,
3210xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4a, 0xc4, 0x54, 0x0f, 0xf5, 0x42, 0xe5, 0x4c, 0xc4, 0x54,
3220x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x61, 0x53, 0x43, 0x0f, 0x80, 0x5c, 0x85, 0x49,
3230x43, 0x85, 0x4b, 0x42, 0x85, 0x4d, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x4d, 0x80, 0x1b, 0xe5,
3240x49, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4b, 0xc4, 0x54, 0x0f, 0xf5, 0x42, 0xe5, 0x4d, 0xc4,
3250x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x30, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x10,
3260xf5, 0x43, 0x80, 0x26, 0xe5, 0x47, 0x64, 0x04, 0x60, 0x05, 0xe5, 0x47, 0xb4, 0x05, 0x06, 0x43,
3270x5e, 0x04, 0x75, 0x42, 0x09, 0xe5, 0x47, 0xb4, 0x06, 0x10, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x30,
3280xf5, 0x43, 0x80, 0x06, 0xd2, 0x4b, 0x80, 0x02, 0xd2, 0x4c, 0xe4, 0xf5, 0x25, 0xe5, 0x42, 0xc4,
3290x54, 0xf0, 0xff, 0xe5, 0x43, 0x54, 0x0f, 0x4f, 0xf5, 0x5f, 0xd2, 0x60, 0x22, 0xd2, 0x15, 0xe5,
3300x47, 0x24, 0xf5, 0x60, 0x0b, 0x24, 0xcb, 0x60, 0x07, 0x24, 0x40, 0x70, 0x06, 0xc2, 0x15, 0x22,
3310x12, 0x17, 0x79, 0x12, 0x14, 0x5f, 0xc2, 0x15, 0xc2, 0xaf, 0xc2, 0x04, 0xd2, 0xaf, 0x22, 0xc2,
3320xaf, 0x90, 0x04, 0x14, 0xe0, 0x54, 0x0e, 0x60, 0x04, 0xd2, 0x18, 0x80, 0x08, 0xe5, 0x4e, 0x45,
3330x4f, 0x24, 0xff, 0x92, 0x18, 0xd2, 0xaf, 0x90, 0x04, 0x14, 0xe0, 0xa2, 0xe4, 0x92, 0x19, 0x74,
3340x1e, 0xf0, 0xe5, 0x5f, 0x54, 0x0f, 0xf5, 0x2d, 0xe5, 0x25, 0x70, 0x13, 0x30, 0x18, 0x05, 0xe5,
3350x5f, 0x20, 0xe5, 0x0b, 0x30, 0x19, 0x19, 0xe5, 0x5f, 0x54, 0x30, 0xff, 0xbf, 0x30, 0x11, 0xe5,
3360x25, 0x70, 0x05, 0x75, 0x25, 0x0c, 0x80, 0x02, 0x15, 0x25, 0xd2, 0x6c, 0xd2, 0x6d, 0x80, 0x0f,
3370xe5, 0x5f, 0x30, 0xe6, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x04, 0xd2, 0x6c, 0xc2, 0x6d, 0xe5,
3380x47, 0x64, 0x03, 0x70, 0x21, 0x30, 0x4b, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x18, 0xe5, 0x25,
3390x70, 0x03, 0x30, 0x4c, 0x11, 0xc2, 0x4c, 0xe5, 0x25, 0x70, 0x05, 0x75, 0x25, 0x07, 0x80, 0x02,
3400x15, 0x25, 0xd2, 0x6c, 0xd2, 0x6d, 0xe5, 0x47, 0xb4, 0x09, 0x14, 0xe5, 0x44, 0x20, 0xe3, 0x0b,
3410xe5, 0x3a, 0x64, 0x02, 0x60, 0x05, 0xe5, 0x3a, 0xb4, 0x03, 0x04, 0xc2, 0x6c, 0xd2, 0x6d, 0xe5,
3420x47, 0xb4, 0x0a, 0x13, 0xe5, 0x3a, 0xb4, 0x01, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x08, 0xe5,
3430x3a, 0x70, 0x04, 0xd2, 0x6c, 0xc2, 0x6d, 0x20, 0x69, 0x07, 0xe5, 0x5e, 0x20, 0xe0, 0x02, 0xb2,
3440x68, 0x20, 0x6b, 0x07, 0xe5, 0x5e, 0x20, 0xe1, 0x02, 0xb2, 0x6a, 0x20, 0x6d, 0x07, 0xe5, 0x5e,
3450x20, 0xe2, 0x02, 0xb2, 0x6c, 0x75, 0x2e, 0x40, 0x20, 0x69, 0x04, 0xa2, 0x68, 0x80, 0x26, 0x30,
3460x68, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe2, 0x04, 0x7f, 0x01, 0x80,
3470x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e,
3480x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x73, 0x92, 0x72, 0x20, 0x6b, 0x04, 0xa2, 0x6a, 0x80, 0x26,
3490x30, 0x6a, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe0, 0x04, 0x7f, 0x01,
3500x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02,
3510x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x75, 0x92, 0x74, 0x20, 0x6d, 0x04, 0xa2, 0x6c, 0x80,
3520x26, 0xe5, 0x47, 0x64, 0x0a, 0x70, 0x22, 0x30, 0x6c, 0x06, 0xe5, 0x46, 0xa2, 0xe3, 0x80, 0x17,
3530xe5, 0x3a, 0xb4, 0x01, 0x06, 0xe5, 0x46, 0xa2, 0xe3, 0x80, 0x34, 0xe5, 0x46, 0x20, 0xe4, 0x03,
3540x30, 0xe5, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x80, 0x26, 0x30, 0x6c, 0x06, 0xe5, 0x46, 0xa2, 0xe2,
3550x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe1, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54,
3560xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92,
3570x71, 0x92, 0x70, 0x90, 0x10, 0x00, 0xe0, 0x90, 0x10, 0x2c, 0xf0, 0x90, 0x10, 0x03, 0xe0, 0xc3,
3580x94, 0x30, 0x40, 0x14, 0xa2, 0x71, 0x92, 0x77, 0xa2, 0x70, 0x92, 0x76, 0xe5, 0x2e, 0x13, 0x13,
3590x54, 0x3f, 0xf5, 0x2e, 0xc2, 0x77, 0xd2, 0x76, 0x90, 0x10, 0x2f, 0xe5, 0x2e, 0xf0, 0xe5, 0x47,
3600x64, 0x06, 0x70, 0x39, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x43, 0xc4, 0x54, 0x0f,
3610x14, 0x60, 0x0c, 0x24, 0xfe, 0x60, 0x0c, 0x24, 0x03, 0x70, 0x13, 0xc2, 0x38, 0x80, 0x0f, 0xd2,
3620x38, 0x80, 0x0b, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x38, 0x30, 0x47,
3630x05, 0xaf, 0x27, 0x02, 0x17, 0x73, 0xe5, 0x27, 0xf4, 0xff, 0x02, 0x17, 0x73, 0xe5, 0x47, 0x64,
3640x07, 0x60, 0x0f, 0xe5, 0x47, 0x64, 0x08, 0x60, 0x09, 0xe5, 0x47, 0x64, 0x09, 0x60, 0x03, 0x02,
3650x16, 0xf2, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xfc, 0xf0, 0xe5, 0x3a, 0x14, 0x60, 0x22, 0x14, 0x60,
3660x25, 0x14, 0x60, 0x2d, 0x24, 0xfc, 0x60, 0x49, 0x24, 0xf9, 0x60, 0x14, 0x24, 0x0e, 0x70, 0x50,
3670xe5, 0x46, 0x13, 0x13, 0x54, 0x3f, 0x75, 0xf0, 0x03, 0x84, 0xe5, 0xf0, 0x24, 0xff, 0x80, 0x3a,
3680xd2, 0x39, 0xc2, 0x38, 0x80, 0x3e, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x1d, 0xc3, 0x80,
3690x1a, 0xe5, 0x46, 0x30, 0xe2, 0x0d, 0x54, 0x38, 0xc3, 0x94, 0x30, 0x50, 0x06, 0x7e, 0x00, 0x7f,
3700x01, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x00, 0xee, 0x4f, 0x24, 0xff, 0x92, 0x38, 0xc2, 0x39, 0x80,
3710x13, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x39, 0xc2, 0x38, 0x80, 0x04,
3720xc2, 0x38, 0xc2, 0x39, 0x30, 0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5, 0x27, 0xf4, 0xff, 0x02,
3730x17, 0x73, 0xe5, 0x47, 0x64, 0x0c, 0x60, 0x06, 0xe5, 0x47, 0x64, 0x0b, 0x70, 0x7a, 0x90, 0x02,
3740x29, 0xe0, 0x54, 0xfd, 0xf0, 0xe5, 0x3a, 0x14, 0x60, 0x20, 0x14, 0x60, 0x21, 0x14, 0x60, 0x2b,
3750x24, 0xfc, 0x60, 0x45, 0x24, 0xf9, 0x60, 0x12, 0x24, 0x0e, 0x70, 0x4a, 0xe5, 0x46, 0x13, 0x13,
3760x54, 0x3f, 0x75, 0xf0, 0x03, 0x84, 0xe5, 0xf0, 0x80, 0x29, 0xd2, 0x39, 0x80, 0x3a, 0xe5, 0x46,
3770x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x39, 0x80, 0x2d, 0xe5, 0x46, 0x30, 0xe2, 0x0d,
3780x54, 0x38, 0xc3, 0x94, 0x30, 0x50, 0x06, 0x7e, 0x00, 0x7f, 0x01, 0x80, 0x04, 0x7e, 0x00, 0x7f,
3790x00, 0xee, 0x4f, 0x24, 0xff, 0x92, 0x39, 0x80, 0x0f, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80,
3800x01, 0xc3, 0x92, 0x39, 0x80, 0x02, 0xc2, 0x39, 0x30, 0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5,
3810x27, 0xf4, 0xff, 0x90, 0x02, 0x28, 0xef, 0xf0, 0x22, 0xe5, 0x47, 0xb4, 0x0b, 0x10, 0x90, 0x02,
3820x29, 0xe0, 0x54, 0xeb, 0xf0, 0xe5, 0x27, 0x54, 0xeb, 0x45, 0x45, 0xf5, 0x27, 0x22, 0xe4, 0x90,
3830x02, 0x29, 0xf0, 0x30, 0x47, 0x04, 0xaf, 0x45, 0x80, 0x04, 0xe5, 0x45, 0xf4, 0xff, 0x90, 0x02,
3840x28, 0xef, 0xf0, 0x22, 0x8f, 0x50, 0xd2, 0x59, 0x22, 0x8f, 0x54, 0xd2, 0x58, 0x22, 0xe4, 0xf5,
3850x62, 0xc2, 0xaf, 0xe5, 0x51, 0x14, 0x60, 0x48, 0x14, 0x60, 0x66, 0x24, 0x02, 0x60, 0x03, 0x02,
3860x18, 0xb6, 0xd2, 0x59, 0x75, 0x55, 0x01, 0x90, 0x02, 0xa2, 0xe0, 0x54, 0x7f, 0xf0, 0xa3, 0xe0,
3870x20, 0xe7, 0x23, 0x90, 0x04, 0x34, 0xe0, 0xb4, 0x02, 0x1c, 0xa3, 0xe0, 0xb4, 0x02, 0x17, 0xa3,
3880xe0, 0xb4, 0x02, 0x12, 0x7f, 0x20, 0x12, 0x17, 0xa4, 0x90, 0x10, 0x04, 0xe0, 0x54, 0xf3, 0xf0,
3890x75, 0x51, 0x01, 0x02, 0x18, 0xb6, 0xe5, 0x50, 0x70, 0x06, 0x75, 0x62, 0x03, 0x02, 0x18, 0xb6,
3900x90, 0x12, 0x00, 0xe0, 0x54, 0x03, 0x70, 0x12, 0x7f, 0x20, 0x12, 0x17, 0xa4, 0x90, 0x02, 0xa2,
3910xe0, 0x54, 0xbf, 0xf0, 0x75, 0x51, 0x02, 0x02, 0x18, 0xb6, 0xe5, 0x50, 0x70, 0x03, 0x02, 0x18,
3920xb1, 0x90, 0x02, 0xa3, 0xe0, 0x30, 0xe6, 0x03, 0x02, 0x18, 0xad, 0x90, 0x04, 0x37, 0xe0, 0x64,
3930x22, 0x70, 0x7a, 0x90, 0x01, 0x8a, 0x74, 0x7e, 0xf0, 0x90, 0x01, 0x96, 0xf0, 0x90, 0x12, 0x04,
3940x74, 0x0a, 0xf0, 0xe5, 0x58, 0xb4, 0x72, 0x15, 0xe5, 0x59, 0xb4, 0x35, 0x10, 0xe4, 0x90, 0x05,
3950x00, 0xf0, 0xa3, 0x74, 0x08, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0x74, 0x03, 0xf0, 0x7f, 0x01, 0x12,
3960x0d, 0x48, 0x90, 0x13, 0x28, 0xe0, 0x54, 0xf0, 0xf0, 0xa3, 0xe0, 0x54, 0xf0, 0xf0, 0xe5, 0x59,
3970xb4, 0x35, 0x14, 0xe5, 0x3c, 0xf4, 0x60, 0x06, 0xa3, 0xe0, 0x54, 0xf3, 0x80, 0x14, 0x90, 0x13,
3980x2a, 0xe0, 0x54, 0xfb, 0xf0, 0x80, 0x14, 0xe5, 0x3c, 0xf4, 0x90, 0x13, 0x2a, 0x60, 0x08, 0xe0,
3990x54, 0xf2, 0x45, 0x3c, 0xf0, 0x80, 0x04, 0xe0, 0x54, 0xfa, 0xf0, 0x90, 0x04, 0x01, 0xe0, 0x54,
4000xfd, 0xf0, 0x75, 0x62, 0x01, 0x75, 0x55, 0x02, 0xe4, 0xf5, 0x51, 0x80, 0x09, 0xe5, 0x50, 0x70,
4010x05, 0x75, 0x62, 0x03, 0xf5, 0x51, 0xe5, 0x62, 0x60, 0x15, 0xc2, 0x01, 0xe4, 0xf5, 0x51, 0xc2,
4020x59, 0xad, 0x62, 0xaf, 0x40, 0x12, 0x19, 0x61, 0xe5, 0x62, 0xb4, 0x03, 0x02, 0xd2, 0x03, 0xd2,
4030xaf, 0x22, 0xc2, 0xaf, 0x30, 0x01, 0x12, 0xe4, 0x90, 0x01, 0x96, 0xf0, 0xf5, 0x51, 0xc2, 0x59,
4040xc2, 0x01, 0x7d, 0x02, 0xaf, 0x40, 0x12, 0x19, 0x61, 0xe5, 0x52, 0x14, 0x60, 0x09, 0x04, 0x70,
4050x6d, 0x75, 0x52, 0x01, 0x75, 0x55, 0x03, 0x90, 0x04, 0x01, 0xe0, 0x44, 0x0e, 0xf0, 0x90, 0x13,
4060x28, 0xe0, 0x44, 0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x05, 0xf0, 0x90,
4070x12, 0x04, 0x74, 0x03, 0xf0, 0xe5, 0x58, 0xb4, 0x72, 0x16, 0xe5, 0x59, 0xb4, 0x35, 0x11, 0x90,
4080x05, 0x00, 0x74, 0xe2, 0xf0, 0xa3, 0x74, 0x08, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0x74, 0x03, 0xf0,
4090x7f, 0x01, 0x12, 0x0d, 0x48, 0x90, 0x02, 0xa2, 0xe0, 0x44, 0xc0, 0xf0, 0x90, 0x10, 0x04, 0xe0,
4100x44, 0x0c, 0xf0, 0xe4, 0xf5, 0x52, 0xf5, 0x55, 0x30, 0x02, 0x09, 0xc2, 0x02, 0x7d, 0x01, 0xaf,
4110x41, 0x12, 0x19, 0x61, 0x30, 0x03, 0x02, 0xc2, 0x03, 0xe4, 0x90, 0x01, 0x96, 0xf0, 0xd2, 0xaf,
4120x22, 0xef, 0xf4, 0x60, 0x2d, 0xe4, 0xfe, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5,
4130x83, 0xe0, 0xb4, 0xff, 0x19, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xef,
4140xf0, 0x74, 0x1c, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xed, 0xf0, 0x22, 0x0e, 0xbe,
4150x04, 0xd5, 0x22, 0x22, 0x22, 0x90, 0x70, 0x2a, 0xe0, 0x30, 0xe1, 0x4d, 0xc2, 0xaf, 0x90, 0x70,
4160x28, 0xe0, 0x90, 0x10, 0x1c, 0xf0, 0x90, 0x70, 0x29, 0xe0, 0x90, 0x10, 0x1d, 0xf0, 0x90, 0x70,
4170x2a, 0xe0, 0x90, 0x10, 0x1e, 0xf0, 0x90, 0x10, 0x1c, 0xe0, 0xf5, 0x62, 0x90, 0x10, 0x1e, 0xe0,
4180x20, 0xe1, 0xf3, 0x90, 0x10, 0x1c, 0xe0, 0x90, 0x70, 0x28, 0xf0, 0x90, 0x10, 0x1d, 0xe0, 0x90,
4190x70, 0x29, 0xf0, 0x90, 0x10, 0x1e, 0xe0, 0x90, 0x70, 0x2a, 0xf0, 0x30, 0x4a, 0x07, 0x90, 0x70,
4200x24, 0xe0, 0x44, 0x01, 0xf0, 0xc2, 0x05, 0xd2, 0xaf, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00,
4210x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4220x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4230x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4240x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4250x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4260x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4270x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4280x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4290x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4300x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4310x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4320x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4330x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4340x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4350x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4360x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4370x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4380x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4390x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4400x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4410x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4420x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4430x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4440x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4450x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4460x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4470x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4480x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4490x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4500x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4510x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4520x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4530x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4540x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4550x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4560x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4570x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4580x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4590x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4600x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4610x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4620x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4630x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4640x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4650x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4660x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4670x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4680x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4690x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4700x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4710x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4720x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4730x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4740x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4750x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4760x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4770x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4780x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4790x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4800x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4810x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4820x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4830x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4840x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4850x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4860x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4870x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4880x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4890x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4900x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4910x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4920x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4930x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4940x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4950x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4960x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4970x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4980x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4990x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5000x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5010x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5020x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5030x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5040x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5050x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5060x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5070x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5080x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5090x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5100x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5110x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5120x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5130x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5140x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5150x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5160x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5170x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x65, 0xd3, } ;
diff --git a/drivers/staging/rt2860/common/mlme.c b/drivers/staging/rt2860/common/mlme.c
index 61a2a4eb714..02627c70b2d 100644
--- a/drivers/staging/rt2860/common/mlme.c
+++ b/drivers/staging/rt2860/common/mlme.c
@@ -127,46 +127,54 @@ UCHAR RateSwitchTable11G[] = {
127 127
128UCHAR RateSwitchTable11N1S[] = { 128UCHAR RateSwitchTable11N1S[] = {
129// 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) 129// 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)
130 0x09, 0x00, 0, 0, 0, // Initial used item after association 130 0x0c, 0x0a, 0, 0, 0, // Initial used item after association
131 0x00, 0x21, 0, 30, 101, 131 0x00, 0x00, 0, 40, 101,
132 0x01, 0x21, 1, 20, 50, 132 0x01, 0x00, 1, 40, 50,
133 0x02, 0x21, 2, 20, 50, 133 0x02, 0x00, 2, 25, 45,
134 0x03, 0x21, 3, 15, 50, 134 0x03, 0x21, 0, 20, 35,
135 0x04, 0x21, 4, 15, 30, 135 0x04, 0x21, 1, 20, 35,
136 0x05, 0x21, 5, 10, 25, 136 0x05, 0x21, 2, 20, 35,
137 0x06, 0x21, 6, 8, 14, 137 0x06, 0x21, 3, 15, 35,
138 0x07, 0x21, 7, 8, 14, 138 0x07, 0x21, 4, 15, 30,
139 0x08, 0x23, 7, 8, 14, 139 0x08, 0x21, 5, 10, 25,
140 0x09, 0x21, 6, 8, 14,
141 0x0a, 0x21, 7, 8, 14,
142 0x0b, 0x23, 7, 8, 14,
140}; 143};
141 144
142UCHAR RateSwitchTable11N2S[] = { 145UCHAR RateSwitchTable11N2S[] = {
143// 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) 146// 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)
144 0x0a, 0x00, 0, 0, 0, // Initial used item after association 147 0x0e, 0x0c, 0, 0, 0, // Initial used item after association
145 0x00, 0x21, 0, 30, 101, 148 0x00, 0x00, 0, 40, 101,
146 0x01, 0x21, 1, 20, 50, 149 0x01, 0x00, 1, 40, 50,
147 0x02, 0x21, 2, 20, 50, 150 0x02, 0x00, 2, 25, 45,
148 0x03, 0x21, 3, 15, 50, 151 0x03, 0x21, 0, 20, 35,
149 0x04, 0x21, 4, 15, 30, 152 0x04, 0x21, 1, 20, 35,
150 0x05, 0x20, 12, 15, 30, 153 0x05, 0x21, 2, 20, 35,
151 0x06, 0x20, 13, 8, 20, 154 0x06, 0x21, 3, 15, 35,
152 0x07, 0x20, 14, 8, 20, 155 0x07, 0x21, 4, 15, 30,
153 0x08, 0x20, 15, 8, 25, 156 0x08, 0x20, 11, 15, 30,
154 0x09, 0x22, 15, 8, 25, 157 0x09, 0x20, 12, 15, 30,
158 0x0a, 0x20, 13, 8, 20,
159 0x0b, 0x20, 14, 8, 20,
160 0x0c, 0x20, 15, 8, 25,
161 0x0d, 0x22, 15, 8, 15,
155}; 162};
156 163
157UCHAR RateSwitchTable11N3S[] = { 164UCHAR RateSwitchTable11N3S[] = {
158// 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) 165// 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)
159 0x0a, 0x00, 0, 0, 0, // Initial used item after association 166 0x0b, 0x00, 0, 0, 0, // 0x0a, 0x00, 0, 0, 0, // Initial used item after association
160 0x00, 0x21, 0, 30, 101, 167 0x00, 0x21, 0, 30, 101,
161 0x01, 0x21, 1, 20, 50, 168 0x01, 0x21, 1, 20, 50,
162 0x02, 0x21, 2, 20, 50, 169 0x02, 0x21, 2, 20, 50,
163 0x03, 0x21, 3, 15, 50, 170 0x03, 0x21, 3, 15, 50,
164 0x04, 0x21, 4, 15, 30, 171 0x04, 0x21, 4, 15, 30,
165 0x05, 0x20, 12, 15, 30, 172 0x05, 0x20, 11, 15, 30, // Required by System-Alan @ 20080812
166 0x06, 0x20, 13, 8, 20, 173 0x06, 0x20, 12, 15, 30, // 0x05, 0x20, 12, 15, 30,
167 0x07, 0x20, 14, 8, 20, 174 0x07, 0x20, 13, 8, 20, // 0x06, 0x20, 13, 8, 20,
168 0x08, 0x20, 15, 8, 25, 175 0x08, 0x20, 14, 8, 20, // 0x07, 0x20, 14, 8, 20,
169 0x09, 0x22, 15, 8, 25, 176 0x09, 0x20, 15, 8, 25, // 0x08, 0x20, 15, 8, 25,
177 0x0a, 0x22, 15, 8, 25, // 0x09, 0x22, 15, 8, 25,
170}; 178};
171 179
172UCHAR RateSwitchTable11N2SForABand[] = { 180UCHAR RateSwitchTable11N2SForABand[] = {
@@ -203,35 +211,38 @@ UCHAR RateSwitchTable11N3SForABand[] = { // 3*3
203 211
204UCHAR RateSwitchTable11BGN1S[] = { 212UCHAR RateSwitchTable11BGN1S[] = {
205// 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) 213// 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)
206 0x0d, 0x00, 0, 0, 0, // Initial used item after association 214 0x0c, 0x0a, 0, 0, 0, // Initial used item after association
207 0x00, 0x00, 0, 40, 101, 215 0x00, 0x00, 0, 40, 101,
208 0x01, 0x00, 1, 40, 50, 216 0x01, 0x00, 1, 40, 50,
209 0x02, 0x00, 2, 35, 45, 217 0x02, 0x00, 2, 25, 45,
210 0x03, 0x00, 3, 20, 45, 218 0x03, 0x21, 0, 20, 35,
211 0x04, 0x21, 0, 30,101, //50 219 0x04, 0x21, 1, 20, 35,
212 0x05, 0x21, 1, 20, 50, 220 0x05, 0x21, 2, 20, 35,
213 0x06, 0x21, 2, 20, 50, 221 0x06, 0x21, 3, 15, 35,
214 0x07, 0x21, 3, 15, 50, 222 0x07, 0x21, 4, 15, 30,
215 0x08, 0x21, 4, 15, 30, 223 0x08, 0x21, 5, 10, 25,
216 0x09, 0x21, 5, 10, 25, 224 0x09, 0x21, 6, 8, 14,
217 0x0a, 0x21, 6, 8, 14, 225 0x0a, 0x21, 7, 8, 14,
218 0x0b, 0x21, 7, 8, 14, 226 0x0b, 0x23, 7, 8, 14,
219 0x0c, 0x23, 7, 8, 14,
220}; 227};
221 228
222UCHAR RateSwitchTable11BGN2S[] = { 229UCHAR RateSwitchTable11BGN2S[] = {
223// 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) 230// 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)
224 0x0a, 0x00, 0, 0, 0, // Initial used item after association 231 0x0e, 0x0c, 0, 0, 0, // Initial used item after association
225 0x00, 0x21, 0, 30,101, //50 232 0x00, 0x00, 0, 40, 101,
226 0x01, 0x21, 1, 20, 50, 233 0x01, 0x00, 1, 40, 50,
227 0x02, 0x21, 2, 20, 50, 234 0x02, 0x00, 2, 25, 45,
228 0x03, 0x21, 3, 15, 50, 235 0x03, 0x21, 0, 20, 35,
229 0x04, 0x21, 4, 15, 30, 236 0x04, 0x21, 1, 20, 35,
230 0x05, 0x20, 12, 15, 30, 237 0x05, 0x21, 2, 20, 35,
231 0x06, 0x20, 13, 8, 20, 238 0x06, 0x21, 3, 15, 35,
232 0x07, 0x20, 14, 8, 20, 239 0x07, 0x21, 4, 15, 30,
233 0x08, 0x20, 15, 8, 25, 240 0x08, 0x20, 11, 15, 30,
234 0x09, 0x22, 15, 8, 25, 241 0x09, 0x20, 12, 15, 30,
242 0x0a, 0x20, 13, 8, 20,
243 0x0b, 0x20, 14, 8, 20,
244 0x0c, 0x20, 15, 8, 25,
245 0x0d, 0x22, 15, 8, 15,
235}; 246};
236 247
237UCHAR RateSwitchTable11BGN3S[] = { // 3*3 248UCHAR RateSwitchTable11BGN3S[] = { // 3*3
@@ -282,27 +293,6 @@ UCHAR RateSwitchTable11BGN3SForABand[] = { // 3*3
282 0x0b, 0x22, 23, 8, 25, 293 0x0b, 0x22, 23, 8, 25,
283}; 294};
284 295
285PUCHAR ReasonString[] = {
286 /* 0 */ "Reserved",
287 /* 1 */ "Unspecified Reason",
288 /* 2 */ "Previous Auth no longer valid",
289 /* 3 */ "STA is leaving / has left",
290 /* 4 */ "DIS-ASSOC due to inactivity",
291 /* 5 */ "AP unable to hanle all associations",
292 /* 6 */ "class 2 error",
293 /* 7 */ "class 3 error",
294 /* 8 */ "STA is leaving / has left",
295 /* 9 */ "require auth before assoc/re-assoc",
296 /* 10 */ "Reserved",
297 /* 11 */ "Reserved",
298 /* 12 */ "Reserved",
299 /* 13 */ "invalid IE",
300 /* 14 */ "MIC error",
301 /* 15 */ "4-way handshake timeout",
302 /* 16 */ "2-way (group key) handshake timeout",
303 /* 17 */ "4-way handshake IE diff among AssosReq/Rsp/Beacon",
304 /* 18 */
305};
306 296
307extern UCHAR OfdmRateToRxwiMCS[]; 297extern UCHAR OfdmRateToRxwiMCS[];
308// since RT61 has better RX sensibility, we have to limit TX ACK rate not to exceed our normal data TX rate. 298// since RT61 has better RX sensibility, we have to limit TX ACK rate not to exceed our normal data TX rate.
@@ -311,7 +301,6 @@ ULONG BasicRateMask[12] = {0xfffff001 /* 1-Mbps */, 0xfffff003 /* 2 Mbps */,
311 0xfffff01f /* 6 */ , 0xfffff03f /* 9 */ , 0xfffff07f /* 12 */ , 0xfffff0ff /* 18 */, 301 0xfffff01f /* 6 */ , 0xfffff03f /* 9 */ , 0xfffff07f /* 12 */ , 0xfffff0ff /* 18 */,
312 0xfffff1ff /* 24 */ , 0xfffff3ff /* 36 */ , 0xfffff7ff /* 48 */ , 0xffffffff /* 54 */}; 302 0xfffff1ff /* 24 */ , 0xfffff3ff /* 36 */ , 0xfffff7ff /* 48 */ , 0xffffffff /* 54 */};
313 303
314UCHAR MULTICAST_ADDR[MAC_ADDR_LEN] = {0x1, 0x00, 0x00, 0x00, 0x00, 0x00};
315UCHAR BROADCAST_ADDR[MAC_ADDR_LEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 304UCHAR BROADCAST_ADDR[MAC_ADDR_LEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
316UCHAR ZERO_MAC_ADDR[MAC_ADDR_LEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 305UCHAR ZERO_MAC_ADDR[MAC_ADDR_LEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
317 306
@@ -336,7 +325,6 @@ UCHAR TimIe = IE_TIM;
336UCHAR WpaIe = IE_WPA; 325UCHAR WpaIe = IE_WPA;
337UCHAR Wpa2Ie = IE_WPA2; 326UCHAR Wpa2Ie = IE_WPA2;
338UCHAR IbssIe = IE_IBSS_PARM; 327UCHAR IbssIe = IE_IBSS_PARM;
339UCHAR Ccx2Ie = IE_CCX_V2;
340 328
341extern UCHAR WPA_OUI[]; 329extern UCHAR WPA_OUI[];
342 330
@@ -345,107 +333,6 @@ UCHAR SES_OUI[] = {0x00, 0x90, 0x4c};
345UCHAR ZeroSsid[32] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 333UCHAR ZeroSsid[32] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
346 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; 334 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
347 335
348// Reset the RFIC setting to new series
349RTMP_RF_REGS RF2850RegTable[] = {
350// ch R1 R2 R3(TX0~4=0) R4
351 {1, 0x98402ecc, 0x984c0786, 0x9816b455, 0x9800510b},
352 {2, 0x98402ecc, 0x984c0786, 0x98168a55, 0x9800519f},
353 {3, 0x98402ecc, 0x984c078a, 0x98168a55, 0x9800518b},
354 {4, 0x98402ecc, 0x984c078a, 0x98168a55, 0x9800519f},
355 {5, 0x98402ecc, 0x984c078e, 0x98168a55, 0x9800518b},
356 {6, 0x98402ecc, 0x984c078e, 0x98168a55, 0x9800519f},
357 {7, 0x98402ecc, 0x984c0792, 0x98168a55, 0x9800518b},
358 {8, 0x98402ecc, 0x984c0792, 0x98168a55, 0x9800519f},
359 {9, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800518b},
360 {10, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800519f},
361 {11, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800518b},
362 {12, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800519f},
363 {13, 0x98402ecc, 0x984c079e, 0x98168a55, 0x9800518b},
364 {14, 0x98402ecc, 0x984c07a2, 0x98168a55, 0x98005193},
365
366 // 802.11 UNI / HyperLan 2
367 {36, 0x98402ecc, 0x984c099a, 0x98158a55, 0x980ed1a3},
368 {38, 0x98402ecc, 0x984c099e, 0x98158a55, 0x980ed193},
369 {40, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed183},
370 {44, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed1a3},
371 {46, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed18b},
372 {48, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed19b},
373 {52, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed193},
374 {54, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed1a3},
375 {56, 0x98402ec8, 0x984c068e, 0x98158a55, 0x980ed18b},
376 {60, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed183},
377 {62, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed193},
378 {64, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed1a3}, // Plugfest#4, Day4, change RFR3 left4th 9->5.
379
380 // 802.11 HyperLan 2
381 {100, 0x98402ec8, 0x984c06b2, 0x98178a55, 0x980ed783},
382
383 // 2008.04.30 modified
384 // The system team has AN to improve the EVM value
385 // for channel 102 to 108 for the RT2850/RT2750 dual band solution.
386 {102, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed793},
387 {104, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed1a3},
388 {108, 0x98402ecc, 0x985c0a32, 0x98578a55, 0x980ed193},
389
390 {110, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed183},
391 {112, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed19b},
392 {116, 0x98402ecc, 0x984c0a3a, 0x98178a55, 0x980ed1a3},
393 {118, 0x98402ecc, 0x984c0a3e, 0x98178a55, 0x980ed193},
394 {120, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed183},
395 {124, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed193},
396 {126, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed15b}, // 0x980ed1bb->0x980ed15b required by Rory 20070927
397 {128, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed1a3},
398 {132, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed18b},
399 {134, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed193},
400 {136, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed19b},
401 {140, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed183},
402
403 // 802.11 UNII
404 {149, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed1a7},
405 {151, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed187},
406 {153, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed18f},
407 {157, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed19f},
408 {159, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed1a7},
409 {161, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed187},
410 {165, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed197},
411
412 // Japan
413 {184, 0x95002ccc, 0x9500491e, 0x9509be55, 0x950c0a0b},
414 {188, 0x95002ccc, 0x95004922, 0x9509be55, 0x950c0a13},
415 {192, 0x95002ccc, 0x95004926, 0x9509be55, 0x950c0a1b},
416 {196, 0x95002ccc, 0x9500492a, 0x9509be55, 0x950c0a23},
417 {208, 0x95002ccc, 0x9500493a, 0x9509be55, 0x950c0a13},
418 {212, 0x95002ccc, 0x9500493e, 0x9509be55, 0x950c0a1b},
419 {216, 0x95002ccc, 0x95004982, 0x9509be55, 0x950c0a23},
420
421 // still lack of MMAC(Japan) ch 34,38,42,46
422};
423UCHAR NUM_OF_2850_CHNL = (sizeof(RF2850RegTable) / sizeof(RTMP_RF_REGS));
424
425FREQUENCY_ITEM FreqItems3020[] =
426{
427 /**************************************************/
428 // ISM : 2.4 to 2.483 GHz //
429 /**************************************************/
430 // 11g
431 /**************************************************/
432 //-CH---N-------R---K-----------
433 {1, 241, 2, 2},
434 {2, 241, 2, 7},
435 {3, 242, 2, 2},
436 {4, 242, 2, 7},
437 {5, 243, 2, 2},
438 {6, 243, 2, 7},
439 {7, 244, 2, 2},
440 {8, 244, 2, 7},
441 {9, 245, 2, 2},
442 {10, 245, 2, 7},
443 {11, 246, 2, 2},
444 {12, 246, 2, 7},
445 {13, 247, 2, 2},
446 {14, 248, 2, 4},
447};
448UCHAR NUM_OF_3020_CHNL=(sizeof(FreqItems3020) / sizeof(FREQUENCY_ITEM));
449 336
450/* 337/*
451 ========================================================================== 338 ==========================================================================
@@ -484,14 +371,19 @@ NDIS_STATUS MlmeInit(
484 AuthStateMachineInit(pAd, &pAd->Mlme.AuthMachine, pAd->Mlme.AuthFunc); 371 AuthStateMachineInit(pAd, &pAd->Mlme.AuthMachine, pAd->Mlme.AuthFunc);
485 AuthRspStateMachineInit(pAd, &pAd->Mlme.AuthRspMachine, pAd->Mlme.AuthRspFunc); 372 AuthRspStateMachineInit(pAd, &pAd->Mlme.AuthRspMachine, pAd->Mlme.AuthRspFunc);
486 SyncStateMachineInit(pAd, &pAd->Mlme.SyncMachine, pAd->Mlme.SyncFunc); 373 SyncStateMachineInit(pAd, &pAd->Mlme.SyncMachine, pAd->Mlme.SyncFunc);
487 WpaPskStateMachineInit(pAd, &pAd->Mlme.WpaPskMachine, pAd->Mlme.WpaPskFunc); 374
488 AironetStateMachineInit(pAd, &pAd->Mlme.AironetMachine, pAd->Mlme.AironetFunc); 375
376
489 377
490 // Since we are using switch/case to implement it, the init is different from the above 378 // Since we are using switch/case to implement it, the init is different from the above
491 // state machine init 379 // state machine init
492 MlmeCntlInit(pAd, &pAd->Mlme.CntlMachine, NULL); 380 MlmeCntlInit(pAd, &pAd->Mlme.CntlMachine, NULL);
493 } 381 }
494 382
383
384 WpaStateMachineInit(pAd, &pAd->Mlme.WpaMachine, pAd->Mlme.WpaFunc);
385
386
495 ActionStateMachineInit(pAd, &pAd->Mlme.ActMachine, pAd->Mlme.ActFunc); 387 ActionStateMachineInit(pAd, &pAd->Mlme.ActMachine, pAd->Mlme.ActFunc);
496 388
497 // Init mlme periodic timer 389 // Init mlme periodic timer
@@ -503,16 +395,24 @@ NDIS_STATUS MlmeInit(
503 // software-based RX Antenna diversity 395 // software-based RX Antenna diversity
504 RTMPInitTimer(pAd, &pAd->Mlme.RxAntEvalTimer, GET_TIMER_FUNCTION(AsicRxAntEvalTimeout), pAd, FALSE); 396 RTMPInitTimer(pAd, &pAd->Mlme.RxAntEvalTimer, GET_TIMER_FUNCTION(AsicRxAntEvalTimeout), pAd, FALSE);
505 397
506#ifdef RT2860
507 { 398 {
399#ifdef RTMP_PCI_SUPPORT
508 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) 400 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
509 { 401 {
510 // only PCIe cards need these two timers 402 // only PCIe cards need these two timers
511 RTMPInitTimer(pAd, &pAd->Mlme.PsPollTimer, GET_TIMER_FUNCTION(PsPollWakeExec), pAd, FALSE); 403 RTMPInitTimer(pAd, &pAd->Mlme.PsPollTimer, GET_TIMER_FUNCTION(PsPollWakeExec), pAd, FALSE);
512 RTMPInitTimer(pAd, &pAd->Mlme.RadioOnOffTimer, GET_TIMER_FUNCTION(RadioOnExec), pAd, FALSE); 404 RTMPInitTimer(pAd, &pAd->Mlme.RadioOnOffTimer, GET_TIMER_FUNCTION(RadioOnExec), pAd, FALSE);
513 } 405 }
406#endif // RTMP_PCI_SUPPORT //
407
408 RTMPInitTimer(pAd, &pAd->Mlme.LinkDownTimer, GET_TIMER_FUNCTION(LinkDownExec), pAd, FALSE);
409
410#ifdef RTMP_MAC_USB
411 RTMPInitTimer(pAd, &pAd->Mlme.AutoWakeupTimer, GET_TIMER_FUNCTION(RtmpUsbStaAsicForceWakeupTimeout), pAd, FALSE);
412 pAd->Mlme.AutoWakeupTimerRunning = FALSE;
413#endif // RTMP_MAC_USB //
514 } 414 }
515#endif 415
516 } while (FALSE); 416 } while (FALSE);
517 417
518 DBGPRINT(RT_DEBUG_TRACE, ("<-- MLME Initialize\n")); 418 DBGPRINT(RT_DEBUG_TRACE, ("<-- MLME Initialize\n"));
@@ -567,7 +467,7 @@ VOID MlmeHandler(
567 //From message type, determine which state machine I should drive 467 //From message type, determine which state machine I should drive
568 if (MlmeDequeue(&pAd->Mlme.Queue, &Elem)) 468 if (MlmeDequeue(&pAd->Mlme.Queue, &Elem))
569 { 469 {
570#ifdef RT2870 470#ifdef RTMP_MAC_USB
571 if (Elem->MsgType == MT2_RESET_CONF) 471 if (Elem->MsgType == MT2_RESET_CONF)
572 { 472 {
573 DBGPRINT_RAW(RT_DEBUG_TRACE, ("!!! reset MLME state machine !!!\n")); 473 DBGPRINT_RAW(RT_DEBUG_TRACE, ("!!! reset MLME state machine !!!\n"));
@@ -576,7 +476,7 @@ VOID MlmeHandler(
576 Elem->MsgLen = 0; 476 Elem->MsgLen = 0;
577 continue; 477 continue;
578 } 478 }
579#endif // RT2870 // 479#endif // RTMP_MAC_USB //
580 480
581 // if dequeue success 481 // if dequeue success
582 switch (Elem->Machine) 482 switch (Elem->Machine)
@@ -600,14 +500,16 @@ VOID MlmeHandler(
600 case WPA_PSK_STATE_MACHINE: 500 case WPA_PSK_STATE_MACHINE:
601 StateMachinePerformAction(pAd, &pAd->Mlme.WpaPskMachine, Elem); 501 StateMachinePerformAction(pAd, &pAd->Mlme.WpaPskMachine, Elem);
602 break; 502 break;
603 case AIRONET_STATE_MACHINE: 503
604 StateMachinePerformAction(pAd, &pAd->Mlme.AironetMachine, Elem); 504
605 break; 505
606 case ACTION_STATE_MACHINE: 506 case ACTION_STATE_MACHINE:
607 StateMachinePerformAction(pAd, &pAd->Mlme.ActMachine, Elem); 507 StateMachinePerformAction(pAd, &pAd->Mlme.ActMachine, Elem);
608 break; 508 break;
609 509
610 510 case WPA_STATE_MACHINE:
511 StateMachinePerformAction(pAd, &pAd->Mlme.WpaMachine, Elem);
512 break;
611 513
612 514
613 default: 515 default:
@@ -647,9 +549,6 @@ VOID MlmeHalt(
647 IN PRTMP_ADAPTER pAd) 549 IN PRTMP_ADAPTER pAd)
648{ 550{
649 BOOLEAN Cancelled; 551 BOOLEAN Cancelled;
650#ifdef RT3070
651 UINT32 TxPinCfg = 0x00050F0F;
652#endif // RT3070 //
653 552
654 DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeHalt\n")); 553 DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeHalt\n"));
655 554
@@ -667,13 +566,21 @@ VOID MlmeHalt(
667 RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &Cancelled); 566 RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &Cancelled);
668 RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &Cancelled); 567 RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &Cancelled);
669 RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled); 568 RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled);
670#ifdef RT2860 569
570
571#ifdef RTMP_MAC_PCI
671 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) 572 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
672 { 573 {
673 RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled); 574 RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
674 RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer, &Cancelled); 575 RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer, &Cancelled);
675 } 576 }
676#endif 577#endif // RTMP_MAC_PCI //
578
579 RTMPCancelTimer(&pAd->Mlme.LinkDownTimer, &Cancelled);
580
581#ifdef RTMP_MAC_USB
582 RTMPCancelTimer(&pAd->Mlme.AutoWakeupTimer, &Cancelled);
583#endif // RTMP_MAC_USB //
677 } 584 }
678 585
679 RTMPCancelTimer(&pAd->Mlme.PeriodicTimer, &Cancelled); 586 RTMPCancelTimer(&pAd->Mlme.PeriodicTimer, &Cancelled);
@@ -683,10 +590,12 @@ VOID MlmeHalt(
683 590
684 if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) 591 if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
685 { 592 {
593 RTMP_CHIP_OP *pChipOps = &pAd->chipOps;
594
686 // Set LED 595 // Set LED
687 RTMPSetLED(pAd, LED_HALT); 596 RTMPSetLED(pAd, LED_HALT);
688 RTMPSetSignalLED(pAd, -100); // Force signal strength Led to be turned off, firmware is not done it. 597 RTMPSetSignalLED(pAd, -100); // Force signal strength Led to be turned off, firmware is not done it.
689#ifdef RT2870 598#ifdef RTMP_MAC_USB
690 { 599 {
691 LED_CFG_STRUC LedCfg; 600 LED_CFG_STRUC LedCfg;
692 RTMP_IO_READ32(pAd, LED_CFG, &LedCfg.word); 601 RTMP_IO_READ32(pAd, LED_CFG, &LedCfg.word);
@@ -696,17 +605,10 @@ VOID MlmeHalt(
696 LedCfg.field.YLedMode = 0; 605 LedCfg.field.YLedMode = 0;
697 RTMP_IO_WRITE32(pAd, LED_CFG, LedCfg.word); 606 RTMP_IO_WRITE32(pAd, LED_CFG, LedCfg.word);
698 } 607 }
699#endif // RT2870 // 608#endif // RTMP_MAC_USB //
700#ifdef RT3070 609
701 // 610 if (pChipOps->AsicHaltAction)
702 // Turn off LNA_PE 611 pChipOps->AsicHaltAction(pAd);
703 //
704 if (IS_RT3070(pAd) || IS_RT3071(pAd))
705 {
706 TxPinCfg &= 0xFFFFF0F0;
707 RTUSBWriteMACRegister(pAd, TX_PIN_CFG, TxPinCfg);
708 }
709#endif // RT3070 //
710 } 612 }
711 613
712 RTMPusecDelay(5000); // 5 msec to gurantee Ant Diversity timer canceled 614 RTMPusecDelay(5000); // 5 msec to gurantee Ant Diversity timer canceled
@@ -730,6 +632,8 @@ VOID MlmeResetRalinkCounters(
730 pAd->RalinkCounters.OneSecTxNoRetryOkCount = 0; 632 pAd->RalinkCounters.OneSecTxNoRetryOkCount = 0;
731 pAd->RalinkCounters.OneSecTxRetryOkCount = 0; 633 pAd->RalinkCounters.OneSecTxRetryOkCount = 0;
732 pAd->RalinkCounters.OneSecRxOkDataCnt = 0; 634 pAd->RalinkCounters.OneSecRxOkDataCnt = 0;
635 pAd->RalinkCounters.OneSecReceivedByteCount = 0;
636 pAd->RalinkCounters.OneSecTransmittedByteCount = 0;
733 637
734 // TODO: for debug only. to be removed 638 // TODO: for debug only. to be removed
735 pAd->RalinkCounters.OneSecOsTxCount[QID_AC_BE] = 0; 639 pAd->RalinkCounters.OneSecOsTxCount[QID_AC_BE] = 0;
@@ -748,8 +652,6 @@ VOID MlmeResetRalinkCounters(
748 return; 652 return;
749} 653}
750 654
751unsigned long rx_AMSDU;
752unsigned long rx_Total;
753 655
754/* 656/*
755 ========================================================================== 657 ==========================================================================
@@ -777,33 +679,19 @@ VOID MlmePeriodicExec(
777 ULONG TxTotalCnt; 679 ULONG TxTotalCnt;
778 PRTMP_ADAPTER pAd = (RTMP_ADAPTER *)FunctionContext; 680 PRTMP_ADAPTER pAd = (RTMP_ADAPTER *)FunctionContext;
779 681
780#ifdef RT2860 682#ifdef RTMP_MAC_PCI
781 //Baron 2008/07/10
782 //printk("Baron_Test:\t%s", RTMPGetRalinkEncryModeStr(pAd->StaCfg.WepStatus));
783 //If the STA security setting is OPEN or WEP, pAd->StaCfg.WpaSupplicantUP = 0.
784 //If the STA security setting is WPAPSK or WPA2PSK, pAd->StaCfg.WpaSupplicantUP = 1.
785 if(pAd->StaCfg.WepStatus<2)
786 {
787 pAd->StaCfg.WpaSupplicantUP = 0;
788 }
789 else
790 {
791 pAd->StaCfg.WpaSupplicantUP = 1;
792 }
793
794 { 683 {
795 // If Hardware controlled Radio enabled, we have to check GPIO pin2 every 2 second. 684 // If Hardware controlled Radio enabled, we have to check GPIO pin2 every 2 second.
796 // Move code to here, because following code will return when radio is off 685 // Move code to here, because following code will return when radio is off
797 if ((pAd->Mlme.PeriodicRound % (MLME_TASK_EXEC_MULTIPLE * 2) == 0) && 686 if ((pAd->Mlme.PeriodicRound % (MLME_TASK_EXEC_MULTIPLE * 2) == 0) && (pAd->StaCfg.bHardwareRadio == TRUE) &&
798 (pAd->StaCfg.bHardwareRadio == TRUE) &&
799 (RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_START_UP)) &&
800 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) && 687 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
801 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))) 688 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))
689 /*&&(pAd->bPCIclkOff == FALSE)*/)
802 { 690 {
803 UINT32 data = 0; 691 UINT32 data = 0;
804 692
805 // Read GPIO pin2 as Hardware controlled radio state 693 // Read GPIO pin2 as Hardware controlled radio state
806 RTMP_IO_FORCE_READ32(pAd, GPIO_CTRL_CFG, &data); 694 RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &data);
807 if (data & 0x04) 695 if (data & 0x04)
808 { 696 {
809 pAd->StaCfg.bHwRadio = TRUE; 697 pAd->StaCfg.bHwRadio = TRUE;
@@ -830,7 +718,7 @@ VOID MlmePeriodicExec(
830 } 718 }
831 } 719 }
832 } 720 }
833#endif /* RT2860 */ 721#endif // RTMP_MAC_PCI //
834 722
835 // Do nothing if the driver is starting halt state. 723 // Do nothing if the driver is starting halt state.
836 // This might happen when timer already been fired before cancel timer with mlmehalt 724 // This might happen when timer already been fired before cancel timer with mlmehalt
@@ -840,46 +728,7 @@ VOID MlmePeriodicExec(
840 fRTMP_ADAPTER_RESET_IN_PROGRESS)))) 728 fRTMP_ADAPTER_RESET_IN_PROGRESS))))
841 return; 729 return;
842 730
843#ifdef RT2860 731 RTMP_MLME_PRE_SANITY_CHECK(pAd);
844 {
845 if ((pAd->RalinkCounters.LastReceivedByteCount == pAd->RalinkCounters.ReceivedByteCount) && (pAd->StaCfg.bRadio == TRUE))
846 {
847 // If ReceiveByteCount doesn't change, increase SameRxByteCount by 1.
848 pAd->SameRxByteCount++;
849 }
850 else
851 pAd->SameRxByteCount = 0;
852
853 // If after BBP, still not work...need to check to reset PBF&MAC.
854 if (pAd->SameRxByteCount == 702)
855 {
856 pAd->SameRxByteCount = 0;
857 AsicResetPBF(pAd);
858 AsicResetMAC(pAd);
859 }
860
861 // If SameRxByteCount keeps happens for 2 second in infra mode, or for 60 seconds in idle mode.
862 if (((INFRA_ON(pAd)) && (pAd->SameRxByteCount > 20)) || ((IDLE_ON(pAd)) && (pAd->SameRxByteCount > 600)))
863 {
864 if ((pAd->StaCfg.bRadio == TRUE) && (pAd->SameRxByteCount < 700))
865 {
866 DBGPRINT(RT_DEBUG_TRACE, ("---> SameRxByteCount = %lu !!!!!!!!!!!!!!! \n", pAd->SameRxByteCount));
867 pAd->SameRxByteCount = 700;
868 AsicResetBBP(pAd);
869 }
870 }
871
872 // Update lastReceiveByteCount.
873 pAd->RalinkCounters.LastReceivedByteCount = pAd->RalinkCounters.ReceivedByteCount;
874
875 if ((pAd->CheckDmaBusyCount > 3) && (IDLE_ON(pAd)))
876 {
877 pAd->CheckDmaBusyCount = 0;
878 AsicResetFromDMABusy(pAd);
879 }
880 }
881#endif /* RT2860 */
882 RT28XX_MLME_PRE_SANITY_CHECK(pAd);
883 732
884 { 733 {
885 // Do nothing if monitor mode is on 734 // Do nothing if monitor mode is on
@@ -911,10 +760,11 @@ VOID MlmePeriodicExec(
911// RECBATimerTimeout(SystemSpecific1,FunctionContext,SystemSpecific2,SystemSpecific3); 760// RECBATimerTimeout(SystemSpecific1,FunctionContext,SystemSpecific2,SystemSpecific3);
912 pAd->Mlme.PeriodicRound ++; 761 pAd->Mlme.PeriodicRound ++;
913 762
914#ifdef RT3070 763#ifdef RTMP_MAC_USB
915 // execute every 100ms, update the Tx FIFO Cnt for update Tx Rate. 764 // execute every 100ms, update the Tx FIFO Cnt for update Tx Rate.
916 NICUpdateFifoStaCounters(pAd); 765 NICUpdateFifoStaCounters(pAd);
917#endif // RT3070 // 766#endif // RTMP_MAC_USB //
767
918 // execute every 500ms 768 // execute every 500ms
919 if ((pAd->Mlme.PeriodicRound % 5 == 0) && RTMPAutoRateSwitchCheck(pAd)/*(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))*/) 769 if ((pAd->Mlme.PeriodicRound % 5 == 0) && RTMPAutoRateSwitchCheck(pAd)/*(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))*/)
920 { 770 {
@@ -932,13 +782,10 @@ VOID MlmePeriodicExec(
932 { 782 {
933 pAd->Mlme.OneSecPeriodicRound ++; 783 pAd->Mlme.OneSecPeriodicRound ++;
934 784
935 if (rx_Total)
936 {
937 785
938 // reset counters 786
939 rx_AMSDU = 0; 787
940 rx_Total = 0; 788 //ORIBATimerTimeout(pAd);
941 }
942 789
943 // Media status changed, report to NDIS 790 // Media status changed, report to NDIS
944 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE)) 791 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE))
@@ -963,14 +810,23 @@ VOID MlmePeriodicExec(
963 // the dynamic tuning mechanism below are based on most up-to-date information 810 // the dynamic tuning mechanism below are based on most up-to-date information
964 NICUpdateRawCounters(pAd); 811 NICUpdateRawCounters(pAd);
965 812
966#ifdef RT2870 813#ifdef RTMP_MAC_USB
967 RT2870_WatchDog(pAd); 814 RTUSBWatchDog(pAd);
968#endif // RT2870 // 815#endif // RTMP_MAC_USB //
969 816
970 // Need statistics after read counter. So put after NICUpdateRawCounters 817 // Need statistics after read counter. So put after NICUpdateRawCounters
971 ORIBATimerTimeout(pAd); 818 ORIBATimerTimeout(pAd);
972 819
820 // if MGMT RING is full more than twice within 1 second, we consider there's
821 // a hardware problem stucking the TX path. In this case, try a hardware reset
822 // to recover the system
823 // if (pAd->RalinkCounters.MgmtRingFullCount >= 2)
824 // RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HARDWARE_ERROR);
825 // else
826 // pAd->RalinkCounters.MgmtRingFullCount = 0;
827
973 // The time period for checking antenna is according to traffic 828 // The time period for checking antenna is according to traffic
829 {
974 if (pAd->Mlme.bEnableAutoAntennaCheck) 830 if (pAd->Mlme.bEnableAutoAntennaCheck)
975 { 831 {
976 TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount + 832 TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
@@ -993,15 +849,16 @@ VOID MlmePeriodicExec(
993 } 849 }
994 } 850 }
995 } 851 }
852 }
996 853
997 STAMlmePeriodicExec(pAd); 854 STAMlmePeriodicExec(pAd);
998 855
999 MlmeResetRalinkCounters(pAd); 856 MlmeResetRalinkCounters(pAd);
1000 857
1001 { 858 {
1002#ifdef RT2860 859#ifdef RTMP_MAC_PCI
1003 if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST) && (pAd->bPCIclkOff == FALSE)) 860 if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST) && (pAd->bPCIclkOff == FALSE))
1004#endif 861#endif // RTMP_MAC_PCI //
1005 { 862 {
1006 // When Adhoc beacon is enabled and RTS/CTS is enabled, there is a chance that hardware MAC FSM will run into a deadlock 863 // When Adhoc beacon is enabled and RTS/CTS is enabled, there is a chance that hardware MAC FSM will run into a deadlock
1007 // and sending CTS-to-self over and over. 864 // and sending CTS-to-self over and over.
@@ -1024,356 +881,13 @@ VOID MlmePeriodicExec(
1024 } 881 }
1025 } 882 }
1026 883
1027 RT28XX_MLME_HANDLER(pAd); 884 RTMP_MLME_HANDLER(pAd);
1028 }
1029
1030 pAd->bUpdateBcnCntDone = FALSE;
1031}
1032
1033VOID STAMlmePeriodicExec(
1034 PRTMP_ADAPTER pAd)
1035{
1036#ifdef RT2860
1037 ULONG TxTotalCnt;
1038#endif
1039#ifdef RT2870
1040 ULONG TxTotalCnt;
1041 int i;
1042#endif
1043
1044 if (pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE)
1045 {
1046 // WPA MIC error should block association attempt for 60 seconds
1047 if (pAd->StaCfg.bBlockAssoc && (pAd->StaCfg.LastMicErrorTime + (60 * OS_HZ) < pAd->Mlme.Now32))
1048 pAd->StaCfg.bBlockAssoc = FALSE;
1049 }
1050
1051#ifdef RT2860
1052 //Baron 2008/07/10
1053 //printk("Baron_Test:\t%s", RTMPGetRalinkEncryModeStr(pAd->StaCfg.WepStatus));
1054 //If the STA security setting is OPEN or WEP, pAd->StaCfg.WpaSupplicantUP = 0.
1055 //If the STA security setting is WPAPSK or WPA2PSK, pAd->StaCfg.WpaSupplicantUP = 1.
1056 if(pAd->StaCfg.WepStatus<2)
1057 {
1058 pAd->StaCfg.WpaSupplicantUP = 0;
1059 }
1060 else
1061 {
1062 pAd->StaCfg.WpaSupplicantUP = 1;
1063 }
1064#endif
1065
1066 if ((pAd->PreMediaState != pAd->IndicateMediaState) && (pAd->CommonCfg.bWirelessEvent))
1067 {
1068 if (pAd->IndicateMediaState == NdisMediaStateConnected)
1069 {
1070 RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1071 }
1072 pAd->PreMediaState = pAd->IndicateMediaState;
1073 }
1074
1075#ifdef RT2860
1076 if ((pAd->OpMode == OPMODE_STA) && (IDLE_ON(pAd)) &&
1077 (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) &&
1078 (pAd->Mlme.SyncMachine.CurrState == SYNC_IDLE) &&
1079 (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) &&
1080 (RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_START_UP)) &&
1081 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)))
1082 {
1083 RT28xxPciAsicRadioOff(pAd, GUI_IDLE_POWER_SAVE, 0);
1084 } 885 }
1085#endif
1086
1087
1088 886
1089 AsicStaBbpTuning(pAd);
1090 887
1091 TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount + 888 pAd->bUpdateBcnCntDone = FALSE;
1092 pAd->RalinkCounters.OneSecTxRetryOkCount +
1093 pAd->RalinkCounters.OneSecTxFailCount;
1094
1095 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1096 {
1097 // update channel quality for Roaming and UI LinkQuality display
1098 MlmeCalculateChannelQuality(pAd, pAd->Mlme.Now32);
1099 }
1100
1101 // must be AFTER MlmeDynamicTxRateSwitching() because it needs to know if
1102 // Radio is currently in noisy environment
1103 if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
1104 AsicAdjustTxPower(pAd);
1105
1106 if (INFRA_ON(pAd))
1107 {
1108 // Is PSM bit consistent with user power management policy?
1109 // This is the only place that will set PSM bit ON.
1110 if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
1111 MlmeCheckPsmChange(pAd, pAd->Mlme.Now32);
1112
1113 pAd->RalinkCounters.LastOneSecTotalTxCount = TxTotalCnt;
1114
1115 if ((pAd->StaCfg.LastBeaconRxTime + 1*OS_HZ < pAd->Mlme.Now32) &&
1116 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) &&
1117 ((TxTotalCnt + pAd->RalinkCounters.OneSecRxOkCnt < 600)))
1118 {
1119 RTMPSetAGCInitValue(pAd, BW_20);
1120 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - No BEACON. restore R66 to the low bound(%d) \n", (0x2E + GET_LNA_GAIN(pAd))));
1121 }
1122
1123 {
1124 if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable)
1125 {
1126 // When APSD is enabled, the period changes as 20 sec
1127 if ((pAd->Mlme.OneSecPeriodicRound % 20) == 8)
1128 RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
1129 }
1130 else
1131 {
1132 // Send out a NULL frame every 10 sec to inform AP that STA is still alive (Avoid being age out)
1133 if ((pAd->Mlme.OneSecPeriodicRound % 10) == 8)
1134 {
1135 if (pAd->CommonCfg.bWmmCapable)
1136 RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
1137 else
1138 RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, FALSE);
1139 }
1140 }
1141 }
1142
1143 if (CQI_IS_DEAD(pAd->Mlme.ChannelQuality))
1144 {
1145 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - No BEACON. Dead CQI. Auto Recovery attempt #%ld\n", pAd->RalinkCounters.BadCQIAutoRecoveryCount));
1146 pAd->StaCfg.CCXAdjacentAPReportFlag = TRUE;
1147 pAd->StaCfg.CCXAdjacentAPLinkDownTime = pAd->StaCfg.LastBeaconRxTime;
1148
1149 // Lost AP, send disconnect & link down event
1150 LinkDown(pAd, FALSE);
1151
1152 {
1153 union iwreq_data wrqu;
1154 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
1155 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
1156 }
1157
1158 MlmeAutoReconnectLastSSID(pAd);
1159 }
1160 else if (CQI_IS_BAD(pAd->Mlme.ChannelQuality))
1161 {
1162 pAd->RalinkCounters.BadCQIAutoRecoveryCount ++;
1163 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Bad CQI. Auto Recovery attempt #%ld\n", pAd->RalinkCounters.BadCQIAutoRecoveryCount));
1164 MlmeAutoReconnectLastSSID(pAd);
1165 }
1166
1167 // Add auto seamless roaming
1168 if (pAd->StaCfg.bFastRoaming)
1169 {
1170 SHORT dBmToRoam = (SHORT)pAd->StaCfg.dBmToRoam;
1171
1172 DBGPRINT(RT_DEBUG_TRACE, ("Rssi=%d, dBmToRoam=%d\n", RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2), (CHAR)dBmToRoam));
1173
1174 if (RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2) <= (CHAR)dBmToRoam)
1175 {
1176 MlmeCheckForFastRoaming(pAd, pAd->Mlme.Now32);
1177 }
1178 }
1179 }
1180 else if (ADHOC_ON(pAd))
1181 {
1182#ifdef RT2860
1183 // 2003-04-17 john. this is a patch that driver forces a BEACON out if ASIC fails
1184 // the "TX BEACON competition" for the entire past 1 sec.
1185 // So that even when ASIC's BEACONgen engine been blocked
1186 // by peer's BEACON due to slower system clock, this STA still can send out
1187 // minimum BEACON to tell the peer I'm alive.
1188 // drawback is that this BEACON won't be well aligned at TBTT boundary.
1189 // EnqueueBeaconFrame(pAd); // software send BEACON
1190
1191 // if all 11b peers leave this BSS more than 5 seconds, update Tx rate,
1192 // restore outgoing BEACON to support B/G-mixed mode
1193 if ((pAd->CommonCfg.Channel <= 14) &&
1194 (pAd->CommonCfg.MaxTxRate <= RATE_11) &&
1195 (pAd->CommonCfg.MaxDesiredRate > RATE_11) &&
1196 ((pAd->StaCfg.Last11bBeaconRxTime + 5*OS_HZ) < pAd->Mlme.Now32))
1197 {
1198 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - last 11B peer left, update Tx rates\n"));
1199 NdisMoveMemory(pAd->StaActive.SupRate, pAd->CommonCfg.SupRate, MAX_LEN_OF_SUPPORTED_RATES);
1200 pAd->StaActive.SupRateLen = pAd->CommonCfg.SupRateLen;
1201 MlmeUpdateTxRates(pAd, FALSE, 0);
1202 MakeIbssBeacon(pAd); // re-build BEACON frame
1203 AsicEnableIbssSync(pAd); // copy to on-chip memory
1204 pAd->StaCfg.AdhocBOnlyJoined = FALSE;
1205 }
1206
1207 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
1208 {
1209 if ((pAd->StaCfg.AdhocBGJoined) &&
1210 ((pAd->StaCfg.Last11gBeaconRxTime + 5 * OS_HZ) < pAd->Mlme.Now32))
1211 {
1212 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - last 11G peer left\n"));
1213 pAd->StaCfg.AdhocBGJoined = FALSE;
1214 }
1215
1216 if ((pAd->StaCfg.Adhoc20NJoined) &&
1217 ((pAd->StaCfg.Last20NBeaconRxTime + 5 * OS_HZ) < pAd->Mlme.Now32))
1218 {
1219 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - last 20MHz N peer left\n"));
1220 pAd->StaCfg.Adhoc20NJoined = FALSE;
1221 }
1222 }
1223#endif /* RT2860 */
1224
1225 //radar detect
1226 if ((pAd->CommonCfg.Channel > 14)
1227 && (pAd->CommonCfg.bIEEE80211H == 1)
1228 && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
1229 {
1230 RadarDetectPeriodic(pAd);
1231 }
1232
1233 // If all peers leave, and this STA becomes the last one in this IBSS, then change MediaState
1234 // to DISCONNECTED. But still holding this IBSS (i.e. sending BEACON) so that other STAs can
1235 // join later.
1236 if ((pAd->StaCfg.LastBeaconRxTime + ADHOC_BEACON_LOST_TIME < pAd->Mlme.Now32) &&
1237 OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1238 {
1239 MLME_START_REQ_STRUCT StartReq;
1240
1241 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - excessive BEACON lost, last STA in this IBSS, MediaState=Disconnected\n"));
1242 LinkDown(pAd, FALSE);
1243
1244 StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
1245 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
1246 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
1247 }
1248
1249#ifdef RT2870
1250 for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++)
1251 {
1252 MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[i];
1253
1254 if (pEntry->ValidAsCLI == FALSE)
1255 continue;
1256
1257 if (pEntry->LastBeaconRxTime + ADHOC_BEACON_LOST_TIME < pAd->Mlme.Now32)
1258 MacTableDeleteEntry(pAd, pEntry->Aid, pEntry->Addr);
1259 }
1260#endif
1261 }
1262 else // no INFRA nor ADHOC connection
1263 {
1264
1265 if (pAd->StaCfg.bScanReqIsFromWebUI &&
1266 ((pAd->StaCfg.LastScanTime + 30 * OS_HZ) > pAd->Mlme.Now32))
1267 goto SKIP_AUTO_SCAN_CONN;
1268 else
1269 pAd->StaCfg.bScanReqIsFromWebUI = FALSE;
1270
1271 if ((pAd->StaCfg.bAutoReconnect == TRUE)
1272 && RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP)
1273 && (MlmeValidateSSID(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen) == TRUE))
1274 {
1275 if ((pAd->ScanTab.BssNr==0) && (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE))
1276 {
1277 MLME_SCAN_REQ_STRUCT ScanReq;
1278
1279 if ((pAd->StaCfg.LastScanTime + 10 * OS_HZ) < pAd->Mlme.Now32)
1280 {
1281 DBGPRINT(RT_DEBUG_TRACE, ("STAMlmePeriodicExec():CNTL - ScanTab.BssNr==0, start a new ACTIVE scan SSID[%s]\n", pAd->MlmeAux.AutoReconnectSsid));
1282 ScanParmFill(pAd, &ScanReq, pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen, BSS_ANY, SCAN_ACTIVE);
1283 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
1284 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
1285 // Reset Missed scan number
1286 pAd->StaCfg.LastScanTime = pAd->Mlme.Now32;
1287 }
1288 else if (pAd->StaCfg.BssType == BSS_ADHOC) // Quit the forever scan when in a very clean room
1289 MlmeAutoReconnectLastSSID(pAd);
1290 }
1291 else if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
1292 {
1293 if ((pAd->Mlme.OneSecPeriodicRound % 7) == 0)
1294 {
1295 MlmeAutoScan(pAd);
1296 pAd->StaCfg.LastScanTime = pAd->Mlme.Now32;
1297 }
1298 else
1299 {
1300 MlmeAutoReconnectLastSSID(pAd);
1301 }
1302 }
1303 }
1304 }
1305
1306SKIP_AUTO_SCAN_CONN:
1307
1308 if ((pAd->MacTab.Content[BSSID_WCID].TXBAbitmap !=0) && (pAd->MacTab.fAnyBASession == FALSE))
1309 {
1310 pAd->MacTab.fAnyBASession = TRUE;
1311 AsicUpdateProtect(pAd, HT_FORCERTSCTS, ALLN_SETPROTECT, FALSE, FALSE);
1312 }
1313 else if ((pAd->MacTab.Content[BSSID_WCID].TXBAbitmap ==0) && (pAd->MacTab.fAnyBASession == TRUE))
1314 {
1315 pAd->MacTab.fAnyBASession = FALSE;
1316 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, FALSE);
1317 }
1318
1319 return;
1320}
1321
1322// Link down report
1323VOID LinkDownExec(
1324 IN PVOID SystemSpecific1,
1325 IN PVOID FunctionContext,
1326 IN PVOID SystemSpecific2,
1327 IN PVOID SystemSpecific3)
1328{
1329
1330 RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
1331
1332 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1333 RTMP_IndicateMediaState(pAd);
1334 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1335}
1336
1337// IRQL = DISPATCH_LEVEL
1338VOID MlmeAutoScan(
1339 IN PRTMP_ADAPTER pAd)
1340{
1341 // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
1342 if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
1343 {
1344 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Driver auto scan\n"));
1345 MlmeEnqueue(pAd,
1346 MLME_CNTL_STATE_MACHINE,
1347 OID_802_11_BSSID_LIST_SCAN,
1348 0,
1349 NULL);
1350 RT28XX_MLME_HANDLER(pAd);
1351 }
1352} 889}
1353 890
1354// IRQL = DISPATCH_LEVEL
1355VOID MlmeAutoReconnectLastSSID(
1356 IN PRTMP_ADAPTER pAd)
1357{
1358
1359
1360 // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
1361 if ((pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) &&
1362 (MlmeValidateSSID(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen) == TRUE))
1363 {
1364 NDIS_802_11_SSID OidSsid;
1365 OidSsid.SsidLength = pAd->MlmeAux.AutoReconnectSsidLen;
1366 NdisMoveMemory(OidSsid.Ssid, pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
1367
1368 DBGPRINT(RT_DEBUG_TRACE, ("Driver auto reconnect to last OID_802_11_SSID setting - %s, len - %d\n", pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen));
1369 MlmeEnqueue(pAd,
1370 MLME_CNTL_STATE_MACHINE,
1371 OID_802_11_SSID,
1372 sizeof(NDIS_802_11_SSID),
1373 &OidSsid);
1374 RT28XX_MLME_HANDLER(pAd);
1375 }
1376}
1377 891
1378/* 892/*
1379 ========================================================================== 893 ==========================================================================
@@ -1394,10 +908,10 @@ BOOLEAN MlmeValidateSSID(
1394 908
1395 // Check each character value 909 // Check each character value
1396 for (index = 0; index < SsidLen; index++) 910 for (index = 0; index < SsidLen; index++)
1397 { 911 {
1398 if (pSsid[index] < 0x20) 912 if (pSsid[index] < 0x20)
1399 return (FALSE); 913 return (FALSE);
1400 } 914 }
1401 915
1402 // All checked 916 // All checked
1403 return (TRUE); 917 return (TRUE);
@@ -1414,27 +928,19 @@ VOID MlmeSelectTxRateTable(
1414 { 928 {
1415 // decide the rate table for tuning 929 // decide the rate table for tuning
1416 if (pAd->CommonCfg.TxRateTableSize > 0) 930 if (pAd->CommonCfg.TxRateTableSize > 0)
1417 { 931 {
1418 *ppTable = RateSwitchTable; 932 *ppTable = RateSwitchTable;
1419 *pTableSize = RateSwitchTable[0]; 933 *pTableSize = RateSwitchTable[0];
1420 *pInitTxRateIdx = RateSwitchTable[1]; 934 *pInitTxRateIdx = RateSwitchTable[1];
1421 935
1422 break; 936 break;
1423 } 937 }
1424 938
1425 if ((pAd->OpMode == OPMODE_STA) && ADHOC_ON(pAd)) 939 if ((pAd->OpMode == OPMODE_STA) && ADHOC_ON(pAd))
1426 { 940 {
1427 if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) && 941 if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) &&
1428#ifdef RT2860
1429 !pAd->StaCfg.AdhocBOnlyJoined &&
1430 !pAd->StaCfg.AdhocBGJoined &&
1431 (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) &&
1432 ((pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1)))
1433#endif
1434#ifdef RT2870
1435 (pEntry->HTCapability.MCSSet[0] == 0xff) && 942 (pEntry->HTCapability.MCSSet[0] == 0xff) &&
1436 ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1))) 943 ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1)))
1437#endif
1438 {// 11N 1S Adhoc 944 {// 11N 1S Adhoc
1439 *ppTable = RateSwitchTable11N1S; 945 *ppTable = RateSwitchTable11N1S;
1440 *pTableSize = RateSwitchTable11N1S[0]; 946 *pTableSize = RateSwitchTable11N1S[0];
@@ -1442,50 +948,29 @@ VOID MlmeSelectTxRateTable(
1442 948
1443 } 949 }
1444 else if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) && 950 else if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) &&
1445#ifdef RT2860
1446 !pAd->StaCfg.AdhocBOnlyJoined &&
1447 !pAd->StaCfg.AdhocBGJoined &&
1448 (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) &&
1449 (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0xff) &&
1450#endif
1451#ifdef RT2870
1452 (pEntry->HTCapability.MCSSet[0] == 0xff) && 951 (pEntry->HTCapability.MCSSet[0] == 0xff) &&
1453 (pEntry->HTCapability.MCSSet[1] == 0xff) && 952 (pEntry->HTCapability.MCSSet[1] == 0xff) &&
1454#endif
1455 (pAd->Antenna.field.TxPath == 2)) 953 (pAd->Antenna.field.TxPath == 2))
1456 {// 11N 2S Adhoc 954 {// 11N 2S Adhoc
1457 if (pAd->LatchRfRegs.Channel <= 14) 955 if (pAd->LatchRfRegs.Channel <= 14)
1458 { 956 {
1459 *ppTable = RateSwitchTable11N2S; 957 *ppTable = RateSwitchTable11N2S;
1460 *pTableSize = RateSwitchTable11N2S[0]; 958 *pTableSize = RateSwitchTable11N2S[0];
1461 *pInitTxRateIdx = RateSwitchTable11N2S[1]; 959 *pInitTxRateIdx = RateSwitchTable11N2S[1];
1462 } 960 }
1463 else 961 else
1464 { 962 {
1465 *ppTable = RateSwitchTable11N2SForABand; 963 *ppTable = RateSwitchTable11N2SForABand;
1466 *pTableSize = RateSwitchTable11N2SForABand[0]; 964 *pTableSize = RateSwitchTable11N2SForABand[0];
1467 *pInitTxRateIdx = RateSwitchTable11N2SForABand[1]; 965 *pInitTxRateIdx = RateSwitchTable11N2SForABand[1];
1468 } 966 }
1469 967
1470 } 968 }
1471 else 969 else
1472#ifdef RT2860
1473 if (pAd->CommonCfg.PhyMode == PHY_11B)
1474 {
1475 *ppTable = RateSwitchTable11B;
1476 *pTableSize = RateSwitchTable11B[0];
1477 *pInitTxRateIdx = RateSwitchTable11B[1];
1478
1479 }
1480 else if((pAd->LatchRfRegs.Channel <= 14) && (pAd->StaCfg.AdhocBOnlyJoined == TRUE))
1481#endif
1482#ifdef RT2870
1483 if ((pEntry->RateLen == 4) 970 if ((pEntry->RateLen == 4)
1484 && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0) 971 && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)
1485 ) 972 )
1486#endif
1487 { 973 {
1488 // USe B Table when Only b-only Station in my IBSS .
1489 *ppTable = RateSwitchTable11B; 974 *ppTable = RateSwitchTable11B;
1490 *pTableSize = RateSwitchTable11B[0]; 975 *pTableSize = RateSwitchTable11B[0];
1491 *pInitTxRateIdx = RateSwitchTable11B[1]; 976 *pInitTxRateIdx = RateSwitchTable11B[1];
@@ -1508,7 +993,9 @@ VOID MlmeSelectTxRateTable(
1508 break; 993 break;
1509 } 994 }
1510 995
1511 if ((pEntry->RateLen == 12) && (pEntry->HTCapability.MCSSet[0] == 0xff) && 996 //if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 12) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) &&
997 // ((pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1)))
998 if (((pEntry->RateLen == 12) || (pAd->OpMode == OPMODE_STA)) && (pEntry->HTCapability.MCSSet[0] == 0xff) &&
1512 ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->CommonCfg.TxStream == 1))) 999 ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->CommonCfg.TxStream == 1)))
1513 {// 11BGN 1S AP 1000 {// 11BGN 1S AP
1514 *ppTable = RateSwitchTable11BGN1S; 1001 *ppTable = RateSwitchTable11BGN1S;
@@ -1516,13 +1003,15 @@ VOID MlmeSelectTxRateTable(
1516 *pInitTxRateIdx = RateSwitchTable11BGN1S[1]; 1003 *pInitTxRateIdx = RateSwitchTable11BGN1S[1];
1517 1004
1518 break; 1005 break;
1519 } 1006 }
1520 1007
1521 if ((pEntry->RateLen == 12) && (pEntry->HTCapability.MCSSet[0] == 0xff) && 1008 //else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 12) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) &&
1009 // (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0xff) && (pAd->Antenna.field.TxPath == 2))
1010 if (((pEntry->RateLen == 12) || (pAd->OpMode == OPMODE_STA)) && (pEntry->HTCapability.MCSSet[0] == 0xff) &&
1522 (pEntry->HTCapability.MCSSet[1] == 0xff) && (pAd->CommonCfg.TxStream == 2)) 1011 (pEntry->HTCapability.MCSSet[1] == 0xff) && (pAd->CommonCfg.TxStream == 2))
1523 {// 11BGN 2S AP 1012 {// 11BGN 2S AP
1524 if (pAd->LatchRfRegs.Channel <= 14) 1013 if (pAd->LatchRfRegs.Channel <= 14)
1525 { 1014 {
1526 *ppTable = RateSwitchTable11BGN2S; 1015 *ppTable = RateSwitchTable11BGN2S;
1527 *pTableSize = RateSwitchTable11BGN2S[0]; 1016 *pTableSize = RateSwitchTable11BGN2S[0];
1528 *pInitTxRateIdx = RateSwitchTable11BGN2S[1]; 1017 *pInitTxRateIdx = RateSwitchTable11BGN2S[1];
@@ -1538,6 +1027,7 @@ VOID MlmeSelectTxRateTable(
1538 break; 1027 break;
1539 } 1028 }
1540 1029
1030 //else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) && ((pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1)))
1541 if ((pEntry->HTCapability.MCSSet[0] == 0xff) && ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->CommonCfg.TxStream == 1))) 1031 if ((pEntry->HTCapability.MCSSet[0] == 0xff) && ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->CommonCfg.TxStream == 1)))
1542 {// 11N 1S AP 1032 {// 11N 1S AP
1543 *ppTable = RateSwitchTable11N1S; 1033 *ppTable = RateSwitchTable11N1S;
@@ -1547,6 +1037,7 @@ VOID MlmeSelectTxRateTable(
1547 break; 1037 break;
1548 } 1038 }
1549 1039
1040 //else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0xff) && (pAd->Antenna.field.TxPath == 2))
1550 if ((pEntry->HTCapability.MCSSet[0] == 0xff) && (pEntry->HTCapability.MCSSet[1] == 0xff) && (pAd->CommonCfg.TxStream == 2)) 1041 if ((pEntry->HTCapability.MCSSet[0] == 0xff) && (pEntry->HTCapability.MCSSet[1] == 0xff) && (pAd->CommonCfg.TxStream == 2))
1551 {// 11N 2S AP 1042 {// 11N 2S AP
1552 if (pAd->LatchRfRegs.Channel <= 14) 1043 if (pAd->LatchRfRegs.Channel <= 14)
@@ -1554,7 +1045,7 @@ VOID MlmeSelectTxRateTable(
1554 *ppTable = RateSwitchTable11N2S; 1045 *ppTable = RateSwitchTable11N2S;
1555 *pTableSize = RateSwitchTable11N2S[0]; 1046 *pTableSize = RateSwitchTable11N2S[0];
1556 *pInitTxRateIdx = RateSwitchTable11N2S[1]; 1047 *pInitTxRateIdx = RateSwitchTable11N2S[1];
1557 } 1048 }
1558 else 1049 else
1559 { 1050 {
1560 *ppTable = RateSwitchTable11N2SForABand; 1051 *ppTable = RateSwitchTable11N2SForABand;
@@ -1564,9 +1055,11 @@ VOID MlmeSelectTxRateTable(
1564 1055
1565 break; 1056 break;
1566 } 1057 }
1567
1568 //else if ((pAd->StaActive.SupRateLen == 4) && (pAd->StaActive.ExtRateLen == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0)) 1058 //else if ((pAd->StaActive.SupRateLen == 4) && (pAd->StaActive.ExtRateLen == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
1569 if (pEntry->RateLen == 4) 1059 if ((pEntry->RateLen == 4 || pAd->CommonCfg.PhyMode==PHY_11B)
1060 //Iverson mark for Adhoc b mode,sta will use rate 54 Mbps when connect with sta b/g/n mode
1061 /* && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)*/
1062 )
1570 {// B only AP 1063 {// B only AP
1571 *ppTable = RateSwitchTable11B; 1064 *ppTable = RateSwitchTable11B;
1572 *pTableSize = RateSwitchTable11B[0]; 1065 *pTableSize = RateSwitchTable11B[0];
@@ -1624,7 +1117,6 @@ VOID MlmeSelectTxRateTable(
1624 } 1117 }
1625 break; 1118 break;
1626 } 1119 }
1627
1628 if (pAd->LatchRfRegs.Channel <= 14) 1120 if (pAd->LatchRfRegs.Channel <= 14)
1629 { 1121 {
1630 if (pAd->CommonCfg.TxStream == 1) 1122 if (pAd->CommonCfg.TxStream == 1)
@@ -1659,13 +1151,363 @@ VOID MlmeSelectTxRateTable(
1659 DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 2S AP \n")); 1151 DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 2S AP \n"));
1660 } 1152 }
1661 } 1153 }
1662
1663 DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode (SupRateLen=%d, ExtRateLen=%d, MCSSet[0]=0x%x, MCSSet[1]=0x%x)\n", 1154 DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode (SupRateLen=%d, ExtRateLen=%d, MCSSet[0]=0x%x, MCSSet[1]=0x%x)\n",
1664 pAd->StaActive.SupRateLen, pAd->StaActive.ExtRateLen, pAd->StaActive.SupportedPhyInfo.MCSSet[0], pAd->StaActive.SupportedPhyInfo.MCSSet[1])); 1155 pAd->StaActive.SupRateLen, pAd->StaActive.ExtRateLen, pAd->StaActive.SupportedPhyInfo.MCSSet[0], pAd->StaActive.SupportedPhyInfo.MCSSet[1]));
1665 } 1156 }
1666 } while(FALSE); 1157 } while(FALSE);
1667} 1158}
1668 1159
1160
1161VOID STAMlmePeriodicExec(
1162 PRTMP_ADAPTER pAd)
1163{
1164 ULONG TxTotalCnt;
1165 int i;
1166
1167 /*
1168 We return here in ATE mode, because the statistics
1169 that ATE need are not collected via this routine.
1170 */
1171#if defined(RT305x)||defined(RT3070)
1172 // 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
1173 if (!pAd->CommonCfg.HighPowerPatchDisabled)
1174 {
1175#ifdef RT3070
1176 if ( (IS_RT3070(pAd) && ((pAd->MACVersion & 0xffff) < 0x0201)))
1177#endif // RT3070 //
1178 {
1179 if ((pAd->StaCfg.RssiSample.AvgRssi0 != 0) && (pAd->StaCfg.RssiSample.AvgRssi0 > (pAd->BbpRssiToDbmDelta - 35)))
1180 {
1181 RT30xxWriteRFRegister(pAd, RF_R27, 0x20);
1182 }
1183 else
1184 {
1185 RT30xxWriteRFRegister(pAd, RF_R27, 0x23);
1186 }
1187 }
1188 }
1189#endif
1190
1191 if (pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE)
1192 {
1193 // WPA MIC error should block association attempt for 60 seconds
1194 if (pAd->StaCfg.bBlockAssoc &&
1195 RTMP_TIME_AFTER(pAd->Mlme.Now32, pAd->StaCfg.LastMicErrorTime + (60*OS_HZ)))
1196 pAd->StaCfg.bBlockAssoc = FALSE;
1197 }
1198
1199 if ((pAd->PreMediaState != pAd->IndicateMediaState) && (pAd->CommonCfg.bWirelessEvent))
1200 {
1201 if (pAd->IndicateMediaState == NdisMediaStateConnected)
1202 {
1203 RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1204 }
1205 pAd->PreMediaState = pAd->IndicateMediaState;
1206 }
1207
1208
1209
1210
1211 if (pAd->CommonCfg.PSPXlink && ADHOC_ON(pAd))
1212 {
1213 }
1214 else
1215 {
1216 AsicStaBbpTuning(pAd);
1217 }
1218
1219 TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
1220 pAd->RalinkCounters.OneSecTxRetryOkCount +
1221 pAd->RalinkCounters.OneSecTxFailCount;
1222
1223 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1224 {
1225 // update channel quality for Roaming and UI LinkQuality display
1226 MlmeCalculateChannelQuality(pAd, NULL, pAd->Mlme.Now32);
1227 }
1228
1229 // must be AFTER MlmeDynamicTxRateSwitching() because it needs to know if
1230 // Radio is currently in noisy environment
1231 if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
1232 AsicAdjustTxPower(pAd);
1233
1234 if (INFRA_ON(pAd))
1235 {
1236
1237 // Is PSM bit consistent with user power management policy?
1238 // This is the only place that will set PSM bit ON.
1239 if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
1240 MlmeCheckPsmChange(pAd, pAd->Mlme.Now32);
1241
1242 pAd->RalinkCounters.LastOneSecTotalTxCount = TxTotalCnt;
1243
1244 if ((RTMP_TIME_AFTER(pAd->Mlme.Now32, pAd->StaCfg.LastBeaconRxTime + (1*OS_HZ))) &&
1245 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) &&
1246 (((TxTotalCnt + pAd->RalinkCounters.OneSecRxOkCnt) < 600)))
1247 {
1248 RTMPSetAGCInitValue(pAd, BW_20);
1249 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - No BEACON. restore R66 to the low bound(%d) \n", (0x2E + GET_LNA_GAIN(pAd))));
1250 }
1251
1252 //if ((pAd->RalinkCounters.OneSecTxNoRetryOkCount == 0) &&
1253 // (pAd->RalinkCounters.OneSecTxRetryOkCount == 0))
1254 {
1255 if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable)
1256 {
1257 // When APSD is enabled, the period changes as 20 sec
1258 if ((pAd->Mlme.OneSecPeriodicRound % 20) == 8)
1259 RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
1260 }
1261 else
1262 {
1263 // Send out a NULL frame every 10 sec to inform AP that STA is still alive (Avoid being age out)
1264 if ((pAd->Mlme.OneSecPeriodicRound % 10) == 8)
1265 {
1266 if (pAd->CommonCfg.bWmmCapable)
1267 RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
1268 else
1269 RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, FALSE);
1270 }
1271 }
1272 }
1273
1274 if (CQI_IS_DEAD(pAd->Mlme.ChannelQuality))
1275 {
1276 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - No BEACON. Dead CQI. Auto Recovery attempt #%ld\n", pAd->RalinkCounters.BadCQIAutoRecoveryCount));
1277
1278 if ((pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE) &&
1279 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2))
1280 pAd->StaCfg.bLostAp = TRUE;
1281
1282 // Lost AP, send disconnect & link down event
1283 LinkDown(pAd, FALSE);
1284
1285
1286 RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1, NULL, NULL, 0);
1287
1288 // RTMPPatchMacBbpBug(pAd);
1289 MlmeAutoReconnectLastSSID(pAd);
1290 }
1291 else if (CQI_IS_BAD(pAd->Mlme.ChannelQuality))
1292 {
1293 pAd->RalinkCounters.BadCQIAutoRecoveryCount ++;
1294 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Bad CQI. Auto Recovery attempt #%ld\n", pAd->RalinkCounters.BadCQIAutoRecoveryCount));
1295 MlmeAutoReconnectLastSSID(pAd);
1296 }
1297
1298 if (pAd->StaCfg.bAutoRoaming)
1299 {
1300 BOOLEAN rv = FALSE;
1301 CHAR dBmToRoam = pAd->StaCfg.dBmToRoam;
1302 CHAR MaxRssi = RTMPMaxRssi(pAd,
1303 pAd->StaCfg.RssiSample.LastRssi0,
1304 pAd->StaCfg.RssiSample.LastRssi1,
1305 pAd->StaCfg.RssiSample.LastRssi2);
1306
1307 // Scanning, ignore Roaming
1308 if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS) &&
1309 (pAd->Mlme.SyncMachine.CurrState == SYNC_IDLE) &&
1310 (MaxRssi <= dBmToRoam))
1311 {
1312 DBGPRINT(RT_DEBUG_TRACE, ("Rssi=%d, dBmToRoam=%d\n", MaxRssi, (CHAR)dBmToRoam));
1313
1314
1315 // Add auto seamless roaming
1316 if (rv == FALSE)
1317 rv = MlmeCheckForFastRoaming(pAd);
1318
1319 if (rv == FALSE)
1320 {
1321 if ((pAd->StaCfg.LastScanTime + 10 * OS_HZ) < pAd->Mlme.Now32)
1322 {
1323 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming, No eligable entry, try new scan!\n"));
1324 pAd->StaCfg.ScanCnt = 2;
1325 pAd->StaCfg.LastScanTime = pAd->Mlme.Now32;
1326 MlmeAutoScan(pAd);
1327 }
1328 }
1329 }
1330 }
1331 }
1332 else if (ADHOC_ON(pAd))
1333 {
1334 // If all peers leave, and this STA becomes the last one in this IBSS, then change MediaState
1335 // to DISCONNECTED. But still holding this IBSS (i.e. sending BEACON) so that other STAs can
1336 // join later.
1337 if (RTMP_TIME_AFTER(pAd->Mlme.Now32, pAd->StaCfg.LastBeaconRxTime + ADHOC_BEACON_LOST_TIME) &&
1338 OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1339 {
1340 MLME_START_REQ_STRUCT StartReq;
1341
1342 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - excessive BEACON lost, last STA in this IBSS, MediaState=Disconnected\n"));
1343 LinkDown(pAd, FALSE);
1344
1345 StartParmFill(pAd, &StartReq, (CHAR *)pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
1346 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
1347 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
1348 }
1349
1350 for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++)
1351 {
1352 MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[i];
1353
1354 if (pEntry->ValidAsCLI == FALSE)
1355 continue;
1356
1357 if (RTMP_TIME_AFTER(pAd->Mlme.Now32, pEntry->LastBeaconRxTime + ADHOC_BEACON_LOST_TIME))
1358 MacTableDeleteEntry(pAd, pEntry->Aid, pEntry->Addr);
1359 }
1360 }
1361 else // no INFRA nor ADHOC connection
1362 {
1363
1364 if (pAd->StaCfg.bScanReqIsFromWebUI &&
1365 RTMP_TIME_BEFORE(pAd->Mlme.Now32, pAd->StaCfg.LastScanTime + (30 * OS_HZ)))
1366 goto SKIP_AUTO_SCAN_CONN;
1367 else
1368 pAd->StaCfg.bScanReqIsFromWebUI = FALSE;
1369
1370 if ((pAd->StaCfg.bAutoReconnect == TRUE)
1371 && RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP)
1372 && (MlmeValidateSSID(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen) == TRUE))
1373 {
1374 if ((pAd->ScanTab.BssNr==0) && (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE))
1375 {
1376 MLME_SCAN_REQ_STRUCT ScanReq;
1377
1378 if (RTMP_TIME_AFTER(pAd->Mlme.Now32, pAd->StaCfg.LastScanTime + (10 * OS_HZ)))
1379 {
1380 DBGPRINT(RT_DEBUG_TRACE, ("STAMlmePeriodicExec():CNTL - ScanTab.BssNr==0, start a new ACTIVE scan SSID[%s]\n", pAd->MlmeAux.AutoReconnectSsid));
1381 ScanParmFill(pAd, &ScanReq, (PSTRING) pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen, BSS_ANY, SCAN_ACTIVE);
1382 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
1383 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
1384 // Reset Missed scan number
1385 pAd->StaCfg.LastScanTime = pAd->Mlme.Now32;
1386 }
1387 else if (pAd->StaCfg.BssType == BSS_ADHOC) // Quit the forever scan when in a very clean room
1388 MlmeAutoReconnectLastSSID(pAd);
1389 }
1390 else if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
1391 {
1392 if ((pAd->Mlme.OneSecPeriodicRound % 7) == 0)
1393 {
1394 MlmeAutoScan(pAd);
1395 pAd->StaCfg.LastScanTime = pAd->Mlme.Now32;
1396 }
1397 else
1398 {
1399 MlmeAutoReconnectLastSSID(pAd);
1400 }
1401 }
1402 }
1403 }
1404
1405SKIP_AUTO_SCAN_CONN:
1406
1407 if ((pAd->MacTab.Content[BSSID_WCID].TXBAbitmap !=0) && (pAd->MacTab.fAnyBASession == FALSE))
1408 {
1409 pAd->MacTab.fAnyBASession = TRUE;
1410 AsicUpdateProtect(pAd, HT_FORCERTSCTS, ALLN_SETPROTECT, FALSE, FALSE);
1411 }
1412 else if ((pAd->MacTab.Content[BSSID_WCID].TXBAbitmap ==0) && (pAd->MacTab.fAnyBASession == TRUE))
1413 {
1414 pAd->MacTab.fAnyBASession = FALSE;
1415 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, FALSE);
1416 }
1417
1418 return;
1419}
1420
1421// Link down report
1422VOID LinkDownExec(
1423 IN PVOID SystemSpecific1,
1424 IN PVOID FunctionContext,
1425 IN PVOID SystemSpecific2,
1426 IN PVOID SystemSpecific3)
1427{
1428 RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
1429
1430 if (pAd != NULL)
1431 {
1432 MLME_DISASSOC_REQ_STRUCT DisassocReq;
1433
1434 if ((pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED) &&
1435 (INFRA_ON(pAd)))
1436 {
1437 DBGPRINT(RT_DEBUG_TRACE, ("LinkDownExec(): disassociate with current AP...\n"));
1438 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
1439 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
1440 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
1441 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
1442
1443 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1444 RTMP_IndicateMediaState(pAd);
1445 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1446 }
1447 }
1448}
1449
1450// IRQL = DISPATCH_LEVEL
1451VOID MlmeAutoScan(
1452 IN PRTMP_ADAPTER pAd)
1453{
1454 // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
1455 if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
1456 {
1457 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Driver auto scan\n"));
1458 MlmeEnqueue(pAd,
1459 MLME_CNTL_STATE_MACHINE,
1460 OID_802_11_BSSID_LIST_SCAN,
1461 pAd->MlmeAux.AutoReconnectSsidLen,
1462 pAd->MlmeAux.AutoReconnectSsid);
1463 RTMP_MLME_HANDLER(pAd);
1464 }
1465}
1466
1467// IRQL = DISPATCH_LEVEL
1468VOID MlmeAutoReconnectLastSSID(
1469 IN PRTMP_ADAPTER pAd)
1470{
1471 if (pAd->StaCfg.bAutoConnectByBssid)
1472 {
1473 DBGPRINT(RT_DEBUG_TRACE, ("Driver auto reconnect to last OID_802_11_BSSID setting - %02X:%02X:%02X:%02X:%02X:%02X\n",
1474 pAd->MlmeAux.Bssid[0],
1475 pAd->MlmeAux.Bssid[1],
1476 pAd->MlmeAux.Bssid[2],
1477 pAd->MlmeAux.Bssid[3],
1478 pAd->MlmeAux.Bssid[4],
1479 pAd->MlmeAux.Bssid[5]));
1480
1481 pAd->MlmeAux.Channel = pAd->CommonCfg.Channel;
1482 MlmeEnqueue(pAd,
1483 MLME_CNTL_STATE_MACHINE,
1484 OID_802_11_BSSID,
1485 MAC_ADDR_LEN,
1486 pAd->MlmeAux.Bssid);
1487
1488 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1489
1490 RTMP_MLME_HANDLER(pAd);
1491 }
1492 // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
1493 else if ((pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) &&
1494 (MlmeValidateSSID(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen) == TRUE))
1495 {
1496 NDIS_802_11_SSID OidSsid;
1497 OidSsid.SsidLength = pAd->MlmeAux.AutoReconnectSsidLen;
1498 NdisMoveMemory(OidSsid.Ssid, pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
1499
1500 DBGPRINT(RT_DEBUG_TRACE, ("Driver auto reconnect to last OID_802_11_SSID setting - %s, len - %d\n", pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen));
1501 MlmeEnqueue(pAd,
1502 MLME_CNTL_STATE_MACHINE,
1503 OID_802_11_SSID,
1504 sizeof(NDIS_802_11_SSID),
1505 &OidSsid);
1506 RTMP_MLME_HANDLER(pAd);
1507 }
1508}
1509
1510
1669/* 1511/*
1670 ========================================================================== 1512 ==========================================================================
1671 Description: 1513 Description:
@@ -1693,7 +1535,7 @@ VOID MlmeCheckForRoaming(
1693 { 1535 {
1694 pBss = &pAd->ScanTab.BssEntry[i]; 1536 pBss = &pAd->ScanTab.BssEntry[i];
1695 1537
1696 if ((pBss->LastBeaconRxTime + BEACON_LOST_TIME) < Now32) 1538 if ((pBss->LastBeaconRxTime + pAd->StaCfg.BeaconLostTime) < Now32)
1697 continue; // AP disappear 1539 continue; // AP disappear
1698 if (pBss->Rssi <= RSSI_THRESHOLD_FOR_ROAMING) 1540 if (pBss->Rssi <= RSSI_THRESHOLD_FOR_ROAMING)
1699 continue; // RSSI too weak. forget it. 1541 continue; // RSSI too weak. forget it.
@@ -1715,7 +1557,7 @@ VOID MlmeCheckForRoaming(
1715 pAd->RalinkCounters.PoorCQIRoamingCount ++; 1557 pAd->RalinkCounters.PoorCQIRoamingCount ++;
1716 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming attempt #%ld\n", pAd->RalinkCounters.PoorCQIRoamingCount)); 1558 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming attempt #%ld\n", pAd->RalinkCounters.PoorCQIRoamingCount));
1717 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_MLME_ROAMING_REQ, 0, NULL); 1559 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_MLME_ROAMING_REQ, 0, NULL);
1718 RT28XX_MLME_HANDLER(pAd); 1560 RTMP_MLME_HANDLER(pAd);
1719 } 1561 }
1720 } 1562 }
1721 DBGPRINT(RT_DEBUG_TRACE, ("<== MlmeCheckForRoaming(# of candidate= %d)\n",pRoamTab->BssNr)); 1563 DBGPRINT(RT_DEBUG_TRACE, ("<== MlmeCheckForRoaming(# of candidate= %d)\n",pRoamTab->BssNr));
@@ -1733,9 +1575,8 @@ VOID MlmeCheckForRoaming(
1733 Output: 1575 Output:
1734 ========================================================================== 1576 ==========================================================================
1735 */ 1577 */
1736VOID MlmeCheckForFastRoaming( 1578BOOLEAN MlmeCheckForFastRoaming(
1737 IN PRTMP_ADAPTER pAd, 1579 IN PRTMP_ADAPTER pAd)
1738 IN ULONG Now)
1739{ 1580{
1740 USHORT i; 1581 USHORT i;
1741 BSS_TABLE *pRoamTab = &pAd->MlmeAux.RoamTab; 1582 BSS_TABLE *pRoamTab = &pAd->MlmeAux.RoamTab;
@@ -1745,7 +1586,7 @@ VOID MlmeCheckForFastRoaming(
1745 // put all roaming candidates into RoamTab, and sort in RSSI order 1586 // put all roaming candidates into RoamTab, and sort in RSSI order
1746 BssTableInit(pRoamTab); 1587 BssTableInit(pRoamTab);
1747 for (i = 0; i < pAd->ScanTab.BssNr; i++) 1588 for (i = 0; i < pAd->ScanTab.BssNr; i++)
1748 { 1589 {
1749 pBss = &pAd->ScanTab.BssEntry[i]; 1590 pBss = &pAd->ScanTab.BssEntry[i];
1750 1591
1751 if ((pBss->Rssi <= -50) && (pBss->Channel == pAd->CommonCfg.Channel)) 1592 if ((pBss->Rssi <= -50) && (pBss->Channel == pAd->CommonCfg.Channel))
@@ -1761,119 +1602,23 @@ VOID MlmeCheckForFastRoaming(
1761 // AP passing all above rules is put into roaming candidate table 1602 // AP passing all above rules is put into roaming candidate table
1762 NdisMoveMemory(&pRoamTab->BssEntry[pRoamTab->BssNr], pBss, sizeof(BSS_ENTRY)); 1603 NdisMoveMemory(&pRoamTab->BssEntry[pRoamTab->BssNr], pBss, sizeof(BSS_ENTRY));
1763 pRoamTab->BssNr += 1; 1604 pRoamTab->BssNr += 1;
1764 } 1605 }
1765 1606
1607 DBGPRINT(RT_DEBUG_TRACE, ("<== MlmeCheckForFastRoaming (BssNr=%d)\n", pRoamTab->BssNr));
1766 if (pRoamTab->BssNr > 0) 1608 if (pRoamTab->BssNr > 0)
1767 { 1609 {
1768 // check CntlMachine.CurrState to avoid collision with NDIS SetOID request 1610 // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
1769 if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) 1611 if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
1770 { 1612 {
1771 pAd->RalinkCounters.PoorCQIRoamingCount ++; 1613 pAd->RalinkCounters.PoorCQIRoamingCount ++;
1772 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming attempt #%ld\n", pAd->RalinkCounters.PoorCQIRoamingCount)); 1614 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming attempt #%ld\n", pAd->RalinkCounters.PoorCQIRoamingCount));
1773 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_MLME_ROAMING_REQ, 0, NULL); 1615 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_MLME_ROAMING_REQ, 0, NULL);
1774 RT28XX_MLME_HANDLER(pAd); 1616 RTMP_MLME_HANDLER(pAd);
1775 } 1617 return TRUE;
1776 } 1618 }
1777 // Maybe site survey required 1619 }
1778 else
1779 {
1780 if ((pAd->StaCfg.LastScanTime + 10 * 1000) < Now)
1781 {
1782 // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
1783 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming, No eligable entry, try new scan!\n"));
1784 pAd->StaCfg.ScanCnt = 2;
1785 pAd->StaCfg.LastScanTime = Now;
1786 MlmeAutoScan(pAd);
1787 }
1788 }
1789
1790 DBGPRINT(RT_DEBUG_TRACE, ("<== MlmeCheckForFastRoaming (BssNr=%d)\n", pRoamTab->BssNr));
1791}
1792
1793/*
1794 ==========================================================================
1795 Description:
1796 This routine calculates TxPER, RxPER of the past N-sec period. And
1797 according to the calculation result, ChannelQuality is calculated here
1798 to decide if current AP is still doing the job.
1799
1800 If ChannelQuality is not good, a ROAMing attempt may be tried later.
1801 Output:
1802 StaCfg.ChannelQuality - 0..100
1803
1804 IRQL = DISPATCH_LEVEL
1805
1806 NOTE: This routine decide channle quality based on RX CRC error ratio.
1807 Caller should make sure a function call to NICUpdateRawCounters(pAd)
1808 is performed right before this routine, so that this routine can decide
1809 channel quality based on the most up-to-date information
1810 ==========================================================================
1811 */
1812VOID MlmeCalculateChannelQuality(
1813 IN PRTMP_ADAPTER pAd,
1814 IN ULONG Now32)
1815{
1816 ULONG TxOkCnt, TxCnt, TxPER, TxPRR;
1817 ULONG RxCnt, RxPER;
1818 UCHAR NorRssi;
1819 CHAR MaxRssi;
1820 ULONG BeaconLostTime = BEACON_LOST_TIME;
1821
1822 MaxRssi = RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2);
1823
1824 //
1825 // calculate TX packet error ratio and TX retry ratio - if too few TX samples, skip TX related statistics
1826 //
1827 TxOkCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount + pAd->RalinkCounters.OneSecTxRetryOkCount;
1828 TxCnt = TxOkCnt + pAd->RalinkCounters.OneSecTxFailCount;
1829 if (TxCnt < 5)
1830 {
1831 TxPER = 0;
1832 TxPRR = 0;
1833 }
1834 else
1835 {
1836 TxPER = (pAd->RalinkCounters.OneSecTxFailCount * 100) / TxCnt;
1837 TxPRR = ((TxCnt - pAd->RalinkCounters.OneSecTxNoRetryOkCount) * 100) / TxCnt;
1838 }
1839
1840 //
1841 // calculate RX PER - don't take RxPER into consideration if too few sample
1842 //
1843 RxCnt = pAd->RalinkCounters.OneSecRxOkCnt + pAd->RalinkCounters.OneSecRxFcsErrCnt;
1844 if (RxCnt < 5)
1845 RxPER = 0;
1846 else
1847 RxPER = (pAd->RalinkCounters.OneSecRxFcsErrCnt * 100) / RxCnt;
1848
1849 //
1850 // decide ChannelQuality based on: 1)last BEACON received time, 2)last RSSI, 3)TxPER, and 4)RxPER
1851 //
1852 if (INFRA_ON(pAd) &&
1853 (pAd->RalinkCounters.OneSecTxNoRetryOkCount < 2) && // no heavy traffic
1854 (pAd->StaCfg.LastBeaconRxTime + BeaconLostTime < Now32))
1855 {
1856 DBGPRINT(RT_DEBUG_TRACE, ("BEACON lost > %ld msec with TxOkCnt=%ld -> CQI=0\n", BeaconLostTime, TxOkCnt));
1857 pAd->Mlme.ChannelQuality = 0;
1858 }
1859 else
1860 {
1861 // Normalize Rssi
1862 if (MaxRssi > -40)
1863 NorRssi = 100;
1864 else if (MaxRssi < -90)
1865 NorRssi = 0;
1866 else
1867 NorRssi = (MaxRssi + 90) * 2;
1868
1869 // ChannelQuality = W1*RSSI + W2*TxPRR + W3*RxPER (RSSI 0..100), (TxPER 100..0), (RxPER 100..0)
1870 pAd->Mlme.ChannelQuality = (RSSI_WEIGHTING * NorRssi +
1871 TX_WEIGHTING * (100 - TxPRR) +
1872 RX_WEIGHTING* (100 - RxPER)) / 100;
1873 if (pAd->Mlme.ChannelQuality >= 100)
1874 pAd->Mlme.ChannelQuality = 100;
1875 }
1876 1620
1621 return FALSE;
1877} 1622}
1878 1623
1879VOID MlmeSetTxRate( 1624VOID MlmeSetTxRate(
@@ -1887,7 +1632,7 @@ VOID MlmeSetTxRate(
1887 1632
1888 if (pTxRate->STBC && (pAd->StaCfg.MaxHTPhyMode.field.STBC) && (pAd->Antenna.field.TxPath == 2)) 1633 if (pTxRate->STBC && (pAd->StaCfg.MaxHTPhyMode.field.STBC) && (pAd->Antenna.field.TxPath == 2))
1889 pAd->StaCfg.HTPhyMode.field.STBC = STBC_USE; 1634 pAd->StaCfg.HTPhyMode.field.STBC = STBC_USE;
1890 else 1635 else
1891 pAd->StaCfg.HTPhyMode.field.STBC = STBC_NONE; 1636 pAd->StaCfg.HTPhyMode.field.STBC = STBC_NONE;
1892 1637
1893 if (pTxRate->CurrMCS < MCS_AUTO) 1638 if (pTxRate->CurrMCS < MCS_AUTO)
@@ -1896,8 +1641,8 @@ VOID MlmeSetTxRate(
1896 if (pAd->StaCfg.HTPhyMode.field.MCS > 7) 1641 if (pAd->StaCfg.HTPhyMode.field.MCS > 7)
1897 pAd->StaCfg.HTPhyMode.field.STBC = STBC_NONE; 1642 pAd->StaCfg.HTPhyMode.field.STBC = STBC_NONE;
1898 1643
1899 if (ADHOC_ON(pAd)) 1644 if (ADHOC_ON(pAd))
1900 { 1645 {
1901 // If peer adhoc is b-only mode, we can't send 11g rate. 1646 // If peer adhoc is b-only mode, we can't send 11g rate.
1902 pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800; 1647 pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
1903 pEntry->HTPhyMode.field.STBC = STBC_NONE; 1648 pEntry->HTPhyMode.field.STBC = STBC_NONE;
@@ -1911,13 +1656,13 @@ VOID MlmeSetTxRate(
1911 1656
1912 // Patch speed error in status page 1657 // Patch speed error in status page
1913 pAd->StaCfg.HTPhyMode.field.MODE = pEntry->HTPhyMode.field.MODE; 1658 pAd->StaCfg.HTPhyMode.field.MODE = pEntry->HTPhyMode.field.MODE;
1914 } 1659 }
1915 else 1660 else
1916 { 1661 {
1917 if (pTxRate->Mode <= MaxMode) 1662 if (pTxRate->Mode <= MaxMode)
1918 pAd->StaCfg.HTPhyMode.field.MODE = pTxRate->Mode; 1663 pAd->StaCfg.HTPhyMode.field.MODE = pTxRate->Mode;
1919 1664
1920 if (pTxRate->ShortGI && (pAd->StaCfg.MaxHTPhyMode.field.ShortGI)) 1665 if (pTxRate->ShortGI && (pAd->StaCfg.MaxHTPhyMode.field.ShortGI))
1921 pAd->StaCfg.HTPhyMode.field.ShortGI = GI_400; 1666 pAd->StaCfg.HTPhyMode.field.ShortGI = GI_400;
1922 else 1667 else
1923 pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800; 1668 pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
@@ -1931,52 +1676,51 @@ VOID MlmeSetTxRate(
1931 pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800; 1676 pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
1932 } 1677 }
1933 1678
1934 // Turn RTS/CTS rate to 6Mbps. 1679 // Turn RTS/CTS rate to 6Mbps.
1935 if ((pEntry->HTPhyMode.field.MCS == 0) && (pAd->StaCfg.HTPhyMode.field.MCS != 0)) 1680 if ((pEntry->HTPhyMode.field.MCS == 0) && (pAd->StaCfg.HTPhyMode.field.MCS != 0))
1936 { 1681 {
1937 pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS; 1682 pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
1938 if (pAd->MacTab.fAnyBASession) 1683 if (pAd->MacTab.fAnyBASession)
1939 { 1684 {
1940 AsicUpdateProtect(pAd, HT_FORCERTSCTS, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent); 1685 AsicUpdateProtect(pAd, HT_FORCERTSCTS, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
1941 } 1686 }
1942 else 1687 else
1943 { 1688 {
1944 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent); 1689 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
1690 }
1945 } 1691 }
1946 }
1947 else if ((pEntry->HTPhyMode.field.MCS == 8) && (pAd->StaCfg.HTPhyMode.field.MCS != 8)) 1692 else if ((pEntry->HTPhyMode.field.MCS == 8) && (pAd->StaCfg.HTPhyMode.field.MCS != 8))
1948 { 1693 {
1949 pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS; 1694 pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
1950 if (pAd->MacTab.fAnyBASession) 1695 if (pAd->MacTab.fAnyBASession)
1951 { 1696 {
1952 AsicUpdateProtect(pAd, HT_FORCERTSCTS, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent); 1697 AsicUpdateProtect(pAd, HT_FORCERTSCTS, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
1953 } 1698 }
1954 else 1699 else
1955 { 1700 {
1956 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent); 1701 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
1702 }
1957 } 1703 }
1958 }
1959 else if ((pEntry->HTPhyMode.field.MCS != 0) && (pAd->StaCfg.HTPhyMode.field.MCS == 0)) 1704 else if ((pEntry->HTPhyMode.field.MCS != 0) && (pAd->StaCfg.HTPhyMode.field.MCS == 0))
1960 { 1705 {
1961 AsicUpdateProtect(pAd, HT_RTSCTS_6M, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent); 1706 AsicUpdateProtect(pAd, HT_RTSCTS_6M, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
1962 1707
1963 } 1708 }
1964 else if ((pEntry->HTPhyMode.field.MCS != 8) && (pAd->StaCfg.HTPhyMode.field.MCS == 8)) 1709 else if ((pEntry->HTPhyMode.field.MCS != 8) && (pAd->StaCfg.HTPhyMode.field.MCS == 8))
1965 { 1710 {
1966 AsicUpdateProtect(pAd, HT_RTSCTS_6M, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent); 1711 AsicUpdateProtect(pAd, HT_RTSCTS_6M, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
1967 } 1712 }
1968 1713
1969 pEntry->HTPhyMode.field.STBC = pAd->StaCfg.HTPhyMode.field.STBC; 1714 pEntry->HTPhyMode.field.STBC = pAd->StaCfg.HTPhyMode.field.STBC;
1970 pEntry->HTPhyMode.field.ShortGI = pAd->StaCfg.HTPhyMode.field.ShortGI; 1715 pEntry->HTPhyMode.field.ShortGI = pAd->StaCfg.HTPhyMode.field.ShortGI;
1971 pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS; 1716 pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
1972 pEntry->HTPhyMode.field.MODE = pAd->StaCfg.HTPhyMode.field.MODE; 1717 pEntry->HTPhyMode.field.MODE = pAd->StaCfg.HTPhyMode.field.MODE;
1718 if ((pAd->StaCfg.MaxHTPhyMode.field.MODE == MODE_HTGREENFIELD) &&
1719 pAd->WIFItestbed.bGreenField)
1720 pEntry->HTPhyMode.field.MODE = MODE_HTGREENFIELD;
1721 }
1973 1722
1974 if ((pAd->StaCfg.MaxHTPhyMode.field.MODE == MODE_HTGREENFIELD) && 1723 pAd->LastTxRate = (USHORT)(pEntry->HTPhyMode.word);
1975 pAd->WIFItestbed.bGreenField)
1976 pEntry->HTPhyMode.field.MODE = MODE_HTGREENFIELD;
1977 }
1978
1979 pAd->LastTxRate = (USHORT)(pEntry->HTPhyMode.word);
1980} 1724}
1981 1725
1982/* 1726/*
@@ -2002,7 +1746,7 @@ VOID MlmeDynamicTxRateSwitching(
2002 UCHAR UpRateIdx = 0, DownRateIdx = 0, CurrRateIdx; 1746 UCHAR UpRateIdx = 0, DownRateIdx = 0, CurrRateIdx;
2003 ULONG i, AccuTxTotalCnt = 0, TxTotalCnt; 1747 ULONG i, AccuTxTotalCnt = 0, TxTotalCnt;
2004 ULONG TxErrorRatio = 0; 1748 ULONG TxErrorRatio = 0;
2005 BOOLEAN bTxRateChanged, bUpgradeQuality = FALSE; 1749 BOOLEAN bTxRateChanged = FALSE, bUpgradeQuality = FALSE;
2006 PRTMP_TX_RATE_SWITCH pCurrTxRate, pNextTxRate = NULL; 1750 PRTMP_TX_RATE_SWITCH pCurrTxRate, pNextTxRate = NULL;
2007 PUCHAR pTable; 1751 PUCHAR pTable;
2008 UCHAR TableSize = 0; 1752 UCHAR TableSize = 0;
@@ -2012,29 +1756,26 @@ VOID MlmeDynamicTxRateSwitching(
2012 TX_STA_CNT0_STRUC TxStaCnt0; 1756 TX_STA_CNT0_STRUC TxStaCnt0;
2013 ULONG TxRetransmit = 0, TxSuccess = 0, TxFailCount = 0; 1757 ULONG TxRetransmit = 0, TxSuccess = 0, TxFailCount = 0;
2014 MAC_TABLE_ENTRY *pEntry; 1758 MAC_TABLE_ENTRY *pEntry;
1759 RSSI_SAMPLE *pRssi = &pAd->StaCfg.RssiSample;
1760
2015 1761
2016 // 1762 //
2017 // walk through MAC table, see if need to change AP's TX rate toward each entry 1763 // walk through MAC table, see if need to change AP's TX rate toward each entry
2018 // 1764 //
2019 for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++) 1765 for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++)
2020 { 1766 {
2021 pEntry = &pAd->MacTab.Content[i]; 1767 pEntry = &pAd->MacTab.Content[i];
2022 1768
2023 // check if this entry need to switch rate automatically 1769 // check if this entry need to switch rate automatically
2024 if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pEntry) == FALSE) 1770 if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pEntry) == FALSE)
2025 continue; 1771 continue;
2026 1772
2027 if ((pAd->MacTab.Size == 1) || (pEntry->ValidAsDls)) 1773 if ((pAd->MacTab.Size == 1) || (pEntry->ValidAsDls))
2028 { 1774 {
2029#ifdef RT2860
2030 Rssi = RTMPMaxRssi(pAd, (CHAR)pAd->StaCfg.RssiSample.AvgRssi0, (CHAR)pAd->StaCfg.RssiSample.AvgRssi1, (CHAR)pAd->StaCfg.RssiSample.AvgRssi2);
2031#endif
2032#ifdef RT2870
2033 Rssi = RTMPMaxRssi(pAd, 1775 Rssi = RTMPMaxRssi(pAd,
2034 pAd->StaCfg.RssiSample.AvgRssi0, 1776 pRssi->AvgRssi0,
2035 pAd->StaCfg.RssiSample.AvgRssi1, 1777 pRssi->AvgRssi1,
2036 pAd->StaCfg.RssiSample.AvgRssi2); 1778 pRssi->AvgRssi2);
2037#endif
2038 1779
2039 // Update statistic counter 1780 // Update statistic counter
2040 RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word); 1781 RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word);
@@ -2063,22 +1804,17 @@ VOID MlmeDynamicTxRateSwitching(
2063 TxErrorRatio = ((TxRetransmit + TxFailCount) * 100) / TxTotalCnt; 1804 TxErrorRatio = ((TxRetransmit + TxFailCount) * 100) / TxTotalCnt;
2064 } 1805 }
2065 else 1806 else
2066 { 1807 {
2067#ifdef RT2860
2068 Rssi = RTMPMaxRssi(pAd, (CHAR)pEntry->RssiSample.AvgRssi0, (CHAR)pEntry->RssiSample.AvgRssi1, (CHAR)pEntry->RssiSample.AvgRssi2);
2069#endif
2070#ifdef RT2870
2071 if (INFRA_ON(pAd) && (i == 1)) 1808 if (INFRA_ON(pAd) && (i == 1))
2072 Rssi = RTMPMaxRssi(pAd, 1809 Rssi = RTMPMaxRssi(pAd,
2073 pAd->StaCfg.RssiSample.AvgRssi0, 1810 pRssi->AvgRssi0,
2074 pAd->StaCfg.RssiSample.AvgRssi1, 1811 pRssi->AvgRssi1,
2075 pAd->StaCfg.RssiSample.AvgRssi2); 1812 pRssi->AvgRssi2);
2076 else 1813 else
2077 Rssi = RTMPMaxRssi(pAd, 1814 Rssi = RTMPMaxRssi(pAd,
2078 pEntry->RssiSample.AvgRssi0, 1815 pEntry->RssiSample.AvgRssi0,
2079 pEntry->RssiSample.AvgRssi1, 1816 pEntry->RssiSample.AvgRssi1,
2080 pEntry->RssiSample.AvgRssi2); 1817 pEntry->RssiSample.AvgRssi2);
2081#endif
2082 1818
2083 TxTotalCnt = pEntry->OneSecTxNoRetryOkCount + 1819 TxTotalCnt = pEntry->OneSecTxNoRetryOkCount +
2084 pEntry->OneSecTxRetryOkCount + 1820 pEntry->OneSecTxRetryOkCount +
@@ -2086,7 +1822,45 @@ VOID MlmeDynamicTxRateSwitching(
2086 1822
2087 if (TxTotalCnt) 1823 if (TxTotalCnt)
2088 TxErrorRatio = ((pEntry->OneSecTxRetryOkCount + pEntry->OneSecTxFailCount) * 100) / TxTotalCnt; 1824 TxErrorRatio = ((pEntry->OneSecTxRetryOkCount + pEntry->OneSecTxFailCount) * 100) / TxTotalCnt;
1825 }
1826
1827 if (TxTotalCnt)
1828 {
1829 /*
1830 Three AdHoc connections can not work normally if one AdHoc connection is disappeared from a heavy traffic environment generated by ping tool
1831 We force to set LongRtyLimit and ShortRtyLimit to 0 to stop retransmitting packet, after a while, resoring original settings
1832 */
1833 if (TxErrorRatio == 100)
1834 {
1835 TX_RTY_CFG_STRUC TxRtyCfg,TxRtyCfgtmp;
1836 ULONG Index;
1837 ULONG MACValue;
1838
1839 RTMP_IO_READ32(pAd, TX_RTY_CFG, &TxRtyCfg.word);
1840 TxRtyCfgtmp.word = TxRtyCfg.word;
1841 TxRtyCfg.field.LongRtyLimit = 0x0;
1842 TxRtyCfg.field.ShortRtyLimit = 0x0;
1843 RTMP_IO_WRITE32(pAd, TX_RTY_CFG, TxRtyCfg.word);
1844
1845 RTMPusecDelay(1);
1846
1847 Index = 0;
1848 MACValue = 0;
1849 do
1850 {
1851 RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
1852 if ((MACValue & 0xffffff) == 0)
1853 break;
1854 Index++;
1855 RTMPusecDelay(1000);
1856 }while((Index < 330)&&(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)));
1857
1858 RTMP_IO_READ32(pAd, TX_RTY_CFG, &TxRtyCfg.word);
1859 TxRtyCfg.field.LongRtyLimit = TxRtyCfgtmp.field.LongRtyLimit;
1860 TxRtyCfg.field.ShortRtyLimit = TxRtyCfgtmp.field.ShortRtyLimit;
1861 RTMP_IO_WRITE32(pAd, TX_RTY_CFG, TxRtyCfg.word);
2089 } 1862 }
1863 }
2090 1864
2091 CurrRateIdx = pEntry->CurrTxRateIndex; 1865 CurrRateIdx = pEntry->CurrTxRateIndex;
2092 1866
@@ -2118,33 +1892,33 @@ VOID MlmeDynamicTxRateSwitching(
2118 1892
2119 // decide the next upgrade rate and downgrade rate, if any 1893 // decide the next upgrade rate and downgrade rate, if any
2120 if ((CurrRateIdx > 0) && (CurrRateIdx < (TableSize - 1))) 1894 if ((CurrRateIdx > 0) && (CurrRateIdx < (TableSize - 1)))
2121 { 1895 {
2122 UpRateIdx = CurrRateIdx + 1; 1896 UpRateIdx = CurrRateIdx + 1;
2123 DownRateIdx = CurrRateIdx -1; 1897 DownRateIdx = CurrRateIdx -1;
2124 } 1898 }
2125 else if (CurrRateIdx == 0) 1899 else if (CurrRateIdx == 0)
2126 { 1900 {
2127 UpRateIdx = CurrRateIdx + 1; 1901 UpRateIdx = CurrRateIdx + 1;
2128 DownRateIdx = CurrRateIdx; 1902 DownRateIdx = CurrRateIdx;
2129 } 1903 }
2130 else if (CurrRateIdx == (TableSize - 1)) 1904 else if (CurrRateIdx == (TableSize - 1))
2131 { 1905 {
2132 UpRateIdx = CurrRateIdx; 1906 UpRateIdx = CurrRateIdx;
2133 DownRateIdx = CurrRateIdx - 1; 1907 DownRateIdx = CurrRateIdx - 1;
2134 } 1908 }
2135 1909
2136 pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(CurrRateIdx+1)*5]; 1910 pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(CurrRateIdx+1)*5];
2137 1911
2138 if ((Rssi > -65) && (pCurrTxRate->Mode >= MODE_HTMIX)) 1912 if ((Rssi > -65) && (pCurrTxRate->Mode >= MODE_HTMIX))
2139 { 1913 {
2140 TrainUp = (pCurrTxRate->TrainUp + (pCurrTxRate->TrainUp >> 1)); 1914 TrainUp = (pCurrTxRate->TrainUp + (pCurrTxRate->TrainUp >> 1));
2141 TrainDown = (pCurrTxRate->TrainDown + (pCurrTxRate->TrainDown >> 1)); 1915 TrainDown = (pCurrTxRate->TrainDown + (pCurrTxRate->TrainDown >> 1));
2142 } 1916 }
2143 else 1917 else
2144 { 1918 {
2145 TrainUp = pCurrTxRate->TrainUp; 1919 TrainUp = pCurrTxRate->TrainUp;
2146 TrainDown = pCurrTxRate->TrainDown; 1920 TrainDown = pCurrTxRate->TrainDown;
2147 } 1921 }
2148 1922
2149 //pAd->DrsCounters.LastTimeTxRateChangeAction = pAd->DrsCounters.LastSecTxRateChangeAction; 1923 //pAd->DrsCounters.LastTimeTxRateChangeAction = pAd->DrsCounters.LastSecTxRateChangeAction;
2150 1924
@@ -2160,10 +1934,9 @@ VOID MlmeDynamicTxRateSwitching(
2160 // (criteria copied from RT2500 for Netopia case) 1934 // (criteria copied from RT2500 for Netopia case)
2161 // 1935 //
2162 if (TxTotalCnt <= 15) 1936 if (TxTotalCnt <= 15)
2163 { 1937 {
2164 CHAR idx = 0; 1938 CHAR idx = 0;
2165 UCHAR TxRateIdx; 1939 UCHAR TxRateIdx;
2166 //UCHAR MCS0 = 0, MCS1 = 0, MCS2 = 0, MCS3 = 0, MCS4 = 0, MCS7 = 0, MCS12 = 0, MCS13 = 0, MCS14 = 0, MCS15 = 0;
2167 UCHAR MCS0 = 0, MCS1 = 0, MCS2 = 0, MCS3 = 0, MCS4 = 0, MCS5 =0, MCS6 = 0, MCS7 = 0; 1940 UCHAR MCS0 = 0, MCS1 = 0, MCS2 = 0, MCS3 = 0, MCS4 = 0, MCS5 =0, MCS6 = 0, MCS7 = 0;
2168 UCHAR MCS12 = 0, MCS13 = 0, MCS14 = 0, MCS15 = 0; 1941 UCHAR MCS12 = 0, MCS13 = 0, MCS14 = 0, MCS15 = 0;
2169 UCHAR MCS20 = 0, MCS21 = 0, MCS22 = 0, MCS23 = 0; // 3*3 1942 UCHAR MCS20 = 0, MCS21 = 0, MCS22 = 0, MCS23 = 0; // 3*3
@@ -2174,54 +1947,55 @@ VOID MlmeDynamicTxRateSwitching(
2174 pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(idx+1)*5]; 1947 pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(idx+1)*5];
2175 1948
2176 if (pCurrTxRate->CurrMCS == MCS_0) 1949 if (pCurrTxRate->CurrMCS == MCS_0)
2177 { 1950 {
2178 MCS0 = idx; 1951 MCS0 = idx;
2179 } 1952 }
2180 else if (pCurrTxRate->CurrMCS == MCS_1) 1953 else if (pCurrTxRate->CurrMCS == MCS_1)
2181 { 1954 {
2182 MCS1 = idx; 1955 MCS1 = idx;
2183 } 1956 }
2184 else if (pCurrTxRate->CurrMCS == MCS_2) 1957 else if (pCurrTxRate->CurrMCS == MCS_2)
2185 { 1958 {
2186 MCS2 = idx; 1959 MCS2 = idx;
2187 } 1960 }
2188 else if (pCurrTxRate->CurrMCS == MCS_3) 1961 else if (pCurrTxRate->CurrMCS == MCS_3)
2189 { 1962 {
2190 MCS3 = idx; 1963 MCS3 = idx;
2191 } 1964 }
2192 else if (pCurrTxRate->CurrMCS == MCS_4) 1965 else if (pCurrTxRate->CurrMCS == MCS_4)
2193 { 1966 {
2194 MCS4 = idx; 1967 MCS4 = idx;
2195 } 1968 }
2196 else if (pCurrTxRate->CurrMCS == MCS_5) 1969 else if (pCurrTxRate->CurrMCS == MCS_5)
2197 { 1970 {
2198 MCS5 = idx; 1971 MCS5 = idx;
2199 } 1972 }
2200 else if (pCurrTxRate->CurrMCS == MCS_6) 1973 else if (pCurrTxRate->CurrMCS == MCS_6)
2201 { 1974 {
2202 MCS6 = idx; 1975 MCS6 = idx;
2203 } 1976 }
2204 //else if (pCurrTxRate->CurrMCS == MCS_7) 1977 //else if (pCurrTxRate->CurrMCS == MCS_7)
2205 else if ((pCurrTxRate->CurrMCS == MCS_7) && (pCurrTxRate->ShortGI == GI_800)) // prevent the highest MCS using short GI when 1T and low throughput 1978 else if ((pCurrTxRate->CurrMCS == MCS_7) && (pCurrTxRate->ShortGI == GI_800)) // prevent the highest MCS using short GI when 1T and low throughput
2206 { 1979 {
2207 MCS7 = idx; 1980 MCS7 = idx;
2208 } 1981 }
2209 else if (pCurrTxRate->CurrMCS == MCS_12) 1982 else if (pCurrTxRate->CurrMCS == MCS_12)
2210 { 1983 {
2211 MCS12 = idx; 1984 MCS12 = idx;
2212 } 1985 }
2213 else if (pCurrTxRate->CurrMCS == MCS_13) 1986 else if (pCurrTxRate->CurrMCS == MCS_13)
2214 { 1987 {
2215 MCS13 = idx; 1988 MCS13 = idx;
2216 } 1989 }
2217 else if (pCurrTxRate->CurrMCS == MCS_14) 1990 else if (pCurrTxRate->CurrMCS == MCS_14)
2218 { 1991 {
2219 MCS14 = idx; 1992 MCS14 = idx;
2220 } 1993 }
1994 //else if ((pCurrTxRate->CurrMCS == MCS_15)/* && (pCurrTxRate->ShortGI == GI_800)*/) //we hope to use ShortGI as initial rate
2221 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 1995 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
2222 { 1996 {
2223 MCS15 = idx; 1997 MCS15 = idx;
2224 } 1998 }
2225 else if (pCurrTxRate->CurrMCS == MCS_20) // 3*3 1999 else if (pCurrTxRate->CurrMCS == MCS_20) // 3*3
2226 { 2000 {
2227 MCS20 = idx; 2001 MCS20 = idx;
@@ -2270,13 +2044,13 @@ VOID MlmeDynamicTxRateSwitching(
2270 (pTable == RateSwitchTable)) 2044 (pTable == RateSwitchTable))
2271 {// N mode with 3 stream // 3*3 2045 {// N mode with 3 stream // 3*3
2272 if (MCS23 && (Rssi >= -70)) 2046 if (MCS23 && (Rssi >= -70))
2273 TxRateIdx = MCS15; 2047 TxRateIdx = MCS23;
2274 else if (MCS22 && (Rssi >= -72)) 2048 else if (MCS22 && (Rssi >= -72))
2275 TxRateIdx = MCS14; 2049 TxRateIdx = MCS22;
2276 else if (MCS21 && (Rssi >= -76)) 2050 else if (MCS21 && (Rssi >= -76))
2277 TxRateIdx = MCS13; 2051 TxRateIdx = MCS21;
2278 else if (MCS20 && (Rssi >= -78)) 2052 else if (MCS20 && (Rssi >= -78))
2279 TxRateIdx = MCS12; 2053 TxRateIdx = MCS20;
2280 else if (MCS4 && (Rssi >= -82)) 2054 else if (MCS4 && (Rssi >= -82))
2281 TxRateIdx = MCS4; 2055 TxRateIdx = MCS4;
2282 else if (MCS3 && (Rssi >= -84)) 2056 else if (MCS3 && (Rssi >= -84))
@@ -2288,6 +2062,7 @@ VOID MlmeDynamicTxRateSwitching(
2288 else 2062 else
2289 TxRateIdx = MCS0; 2063 TxRateIdx = MCS0;
2290 } 2064 }
2065// else if ((pTable == RateSwitchTable11BGN2S) || (pTable == RateSwitchTable11BGN2SForABand) ||(pTable == RateSwitchTable11N2S) ||(pTable == RateSwitchTable11N2SForABand) || (pTable == RateSwitchTable))
2291 else if ((pTable == RateSwitchTable11BGN2S) || (pTable == RateSwitchTable11BGN2SForABand) ||(pTable == RateSwitchTable11N2S) ||(pTable == RateSwitchTable11N2SForABand)) // 3*3 2066 else if ((pTable == RateSwitchTable11BGN2S) || (pTable == RateSwitchTable11BGN2SForABand) ||(pTable == RateSwitchTable11N2S) ||(pTable == RateSwitchTable11N2SForABand)) // 3*3
2292 {// N mode with 2 stream 2067 {// N mode with 2 stream
2293 if (MCS15 && (Rssi >= (-70+RssiOffset))) 2068 if (MCS15 && (Rssi >= (-70+RssiOffset)))
@@ -2350,6 +2125,7 @@ VOID MlmeDynamicTxRateSwitching(
2350 TxRateIdx = MCS0; 2125 TxRateIdx = MCS0;
2351 } 2126 }
2352 2127
2128 // if (TxRateIdx != pAd->CommonCfg.TxRateIndex)
2353 { 2129 {
2354 pEntry->CurrTxRateIndex = TxRateIdx; 2130 pEntry->CurrTxRateIndex = TxRateIdx;
2355 pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(pEntry->CurrTxRateIndex+1)*5]; 2131 pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(pEntry->CurrTxRateIndex+1)*5];
@@ -2464,15 +2240,34 @@ VOID MlmeDynamicTxRateSwitching(
2464 } 2240 }
2465 2241
2466 pEntry->LastTxOkCount = TxSuccess; 2242 pEntry->LastTxOkCount = TxSuccess;
2243#ifdef RT2860
2244 pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(pEntry->CurrTxRateIndex+1)*5];
2245#endif // RT2860 //
2246#if defined(RT2870) || defined(RT3070)
2247 {
2248 UCHAR tmpTxRate;
2467 2249
2468 // reset all OneSecTx counters 2250 // to fix tcp ack issue
2469 RESET_ONE_SEC_TX_CNT(pEntry); 2251 if (!bTxRateChanged && (pAd->RalinkCounters.OneSecReceivedByteCount > (pAd->RalinkCounters.OneSecTransmittedByteCount * 5)))
2252 {
2253 tmpTxRate = DownRateIdx;
2254 DBGPRINT_RAW(RT_DEBUG_TRACE,("DRS: Rx(%d) is 5 times larger than Tx(%d), use low rate (curr=%d, tmp=%d)\n",
2255 pAd->RalinkCounters.OneSecReceivedByteCount, pAd->RalinkCounters.OneSecTransmittedByteCount, pEntry->CurrTxRateIndex, tmpTxRate));
2256 }
2257 else
2258 {
2259 tmpTxRate = pEntry->CurrTxRateIndex;
2260 }
2470 2261
2471 pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(pEntry->CurrTxRateIndex+1)*5]; 2262 pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(tmpTxRate+1)*5];
2263 }
2264#endif // RT2870 //
2472 if (bTxRateChanged && pNextTxRate) 2265 if (bTxRateChanged && pNextTxRate)
2473 { 2266 {
2474 MlmeSetTxRate(pAd, pEntry, pNextTxRate); 2267 MlmeSetTxRate(pAd, pEntry, pNextTxRate);
2475 } 2268 }
2269 // reset all OneSecTx counters
2270 RESET_ONE_SEC_TX_CNT(pEntry);
2476 } 2271 }
2477} 2272}
2478 2273
@@ -2502,12 +2297,7 @@ VOID StaQuickResponeForRateUpExec(
2502 UCHAR UpRateIdx = 0, DownRateIdx = 0, CurrRateIdx = 0; 2297 UCHAR UpRateIdx = 0, DownRateIdx = 0, CurrRateIdx = 0;
2503 ULONG TxTotalCnt; 2298 ULONG TxTotalCnt;
2504 ULONG TxErrorRatio = 0; 2299 ULONG TxErrorRatio = 0;
2505#ifdef RT2860
2506 BOOLEAN bTxRateChanged = TRUE; //, bUpgradeQuality = FALSE;
2507#endif
2508#ifdef RT2870
2509 BOOLEAN bTxRateChanged; //, bUpgradeQuality = FALSE; 2300 BOOLEAN bTxRateChanged; //, bUpgradeQuality = FALSE;
2510#endif
2511 PRTMP_TX_RATE_SWITCH pCurrTxRate, pNextTxRate = NULL; 2301 PRTMP_TX_RATE_SWITCH pCurrTxRate, pNextTxRate = NULL;
2512 PUCHAR pTable; 2302 PUCHAR pTable;
2513 UCHAR TableSize = 0; 2303 UCHAR TableSize = 0;
@@ -2532,14 +2322,6 @@ VOID StaQuickResponeForRateUpExec(
2532 if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pEntry) == FALSE) 2322 if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pEntry) == FALSE)
2533 continue; 2323 continue;
2534 2324
2535#ifdef RT2860
2536 //Rssi = RTMPMaxRssi(pAd, (CHAR)pAd->StaCfg.AvgRssi0, (CHAR)pAd->StaCfg.AvgRssi1, (CHAR)pAd->StaCfg.AvgRssi2);
2537 if (pAd->Antenna.field.TxPath > 1)
2538 Rssi = (pAd->StaCfg.RssiSample.AvgRssi0 + pAd->StaCfg.RssiSample.AvgRssi1) >> 1;
2539 else
2540 Rssi = pAd->StaCfg.RssiSample.AvgRssi0;
2541#endif
2542#ifdef RT2870
2543 if (INFRA_ON(pAd) && (i == 1)) 2325 if (INFRA_ON(pAd) && (i == 1))
2544 Rssi = RTMPMaxRssi(pAd, 2326 Rssi = RTMPMaxRssi(pAd,
2545 pAd->StaCfg.RssiSample.AvgRssi0, 2327 pAd->StaCfg.RssiSample.AvgRssi0,
@@ -2550,7 +2332,6 @@ VOID StaQuickResponeForRateUpExec(
2550 pEntry->RssiSample.AvgRssi0, 2332 pEntry->RssiSample.AvgRssi0,
2551 pEntry->RssiSample.AvgRssi1, 2333 pEntry->RssiSample.AvgRssi1,
2552 pEntry->RssiSample.AvgRssi2); 2334 pEntry->RssiSample.AvgRssi2);
2553#endif
2554 2335
2555 CurrRateIdx = pAd->CommonCfg.TxRateIndex; 2336 CurrRateIdx = pAd->CommonCfg.TxRateIndex;
2556 2337
@@ -2690,9 +2471,7 @@ VOID StaQuickResponeForRateUpExec(
2690 pAd->DrsCounters.TxRateUpPenalty = 0; 2471 pAd->DrsCounters.TxRateUpPenalty = 0;
2691 NdisZeroMemory(pAd->DrsCounters.TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH); 2472 NdisZeroMemory(pAd->DrsCounters.TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH);
2692 NdisZeroMemory(pAd->DrsCounters.PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH); 2473 NdisZeroMemory(pAd->DrsCounters.PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH);
2693#ifdef RT2870
2694 bTxRateChanged = TRUE; 2474 bTxRateChanged = TRUE;
2695#endif
2696 } 2475 }
2697 // if rate-down happen, only clear DownRate's bad history 2476 // if rate-down happen, only clear DownRate's bad history
2698 else if (pAd->CommonCfg.TxRateIndex < CurrRateIdx) 2477 else if (pAd->CommonCfg.TxRateIndex < CurrRateIdx)
@@ -2702,9 +2481,7 @@ VOID StaQuickResponeForRateUpExec(
2702 pAd->DrsCounters.TxRateUpPenalty = 0; // no penalty 2481 pAd->DrsCounters.TxRateUpPenalty = 0; // no penalty
2703 pAd->DrsCounters.TxQuality[pAd->CommonCfg.TxRateIndex] = 0; 2482 pAd->DrsCounters.TxQuality[pAd->CommonCfg.TxRateIndex] = 0;
2704 pAd->DrsCounters.PER[pAd->CommonCfg.TxRateIndex] = 0; 2483 pAd->DrsCounters.PER[pAd->CommonCfg.TxRateIndex] = 0;
2705#ifdef RT2870
2706 bTxRateChanged = TRUE; 2484 bTxRateChanged = TRUE;
2707#endif
2708 } 2485 }
2709 else 2486 else
2710 { 2487 {
@@ -2750,34 +2527,21 @@ VOID MlmeCheckPsmChange(
2750 // 3. but current psm is not in PWR_SAVE 2527 // 3. but current psm is not in PWR_SAVE
2751 // 4. CNTL state machine is not doing SCANning 2528 // 4. CNTL state machine is not doing SCANning
2752 // 5. no TX SUCCESS event for the past 1-sec period 2529 // 5. no TX SUCCESS event for the past 1-sec period
2753#ifdef NDIS51_MINIPORT
2754 if (pAd->StaCfg.WindowsPowerProfile == NdisPowerProfileBattery)
2755 PowerMode = pAd->StaCfg.WindowsBatteryPowerMode;
2756 else
2757#endif
2758 PowerMode = pAd->StaCfg.WindowsPowerMode; 2530 PowerMode = pAd->StaCfg.WindowsPowerMode;
2759 2531
2760 if (INFRA_ON(pAd) && 2532 if (INFRA_ON(pAd) &&
2761 (PowerMode != Ndis802_11PowerModeCAM) && 2533 (PowerMode != Ndis802_11PowerModeCAM) &&
2762 (pAd->StaCfg.Psm == PWR_ACTIVE) && 2534 (pAd->StaCfg.Psm == PWR_ACTIVE) &&
2763#ifdef RT2860 2535// (! RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
2764 RTMP_TEST_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP)) 2536 (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)&&
2765#else 2537 RTMP_TEST_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP)
2766 (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)) 2538 /*&&
2767#endif 2539 (pAd->RalinkCounters.OneSecTxNoRetryOkCount == 0) &&
2540 (pAd->RalinkCounters.OneSecTxRetryOkCount == 0)*/)
2768 { 2541 {
2769 // add by johnli, use Rx OK data count per second to calculate throughput
2770 // If Ttraffic is too high ( > 400 Rx per second), don't go to sleep mode. If tx rate is low, use low criteria
2771 // Mode=CCK/MCS=3 => 11 Mbps, Mode=OFDM/MCS=3 => 18 Mbps
2772 if (((pAd->StaCfg.HTPhyMode.field.MCS <= 3) &&
2773 (pAd->RalinkCounters.OneSecRxOkDataCnt < (ULONG)100)) ||
2774 ((pAd->StaCfg.HTPhyMode.field.MCS > 3) &&
2775 (pAd->RalinkCounters.OneSecRxOkDataCnt < (ULONG)400)))
2776 {
2777 // Get this time
2778 NdisGetSystemUpTime(&pAd->Mlme.LastSendNULLpsmTime); 2542 NdisGetSystemUpTime(&pAd->Mlme.LastSendNULLpsmTime);
2779 pAd->RalinkCounters.RxCountSinceLastNULL = 0; 2543 pAd->RalinkCounters.RxCountSinceLastNULL = 0;
2780 MlmeSetPsmBit(pAd, PWR_SAVE); 2544 RTMP_SET_PSM_BIT(pAd, PWR_SAVE);
2781 if (!(pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable)) 2545 if (!(pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable))
2782 { 2546 {
2783 RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, FALSE); 2547 RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, FALSE);
@@ -2787,7 +2551,6 @@ VOID MlmeCheckPsmChange(
2787 RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE); 2551 RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
2788 } 2552 }
2789 } 2553 }
2790 }
2791} 2554}
2792 2555
2793// IRQL = PASSIVE_LEVEL 2556// IRQL = PASSIVE_LEVEL
@@ -2806,6 +2569,118 @@ VOID MlmeSetPsmBit(
2806 DBGPRINT(RT_DEBUG_TRACE, ("MlmeSetPsmBit = %d\n", psm)); 2569 DBGPRINT(RT_DEBUG_TRACE, ("MlmeSetPsmBit = %d\n", psm));
2807} 2570}
2808 2571
2572/*
2573 ==========================================================================
2574 Description:
2575 This routine calculates TxPER, RxPER of the past N-sec period. And
2576 according to the calculation result, ChannelQuality is calculated here
2577 to decide if current AP is still doing the job.
2578
2579 If ChannelQuality is not good, a ROAMing attempt may be tried later.
2580 Output:
2581 StaCfg.ChannelQuality - 0..100
2582
2583 IRQL = DISPATCH_LEVEL
2584
2585 NOTE: This routine decide channle quality based on RX CRC error ratio.
2586 Caller should make sure a function call to NICUpdateRawCounters(pAd)
2587 is performed right before this routine, so that this routine can decide
2588 channel quality based on the most up-to-date information
2589 ==========================================================================
2590 */
2591VOID MlmeCalculateChannelQuality(
2592 IN PRTMP_ADAPTER pAd,
2593 IN PMAC_TABLE_ENTRY pMacEntry,
2594 IN ULONG Now32)
2595{
2596 ULONG TxOkCnt, TxCnt, TxPER, TxPRR;
2597 ULONG RxCnt, RxPER;
2598 UCHAR NorRssi;
2599 CHAR MaxRssi;
2600 RSSI_SAMPLE *pRssiSample = NULL;
2601 UINT32 OneSecTxNoRetryOkCount = 0;
2602 UINT32 OneSecTxRetryOkCount = 0;
2603 UINT32 OneSecTxFailCount = 0;
2604 UINT32 OneSecRxOkCnt = 0;
2605 UINT32 OneSecRxFcsErrCnt = 0;
2606 ULONG ChannelQuality = 0; // 0..100, Channel Quality Indication for Roaming
2607 ULONG BeaconLostTime = pAd->StaCfg.BeaconLostTime;
2608
2609
2610 if (pAd->OpMode == OPMODE_STA)
2611 {
2612 pRssiSample = &pAd->StaCfg.RssiSample;
2613 OneSecTxNoRetryOkCount = pAd->RalinkCounters.OneSecTxNoRetryOkCount;
2614 OneSecTxRetryOkCount = pAd->RalinkCounters.OneSecTxRetryOkCount;
2615 OneSecTxFailCount = pAd->RalinkCounters.OneSecTxFailCount;
2616 OneSecRxOkCnt = pAd->RalinkCounters.OneSecRxOkCnt;
2617 OneSecRxFcsErrCnt = pAd->RalinkCounters.OneSecRxFcsErrCnt;
2618 }
2619
2620 MaxRssi = RTMPMaxRssi(pAd, pRssiSample->LastRssi0,
2621 pRssiSample->LastRssi1,
2622 pRssiSample->LastRssi2);
2623
2624 //
2625 // calculate TX packet error ratio and TX retry ratio - if too few TX samples, skip TX related statistics
2626 //
2627 TxOkCnt = OneSecTxNoRetryOkCount + OneSecTxRetryOkCount;
2628 TxCnt = TxOkCnt + OneSecTxFailCount;
2629 if (TxCnt < 5)
2630 {
2631 TxPER = 0;
2632 TxPRR = 0;
2633 }
2634 else
2635 {
2636 TxPER = (OneSecTxFailCount * 100) / TxCnt;
2637 TxPRR = ((TxCnt - OneSecTxNoRetryOkCount) * 100) / TxCnt;
2638 }
2639
2640 //
2641 // calculate RX PER - don't take RxPER into consideration if too few sample
2642 //
2643 RxCnt = OneSecRxOkCnt + OneSecRxFcsErrCnt;
2644 if (RxCnt < 5)
2645 RxPER = 0;
2646 else
2647 RxPER = (OneSecRxFcsErrCnt * 100) / RxCnt;
2648
2649 //
2650 // decide ChannelQuality based on: 1)last BEACON received time, 2)last RSSI, 3)TxPER, and 4)RxPER
2651 //
2652 if ((pAd->OpMode == OPMODE_STA) &&
2653 INFRA_ON(pAd) &&
2654 (OneSecTxNoRetryOkCount < 2) && // no heavy traffic
2655 ((pAd->StaCfg.LastBeaconRxTime + BeaconLostTime) < Now32))
2656 {
2657 DBGPRINT(RT_DEBUG_TRACE, ("BEACON lost > %ld msec with TxOkCnt=%ld -> CQI=0\n", BeaconLostTime, TxOkCnt));
2658 ChannelQuality = 0;
2659 }
2660 else
2661 {
2662 // Normalize Rssi
2663 if (MaxRssi > -40)
2664 NorRssi = 100;
2665 else if (MaxRssi < -90)
2666 NorRssi = 0;
2667 else
2668 NorRssi = (MaxRssi + 90) * 2;
2669
2670 // ChannelQuality = W1*RSSI + W2*TxPRR + W3*RxPER (RSSI 0..100), (TxPER 100..0), (RxPER 100..0)
2671 ChannelQuality = (RSSI_WEIGHTING * NorRssi +
2672 TX_WEIGHTING * (100 - TxPRR) +
2673 RX_WEIGHTING* (100 - RxPER)) / 100;
2674 }
2675
2676
2677 if (pAd->OpMode == OPMODE_STA)
2678 pAd->Mlme.ChannelQuality = (ChannelQuality > 100) ? 100 : ChannelQuality;
2679
2680
2681}
2682
2683
2809// IRQL = DISPATCH_LEVEL 2684// IRQL = DISPATCH_LEVEL
2810VOID MlmeSetTxPreamble( 2685VOID MlmeSetTxPreamble(
2811 IN PRTMP_ADAPTER pAd, 2686 IN PRTMP_ADAPTER pAd,
@@ -2968,23 +2843,29 @@ VOID MlmeUpdateTxRates(
2968 // specified; otherwise disabled 2843 // specified; otherwise disabled
2969 if (num <= 1) 2844 if (num <= 1)
2970 { 2845 {
2846 //OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED);
2847 //pAd->CommonCfg.bAutoTxRateSwitch = FALSE;
2971 *auto_rate_cur_p = FALSE; 2848 *auto_rate_cur_p = FALSE;
2972 } 2849 }
2973 else 2850 else
2974 { 2851 {
2852 //OPSTATUS_SET_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED);
2853 //pAd->CommonCfg.bAutoTxRateSwitch = TRUE;
2975 *auto_rate_cur_p = TRUE; 2854 *auto_rate_cur_p = TRUE;
2976 } 2855 }
2977 2856
2978#if 1
2979 if (HtMcs != MCS_AUTO) 2857 if (HtMcs != MCS_AUTO)
2980 { 2858 {
2859 //OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED);
2860 //pAd->CommonCfg.bAutoTxRateSwitch = FALSE;
2981 *auto_rate_cur_p = FALSE; 2861 *auto_rate_cur_p = FALSE;
2982 } 2862 }
2983 else 2863 else
2984 { 2864 {
2865 //OPSTATUS_SET_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED);
2866 //pAd->CommonCfg.bAutoTxRateSwitch = TRUE;
2985 *auto_rate_cur_p = TRUE; 2867 *auto_rate_cur_p = TRUE;
2986 } 2868 }
2987#endif
2988 2869
2989 if ((ADHOC_ON(pAd) || INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA)) 2870 if ((ADHOC_ON(pAd) || INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA))
2990 { 2871 {
@@ -3050,6 +2931,9 @@ VOID MlmeUpdateTxRates(
3050 2931
3051 RTMP_IO_WRITE32(pAd, LEGACY_BASIC_RATE, BasicRateBitmap); 2932 RTMP_IO_WRITE32(pAd, LEGACY_BASIC_RATE, BasicRateBitmap);
3052 2933
2934 // bug fix
2935 // pAd->CommonCfg.BasicRateBitmap = BasicRateBitmap;
2936
3053 // calculate the exptected ACK rate for each TX rate. This info is used to caculate 2937 // calculate the exptected ACK rate for each TX rate. This info is used to caculate
3054 // the DURATION field of outgoing uniicast DATA/MGMT frame 2938 // the DURATION field of outgoing uniicast DATA/MGMT frame
3055 for (i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++) 2939 for (i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
@@ -3067,6 +2951,14 @@ VOID MlmeUpdateTxRates(
3067 pAd->CommonCfg.MaxTxRate = MaxDesire; 2951 pAd->CommonCfg.MaxTxRate = MaxDesire;
3068 2952
3069 pAd->CommonCfg.MinTxRate = MinSupport; 2953 pAd->CommonCfg.MinTxRate = MinSupport;
2954 // 2003-07-31 john - 2500 doesn't have good sensitivity at high OFDM rates. to increase the success
2955 // ratio of initial DHCP packet exchange, TX rate starts from a lower rate depending
2956 // on average RSSI
2957 // 1. RSSI >= -70db, start at 54 Mbps (short distance)
2958 // 2. -70 > RSSI >= -75, start at 24 Mbps (mid distance)
2959 // 3. -75 > RSSI, start at 11 Mbps (long distance)
2960 //if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)/* &&
2961 // OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)*/)
3070 if (*auto_rate_cur_p) 2962 if (*auto_rate_cur_p)
3071 { 2963 {
3072 short dbm = 0; 2964 short dbm = 0;
@@ -3134,7 +3026,12 @@ VOID MlmeUpdateTxRates(
3134 pAd->CommonCfg.MlmeRate = RATE_1; 3026 pAd->CommonCfg.MlmeRate = RATE_1;
3135 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK; 3027 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
3136 pAd->CommonCfg.MlmeTransmit.field.MCS = RATE_1; 3028 pAd->CommonCfg.MlmeTransmit.field.MCS = RATE_1;
3029
3030//#ifdef WIFI_TEST
3137 pAd->CommonCfg.RtsRate = RATE_11; 3031 pAd->CommonCfg.RtsRate = RATE_11;
3032//#else
3033// pAd->CommonCfg.RtsRate = RATE_1;
3034//#endif
3138 break; 3035 break;
3139 case PHY_11G: 3036 case PHY_11G:
3140 case PHY_11A: 3037 case PHY_11A:
@@ -3151,23 +3048,23 @@ VOID MlmeUpdateTxRates(
3151 case PHY_11ABG_MIXED: 3048 case PHY_11ABG_MIXED:
3152 case PHY_11ABGN_MIXED: 3049 case PHY_11ABGN_MIXED:
3153 if (pAd->CommonCfg.Channel <= 14) 3050 if (pAd->CommonCfg.Channel <= 14)
3154 { 3051 {
3155 pAd->CommonCfg.MlmeRate = RATE_1; 3052 pAd->CommonCfg.MlmeRate = RATE_1;
3156 pAd->CommonCfg.RtsRate = RATE_1; 3053 pAd->CommonCfg.RtsRate = RATE_1;
3157 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK; 3054 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
3158 pAd->CommonCfg.MlmeTransmit.field.MCS = RATE_1; 3055 pAd->CommonCfg.MlmeTransmit.field.MCS = RATE_1;
3159 } 3056 }
3160 else 3057 else
3161 { 3058 {
3162 pAd->CommonCfg.MlmeRate = RATE_6; 3059 pAd->CommonCfg.MlmeRate = RATE_6;
3163 pAd->CommonCfg.RtsRate = RATE_6; 3060 pAd->CommonCfg.RtsRate = RATE_6;
3164 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM; 3061 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
3165 pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate]; 3062 pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
3166 } 3063 }
3167 break; 3064 break;
3168 default: // error 3065 default: // error
3169 pAd->CommonCfg.MlmeRate = RATE_6; 3066 pAd->CommonCfg.MlmeRate = RATE_6;
3170 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM; 3067 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
3171 pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate]; 3068 pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
3172 pAd->CommonCfg.RtsRate = RATE_1; 3069 pAd->CommonCfg.RtsRate = RATE_1;
3173 break; 3070 break;
@@ -3198,19 +3095,19 @@ VOID MlmeUpdateTxRates(
3198 This function update HT Rate setting. 3095 This function update HT Rate setting.
3199 Input Wcid value is valid for 2 case : 3096 Input Wcid value is valid for 2 case :
3200 1. it's used for Station in infra mode that copy AP rate to Mactable. 3097 1. it's used for Station in infra mode that copy AP rate to Mactable.
3201 2. OR Station in adhoc mode to copy peer's HT rate to Mactable. 3098 2. OR Station in adhoc mode to copy peer's HT rate to Mactable.
3202 3099
3203 IRQL = DISPATCH_LEVEL 3100 IRQL = DISPATCH_LEVEL
3204 3101
3205 ========================================================================== 3102 ==========================================================================
3206 */ 3103 */
3207VOID MlmeUpdateHtTxRates( 3104VOID MlmeUpdateHtTxRates(
3208 IN PRTMP_ADAPTER pAd, 3105 IN PRTMP_ADAPTER pAd,
3209 IN UCHAR apidx) 3106 IN UCHAR apidx)
3210{ 3107{
3211 UCHAR StbcMcs; //j, StbcMcs, bitmask; 3108 UCHAR StbcMcs; //j, StbcMcs, bitmask;
3212 CHAR i; // 3*3 3109 CHAR i; // 3*3
3213 RT_HT_CAPABILITY *pRtHtCap = NULL; 3110 RT_HT_CAPABILITY *pRtHtCap = NULL;
3214 RT_HT_PHY_INFO *pActiveHtPhy = NULL; 3111 RT_HT_PHY_INFO *pActiveHtPhy = NULL;
3215 ULONG BasicMCS; 3112 ULONG BasicMCS;
3216 UCHAR j, bitmask; 3113 UCHAR j, bitmask;
@@ -3218,7 +3115,7 @@ VOID MlmeUpdateHtTxRates(
3218 PHTTRANSMIT_SETTING pHtPhy = NULL; 3115 PHTTRANSMIT_SETTING pHtPhy = NULL;
3219 PHTTRANSMIT_SETTING pMaxHtPhy = NULL; 3116 PHTTRANSMIT_SETTING pMaxHtPhy = NULL;
3220 PHTTRANSMIT_SETTING pMinHtPhy = NULL; 3117 PHTTRANSMIT_SETTING pMinHtPhy = NULL;
3221 BOOLEAN *auto_rate_cur_p; 3118 BOOLEAN *auto_rate_cur_p;
3222 3119
3223 DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateHtTxRates===> \n")); 3120 DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateHtTxRates===> \n"));
3224 3121
@@ -3227,7 +3124,7 @@ VOID MlmeUpdateHtTxRates(
3227 { 3124 {
3228 pDesireHtPhy = &pAd->StaCfg.DesiredHtPhyInfo; 3125 pDesireHtPhy = &pAd->StaCfg.DesiredHtPhyInfo;
3229 pActiveHtPhy = &pAd->StaCfg.DesiredHtPhyInfo; 3126 pActiveHtPhy = &pAd->StaCfg.DesiredHtPhyInfo;
3230 pHtPhy = &pAd->StaCfg.HTPhyMode; 3127 pHtPhy = &pAd->StaCfg.HTPhyMode;
3231 pMaxHtPhy = &pAd->StaCfg.MaxHTPhyMode; 3128 pMaxHtPhy = &pAd->StaCfg.MaxHTPhyMode;
3232 pMinHtPhy = &pAd->StaCfg.MinHTPhyMode; 3129 pMinHtPhy = &pAd->StaCfg.MinHTPhyMode;
3233 3130
@@ -3278,16 +3175,21 @@ VOID MlmeUpdateHtTxRates(
3278 else 3175 else
3279 pMaxHtPhy->field.ShortGI = (pAd->CommonCfg.DesiredHtPhy.ShortGIfor40 & pRtHtCap->ShortGIfor40); 3176 pMaxHtPhy->field.ShortGI = (pAd->CommonCfg.DesiredHtPhy.ShortGIfor40 & pRtHtCap->ShortGIfor40);
3280 3177
3178 if (pDesireHtPhy->MCSSet[4] != 0)
3179 {
3180 pMaxHtPhy->field.MCS = 32;
3181 }
3182
3281 for (i=23; i>=0; i--) // 3*3 3183 for (i=23; i>=0; i--) // 3*3
3282 { 3184 {
3283 j = i/8; 3185 j = i/8;
3284 bitmask = (1<<(i-(j*8))); 3186 bitmask = (1<<(i-(j*8)));
3285 3187
3286 if ((pActiveHtPhy->MCSSet[j] & bitmask) && (pDesireHtPhy->MCSSet[j] & bitmask)) 3188 if ((pActiveHtPhy->MCSSet[j] & bitmask) && (pDesireHtPhy->MCSSet[j] & bitmask))
3287 { 3189 {
3288 pMaxHtPhy->field.MCS = i; 3190 pMaxHtPhy->field.MCS = i;
3289 break; 3191 break;
3290 } 3192 }
3291 3193
3292 if (i==0) 3194 if (i==0)
3293 break; 3195 break;
@@ -3302,26 +3204,27 @@ VOID MlmeUpdateHtTxRates(
3302 if ( (pAd->OpMode == OPMODE_STA) && (pDesireHtPhy->MCSSet[0] != 0xff)) 3204 if ( (pAd->OpMode == OPMODE_STA) && (pDesireHtPhy->MCSSet[0] != 0xff))
3303 { 3205 {
3304 if (pDesireHtPhy->MCSSet[4] != 0) 3206 if (pDesireHtPhy->MCSSet[4] != 0)
3305 { 3207 {
3306 pMaxHtPhy->field.MCS = 32; 3208 pMaxHtPhy->field.MCS = 32;
3307 pMinHtPhy->field.MCS = 32; 3209 pMinHtPhy->field.MCS = 32;
3308 DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateHtTxRates<=== Use Fixed MCS = %d\n",pMinHtPhy->field.MCS)); 3210 DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateHtTxRates<=== Use Fixed MCS = %d\n",pMinHtPhy->field.MCS));
3309 } 3211 }
3310 3212
3311 for (i=23; (CHAR)i >= 0; i--) // 3*3 3213 for (i=23; (CHAR)i >= 0; i--) // 3*3
3312 { 3214 {
3313 j = i/8; 3215 j = i/8;
3314 bitmask = (1<<(i-(j*8))); 3216 bitmask = (1<<(i-(j*8)));
3315 if ( (pDesireHtPhy->MCSSet[j] & bitmask) && (pActiveHtPhy->MCSSet[j] & bitmask)) 3217 if ( (pDesireHtPhy->MCSSet[j] & bitmask) && (pActiveHtPhy->MCSSet[j] & bitmask))
3316 { 3218 {
3317 pMaxHtPhy->field.MCS = i; 3219 pMaxHtPhy->field.MCS = i;
3318 pMinHtPhy->field.MCS = i; 3220 pMinHtPhy->field.MCS = i;
3319 break; 3221 break;
3320 } 3222 }
3321 if (i==0) 3223 if (i==0)
3322 break; 3224 break;
3323 }
3324 } 3225 }
3226 }
3227
3325 3228
3326 // Decide ht rate 3229 // Decide ht rate
3327 pHtPhy->field.STBC = pMaxHtPhy->field.STBC; 3230 pHtPhy->field.STBC = pMaxHtPhy->field.STBC;
@@ -3342,18 +3245,40 @@ VOID MlmeUpdateHtTxRates(
3342 DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateHtTxRates<=== \n")); 3245 DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateHtTxRates<=== \n"));
3343} 3246}
3344 3247
3248
3249VOID BATableInit(
3250 IN PRTMP_ADAPTER pAd,
3251 IN BA_TABLE *Tab)
3252{
3253 int i;
3254
3255 Tab->numAsOriginator = 0;
3256 Tab->numAsRecipient = 0;
3257 Tab->numDoneOriginator = 0;
3258 NdisAllocateSpinLock(&pAd->BATabLock);
3259 for (i = 0; i < MAX_LEN_OF_BA_REC_TABLE; i++)
3260 {
3261 Tab->BARecEntry[i].REC_BA_Status = Recipient_NONE;
3262 NdisAllocateSpinLock(&(Tab->BARecEntry[i].RxReRingLock));
3263 }
3264 for (i = 0; i < MAX_LEN_OF_BA_ORI_TABLE; i++)
3265 {
3266 Tab->BAOriEntry[i].ORI_BA_Status = Originator_NONE;
3267 }
3268}
3269
3345// IRQL = DISPATCH_LEVEL 3270// IRQL = DISPATCH_LEVEL
3346VOID MlmeRadioOff( 3271VOID MlmeRadioOff(
3347 IN PRTMP_ADAPTER pAd) 3272 IN PRTMP_ADAPTER pAd)
3348{ 3273{
3349 RT28XX_MLME_RADIO_OFF(pAd); 3274 RTMP_MLME_RADIO_OFF(pAd);
3350} 3275}
3351 3276
3352// IRQL = DISPATCH_LEVEL 3277// IRQL = DISPATCH_LEVEL
3353VOID MlmeRadioOn( 3278VOID MlmeRadioOn(
3354 IN PRTMP_ADAPTER pAd) 3279 IN PRTMP_ADAPTER pAd)
3355{ 3280{
3356 RT28XX_MLME_RADIO_ON(pAd); 3281 RTMP_MLME_RADIO_ON(pAd);
3357} 3282}
3358 3283
3359// =========================================================================================== 3284// ===========================================================================================
@@ -3379,31 +3304,12 @@ VOID BssTableInit(
3379 Tab->BssNr = 0; 3304 Tab->BssNr = 0;
3380 Tab->BssOverlapNr = 0; 3305 Tab->BssOverlapNr = 0;
3381 for (i = 0; i < MAX_LEN_OF_BSS_TABLE; i++) 3306 for (i = 0; i < MAX_LEN_OF_BSS_TABLE; i++)
3382 { 3307 {
3383 NdisZeroMemory(&Tab->BssEntry[i], sizeof(BSS_ENTRY)); 3308 NdisZeroMemory(&Tab->BssEntry[i], sizeof(BSS_ENTRY));
3384 Tab->BssEntry[i].Rssi = -127; // initial the rssi as a minimum value 3309 Tab->BssEntry[i].Rssi = -127; // initial the rssi as a minimum value
3385 } 3310 }
3386} 3311}
3387 3312
3388VOID BATableInit(
3389 IN PRTMP_ADAPTER pAd,
3390 IN BA_TABLE *Tab)
3391{
3392 int i;
3393
3394 Tab->numAsOriginator = 0;
3395 Tab->numAsRecipient = 0;
3396 NdisAllocateSpinLock(&pAd->BATabLock);
3397 for (i = 0; i < MAX_LEN_OF_BA_REC_TABLE; i++)
3398 {
3399 Tab->BARecEntry[i].REC_BA_Status = Recipient_NONE;
3400 NdisAllocateSpinLock(&(Tab->BARecEntry[i].RxReRingLock));
3401 }
3402 for (i = 0; i < MAX_LEN_OF_BA_ORI_TABLE; i++)
3403 {
3404 Tab->BAOriEntry[i].ORI_BA_Status = Originator_NONE;
3405 }
3406}
3407 3313
3408/*! \brief search the BSS table by SSID 3314/*! \brief search the BSS table by SSID
3409 * \param p_tab pointer to the bss table 3315 * \param p_tab pointer to the bss table
@@ -3489,6 +3395,25 @@ ULONG BssTableSearchWithSSID(
3489 return (ULONG)BSS_NOT_FOUND; 3395 return (ULONG)BSS_NOT_FOUND;
3490} 3396}
3491 3397
3398
3399ULONG BssSsidTableSearchBySSID(
3400 IN BSS_TABLE *Tab,
3401 IN PUCHAR pSsid,
3402 IN UCHAR SsidLen)
3403{
3404 UCHAR i;
3405
3406 for (i = 0; i < Tab->BssNr; i++)
3407 {
3408 if (SSID_EQUAL(pSsid, SsidLen, Tab->BssEntry[i].Ssid, Tab->BssEntry[i].SsidLen))
3409 {
3410 return i;
3411 }
3412 }
3413 return (ULONG)BSS_NOT_FOUND;
3414}
3415
3416
3492// IRQL = DISPATCH_LEVEL 3417// IRQL = DISPATCH_LEVEL
3493VOID BssTableDeleteEntry( 3418VOID BssTableDeleteEntry(
3494 IN OUT BSS_TABLE *Tab, 3419 IN OUT BSS_TABLE *Tab,
@@ -3555,7 +3480,7 @@ VOID BATableDeleteORIEntry(
3555 3480
3556 */ 3481 */
3557VOID BssEntrySet( 3482VOID BssEntrySet(
3558 IN PRTMP_ADAPTER pAd, 3483 IN PRTMP_ADAPTER pAd,
3559 OUT BSS_ENTRY *pBss, 3484 OUT BSS_ENTRY *pBss,
3560 IN PUCHAR pBssid, 3485 IN PUCHAR pBssid,
3561 IN CHAR Ssid[], 3486 IN CHAR Ssid[],
@@ -3632,8 +3557,6 @@ VOID BssEntrySet(
3632 pBss->SupRateLen = SupRateLen; 3557 pBss->SupRateLen = SupRateLen;
3633 ASSERT(ExtRateLen <= MAX_LEN_OF_SUPPORTED_RATES); 3558 ASSERT(ExtRateLen <= MAX_LEN_OF_SUPPORTED_RATES);
3634 NdisMoveMemory(pBss->ExtRate, ExtRate, ExtRateLen); 3559 NdisMoveMemory(pBss->ExtRate, ExtRate, ExtRateLen);
3635 NdisMoveMemory(&pBss->HtCapability, pHtCapability, HtCapabilityLen);
3636 NdisMoveMemory(&pBss->AddHtInfo, pAddHtInfo, AddHtInfoLen);
3637 pBss->NewExtChanOffset = NewExtChanOffset; 3560 pBss->NewExtChanOffset = NewExtChanOffset;
3638 pBss->ExtRateLen = ExtRateLen; 3561 pBss->ExtRateLen = ExtRateLen;
3639 pBss->Channel = Channel; 3562 pBss->Channel = Channel;
@@ -3660,7 +3583,6 @@ VOID BssEntrySet(
3660 3583
3661 pBss->AddHtInfoLen = 0; 3584 pBss->AddHtInfoLen = 0;
3662 pBss->HtCapabilityLen = 0; 3585 pBss->HtCapabilityLen = 0;
3663
3664 if (HtCapabilityLen> 0) 3586 if (HtCapabilityLen> 0)
3665 { 3587 {
3666 pBss->HtCapabilityLen = HtCapabilityLen; 3588 pBss->HtCapabilityLen = HtCapabilityLen;
@@ -3670,13 +3592,13 @@ VOID BssEntrySet(
3670 pBss->AddHtInfoLen = AddHtInfoLen; 3592 pBss->AddHtInfoLen = AddHtInfoLen;
3671 NdisMoveMemory(&pBss->AddHtInfo, pAddHtInfo, AddHtInfoLen); 3593 NdisMoveMemory(&pBss->AddHtInfo, pAddHtInfo, AddHtInfoLen);
3672 3594
3673 if ((pAddHtInfo->ControlChan > 2)&& (pAddHtInfo->AddHtInfo.ExtChanOffset == EXTCHA_BELOW) && (pHtCapability->HtCapInfo.ChannelWidth == BW_40)) 3595 if ((pAddHtInfo->ControlChan > 2)&& (pAddHtInfo->AddHtInfo.ExtChanOffset == EXTCHA_BELOW) && (pHtCapability->HtCapInfo.ChannelWidth == BW_40))
3674 {
3675 pBss->CentralChannel = pAddHtInfo->ControlChan - 2;
3676 }
3677 else if ((pAddHtInfo->AddHtInfo.ExtChanOffset == EXTCHA_ABOVE) && (pHtCapability->HtCapInfo.ChannelWidth == BW_40))
3678 { 3596 {
3679 pBss->CentralChannel = pAddHtInfo->ControlChan + 2; 3597 pBss->CentralChannel = pAddHtInfo->ControlChan - 2;
3598 }
3599 else if ((pAddHtInfo->AddHtInfo.ExtChanOffset == EXTCHA_ABOVE) && (pHtCapability->HtCapInfo.ChannelWidth == BW_40))
3600 {
3601 pBss->CentralChannel = pAddHtInfo->ControlChan + 2;
3680 } 3602 }
3681 } 3603 }
3682 } 3604 }
@@ -3704,38 +3626,36 @@ VOID BssEntrySet(
3704 3626
3705 NdisZeroMemory(&pBss->WpaIE.IE[0], MAX_CUSTOM_LEN); 3627 NdisZeroMemory(&pBss->WpaIE.IE[0], MAX_CUSTOM_LEN);
3706 NdisZeroMemory(&pBss->RsnIE.IE[0], MAX_CUSTOM_LEN); 3628 NdisZeroMemory(&pBss->RsnIE.IE[0], MAX_CUSTOM_LEN);
3707
3708 pEid = (PEID_STRUCT) pVIE; 3629 pEid = (PEID_STRUCT) pVIE;
3709
3710 while ((Length + 2 + (USHORT)pEid->Len) <= LengthVIE) 3630 while ((Length + 2 + (USHORT)pEid->Len) <= LengthVIE)
3711 { 3631 {
3712 switch(pEid->Eid) 3632 switch(pEid->Eid)
3713 { 3633 {
3714 case IE_WPA: 3634 case IE_WPA:
3715 if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4)) 3635 if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4))
3716 { 3636 {
3717 if ((pEid->Len + 2) > MAX_CUSTOM_LEN) 3637 if ((pEid->Len + 2) > MAX_CUSTOM_LEN)
3718 { 3638 {
3719 pBss->WpaIE.IELen = 0; 3639 pBss->WpaIE.IELen = 0;
3720 break; 3640 break;
3721 } 3641 }
3722 pBss->WpaIE.IELen = pEid->Len + 2; 3642 pBss->WpaIE.IELen = pEid->Len + 2;
3723 NdisMoveMemory(pBss->WpaIE.IE, pEid, pBss->WpaIE.IELen); 3643 NdisMoveMemory(pBss->WpaIE.IE, pEid, pBss->WpaIE.IELen);
3724 } 3644 }
3725 break; 3645 break;
3726 case IE_RSN: 3646 case IE_RSN:
3727 if (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3)) 3647 if (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3))
3728 { 3648 {
3729 if ((pEid->Len + 2) > MAX_CUSTOM_LEN) 3649 if ((pEid->Len + 2) > MAX_CUSTOM_LEN)
3730 { 3650 {
3731 pBss->RsnIE.IELen = 0; 3651 pBss->RsnIE.IELen = 0;
3732 break; 3652 break;
3733 } 3653 }
3734 pBss->RsnIE.IELen = pEid->Len + 2; 3654 pBss->RsnIE.IELen = pEid->Len + 2;
3735 NdisMoveMemory(pBss->RsnIE.IE, pEid, pBss->RsnIE.IELen); 3655 NdisMoveMemory(pBss->RsnIE.IE, pEid, pBss->RsnIE.IELen);
3736 } 3656 }
3737 break; 3657 break;
3738 } 3658 }
3739 Length = Length + 2 + (USHORT)pEid->Len; // Eid[1] + Len[1]+ content[Len] 3659 Length = Length + 2 + (USHORT)pEid->Len; // Eid[1] + Len[1]+ content[Len]
3740 pEid = (PEID_STRUCT)((UCHAR*)pEid + 2 + pEid->Len); 3660 pEid = (PEID_STRUCT)((UCHAR*)pEid + 2 + pEid->Len);
3741 } 3661 }
@@ -3766,7 +3686,7 @@ VOID BssEntrySet(
3766 3686
3767 */ 3687 */
3768ULONG BssTableSetEntry( 3688ULONG BssTableSetEntry(
3769 IN PRTMP_ADAPTER pAd, 3689 IN PRTMP_ADAPTER pAd,
3770 OUT BSS_TABLE *Tab, 3690 OUT BSS_TABLE *Tab,
3771 IN PUCHAR pBssid, 3691 IN PUCHAR pBssid,
3772 IN CHAR Ssid[], 3692 IN CHAR Ssid[],
@@ -3797,7 +3717,7 @@ ULONG BssTableSetEntry(
3797{ 3717{
3798 ULONG Idx; 3718 ULONG Idx;
3799 3719
3800 Idx = BssTableSearchWithSSID(Tab, pBssid, Ssid, SsidLen, ChannelNo); 3720 Idx = BssTableSearchWithSSID(Tab, pBssid, (UCHAR *)Ssid, SsidLen, ChannelNo);
3801 if (Idx == BSS_NOT_FOUND) 3721 if (Idx == BSS_NOT_FOUND)
3802 { 3722 {
3803 if (Tab->BssNr >= MAX_LEN_OF_BSS_TABLE) 3723 if (Tab->BssNr >= MAX_LEN_OF_BSS_TABLE)
@@ -3808,10 +3728,10 @@ ULONG BssTableSetEntry(
3808 // In this case, if we found the desired AP then overwrite BSS Table. 3728 // In this case, if we found the desired AP then overwrite BSS Table.
3809 // 3729 //
3810 if(!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) 3730 if(!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
3811 { 3731 {
3812 if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, pBssid) || 3732 if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, pBssid) ||
3813 SSID_EQUAL(pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, Ssid, SsidLen)) 3733 SSID_EQUAL(pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, Ssid, SsidLen))
3814 { 3734 {
3815 Idx = Tab->BssOverlapNr; 3735 Idx = Tab->BssOverlapNr;
3816 BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, BssType, BeaconPeriod, CfParm, AtimWin, 3736 BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, BssType, BeaconPeriod, CfParm, AtimWin,
3817 CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,pHtCapability, pAddHtInfo,HtCapabilityLen, AddHtInfoLen, 3737 CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,pHtCapability, pAddHtInfo,HtCapabilityLen, AddHtInfoLen,
@@ -3819,11 +3739,11 @@ ULONG BssTableSetEntry(
3819 Tab->BssOverlapNr = (Tab->BssOverlapNr++) % MAX_LEN_OF_BSS_TABLE; 3739 Tab->BssOverlapNr = (Tab->BssOverlapNr++) % MAX_LEN_OF_BSS_TABLE;
3820 } 3740 }
3821 return Idx; 3741 return Idx;
3822 } 3742 }
3823 else 3743 else
3824 { 3744 {
3825 return BSS_NOT_FOUND; 3745 return BSS_NOT_FOUND;
3826 } 3746 }
3827 } 3747 }
3828 Idx = Tab->BssNr; 3748 Idx = Tab->BssNr;
3829 BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, BssType, BeaconPeriod, CfParm, AtimWin, 3749 BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, BssType, BeaconPeriod, CfParm, AtimWin,
@@ -3837,15 +3757,16 @@ ULONG BssTableSetEntry(
3837 if ((SSID_EQUAL(Ssid, SsidLen, Tab->BssEntry[Idx].Ssid, Tab->BssEntry[Idx].SsidLen)) || 3757 if ((SSID_EQUAL(Ssid, SsidLen, Tab->BssEntry[Idx].Ssid, Tab->BssEntry[Idx].SsidLen)) ||
3838 (NdisEqualMemory(Tab->BssEntry[Idx].Ssid, ZeroSsid, Tab->BssEntry[Idx].SsidLen))) 3758 (NdisEqualMemory(Tab->BssEntry[Idx].Ssid, ZeroSsid, Tab->BssEntry[Idx].SsidLen)))
3839 { 3759 {
3840 BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, BssType, BeaconPeriod,CfParm, AtimWin, 3760 BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, BssType, BeaconPeriod,CfParm, AtimWin,
3841 CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,pHtCapability, pAddHtInfo,HtCapabilityLen, AddHtInfoLen, 3761 CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,pHtCapability, pAddHtInfo,HtCapabilityLen, AddHtInfoLen,
3842 NewExtChanOffset, ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm, pQosCapability, pQbssLoad, LengthVIE, pVIE); 3762 NewExtChanOffset, ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm, pQosCapability, pQbssLoad, LengthVIE, pVIE);
3843 } 3763 }
3844 } 3764 }
3845 3765
3846 return Idx; 3766 return Idx;
3847} 3767}
3848 3768
3769
3849// IRQL = DISPATCH_LEVEL 3770// IRQL = DISPATCH_LEVEL
3850VOID BssTableSsidSort( 3771VOID BssTableSsidSort(
3851 IN PRTMP_ADAPTER pAd, 3772 IN PRTMP_ADAPTER pAd,
@@ -3865,24 +3786,33 @@ VOID BssTableSsidSort(
3865 (pAd->MlmeAux.Channel > 14) && 3786 (pAd->MlmeAux.Channel > 14) &&
3866 RadarChannelCheck(pAd, pInBss->Channel)) 3787 RadarChannelCheck(pAd, pInBss->Channel))
3867 ) 3788 )
3868 { 3789{
3869 if (pInBss->Hidden) 3790 if (pInBss->Hidden)
3870 bIsHiddenApIncluded = TRUE; 3791 bIsHiddenApIncluded = TRUE;
3871 } 3792}
3872 3793
3873 if ((pInBss->BssType == pAd->StaCfg.BssType) && 3794 if ((pInBss->BssType == pAd->StaCfg.BssType) &&
3874 (SSID_EQUAL(Ssid, SsidLen, pInBss->Ssid, pInBss->SsidLen) || bIsHiddenApIncluded)) 3795 (SSID_EQUAL(Ssid, SsidLen, pInBss->Ssid, pInBss->SsidLen) || bIsHiddenApIncluded))
3875 { 3796 {
3876 BSS_ENTRY *pOutBss = &OutTab->BssEntry[OutTab->BssNr]; 3797 BSS_ENTRY *pOutBss = &OutTab->BssEntry[OutTab->BssNr];
3877 3798
3799
3800
3878 // 2.4G/5G N only mode 3801 // 2.4G/5G N only mode
3879 if ((pInBss->HtCapabilityLen == 0) && 3802 if ((pInBss->HtCapabilityLen == 0) &&
3880 ((pAd->CommonCfg.PhyMode == PHY_11N_2_4G) || (pAd->CommonCfg.PhyMode == PHY_11N_5G))) 3803 ((pAd->CommonCfg.PhyMode == PHY_11N_2_4G) || (pAd->CommonCfg.PhyMode == PHY_11N_5G)))
3881 { 3804 {
3882 DBGPRINT(RT_DEBUG_TRACE,("STA is in N-only Mode, this AP don't have Ht capability in Beacon.\n")); 3805 DBGPRINT(RT_DEBUG_TRACE,("STA is in N-only Mode, this AP don't have Ht capability in Beacon.\n"));
3883 continue; 3806 continue;
3884 } 3807 }
3885 3808#ifdef RT2860
3809 if ((pAd->CommonCfg.PhyMode == PHY_11GN_MIXED) &&
3810 ((pInBss->SupRateLen + pInBss->ExtRateLen) < 12))
3811 {
3812 DBGPRINT(RT_DEBUG_TRACE,("STA is in GN-only Mode, this AP is in B mode.\n"));
3813 continue;
3814 }
3815#endif // RT2860 //
3886 // New for WPA2 3816 // New for WPA2
3887 // Check the Authmode first 3817 // Check the Authmode first
3888 if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) 3818 if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
@@ -3901,9 +3831,9 @@ VOID BssTableSsidSort(
3901 continue; 3831 continue;
3902 3832
3903 // check group cipher 3833 // check group cipher
3904 if (pInBss->WPA.GroupCipher != Ndis802_11GroupWEP40Enabled && 3834 if ((pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher) &&
3905 pInBss->WPA.GroupCipher != Ndis802_11GroupWEP104Enabled && 3835 (pInBss->WPA.GroupCipher != Ndis802_11GroupWEP40Enabled) &&
3906 pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher) 3836 (pInBss->WPA.GroupCipher != Ndis802_11GroupWEP104Enabled))
3907 continue; 3837 continue;
3908 3838
3909 // check pairwise cipher, skip if none matched 3839 // check pairwise cipher, skip if none matched
@@ -3922,9 +3852,9 @@ VOID BssTableSsidSort(
3922 continue; 3852 continue;
3923 3853
3924 // check group cipher 3854 // check group cipher
3925 if (pInBss->WPA2.GroupCipher != Ndis802_11GroupWEP40Enabled && 3855 if ((pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher) &&
3926 pInBss->WPA2.GroupCipher != Ndis802_11GroupWEP104Enabled && 3856 (pInBss->WPA2.GroupCipher != Ndis802_11GroupWEP40Enabled) &&
3927 pAd->StaCfg.WepStatus < pInBss->WPA2.GroupCipher) 3857 (pInBss->WPA2.GroupCipher != Ndis802_11GroupWEP104Enabled))
3928 continue; 3858 continue;
3929 3859
3930 // check pairwise cipher, skip if none matched 3860 // check pairwise cipher, skip if none matched
@@ -3943,7 +3873,7 @@ VOID BssTableSsidSort(
3943 DBGPRINT(RT_DEBUG_TRACE,("StaCfg.WepStatus=%d, while pInBss->WepStatus=%d\n", pAd->StaCfg.WepStatus, pInBss->WepStatus)); 3873 DBGPRINT(RT_DEBUG_TRACE,("StaCfg.WepStatus=%d, while pInBss->WepStatus=%d\n", pAd->StaCfg.WepStatus, pInBss->WepStatus));
3944 // 3874 //
3945 // For the SESv2 case, we will not qualify WepStatus. 3875 // For the SESv2 case, we will not qualify WepStatus.
3946 // 3876 //
3947 if (!pInBss->bSES) 3877 if (!pInBss->bSES)
3948 continue; 3878 continue;
3949 } 3879 }
@@ -3958,9 +3888,9 @@ VOID BssTableSsidSort(
3958 // If this 40MHz wideband is not allowed in my country list, use bandwidth 20MHZ instead, 3888 // If this 40MHz wideband is not allowed in my country list, use bandwidth 20MHZ instead,
3959 if ((pInBss->CentralChannel != pInBss->Channel) && 3889 if ((pInBss->CentralChannel != pInBss->Channel) &&
3960 (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40)) 3890 (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40))
3961 { 3891 {
3962 if (RTMPCheckChannel(pAd, pInBss->CentralChannel, pInBss->Channel) == FALSE) 3892 if (RTMPCheckChannel(pAd, pInBss->CentralChannel, pInBss->Channel) == FALSE)
3963 { 3893 {
3964 pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20; 3894 pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
3965 SetCommonHT(pAd); 3895 SetCommonHT(pAd);
3966 pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40; 3896 pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40;
@@ -3971,8 +3901,8 @@ VOID BssTableSsidSort(
3971 { 3901 {
3972 SetCommonHT(pAd); 3902 SetCommonHT(pAd);
3973 } 3903 }
3974 } 3904 }
3975 } 3905 }
3976 3906
3977 // copy matching BSS from InTab to OutTab 3907 // copy matching BSS from InTab to OutTab
3978 NdisMoveMemory(pOutBss, pInBss, sizeof(BSS_ENTRY)); 3908 NdisMoveMemory(pOutBss, pInBss, sizeof(BSS_ENTRY));
@@ -3980,17 +3910,25 @@ VOID BssTableSsidSort(
3980 OutTab->BssNr++; 3910 OutTab->BssNr++;
3981 } 3911 }
3982 else if ((pInBss->BssType == pAd->StaCfg.BssType) && (SsidLen == 0)) 3912 else if ((pInBss->BssType == pAd->StaCfg.BssType) && (SsidLen == 0))
3983 { 3913 {
3984 BSS_ENTRY *pOutBss = &OutTab->BssEntry[OutTab->BssNr]; 3914 BSS_ENTRY *pOutBss = &OutTab->BssEntry[OutTab->BssNr];
3985 3915
3916
3986 // 2.4G/5G N only mode 3917 // 2.4G/5G N only mode
3987 if ((pInBss->HtCapabilityLen == 0) && 3918 if ((pInBss->HtCapabilityLen == 0) &&
3988 ((pAd->CommonCfg.PhyMode == PHY_11N_2_4G) || (pAd->CommonCfg.PhyMode == PHY_11N_5G))) 3919 ((pAd->CommonCfg.PhyMode == PHY_11N_2_4G) || (pAd->CommonCfg.PhyMode == PHY_11N_5G)))
3989 { 3920 {
3990 DBGPRINT(RT_DEBUG_TRACE,("STA is in N-only Mode, this AP don't have Ht capability in Beacon.\n")); 3921 DBGPRINT(RT_DEBUG_TRACE,("STA is in N-only Mode, this AP don't have Ht capability in Beacon.\n"));
3991 continue; 3922 continue;
3992 } 3923 }
3993 3924#ifdef RT2860
3925 if ((pAd->CommonCfg.PhyMode == PHY_11GN_MIXED) &&
3926 ((pInBss->SupRateLen + pInBss->ExtRateLen) < 12))
3927 {
3928 DBGPRINT(RT_DEBUG_TRACE,("STA is in GN-only Mode, this AP is in B mode.\n"));
3929 continue;
3930 }
3931#endif // RT2860 //
3994 // New for WPA2 3932 // New for WPA2
3995 // Check the Authmode first 3933 // Check the Authmode first
3996 if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) 3934 if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
@@ -4049,14 +3987,14 @@ VOID BssTableSsidSort(
4049 // If this 40MHz wideband is not allowed in my country list, use bandwidth 20MHZ instead, 3987 // If this 40MHz wideband is not allowed in my country list, use bandwidth 20MHZ instead,
4050 if ((pInBss->CentralChannel != pInBss->Channel) && 3988 if ((pInBss->CentralChannel != pInBss->Channel) &&
4051 (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40)) 3989 (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40))
4052 { 3990 {
4053 if (RTMPCheckChannel(pAd, pInBss->CentralChannel, pInBss->Channel) == FALSE) 3991 if (RTMPCheckChannel(pAd, pInBss->CentralChannel, pInBss->Channel) == FALSE)
4054 { 3992 {
4055 pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20; 3993 pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
4056 SetCommonHT(pAd); 3994 SetCommonHT(pAd);
4057 pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40; 3995 pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40;
4058 } 3996 }
4059 } 3997 }
4060 3998
4061 // copy matching BSS from InTab to OutTab 3999 // copy matching BSS from InTab to OutTab
4062 NdisMoveMemory(pOutBss, pInBss, sizeof(BSS_ENTRY)); 4000 NdisMoveMemory(pOutBss, pInBss, sizeof(BSS_ENTRY));
@@ -4065,8 +4003,8 @@ VOID BssTableSsidSort(
4065 } 4003 }
4066 4004
4067 if (OutTab->BssNr >= MAX_LEN_OF_BSS_TABLE) 4005 if (OutTab->BssNr >= MAX_LEN_OF_BSS_TABLE)
4068 break; 4006 break;
4069 } 4007 }
4070 4008
4071 BssTableSortByRssi(OutTab); 4009 BssTableSortByRssi(OutTab);
4072} 4010}
@@ -4076,27 +4014,28 @@ VOID BssTableSsidSort(
4076VOID BssTableSortByRssi( 4014VOID BssTableSortByRssi(
4077 IN OUT BSS_TABLE *OutTab) 4015 IN OUT BSS_TABLE *OutTab)
4078{ 4016{
4079 INT i, j; 4017 INT i, j;
4080 BSS_ENTRY TmpBss; 4018 BSS_ENTRY TmpBss;
4081 4019
4082 for (i = 0; i < OutTab->BssNr - 1; i++) 4020 for (i = 0; i < OutTab->BssNr - 1; i++)
4083 { 4021 {
4084 for (j = i+1; j < OutTab->BssNr; j++) 4022 for (j = i+1; j < OutTab->BssNr; j++)
4085 { 4023 {
4086 if (OutTab->BssEntry[j].Rssi > OutTab->BssEntry[i].Rssi) 4024 if (OutTab->BssEntry[j].Rssi > OutTab->BssEntry[i].Rssi)
4087 { 4025 {
4088 NdisMoveMemory(&TmpBss, &OutTab->BssEntry[j], sizeof(BSS_ENTRY)); 4026 NdisMoveMemory(&TmpBss, &OutTab->BssEntry[j], sizeof(BSS_ENTRY));
4089 NdisMoveMemory(&OutTab->BssEntry[j], &OutTab->BssEntry[i], sizeof(BSS_ENTRY)); 4027 NdisMoveMemory(&OutTab->BssEntry[j], &OutTab->BssEntry[i], sizeof(BSS_ENTRY));
4090 NdisMoveMemory(&OutTab->BssEntry[i], &TmpBss, sizeof(BSS_ENTRY)); 4028 NdisMoveMemory(&OutTab->BssEntry[i], &TmpBss, sizeof(BSS_ENTRY));
4091 } 4029 }
4092 } 4030 }
4093 } 4031 }
4094} 4032}
4095 4033
4034
4096VOID BssCipherParse( 4035VOID BssCipherParse(
4097 IN OUT PBSS_ENTRY pBss) 4036 IN OUT PBSS_ENTRY pBss)
4098{ 4037{
4099 PEID_STRUCT pEid; 4038 PEID_STRUCT pEid;
4100 PUCHAR pTmp; 4039 PUCHAR pTmp;
4101 PRSN_IE_HEADER_STRUCT pRsnHeader; 4040 PRSN_IE_HEADER_STRUCT pRsnHeader;
4102 PCIPHER_SUITE_STRUCT pCipher; 4041 PCIPHER_SUITE_STRUCT pCipher;
@@ -4109,13 +4048,13 @@ VOID BssCipherParse(
4109 // WepStatus will be reset later, if AP announce TKIP or AES on the beacon frame. 4048 // WepStatus will be reset later, if AP announce TKIP or AES on the beacon frame.
4110 // 4049 //
4111 if (pBss->Privacy) 4050 if (pBss->Privacy)
4112 { 4051 {
4113 pBss->WepStatus = Ndis802_11WEPEnabled; 4052 pBss->WepStatus = Ndis802_11WEPEnabled;
4114 } 4053 }
4115 else 4054 else
4116 { 4055 {
4117 pBss->WepStatus = Ndis802_11WEPDisabled; 4056 pBss->WepStatus = Ndis802_11WEPDisabled;
4118 } 4057 }
4119 // Set default to disable & open authentication before parsing variable IE 4058 // Set default to disable & open authentication before parsing variable IE
4120 pBss->AuthMode = Ndis802_11AuthModeOpen; 4059 pBss->AuthMode = Ndis802_11AuthModeOpen;
4121 pBss->AuthModeAux = Ndis802_11AuthModeOpen; 4060 pBss->AuthModeAux = Ndis802_11AuthModeOpen;
@@ -4132,58 +4071,29 @@ VOID BssCipherParse(
4132 pBss->WPA2.PairCipherAux = Ndis802_11WEPDisabled; 4071 pBss->WPA2.PairCipherAux = Ndis802_11WEPDisabled;
4133 pBss->WPA2.GroupCipher = Ndis802_11WEPDisabled; 4072 pBss->WPA2.GroupCipher = Ndis802_11WEPDisabled;
4134 pBss->WPA2.RsnCapability = 0; 4073 pBss->WPA2.RsnCapability = 0;
4135 pBss->WPA2.bMixMode = FALSE; 4074 pBss->WPA2.bMixMode = FALSE;
4136 4075
4137 4076
4138 Length = (INT) pBss->VarIELen; 4077 Length = (INT) pBss->VarIELen;
4139 4078
4140 while (Length > 0) 4079 while (Length > 0)
4141 { 4080 {
4142 // Parse cipher suite base on WPA1 & WPA2, they should be parsed differently 4081 // Parse cipher suite base on WPA1 & WPA2, they should be parsed differently
4143 pTmp = ((PUCHAR) pBss->VarIEs) + pBss->VarIELen - Length; 4082 pTmp = ((PUCHAR) pBss->VarIEs) + pBss->VarIELen - Length;
4144 pEid = (PEID_STRUCT) pTmp; 4083 pEid = (PEID_STRUCT) pTmp;
4145 switch (pEid->Eid) 4084 switch (pEid->Eid)
4146 { 4085 {
4147 case IE_WPA: 4086 case IE_WPA:
4148 //Parse Cisco IE_WPA (LEAP, CCKM, etc.) 4087 if (NdisEqualMemory(pEid->Octet, SES_OUI, 3) && (pEid->Len == 7))
4149 if ( NdisEqualMemory((pTmp+8), CISCO_OUI, 3)) 4088 {
4150 {
4151 pTmp += 11;
4152 switch (*pTmp)
4153 {
4154 case 1:
4155 case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
4156 pBss->WepStatus = Ndis802_11Encryption1Enabled;
4157 pBss->WPA.PairCipher = Ndis802_11Encryption1Enabled;
4158 pBss->WPA.GroupCipher = Ndis802_11Encryption1Enabled;
4159 break;
4160 case 2:
4161 pBss->WepStatus = Ndis802_11Encryption2Enabled;
4162 pBss->WPA.PairCipher = Ndis802_11Encryption1Enabled;
4163 pBss->WPA.GroupCipher = Ndis802_11Encryption1Enabled;
4164 break;
4165 case 4:
4166 pBss->WepStatus = Ndis802_11Encryption3Enabled;
4167 pBss->WPA.PairCipher = Ndis802_11Encryption1Enabled;
4168 pBss->WPA.GroupCipher = Ndis802_11Encryption1Enabled;
4169 break;
4170 default:
4171 break;
4172 }
4173
4174 // if Cisco IE_WPA, break
4175 break;
4176 }
4177 else if (NdisEqualMemory(pEid->Octet, SES_OUI, 3) && (pEid->Len == 7))
4178 {
4179 pBss->bSES = TRUE; 4089 pBss->bSES = TRUE;
4180 break; 4090 break;
4181 } 4091 }
4182 else if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4) != 1) 4092 else if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4) != 1)
4183 { 4093 {
4184 // if unsupported vendor specific IE 4094 // if unsupported vendor specific IE
4185 break; 4095 break;
4186 } 4096 }
4187 // Skip OUI, version, and multicast suite 4097 // Skip OUI, version, and multicast suite
4188 // This part should be improved in the future when AP supported multiple cipher suite. 4098 // This part should be improved in the future when AP supported multiple cipher suite.
4189 // For now, it's OK since almost all APs have fixed cipher suite supported. 4099 // For now, it's OK since almost all APs have fixed cipher suite supported.
@@ -4200,7 +4110,7 @@ VOID BssCipherParse(
4200 // 5 WEP-104 4110 // 5 WEP-104
4201 // Parse group cipher 4111 // Parse group cipher
4202 switch (*pTmp) 4112 switch (*pTmp)
4203 { 4113 {
4204 case 1: 4114 case 1:
4205 pBss->WPA.GroupCipher = Ndis802_11GroupWEP40Enabled; 4115 pBss->WPA.GroupCipher = Ndis802_11GroupWEP40Enabled;
4206 break; 4116 break;
@@ -4226,12 +4136,12 @@ VOID BssCipherParse(
4226 4136
4227 // Parsing all unicast cipher suite 4137 // Parsing all unicast cipher suite
4228 while (Count > 0) 4138 while (Count > 0)
4229 { 4139 {
4230 // Skip OUI 4140 // Skip OUI
4231 pTmp += 3; 4141 pTmp += 3;
4232 TmpCipher = Ndis802_11WEPDisabled; 4142 TmpCipher = Ndis802_11WEPDisabled;
4233 switch (*pTmp) 4143 switch (*pTmp)
4234 { 4144 {
4235 case 1: 4145 case 1:
4236 case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway 4146 case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
4237 TmpCipher = Ndis802_11Encryption1Enabled; 4147 TmpCipher = Ndis802_11Encryption1Enabled;
@@ -4244,20 +4154,20 @@ VOID BssCipherParse(
4244 break; 4154 break;
4245 default: 4155 default:
4246 break; 4156 break;
4247 } 4157 }
4248 if (TmpCipher > pBss->WPA.PairCipher) 4158 if (TmpCipher > pBss->WPA.PairCipher)
4249 { 4159 {
4250 // Move the lower cipher suite to PairCipherAux 4160 // Move the lower cipher suite to PairCipherAux
4251 pBss->WPA.PairCipherAux = pBss->WPA.PairCipher; 4161 pBss->WPA.PairCipherAux = pBss->WPA.PairCipher;
4252 pBss->WPA.PairCipher = TmpCipher; 4162 pBss->WPA.PairCipher = TmpCipher;
4253 } 4163 }
4254 else 4164 else
4255 { 4165 {
4256 pBss->WPA.PairCipherAux = TmpCipher; 4166 pBss->WPA.PairCipherAux = TmpCipher;
4257 } 4167 }
4258 pTmp++; 4168 pTmp++;
4259 Count--; 4169 Count--;
4260 } 4170 }
4261 4171
4262 // 4. get AKM suite counts 4172 // 4. get AKM suite counts
4263 //Count = *(PUSHORT) pTmp; 4173 //Count = *(PUSHORT) pTmp;
@@ -4266,36 +4176,37 @@ VOID BssCipherParse(
4266 pTmp += 3; 4176 pTmp += 3;
4267 4177
4268 switch (*pTmp) 4178 switch (*pTmp)
4269 { 4179 {
4270 case 1: 4180 case 1:
4271 // Set AP support WPA mode 4181 // Set AP support WPA-enterprise mode
4272 if (pBss->AuthMode == Ndis802_11AuthModeOpen) 4182 if (pBss->AuthMode == Ndis802_11AuthModeOpen)
4273 pBss->AuthMode = Ndis802_11AuthModeWPA; 4183 pBss->AuthMode = Ndis802_11AuthModeWPA;
4274 else 4184 else
4275 pBss->AuthModeAux = Ndis802_11AuthModeWPA; 4185 pBss->AuthModeAux = Ndis802_11AuthModeWPA;
4276 break; 4186 break;
4277 case 2: 4187 case 2:
4278 // Set AP support WPA mode 4188 // Set AP support WPA-PSK mode
4279 if (pBss->AuthMode == Ndis802_11AuthModeOpen) 4189 if (pBss->AuthMode == Ndis802_11AuthModeOpen)
4280 pBss->AuthMode = Ndis802_11AuthModeWPAPSK; 4190 pBss->AuthMode = Ndis802_11AuthModeWPAPSK;
4281 else 4191 else
4282 pBss->AuthModeAux = Ndis802_11AuthModeWPAPSK; 4192 pBss->AuthModeAux = Ndis802_11AuthModeWPAPSK;
4283 break; 4193 break;
4284 default: 4194 default:
4285 break; 4195 break;
4286 } 4196 }
4287 pTmp += 1; 4197 pTmp += 1;
4288 4198
4289 // Fixed for WPA-None 4199 // Fixed for WPA-None
4290 if (pBss->BssType == BSS_ADHOC) 4200 if (pBss->BssType == BSS_ADHOC)
4291 { 4201 {
4292 pBss->AuthMode = Ndis802_11AuthModeWPANone; 4202 pBss->AuthMode = Ndis802_11AuthModeWPANone;
4293 pBss->AuthModeAux = Ndis802_11AuthModeWPANone; 4203 pBss->AuthModeAux = Ndis802_11AuthModeWPANone;
4294 pBss->WepStatus = pBss->WPA.GroupCipher; 4204 pBss->WepStatus = pBss->WPA.GroupCipher;
4205 // Patched bugs for old driver
4295 if (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled) 4206 if (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled)
4296 pBss->WPA.PairCipherAux = pBss->WPA.GroupCipher; 4207 pBss->WPA.PairCipherAux = pBss->WPA.GroupCipher;
4297 } 4208 }
4298 else 4209 else
4299 pBss->WepStatus = pBss->WPA.PairCipher; 4210 pBss->WepStatus = pBss->WPA.PairCipher;
4300 4211
4301 // Check the Pair & Group, if different, turn on mixed mode flag 4212 // Check the Pair & Group, if different, turn on mixed mode flag
@@ -4315,7 +4226,7 @@ VOID BssCipherParse(
4315 // 1. Check group cipher 4226 // 1. Check group cipher
4316 pCipher = (PCIPHER_SUITE_STRUCT) pTmp; 4227 pCipher = (PCIPHER_SUITE_STRUCT) pTmp;
4317 if (!RTMPEqualMemory(pTmp, RSN_OUI, 3)) 4228 if (!RTMPEqualMemory(pTmp, RSN_OUI, 3))
4318 break; 4229 break;
4319 4230
4320 // Parse group cipher 4231 // Parse group cipher
4321 switch (pCipher->Type) 4232 switch (pCipher->Type)
@@ -4346,12 +4257,12 @@ VOID BssCipherParse(
4346 // 3. Get pairwise cipher 4257 // 3. Get pairwise cipher
4347 // Parsing all unicast cipher suite 4258 // Parsing all unicast cipher suite
4348 while (Count > 0) 4259 while (Count > 0)
4349 { 4260 {
4350 // Skip OUI 4261 // Skip OUI
4351 pCipher = (PCIPHER_SUITE_STRUCT) pTmp; 4262 pCipher = (PCIPHER_SUITE_STRUCT) pTmp;
4352 TmpCipher = Ndis802_11WEPDisabled; 4263 TmpCipher = Ndis802_11WEPDisabled;
4353 switch (pCipher->Type) 4264 switch (pCipher->Type)
4354 { 4265 {
4355 case 1: 4266 case 1:
4356 case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway 4267 case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
4357 TmpCipher = Ndis802_11Encryption1Enabled; 4268 TmpCipher = Ndis802_11Encryption1Enabled;
@@ -4364,20 +4275,20 @@ VOID BssCipherParse(
4364 break; 4275 break;
4365 default: 4276 default:
4366 break; 4277 break;
4367 } 4278 }
4368 if (TmpCipher > pBss->WPA2.PairCipher) 4279 if (TmpCipher > pBss->WPA2.PairCipher)
4369 { 4280 {
4370 // Move the lower cipher suite to PairCipherAux 4281 // Move the lower cipher suite to PairCipherAux
4371 pBss->WPA2.PairCipherAux = pBss->WPA2.PairCipher; 4282 pBss->WPA2.PairCipherAux = pBss->WPA2.PairCipher;
4372 pBss->WPA2.PairCipher = TmpCipher; 4283 pBss->WPA2.PairCipher = TmpCipher;
4373 } 4284 }
4374 else 4285 else
4375 { 4286 {
4376 pBss->WPA2.PairCipherAux = TmpCipher; 4287 pBss->WPA2.PairCipherAux = TmpCipher;
4377 } 4288 }
4378 pTmp += sizeof(CIPHER_SUITE_STRUCT); 4289 pTmp += sizeof(CIPHER_SUITE_STRUCT);
4379 Count--; 4290 Count--;
4380 } 4291 }
4381 4292
4382 // 4. get AKM suite counts 4293 // 4. get AKM suite counts
4383 //Count = *(PUSHORT) pTmp; 4294 //Count = *(PUSHORT) pTmp;
@@ -4385,30 +4296,39 @@ VOID BssCipherParse(
4385 pTmp += sizeof(USHORT); 4296 pTmp += sizeof(USHORT);
4386 4297
4387 // 5. Get AKM ciphers 4298 // 5. Get AKM ciphers
4388 pAKM = (PAKM_SUITE_STRUCT) pTmp; 4299 // Parsing all AKM ciphers
4389 if (!RTMPEqualMemory(pTmp, RSN_OUI, 3)) 4300 while (Count > 0)
4390 break; 4301 {
4302 pAKM = (PAKM_SUITE_STRUCT) pTmp;
4303 if (!RTMPEqualMemory(pTmp, RSN_OUI, 3))
4304 break;
4391 4305
4392 switch (pAKM->Type) 4306 switch (pAKM->Type)
4393 { 4307 {
4394 case 1: 4308 case 1:
4395 // Set AP support WPA mode 4309 // Set AP support WPA-enterprise mode
4396 if (pBss->AuthMode == Ndis802_11AuthModeOpen) 4310 if (pBss->AuthMode == Ndis802_11AuthModeOpen)
4397 pBss->AuthMode = Ndis802_11AuthModeWPA2; 4311 pBss->AuthMode = Ndis802_11AuthModeWPA2;
4398 else 4312 else
4399 pBss->AuthModeAux = Ndis802_11AuthModeWPA2; 4313 pBss->AuthModeAux = Ndis802_11AuthModeWPA2;
4400 break; 4314 break;
4401 case 2: 4315 case 2:
4402 // Set AP support WPA mode 4316 // Set AP support WPA-PSK mode
4403 if (pBss->AuthMode == Ndis802_11AuthModeOpen) 4317 if (pBss->AuthMode == Ndis802_11AuthModeOpen)
4404 pBss->AuthMode = Ndis802_11AuthModeWPA2PSK; 4318 pBss->AuthMode = Ndis802_11AuthModeWPA2PSK;
4405 else 4319 else
4406 pBss->AuthModeAux = Ndis802_11AuthModeWPA2PSK; 4320 pBss->AuthModeAux = Ndis802_11AuthModeWPA2PSK;
4407 break; 4321 break;
4408 default: 4322 default:
4409 break; 4323 if (pBss->AuthMode == Ndis802_11AuthModeOpen)
4324 pBss->AuthMode = Ndis802_11AuthModeMax;
4325 else
4326 pBss->AuthModeAux = Ndis802_11AuthModeMax;
4327 break;
4410 } 4328 }
4411 pTmp += (Count * sizeof(AKM_SUITE_STRUCT)); 4329 pTmp += (Count * sizeof(AKM_SUITE_STRUCT));
4330 Count--;
4331 }
4412 4332
4413 // Fixed for WPA-None 4333 // Fixed for WPA-None
4414 if (pBss->BssType == BSS_ADHOC) 4334 if (pBss->BssType == BSS_ADHOC)
@@ -4417,10 +4337,11 @@ VOID BssCipherParse(
4417 pBss->AuthModeAux = Ndis802_11AuthModeWPANone; 4337 pBss->AuthModeAux = Ndis802_11AuthModeWPANone;
4418 pBss->WPA.PairCipherAux = pBss->WPA2.PairCipherAux; 4338 pBss->WPA.PairCipherAux = pBss->WPA2.PairCipherAux;
4419 pBss->WPA.GroupCipher = pBss->WPA2.GroupCipher; 4339 pBss->WPA.GroupCipher = pBss->WPA2.GroupCipher;
4420 pBss->WepStatus = pBss->WPA.GroupCipher; 4340 pBss->WepStatus = pBss->WPA.GroupCipher;
4341 // Patched bugs for old driver
4421 if (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled) 4342 if (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled)
4422 pBss->WPA.PairCipherAux = pBss->WPA.GroupCipher; 4343 pBss->WPA.PairCipherAux = pBss->WPA.GroupCipher;
4423 } 4344 }
4424 pBss->WepStatus = pBss->WPA2.PairCipher; 4345 pBss->WepStatus = pBss->WPA2.PairCipher;
4425 4346
4426 // 6. Get RSN capability 4347 // 6. Get RSN capability
@@ -4475,8 +4396,8 @@ VOID MacAddrRandomBssid(
4475 * \post 4396 * \post
4476 * \note this function initializes the following field 4397 * \note this function initializes the following field
4477 4398
4478 IRQL = PASSIVE_LEVEL 4399 IRQL = PASSIVE_LEVEL
4479 IRQL = DISPATCH_LEVEL 4400 IRQL = DISPATCH_LEVEL
4480 4401
4481 */ 4402 */
4482VOID MgtMacHeaderInit( 4403VOID MgtMacHeaderInit(
@@ -4491,11 +4412,11 @@ VOID MgtMacHeaderInit(
4491 4412
4492 pHdr80211->FC.Type = BTYPE_MGMT; 4413 pHdr80211->FC.Type = BTYPE_MGMT;
4493 pHdr80211->FC.SubType = SubType; 4414 pHdr80211->FC.SubType = SubType;
4415// if (SubType == SUBTYPE_ACK) // sample, no use, it will conflict with ACTION frame sub type
4416// pHdr80211->FC.Type = BTYPE_CNTL;
4494 pHdr80211->FC.ToDs = ToDs; 4417 pHdr80211->FC.ToDs = ToDs;
4495 COPY_MAC_ADDR(pHdr80211->Addr1, pDA); 4418 COPY_MAC_ADDR(pHdr80211->Addr1, pDA);
4496 4419 COPY_MAC_ADDR(pHdr80211->Addr2, pAd->CurrentAddress);
4497 COPY_MAC_ADDR(pHdr80211->Addr2, pAd->CurrentAddress);
4498
4499 COPY_MAC_ADDR(pHdr80211->Addr3, pBssid); 4420 COPY_MAC_ADDR(pHdr80211->Addr3, pBssid);
4500} 4421}
4501 4422
@@ -4518,15 +4439,15 @@ VOID MgtMacHeaderInit(
4518 * MakeOutgoingFrame(Buffer, output_length, 2, &fc, 2, &dur, 6, p_addr1, 6,p_addr2, END_OF_ARGS); 4439 * MakeOutgoingFrame(Buffer, output_length, 2, &fc, 2, &dur, 6, p_addr1, 6,p_addr2, END_OF_ARGS);
4519 4440
4520 IRQL = PASSIVE_LEVEL 4441 IRQL = PASSIVE_LEVEL
4521 IRQL = DISPATCH_LEVEL 4442 IRQL = DISPATCH_LEVEL
4522 4443
4523 ****************************************************************************/ 4444 ****************************************************************************/
4524ULONG MakeOutgoingFrame( 4445ULONG MakeOutgoingFrame(
4525 OUT CHAR *Buffer, 4446 OUT UCHAR *Buffer,
4526 OUT ULONG *FrameLen, ...) 4447 OUT ULONG *FrameLen, ...)
4527{ 4448{
4528 CHAR *p; 4449 UCHAR *p;
4529 int leng; 4450 int leng;
4530 ULONG TotLeng; 4451 ULONG TotLeng;
4531 va_list Args; 4452 va_list Args;
4532 4453
@@ -4539,7 +4460,7 @@ ULONG MakeOutgoingFrame(
4539 if (leng == END_OF_ARGS) 4460 if (leng == END_OF_ARGS)
4540 { 4461 {
4541 break; 4462 break;
4542 } 4463 }
4543 p = va_arg(Args, PVOID); 4464 p = va_arg(Args, PVOID);
4544 NdisMoveMemory(&Buffer[TotLeng], p, leng); 4465 NdisMoveMemory(&Buffer[TotLeng], p, leng);
4545 TotLeng = TotLeng + leng; 4466 TotLeng = TotLeng + leng;
@@ -4596,12 +4517,12 @@ NDIS_STATUS MlmeQueueInit(
4596 * \post 4517 * \post
4597 * \note The message has to be initialized 4518 * \note The message has to be initialized
4598 4519
4599 IRQL = PASSIVE_LEVEL 4520 IRQL = PASSIVE_LEVEL
4600 IRQL = DISPATCH_LEVEL 4521 IRQL = DISPATCH_LEVEL
4601 4522
4602 */ 4523 */
4603BOOLEAN MlmeEnqueue( 4524BOOLEAN MlmeEnqueue(
4604 IN PRTMP_ADAPTER pAd, 4525 IN PRTMP_ADAPTER pAd,
4605 IN ULONG Machine, 4526 IN ULONG Machine,
4606 IN ULONG MsgType, 4527 IN ULONG MsgType,
4607 IN ULONG MsgLen, 4528 IN ULONG MsgLen,
@@ -4617,24 +4538,24 @@ BOOLEAN MlmeEnqueue(
4617 4538
4618 // First check the size, it MUST not exceed the mlme queue size 4539 // First check the size, it MUST not exceed the mlme queue size
4619 if (MsgLen > MGMT_DMA_BUFFER_SIZE) 4540 if (MsgLen > MGMT_DMA_BUFFER_SIZE)
4620 { 4541 {
4621 DBGPRINT_ERR(("MlmeEnqueue: msg too large, size = %ld \n", MsgLen)); 4542 DBGPRINT_ERR(("MlmeEnqueue: msg too large, size = %ld \n", MsgLen));
4622 return FALSE; 4543 return FALSE;
4623 } 4544 }
4624 4545
4625 if (MlmeQueueFull(Queue)) 4546 if (MlmeQueueFull(Queue))
4626 { 4547 {
4627 return FALSE; 4548 return FALSE;
4628 } 4549 }
4629 4550
4630 NdisAcquireSpinLock(&(Queue->Lock)); 4551 NdisAcquireSpinLock(&(Queue->Lock));
4631 Tail = Queue->Tail; 4552 Tail = Queue->Tail;
4632 Queue->Tail++; 4553 Queue->Tail++;
4633 Queue->Num++; 4554 Queue->Num++;
4634 if (Queue->Tail == MAX_LEN_OF_MLME_QUEUE) 4555 if (Queue->Tail == MAX_LEN_OF_MLME_QUEUE)
4635 { 4556 {
4636 Queue->Tail = 0; 4557 Queue->Tail = 0;
4637 } 4558 }
4638 4559
4639 Queue->Entry[Tail].Wcid = RESERVED_WCID; 4560 Queue->Entry[Tail].Wcid = RESERVED_WCID;
4640 Queue->Entry[Tail].Occupied = TRUE; 4561 Queue->Entry[Tail].Occupied = TRUE;
@@ -4643,9 +4564,9 @@ BOOLEAN MlmeEnqueue(
4643 Queue->Entry[Tail].MsgLen = MsgLen; 4564 Queue->Entry[Tail].MsgLen = MsgLen;
4644 4565
4645 if (Msg != NULL) 4566 if (Msg != NULL)
4646 { 4567 {
4647 NdisMoveMemory(Queue->Entry[Tail].Msg, Msg, MsgLen); 4568 NdisMoveMemory(Queue->Entry[Tail].Msg, Msg, MsgLen);
4648 } 4569 }
4649 4570
4650 NdisReleaseSpinLock(&(Queue->Lock)); 4571 NdisReleaseSpinLock(&(Queue->Lock));
4651 return TRUE; 4572 return TRUE;
@@ -4656,7 +4577,7 @@ BOOLEAN MlmeEnqueue(
4656 * \param TimeStampHigh The upper 32 bit of timestamp 4577 * \param TimeStampHigh The upper 32 bit of timestamp
4657 * \param TimeStampLow The lower 32 bit of timestamp 4578 * \param TimeStampLow The lower 32 bit of timestamp
4658 * \param Rssi The receiving RSSI strength 4579 * \param Rssi The receiving RSSI strength
4659 * \param MsgLen The length of the message 4580 * \param MsgLen The length of the message
4660 * \param *Msg The message pointer 4581 * \param *Msg The message pointer
4661 * \return TRUE if everything ok, FALSE otherwise (like Queue Full) 4582 * \return TRUE if everything ok, FALSE otherwise (like Queue Full)
4662 * \pre 4583 * \pre
@@ -4677,11 +4598,12 @@ BOOLEAN MlmeEnqueueForRecv(
4677 IN VOID *Msg, 4598 IN VOID *Msg,
4678 IN UCHAR Signal) 4599 IN UCHAR Signal)
4679{ 4600{
4680 INT Tail, Machine; 4601 INT Tail, Machine;
4681 PFRAME_802_11 pFrame = (PFRAME_802_11)Msg; 4602 PFRAME_802_11 pFrame = (PFRAME_802_11)Msg;
4682 INT MsgType; 4603 INT MsgType;
4683 MLME_QUEUE *Queue = (MLME_QUEUE *)&pAd->Mlme.Queue; 4604 MLME_QUEUE *Queue = (MLME_QUEUE *)&pAd->Mlme.Queue;
4684 4605
4606
4685 // Do nothing if the driver is starting halt state. 4607 // Do nothing if the driver is starting halt state.
4686 // This might happen when timer already been fired before cancel timer with mlmehalt 4608 // This might happen when timer already been fired before cancel timer with mlmehalt
4687 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)) 4609 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
@@ -4698,17 +4620,17 @@ BOOLEAN MlmeEnqueueForRecv(
4698 } 4620 }
4699 4621
4700 if (MlmeQueueFull(Queue)) 4622 if (MlmeQueueFull(Queue))
4701 { 4623 {
4702 return FALSE; 4624 return FALSE;
4703 } 4625 }
4704 4626
4705 { 4627 {
4706 if (!MsgTypeSubst(pAd, pFrame, &Machine, &MsgType)) 4628 if (!MsgTypeSubst(pAd, pFrame, &Machine, &MsgType))
4707 { 4629 {
4708 DBGPRINT_ERR(("MlmeEnqueueForRecv: un-recongnized mgmt->subtype=%d\n",pFrame->Hdr.FC.SubType)); 4630 DBGPRINT_ERR(("MlmeEnqueueForRecv: un-recongnized mgmt->subtype=%d\n",pFrame->Hdr.FC.SubType));
4709 return FALSE; 4631 return FALSE;
4632 }
4710 } 4633 }
4711 }
4712 4634
4713 // OK, we got all the informations, it is time to put things into queue 4635 // OK, we got all the informations, it is time to put things into queue
4714 NdisAcquireSpinLock(&(Queue->Lock)); 4636 NdisAcquireSpinLock(&(Queue->Lock));
@@ -4716,9 +4638,9 @@ BOOLEAN MlmeEnqueueForRecv(
4716 Queue->Tail++; 4638 Queue->Tail++;
4717 Queue->Num++; 4639 Queue->Num++;
4718 if (Queue->Tail == MAX_LEN_OF_MLME_QUEUE) 4640 if (Queue->Tail == MAX_LEN_OF_MLME_QUEUE)
4719 { 4641 {
4720 Queue->Tail = 0; 4642 Queue->Tail = 0;
4721 } 4643 }
4722 Queue->Entry[Tail].Occupied = TRUE; 4644 Queue->Entry[Tail].Occupied = TRUE;
4723 Queue->Entry[Tail].Machine = Machine; 4645 Queue->Entry[Tail].Machine = Machine;
4724 Queue->Entry[Tail].MsgType = MsgType; 4646 Queue->Entry[Tail].MsgType = MsgType;
@@ -4740,7 +4662,7 @@ BOOLEAN MlmeEnqueueForRecv(
4740 4662
4741 NdisReleaseSpinLock(&(Queue->Lock)); 4663 NdisReleaseSpinLock(&(Queue->Lock));
4742 4664
4743 RT28XX_MLME_HANDLER(pAd); 4665 RTMP_MLME_HANDLER(pAd);
4744 4666
4745 return TRUE; 4667 return TRUE;
4746} 4668}
@@ -4776,14 +4698,14 @@ BOOLEAN MlmeDequeue(
4776VOID MlmeRestartStateMachine( 4698VOID MlmeRestartStateMachine(
4777 IN PRTMP_ADAPTER pAd) 4699 IN PRTMP_ADAPTER pAd)
4778{ 4700{
4779#ifdef RT2860 4701#ifdef RTMP_MAC_PCI
4780 MLME_QUEUE_ELEM *Elem = NULL; 4702 MLME_QUEUE_ELEM *Elem = NULL;
4781#endif 4703#endif // RTMP_MAC_PCI //
4782 BOOLEAN Cancelled; 4704 BOOLEAN Cancelled;
4783 4705
4784 DBGPRINT(RT_DEBUG_TRACE, ("MlmeRestartStateMachine \n")); 4706 DBGPRINT(RT_DEBUG_TRACE, ("MlmeRestartStateMachine \n"));
4785 4707
4786#ifdef RT2860 4708#ifdef RTMP_MAC_PCI
4787 NdisAcquireSpinLock(&pAd->Mlme.TaskLock); 4709 NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
4788 if(pAd->Mlme.bRunning) 4710 if(pAd->Mlme.bRunning)
4789 { 4711 {
@@ -4809,9 +4731,9 @@ VOID MlmeRestartStateMachine(
4809 } 4731 }
4810 else { 4732 else {
4811 DBGPRINT_ERR(("MlmeRestartStateMachine: MlmeQueue empty\n")); 4733 DBGPRINT_ERR(("MlmeRestartStateMachine: MlmeQueue empty\n"));
4812 }
4813 } 4734 }
4814#endif /* RT2860 */ 4735 }
4736#endif // RTMP_MAC_PCI //
4815 4737
4816 { 4738 {
4817 // Cancel all timer events 4739 // Cancel all timer events
@@ -4822,6 +4744,7 @@ VOID MlmeRestartStateMachine(
4822 RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &Cancelled); 4744 RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &Cancelled);
4823 RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &Cancelled); 4745 RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &Cancelled);
4824 RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled); 4746 RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled);
4747
4825 } 4748 }
4826 4749
4827 // Change back to original channel in case of doing scan 4750 // Change back to original channel in case of doing scan
@@ -4841,12 +4764,12 @@ VOID MlmeRestartStateMachine(
4841 pAd->Mlme.ActMachine.CurrState = ACT_IDLE; 4764 pAd->Mlme.ActMachine.CurrState = ACT_IDLE;
4842 } 4765 }
4843 4766
4844#ifdef RT2860 4767#ifdef RTMP_MAC_PCI
4845 // Remove running state 4768 // Remove running state
4846 NdisAcquireSpinLock(&pAd->Mlme.TaskLock); 4769 NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
4847 pAd->Mlme.bRunning = FALSE; 4770 pAd->Mlme.bRunning = FALSE;
4848 NdisReleaseSpinLock(&pAd->Mlme.TaskLock); 4771 NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
4849#endif 4772#endif // RTMP_MAC_PCI //
4850} 4773}
4851 4774
4852/*! \brief test if the MLME Queue is empty 4775/*! \brief test if the MLME Queue is empty
@@ -4871,7 +4794,7 @@ BOOLEAN MlmeQueueEmpty(
4871} 4794}
4872 4795
4873/*! \brief test if the MLME Queue is full 4796/*! \brief test if the MLME Queue is full
4874 * \param *Queue The MLME Queue 4797 * \param *Queue The MLME Queue
4875 * \return TRUE if the Queue is empty, FALSE otherwise 4798 * \return TRUE if the Queue is empty, FALSE otherwise
4876 * \pre 4799 * \pre
4877 * \post 4800 * \post
@@ -4913,6 +4836,7 @@ VOID MlmeQueueDestroy(
4913 NdisFreeSpinLock(&(pQueue->Lock)); 4836 NdisFreeSpinLock(&(pQueue->Lock));
4914} 4837}
4915 4838
4839
4916/*! \brief To substitute the message type if the message is coming from external 4840/*! \brief To substitute the message type if the message is coming from external
4917 * \param pFrame The frame received 4841 * \param pFrame The frame received
4918 * \param *Machine The state machine 4842 * \param *Machine The state machine
@@ -4930,7 +4854,7 @@ BOOLEAN MsgTypeSubst(
4930 OUT INT *Machine, 4854 OUT INT *Machine,
4931 OUT INT *MsgType) 4855 OUT INT *MsgType)
4932{ 4856{
4933 USHORT Seq; 4857 USHORT Seq, Alg;
4934 UCHAR EAPType; 4858 UCHAR EAPType;
4935 PUCHAR pData; 4859 PUCHAR pData;
4936 4860
@@ -4940,17 +4864,10 @@ BOOLEAN MsgTypeSubst(
4940 // The only data type will pass to this function is EAPOL frame 4864 // The only data type will pass to this function is EAPOL frame
4941 if (pFrame->Hdr.FC.Type == BTYPE_DATA) 4865 if (pFrame->Hdr.FC.Type == BTYPE_DATA)
4942 { 4866 {
4943 if (NdisEqualMemory(SNAP_AIRONET, pData, LENGTH_802_1_H))
4944 { 4867 {
4945 // Cisco Aironet SNAP header 4868 *Machine = WPA_STATE_MACHINE;
4946 *Machine = AIRONET_STATE_MACHINE;
4947 *MsgType = MT2_AIRONET_MSG;
4948 return (TRUE);
4949 }
4950 {
4951 *Machine = WPA_PSK_STATE_MACHINE;
4952 EAPType = *((UCHAR*)pFrame + LENGTH_802_11 + LENGTH_802_1_H + 1); 4869 EAPType = *((UCHAR*)pFrame + LENGTH_802_11 + LENGTH_802_1_H + 1);
4953 return(WpaMsgTypeSubst(EAPType, MsgType)); 4870 return (WpaMsgTypeSubst(EAPType, (INT *) MsgType));
4954 } 4871 }
4955 } 4872 }
4956 4873
@@ -4995,18 +4912,22 @@ BOOLEAN MsgTypeSubst(
4995 case SUBTYPE_AUTH: 4912 case SUBTYPE_AUTH:
4996 // get the sequence number from payload 24 Mac Header + 2 bytes algorithm 4913 // get the sequence number from payload 24 Mac Header + 2 bytes algorithm
4997 NdisMoveMemory(&Seq, &pFrame->Octet[2], sizeof(USHORT)); 4914 NdisMoveMemory(&Seq, &pFrame->Octet[2], sizeof(USHORT));
4915 NdisMoveMemory(&Alg, &pFrame->Octet[0], sizeof(USHORT));
4998 if (Seq == 1 || Seq == 3) 4916 if (Seq == 1 || Seq == 3)
4999 { 4917 {
5000 *Machine = AUTH_RSP_STATE_MACHINE; 4918 *Machine = AUTH_RSP_STATE_MACHINE;
5001 *MsgType = MT2_PEER_AUTH_ODD; 4919 *MsgType = MT2_PEER_AUTH_ODD;
5002 } 4920 }
5003 else if (Seq == 2 || Seq == 4) 4921 else if (Seq == 2 || Seq == 4)
5004 { 4922 {
5005 *Machine = AUTH_STATE_MACHINE; 4923 if (Alg == AUTH_MODE_OPEN || Alg == AUTH_MODE_KEY)
5006 *MsgType = MT2_PEER_AUTH_EVEN; 4924 {
5007 } 4925 *Machine = AUTH_STATE_MACHINE;
4926 *MsgType = MT2_PEER_AUTH_EVEN;
4927 }
4928 }
5008 else 4929 else
5009 { 4930 {
5010 return FALSE; 4931 return FALSE;
5011 } 4932 }
5012 break; 4933 break;
@@ -5018,13 +4939,13 @@ BOOLEAN MsgTypeSubst(
5018 *Machine = ACTION_STATE_MACHINE; 4939 *Machine = ACTION_STATE_MACHINE;
5019 // Sometimes Sta will return with category bytes with MSB = 1, if they receive catogory out of their support 4940 // Sometimes Sta will return with category bytes with MSB = 1, if they receive catogory out of their support
5020 if ((pFrame->Octet[0]&0x7F) > MAX_PEER_CATE_MSG) 4941 if ((pFrame->Octet[0]&0x7F) > MAX_PEER_CATE_MSG)
5021 { 4942 {
5022 *MsgType = MT2_ACT_INVALID; 4943 *MsgType = MT2_ACT_INVALID;
5023 } 4944 }
5024 else 4945 else
5025 { 4946 {
5026 *MsgType = (pFrame->Octet[0]&0x7F); 4947 *MsgType = (pFrame->Octet[0]&0x7F);
5027 } 4948 }
5028 break; 4949 break;
5029 default: 4950 default:
5030 return FALSE; 4951 return FALSE;
@@ -5043,7 +4964,7 @@ BOOLEAN MsgTypeSubst(
5043 * \param Trans State machine transition function 4964 * \param Trans State machine transition function
5044 * \param StNr number of states 4965 * \param StNr number of states
5045 * \param MsgNr number of messages 4966 * \param MsgNr number of messages
5046 * \param DefFunc default function, when there is invalid state/message combination 4967 * \param DefFunc default function, when there is invalid state/message combination
5047 * \param InitState initial state of the state machine 4968 * \param InitState initial state of the state machine
5048 * \param Base StateMachine base, internal use only 4969 * \param Base StateMachine base, internal use only
5049 * \pre p_sm should be a legal pointer 4970 * \pre p_sm should be a legal pointer
@@ -5113,7 +5034,7 @@ VOID StateMachineSetAction(
5113 5034
5114/*! \brief This function does the state transition 5035/*! \brief This function does the state transition
5115 * \param *Adapter the NIC adapter pointer 5036 * \param *Adapter the NIC adapter pointer
5116 * \param *S the state machine 5037 * \param *S the state machine
5117 * \param *Elem the message to be executed 5038 * \param *Elem the message to be executed
5118 * \return None 5039 * \return None
5119 5040
@@ -5186,9 +5107,9 @@ UCHAR RandomByte(
5186 { 5107 {
5187 pAd->Mlme.ShiftReg = ((pAd->Mlme.ShiftReg ^ LFSR_MASK) >> 1) | 0x80000000; 5108 pAd->Mlme.ShiftReg = ((pAd->Mlme.ShiftReg ^ LFSR_MASK) >> 1) | 0x80000000;
5188 Result = 1; 5109 Result = 1;
5189 } 5110 }
5190 else 5111 else
5191 { 5112 {
5192 pAd->Mlme.ShiftReg = pAd->Mlme.ShiftReg >> 1; 5113 pAd->Mlme.ShiftReg = pAd->Mlme.ShiftReg >> 1;
5193 Result = 0; 5114 Result = 0;
5194 } 5115 }
@@ -5198,2453 +5119,6 @@ UCHAR RandomByte(
5198 return R; 5119 return R;
5199} 5120}
5200 5121
5201VOID AsicUpdateAutoFallBackTable(
5202 IN PRTMP_ADAPTER pAd,
5203 IN PUCHAR pRateTable)
5204{
5205 UCHAR i;
5206 HT_FBK_CFG0_STRUC HtCfg0;
5207 HT_FBK_CFG1_STRUC HtCfg1;
5208 LG_FBK_CFG0_STRUC LgCfg0;
5209 LG_FBK_CFG1_STRUC LgCfg1;
5210 PRTMP_TX_RATE_SWITCH pCurrTxRate, pNextTxRate;
5211
5212 // set to initial value
5213 HtCfg0.word = 0x65432100;
5214 HtCfg1.word = 0xedcba988;
5215 LgCfg0.word = 0xedcba988;
5216 LgCfg1.word = 0x00002100;
5217
5218 pNextTxRate = (PRTMP_TX_RATE_SWITCH)pRateTable+1;
5219 for (i = 1; i < *((PUCHAR) pRateTable); i++)
5220 {
5221 pCurrTxRate = (PRTMP_TX_RATE_SWITCH)pRateTable+1+i;
5222 switch (pCurrTxRate->Mode)
5223 {
5224 case 0: //CCK
5225 break;
5226 case 1: //OFDM
5227 {
5228 switch(pCurrTxRate->CurrMCS)
5229 {
5230 case 0:
5231 LgCfg0.field.OFDMMCS0FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
5232 break;
5233 case 1:
5234 LgCfg0.field.OFDMMCS1FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
5235 break;
5236 case 2:
5237 LgCfg0.field.OFDMMCS2FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
5238 break;
5239 case 3:
5240 LgCfg0.field.OFDMMCS3FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
5241 break;
5242 case 4:
5243 LgCfg0.field.OFDMMCS4FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
5244 break;
5245 case 5:
5246 LgCfg0.field.OFDMMCS5FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
5247 break;
5248 case 6:
5249 LgCfg0.field.OFDMMCS6FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
5250 break;
5251 case 7:
5252 LgCfg0.field.OFDMMCS7FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
5253 break;
5254 }
5255 }
5256 break;
5257 case 2: //HT-MIX
5258 case 3: //HT-GF
5259 {
5260 if ((pNextTxRate->Mode >= MODE_HTMIX) && (pCurrTxRate->CurrMCS != pNextTxRate->CurrMCS))
5261 {
5262 switch(pCurrTxRate->CurrMCS)
5263 {
5264 case 0:
5265 HtCfg0.field.HTMCS0FBK = pNextTxRate->CurrMCS;
5266 break;
5267 case 1:
5268 HtCfg0.field.HTMCS1FBK = pNextTxRate->CurrMCS;
5269 break;
5270 case 2:
5271 HtCfg0.field.HTMCS2FBK = pNextTxRate->CurrMCS;
5272 break;
5273 case 3:
5274 HtCfg0.field.HTMCS3FBK = pNextTxRate->CurrMCS;
5275 break;
5276 case 4:
5277 HtCfg0.field.HTMCS4FBK = pNextTxRate->CurrMCS;
5278 break;
5279 case 5:
5280 HtCfg0.field.HTMCS5FBK = pNextTxRate->CurrMCS;
5281 break;
5282 case 6:
5283 HtCfg0.field.HTMCS6FBK = pNextTxRate->CurrMCS;
5284 break;
5285 case 7:
5286 HtCfg0.field.HTMCS7FBK = pNextTxRate->CurrMCS;
5287 break;
5288 case 8:
5289 HtCfg1.field.HTMCS8FBK = pNextTxRate->CurrMCS;
5290 break;
5291 case 9:
5292 HtCfg1.field.HTMCS9FBK = pNextTxRate->CurrMCS;
5293 break;
5294 case 10:
5295 HtCfg1.field.HTMCS10FBK = pNextTxRate->CurrMCS;
5296 break;
5297 case 11:
5298 HtCfg1.field.HTMCS11FBK = pNextTxRate->CurrMCS;
5299 break;
5300 case 12:
5301 HtCfg1.field.HTMCS12FBK = pNextTxRate->CurrMCS;
5302 break;
5303 case 13:
5304 HtCfg1.field.HTMCS13FBK = pNextTxRate->CurrMCS;
5305 break;
5306 case 14:
5307 HtCfg1.field.HTMCS14FBK = pNextTxRate->CurrMCS;
5308 break;
5309 case 15:
5310 HtCfg1.field.HTMCS15FBK = pNextTxRate->CurrMCS;
5311 break;
5312 default:
5313 DBGPRINT(RT_DEBUG_ERROR, ("AsicUpdateAutoFallBackTable: not support CurrMCS=%d\n", pCurrTxRate->CurrMCS));
5314 }
5315 }
5316 }
5317 break;
5318 }
5319
5320 pNextTxRate = pCurrTxRate;
5321 }
5322
5323 RTMP_IO_WRITE32(pAd, HT_FBK_CFG0, HtCfg0.word);
5324 RTMP_IO_WRITE32(pAd, HT_FBK_CFG1, HtCfg1.word);
5325 RTMP_IO_WRITE32(pAd, LG_FBK_CFG0, LgCfg0.word);
5326 RTMP_IO_WRITE32(pAd, LG_FBK_CFG1, LgCfg1.word);
5327}
5328
5329/*
5330 ========================================================================
5331
5332 Routine Description:
5333 Set MAC register value according operation mode.
5334 OperationMode AND bNonGFExist are for MM and GF Proteciton.
5335 If MM or GF mask is not set, those passing argument doesn't not take effect.
5336
5337 Operation mode meaning:
5338 = 0 : Pure HT, no preotection.
5339 = 0x01; there may be non-HT devices in both the control and extension channel, protection is optional in BSS.
5340 = 0x10: No Transmission in 40M is protected.
5341 = 0x11: Transmission in both 40M and 20M shall be protected
5342 if (bNonGFExist)
5343 we should choose not to use GF. But still set correct ASIC registers.
5344 ========================================================================
5345*/
5346VOID AsicUpdateProtect(
5347 IN PRTMP_ADAPTER pAd,
5348 IN USHORT OperationMode,
5349 IN UCHAR SetMask,
5350 IN BOOLEAN bDisableBGProtect,
5351 IN BOOLEAN bNonGFExist)
5352{
5353 PROT_CFG_STRUC ProtCfg, ProtCfg4;
5354 UINT32 Protect[6];
5355 USHORT offset;
5356 UCHAR i;
5357 UINT32 MacReg = 0;
5358
5359 if (!(pAd->CommonCfg.bHTProtect) && (OperationMode != 8))
5360 {
5361 return;
5362 }
5363
5364 if (pAd->BATable.numAsOriginator)
5365 {
5366 //
5367 // enable the RTS/CTS to avoid channel collision
5368 //
5369 SetMask = ALLN_SETPROTECT;
5370 OperationMode = 8;
5371 }
5372
5373 // Config ASIC RTS threshold register
5374 RTMP_IO_READ32(pAd, TX_RTS_CFG, &MacReg);
5375 MacReg &= 0xFF0000FF;
5376
5377 // If the user want disable RtsThreshold and enable Amsdu/Ralink-Aggregation, set the RtsThreshold as 4096
5378 if ((
5379 (pAd->CommonCfg.BACapability.field.AmsduEnable) ||
5380 (pAd->CommonCfg.bAggregationCapable == TRUE))
5381 && pAd->CommonCfg.RtsThreshold == MAX_RTS_THRESHOLD)
5382 {
5383 MacReg |= (0x1000 << 8);
5384 }
5385 else
5386 {
5387 MacReg |= (pAd->CommonCfg.RtsThreshold << 8);
5388 }
5389
5390 RTMP_IO_WRITE32(pAd, TX_RTS_CFG, MacReg);
5391
5392 // Initial common protection settings
5393 RTMPZeroMemory(Protect, sizeof(Protect));
5394 ProtCfg4.word = 0;
5395 ProtCfg.word = 0;
5396 ProtCfg.field.TxopAllowGF40 = 1;
5397 ProtCfg.field.TxopAllowGF20 = 1;
5398 ProtCfg.field.TxopAllowMM40 = 1;
5399 ProtCfg.field.TxopAllowMM20 = 1;
5400 ProtCfg.field.TxopAllowOfdm = 1;
5401 ProtCfg.field.TxopAllowCck = 1;
5402 ProtCfg.field.RTSThEn = 1;
5403 ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
5404
5405 // update PHY mode and rate
5406 if (pAd->CommonCfg.Channel > 14)
5407 ProtCfg.field.ProtectRate = 0x4000;
5408 ProtCfg.field.ProtectRate |= pAd->CommonCfg.RtsRate;
5409
5410 // Handle legacy(B/G) protection
5411 if (bDisableBGProtect)
5412 {
5413 //ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate;
5414 ProtCfg.field.ProtectCtrl = 0;
5415 Protect[0] = ProtCfg.word;
5416 Protect[1] = ProtCfg.word;
5417 }
5418 else
5419 {
5420 //ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate;
5421 ProtCfg.field.ProtectCtrl = 0; // CCK do not need to be protected
5422 Protect[0] = ProtCfg.word;
5423 ProtCfg.field.ProtectCtrl = ASIC_CTS; // OFDM needs using CCK to protect
5424 Protect[1] = ProtCfg.word;
5425 }
5426
5427 // Decide HT frame protection.
5428 if ((SetMask & ALLN_SETPROTECT) != 0)
5429 {
5430 switch(OperationMode)
5431 {
5432 case 0x0:
5433 // NO PROTECT
5434 // 1.All STAs in the BSS are 20/40 MHz HT
5435 // 2. in ai 20/40MHz BSS
5436 // 3. all STAs are 20MHz in a 20MHz BSS
5437 // Pure HT. no protection.
5438
5439 // MM20_PROT_CFG
5440 // Reserved (31:27)
5441 // PROT_TXOP(25:20) -- 010111
5442 // PROT_NAV(19:18) -- 01 (Short NAV protection)
5443 // PROT_CTRL(17:16) -- 00 (None)
5444 // PROT_RATE(15:0) -- 0x4004 (OFDM 24M)
5445 Protect[2] = 0x01744004;
5446
5447 // MM40_PROT_CFG
5448 // Reserved (31:27)
5449 // PROT_TXOP(25:20) -- 111111
5450 // PROT_NAV(19:18) -- 01 (Short NAV protection)
5451 // PROT_CTRL(17:16) -- 00 (None)
5452 // PROT_RATE(15:0) -- 0x4084 (duplicate OFDM 24M)
5453 Protect[3] = 0x03f44084;
5454
5455 // CF20_PROT_CFG
5456 // Reserved (31:27)
5457 // PROT_TXOP(25:20) -- 010111
5458 // PROT_NAV(19:18) -- 01 (Short NAV protection)
5459 // PROT_CTRL(17:16) -- 00 (None)
5460 // PROT_RATE(15:0) -- 0x4004 (OFDM 24M)
5461 Protect[4] = 0x01744004;
5462
5463 // CF40_PROT_CFG
5464 // Reserved (31:27)
5465 // PROT_TXOP(25:20) -- 111111
5466 // PROT_NAV(19:18) -- 01 (Short NAV protection)
5467 // PROT_CTRL(17:16) -- 00 (None)
5468 // PROT_RATE(15:0) -- 0x4084 (duplicate OFDM 24M)
5469 Protect[5] = 0x03f44084;
5470
5471 if (bNonGFExist)
5472 {
5473 // PROT_NAV(19:18) -- 01 (Short NAV protectiion)
5474 // PROT_CTRL(17:16) -- 01 (RTS/CTS)
5475 Protect[4] = 0x01754004;
5476 Protect[5] = 0x03f54084;
5477 }
5478 pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE;
5479 break;
5480
5481 case 1:
5482 // This is "HT non-member protection mode."
5483 // If there may be non-HT STAs my BSS
5484 ProtCfg.word = 0x01744004; // PROT_CTRL(17:16) : 0 (None)
5485 ProtCfg4.word = 0x03f44084; // duplicaet legacy 24M. BW set 1.
5486 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED))
5487 {
5488 ProtCfg.word = 0x01740003; //ERP use Protection bit is set, use protection rate at Clause 18..
5489 ProtCfg4.word = 0x03f40003; // Don't duplicate RTS/CTS in CCK mode. 0x03f40083;
5490 }
5491 //Assign Protection method for 20&40 MHz packets
5492 ProtCfg.field.ProtectCtrl = ASIC_RTS;
5493 ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
5494 ProtCfg4.field.ProtectCtrl = ASIC_RTS;
5495 ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
5496 Protect[2] = ProtCfg.word;
5497 Protect[3] = ProtCfg4.word;
5498 Protect[4] = ProtCfg.word;
5499 Protect[5] = ProtCfg4.word;
5500 pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
5501 break;
5502
5503 case 2:
5504 // If only HT STAs are in BSS. at least one is 20MHz. Only protect 40MHz packets
5505 ProtCfg.word = 0x01744004; // PROT_CTRL(17:16) : 0 (None)
5506 ProtCfg4.word = 0x03f44084; // duplicaet legacy 24M. BW set 1.
5507
5508 //Assign Protection method for 40MHz packets
5509 ProtCfg4.field.ProtectCtrl = ASIC_RTS;
5510 ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
5511 Protect[2] = ProtCfg.word;
5512 Protect[3] = ProtCfg4.word;
5513 if (bNonGFExist)
5514 {
5515 ProtCfg.field.ProtectCtrl = ASIC_RTS;
5516 ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
5517 }
5518 Protect[4] = ProtCfg.word;
5519 Protect[5] = ProtCfg4.word;
5520
5521 pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE;
5522 break;
5523
5524 case 3:
5525 // HT mixed mode. PROTECT ALL!
5526 // Assign Rate
5527 ProtCfg.word = 0x01744004; //duplicaet legacy 24M. BW set 1.
5528 ProtCfg4.word = 0x03f44084;
5529 // both 20MHz and 40MHz are protected. Whether use RTS or CTS-to-self depends on the
5530 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED))
5531 {
5532 ProtCfg.word = 0x01740003; //ERP use Protection bit is set, use protection rate at Clause 18..
5533 ProtCfg4.word = 0x03f40003; // Don't duplicate RTS/CTS in CCK mode. 0x03f40083
5534 }
5535 //Assign Protection method for 20&40 MHz packets
5536 ProtCfg.field.ProtectCtrl = ASIC_RTS;
5537 ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
5538 ProtCfg4.field.ProtectCtrl = ASIC_RTS;
5539 ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
5540 Protect[2] = ProtCfg.word;
5541 Protect[3] = ProtCfg4.word;
5542 Protect[4] = ProtCfg.word;
5543 Protect[5] = ProtCfg4.word;
5544 pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
5545 break;
5546
5547 case 8:
5548 // Special on for Atheros problem n chip.
5549 Protect[2] = 0x01754004;
5550 Protect[3] = 0x03f54084;
5551 Protect[4] = 0x01754004;
5552 Protect[5] = 0x03f54084;
5553 pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
5554 break;
5555 }
5556 }
5557
5558 offset = CCK_PROT_CFG;
5559 for (i = 0;i < 6;i++)
5560 {
5561 if ((SetMask & (1<< i)))
5562 {
5563 RTMP_IO_WRITE32(pAd, offset + i*4, Protect[i]);
5564 }
5565 }
5566}
5567
5568#ifdef RT2870
5569/*
5570 ==========================================================================
5571 Description:
5572
5573 Load RF normal operation-mode setup
5574
5575 ==========================================================================
5576 */
5577VOID RT30xxLoadRFNormalModeSetup(
5578 IN PRTMP_ADAPTER pAd)
5579{
5580 UCHAR RFValue;
5581
5582 // RX0_PD & TX0_PD, RF R1 register Bit 2 & Bit 3 to 0 and RF_BLOCK_en,RX1_PD & TX1_PD, Bit0, Bit 4 & Bit5 to 1
5583 RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
5584 RFValue = (RFValue & (~0x0C)) | 0x31;
5585 RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
5586
5587 // TX_LO2_en, RF R15 register Bit 3 to 0
5588 RT30xxReadRFRegister(pAd, RF_R15, &RFValue);
5589 RFValue &= (~0x08);
5590 RT30xxWriteRFRegister(pAd, RF_R15, RFValue);
5591
5592 // TX_LO1_en, RF R17 register Bit 3 to 0
5593 RT30xxReadRFRegister(pAd, RF_R17, &RFValue);
5594 RFValue &= (~0x08);
5595 // to fix rx long range issue
5596 if (((pAd->MACVersion & 0xffff) >= 0x0211) && (pAd->NicConfig2.field.ExternalLNAForG == 0))
5597 {
5598 RFValue |= 0x20;
5599 }
5600 RT30xxWriteRFRegister(pAd, RF_R17, RFValue);
5601
5602 // RX_LO1_en, RF R20 register Bit 3 to 0
5603 RT30xxReadRFRegister(pAd, RF_R20, &RFValue);
5604 RFValue &= (~0x08);
5605 RT30xxWriteRFRegister(pAd, RF_R20, RFValue);
5606
5607 // RX_LO2_en, RF R21 register Bit 3 to 0
5608 RT30xxReadRFRegister(pAd, RF_R21, &RFValue);
5609 RFValue &= (~0x08);
5610 RT30xxWriteRFRegister(pAd, RF_R21, RFValue);
5611
5612 // LDORF_VC, RF R27 register Bit 2 to 0
5613 RT30xxReadRFRegister(pAd, RF_R27, &RFValue);
5614 if ((pAd->MACVersion & 0xffff) < 0x0211)
5615 RFValue = (RFValue & (~0x77)) | 0x3;
5616 else
5617 RFValue = (RFValue & (~0x77));
5618 RT30xxWriteRFRegister(pAd, RF_R27, RFValue);
5619 /* end johnli */
5620}
5621
5622/*
5623 ==========================================================================
5624 Description:
5625
5626 Load RF sleep-mode setup
5627
5628 ==========================================================================
5629 */
5630VOID RT30xxLoadRFSleepModeSetup(
5631 IN PRTMP_ADAPTER pAd)
5632{
5633 UCHAR RFValue;
5634 UINT32 MACValue;
5635
5636 // RF_BLOCK_en. RF R1 register Bit 0 to 0
5637 RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
5638 RFValue &= (~0x01);
5639 RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
5640
5641 // VCO_IC, RF R7 register Bit 4 & Bit 5 to 0
5642 RT30xxReadRFRegister(pAd, RF_R07, &RFValue);
5643 RFValue &= (~0x30);
5644 RT30xxWriteRFRegister(pAd, RF_R07, RFValue);
5645
5646 // Idoh, RF R9 register Bit 1, Bit 2 & Bit 3 to 0
5647 RT30xxReadRFRegister(pAd, RF_R09, &RFValue);
5648 RFValue &= (~0x0E);
5649 RT30xxWriteRFRegister(pAd, RF_R09, RFValue);
5650
5651 // RX_CTB_en, RF R21 register Bit 7 to 0
5652 RT30xxReadRFRegister(pAd, RF_R21, &RFValue);
5653 RFValue &= (~0x80);
5654 RT30xxWriteRFRegister(pAd, RF_R21, RFValue);
5655
5656 // LDORF_VC, RF R27 register Bit 0, Bit 1 & Bit 2 to 1
5657 RT30xxReadRFRegister(pAd, RF_R27, &RFValue);
5658 RFValue |= 0x77;
5659 RT30xxWriteRFRegister(pAd, RF_R27, RFValue);
5660
5661 RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue);
5662 MACValue |= 0x1D000000;
5663 RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue);
5664}
5665
5666/*
5667 ==========================================================================
5668 Description:
5669
5670 Reverse RF sleep-mode setup
5671
5672 ==========================================================================
5673 */
5674VOID RT30xxReverseRFSleepModeSetup(
5675 IN PRTMP_ADAPTER pAd)
5676{
5677 UCHAR RFValue;
5678 UINT32 MACValue;
5679
5680 // RF_BLOCK_en, RF R1 register Bit 0 to 1
5681 RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
5682 RFValue |= 0x01;
5683 RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
5684
5685 // VCO_IC, RF R7 register Bit 4 & Bit 5 to 1
5686 RT30xxReadRFRegister(pAd, RF_R07, &RFValue);
5687 RFValue |= 0x30;
5688 RT30xxWriteRFRegister(pAd, RF_R07, RFValue);
5689
5690 // Idoh, RF R9 register Bit 1, Bit 2 & Bit 3 to 1
5691 RT30xxReadRFRegister(pAd, RF_R09, &RFValue);
5692 RFValue |= 0x0E;
5693 RT30xxWriteRFRegister(pAd, RF_R09, RFValue);
5694
5695 // RX_CTB_en, RF R21 register Bit 7 to 1
5696 RT30xxReadRFRegister(pAd, RF_R21, &RFValue);
5697 RFValue |= 0x80;
5698 RT30xxWriteRFRegister(pAd, RF_R21, RFValue);
5699
5700 // LDORF_VC, RF R27 register Bit 2 to 0
5701 RT30xxReadRFRegister(pAd, RF_R27, &RFValue);
5702 if ((pAd->MACVersion & 0xffff) < 0x0211)
5703 RFValue = (RFValue & (~0x77)) | 0x3;
5704 else
5705 RFValue = (RFValue & (~0x77));
5706 RT30xxWriteRFRegister(pAd, RF_R27, RFValue);
5707
5708 // RT3071 version E has fixed this issue
5709 if ((pAd->NicConfig2.field.DACTestBit == 1) && ((pAd->MACVersion & 0xffff) < 0x0211))
5710 {
5711 // patch tx EVM issue temporarily
5712 RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue);
5713 MACValue = ((MACValue & 0xE0FFFFFF) | 0x0D000000);
5714 RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue);
5715 }
5716 else
5717 {
5718 RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue);
5719 MACValue = ((MACValue & 0xE0FFFFFF) | 0x01000000);
5720 RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue);
5721 }
5722}
5723#endif
5724
5725/*
5726 ==========================================================================
5727 Description:
5728
5729 IRQL = PASSIVE_LEVEL
5730 IRQL = DISPATCH_LEVEL
5731
5732 ==========================================================================
5733 */
5734VOID AsicSwitchChannel(
5735 IN PRTMP_ADAPTER pAd,
5736 IN UCHAR Channel,
5737 IN BOOLEAN bScan)
5738{
5739 ULONG R2 = 0, R3 = DEFAULT_RF_TX_POWER, R4 = 0;
5740 CHAR TxPwer = 0, TxPwer2 = DEFAULT_RF_TX_POWER; //Bbp94 = BBPR94_DEFAULT, TxPwer2 = DEFAULT_RF_TX_POWER;
5741 UCHAR index;
5742 UINT32 Value = 0; //BbpReg, Value;
5743 RTMP_RF_REGS *RFRegTable;
5744
5745 // Search Tx power value
5746 // We can't use ChannelList to search channel, since some central channl's txpowr doesn't list
5747 // in ChannelList, so use TxPower array instead.
5748 //
5749 for (index = 0; index < MAX_NUM_OF_CHANNELS; index++)
5750 {
5751 if (Channel == pAd->TxPower[index].Channel)
5752 {
5753 TxPwer = pAd->TxPower[index].Power;
5754 TxPwer2 = pAd->TxPower[index].Power2;
5755 break;
5756 }
5757 }
5758
5759 if (index == MAX_NUM_OF_CHANNELS)
5760 DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: Can't find the Channel#%d \n", Channel));
5761
5762#ifdef RT2870
5763 // The RF programming sequence is difference between 3xxx and 2xxx
5764 if ((IS_RT3070(pAd) || IS_RT3090(pAd)) && (
5765 (pAd->RfIcType == RFIC_3022) || (pAd->RfIcType == RFIC_3021) ||
5766 (pAd->RfIcType == RFIC_3020) || (pAd->RfIcType == RFIC_2020)))
5767 {
5768 /* modify by WY for Read RF Reg. error */
5769 UCHAR RFValue;
5770
5771 for (index = 0; index < NUM_OF_3020_CHNL; index++)
5772 {
5773 if (Channel == FreqItems3020[index].Channel)
5774 {
5775 // Programming channel parameters
5776 RT30xxWriteRFRegister(pAd, RF_R02, FreqItems3020[index].N);
5777 RT30xxWriteRFRegister(pAd, RF_R03, FreqItems3020[index].K);
5778
5779 RT30xxReadRFRegister(pAd, RF_R06, &RFValue);
5780 RFValue = (RFValue & 0xFC) | FreqItems3020[index].R;
5781 RT30xxWriteRFRegister(pAd, RF_R06, RFValue);
5782
5783 // Set Tx0 Power
5784 RT30xxReadRFRegister(pAd, RF_R12, &RFValue);
5785 RFValue = (RFValue & 0xE0) | TxPwer;
5786 RT30xxWriteRFRegister(pAd, RF_R12, RFValue);
5787
5788 // Set Tx1 Power
5789 RT30xxReadRFRegister(pAd, RF_R13, &RFValue);
5790 RFValue = (RFValue & 0xE0) | TxPwer2;
5791 RT30xxWriteRFRegister(pAd, RF_R13, RFValue);
5792
5793 // Tx/Rx Stream setting
5794 RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
5795 //if (IS_RT3090(pAd))
5796 // RFValue |= 0x01; // Enable RF block.
5797 RFValue &= 0x03; //clear bit[7~2]
5798 if (pAd->Antenna.field.TxPath == 1)
5799 RFValue |= 0xA0;
5800 else if (pAd->Antenna.field.TxPath == 2)
5801 RFValue |= 0x80;
5802 if (pAd->Antenna.field.RxPath == 1)
5803 RFValue |= 0x50;
5804 else if (pAd->Antenna.field.RxPath == 2)
5805 RFValue |= 0x40;
5806 RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
5807
5808 // Set RF offset
5809 RT30xxReadRFRegister(pAd, RF_R23, &RFValue);
5810 RFValue = (RFValue & 0x80) | pAd->RfFreqOffset;
5811 RT30xxWriteRFRegister(pAd, RF_R23, RFValue);
5812
5813 // Set BW
5814 if (!bScan && (pAd->CommonCfg.BBPCurrentBW == BW_40))
5815 {
5816 RFValue = pAd->Mlme.CaliBW40RfR24;
5817 //DISABLE_11N_CHECK(pAd);
5818 }
5819 else
5820 {
5821 RFValue = pAd->Mlme.CaliBW20RfR24;
5822 }
5823 RT30xxWriteRFRegister(pAd, RF_R24, RFValue);
5824 RT30xxWriteRFRegister(pAd, RF_R31, RFValue);
5825
5826 // Enable RF tuning
5827 RT30xxReadRFRegister(pAd, RF_R07, &RFValue);
5828 RFValue = RFValue | 0x1;
5829 RT30xxWriteRFRegister(pAd, RF_R07, RFValue);
5830
5831 // latch channel for future usage.
5832 pAd->LatchRfRegs.Channel = Channel;
5833
5834 DBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, Pwr0=%d, Pwr1=%d, %dT), N=0x%02X, K=0x%02X, R=0x%02X\n",
5835 Channel,
5836 pAd->RfIcType,
5837 TxPwer,
5838 TxPwer2,
5839 pAd->Antenna.field.TxPath,
5840 FreqItems3020[index].N,
5841 FreqItems3020[index].K,
5842 FreqItems3020[index].R));
5843 break;
5844 }
5845 }
5846
5847 DBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, Pwr0=%d, Pwr1=%d, %dT), N=0x%02X, K=0x%02X, R=0x%02X\n",
5848 Channel,
5849 pAd->RfIcType,
5850 TxPwer,
5851 TxPwer2,
5852 pAd->Antenna.field.TxPath,
5853 FreqItems3020[index].N,
5854 FreqItems3020[index].K,
5855 FreqItems3020[index].R));
5856 }
5857 else
5858#endif // RT2870 //
5859 {
5860 RFRegTable = RF2850RegTable;
5861
5862 switch (pAd->RfIcType)
5863 {
5864 case RFIC_2820:
5865 case RFIC_2850:
5866 case RFIC_2720:
5867 case RFIC_2750:
5868
5869 for (index = 0; index < NUM_OF_2850_CHNL; index++)
5870 {
5871 if (Channel == RFRegTable[index].Channel)
5872 {
5873 R2 = RFRegTable[index].R2;
5874 if (pAd->Antenna.field.TxPath == 1)
5875 {
5876 R2 |= 0x4000; // If TXpath is 1, bit 14 = 1;
5877 }
5878
5879 if (pAd->Antenna.field.RxPath == 2)
5880 {
5881 R2 |= 0x40; // write 1 to off Rxpath.
5882 }
5883 else if (pAd->Antenna.field.RxPath == 1)
5884 {
5885 R2 |= 0x20040; // write 1 to off RxPath
5886 }
5887
5888 if (Channel > 14)
5889 {
5890 // initialize R3, R4
5891 R3 = (RFRegTable[index].R3 & 0xffffc1ff);
5892 R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->RfFreqOffset << 15);
5893
5894 // 5G band power range: 0xF9~0X0F, TX0 Reg3 bit9/TX1 Reg4 bit6="0" means the TX power reduce 7dB
5895 // R3
5896 if ((TxPwer >= -7) && (TxPwer < 0))
5897 {
5898 TxPwer = (7+TxPwer);
5899 TxPwer = (TxPwer > 0xF) ? (0xF) : (TxPwer);
5900 R3 |= (TxPwer << 10);
5901 DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: TxPwer=%d \n", TxPwer));
5902 }
5903 else
5904 {
5905 TxPwer = (TxPwer > 0xF) ? (0xF) : (TxPwer);
5906 R3 |= (TxPwer << 10) | (1 << 9);
5907 }
5908
5909 // R4
5910 if ((TxPwer2 >= -7) && (TxPwer2 < 0))
5911 {
5912 TxPwer2 = (7+TxPwer2);
5913 TxPwer2 = (TxPwer2 > 0xF) ? (0xF) : (TxPwer2);
5914 R4 |= (TxPwer2 << 7);
5915 DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: TxPwer2=%d \n", TxPwer2));
5916 }
5917 else
5918 {
5919 TxPwer2 = (TxPwer2 > 0xF) ? (0xF) : (TxPwer2);
5920 R4 |= (TxPwer2 << 7) | (1 << 6);
5921 }
5922 }
5923 else
5924 {
5925 R3 = (RFRegTable[index].R3 & 0xffffc1ff) | (TxPwer << 9); // set TX power0
5926 R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->RfFreqOffset << 15) | (TxPwer2 <<6);// Set freq Offset & TxPwr1
5927 }
5928
5929 // Based on BBP current mode before changing RF channel.
5930 if (!bScan && (pAd->CommonCfg.BBPCurrentBW == BW_40))
5931 {
5932 R4 |=0x200000;
5933 }
5934
5935 // Update variables
5936 pAd->LatchRfRegs.Channel = Channel;
5937 pAd->LatchRfRegs.R1 = RFRegTable[index].R1;
5938 pAd->LatchRfRegs.R2 = R2;
5939 pAd->LatchRfRegs.R3 = R3;
5940 pAd->LatchRfRegs.R4 = R4;
5941
5942 // Set RF value 1's set R3[bit2] = [0]
5943 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
5944 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
5945 RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 & (~0x04)));
5946 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
5947
5948 RTMPusecDelay(200);
5949
5950 // Set RF value 2's set R3[bit2] = [1]
5951 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
5952 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
5953 RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 | 0x04));
5954 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
5955
5956 RTMPusecDelay(200);
5957
5958 // Set RF value 3's set R3[bit2] = [0]
5959 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
5960 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
5961 RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 & (~0x04)));
5962 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
5963
5964 break;
5965 }
5966 }
5967 break;
5968
5969 default:
5970 break;
5971 }
5972 }
5973
5974 // Change BBP setting during siwtch from a->g, g->a
5975 if (Channel <= 14)
5976 {
5977 ULONG TxPinCfg = 0x00050F0A;//Gary 2007/08/09 0x050A0A
5978
5979 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd)));
5980 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd)));
5981 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd)));
5982 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.
5983 //RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62);
5984
5985 // Rx High power VGA offset for LNA select
5986 if (pAd->NicConfig2.field.ExternalLNAForG)
5987 {
5988 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62);
5989 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46);
5990 }
5991 else
5992 {
5993 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x84);
5994 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50);
5995 }
5996
5997 // 5G band selection PIN, bit1 and bit2 are complement
5998 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
5999 Value &= (~0x6);
6000 Value |= (0x04);
6001 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
6002
6003 // Turn off unused PA or LNA when only 1T or 1R
6004 if (pAd->Antenna.field.TxPath == 1)
6005 {
6006 TxPinCfg &= 0xFFFFFFF3;
6007 }
6008 if (pAd->Antenna.field.RxPath == 1)
6009 {
6010 TxPinCfg &= 0xFFFFF3FF;
6011 }
6012
6013 RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
6014 }
6015 else
6016 {
6017 ULONG TxPinCfg = 0x00050F05;//Gary 2007/8/9 0x050505
6018
6019 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd)));
6020 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd)));
6021 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd)));
6022 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.
6023 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0xF2);
6024
6025 // Rx High power VGA offset for LNA select
6026 if (pAd->NicConfig2.field.ExternalLNAForA)
6027 {
6028 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46);
6029 }
6030 else
6031 {
6032 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50);
6033 }
6034
6035 // 5G band selection PIN, bit1 and bit2 are complement
6036 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
6037 Value &= (~0x6);
6038 Value |= (0x02);
6039 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
6040
6041 // Turn off unused PA or LNA when only 1T or 1R
6042 if (pAd->Antenna.field.TxPath == 1)
6043 {
6044 TxPinCfg &= 0xFFFFFFF3;
6045 }
6046 if (pAd->Antenna.field.RxPath == 1)
6047 {
6048 TxPinCfg &= 0xFFFFF3FF;
6049 }
6050
6051 RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
6052 }
6053
6054 // R66 should be set according to Channel and use 20MHz when scanning
6055 //RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, (0x2E + GET_LNA_GAIN(pAd)));
6056 if (bScan)
6057 RTMPSetAGCInitValue(pAd, BW_20);
6058 else
6059 RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW);
6060
6061 //
6062 // On 11A, We should delay and wait RF/BBP to be stable
6063 // and the appropriate time should be 1000 micro seconds
6064 // 2005/06/05 - On 11G, We also need this delay time. Otherwise it's difficult to pass the WHQL.
6065 //
6066 RTMPusecDelay(1000);
6067
6068 DBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, Pwr0=%lu, Pwr1=%lu, %dT) to , R1=0x%08lx, R2=0x%08lx, R3=0x%08lx, R4=0x%08lx\n",
6069 Channel,
6070 pAd->RfIcType,
6071 (R3 & 0x00003e00) >> 9,
6072 (R4 & 0x000007c0) >> 6,
6073 pAd->Antenna.field.TxPath,
6074 pAd->LatchRfRegs.R1,
6075 pAd->LatchRfRegs.R2,
6076 pAd->LatchRfRegs.R3,
6077 pAd->LatchRfRegs.R4));
6078}
6079
6080/*
6081 ==========================================================================
6082 Description:
6083 This function is required for 2421 only, and should not be used during
6084 site survey. It's only required after NIC decided to stay at a channel
6085 for a longer period.
6086 When this function is called, it's always after AsicSwitchChannel().
6087
6088 IRQL = PASSIVE_LEVEL
6089 IRQL = DISPATCH_LEVEL
6090
6091 ==========================================================================
6092 */
6093VOID AsicLockChannel(
6094 IN PRTMP_ADAPTER pAd,
6095 IN UCHAR Channel)
6096{
6097}
6098
6099VOID AsicRfTuningExec(
6100 IN PVOID SystemSpecific1,
6101 IN PVOID FunctionContext,
6102 IN PVOID SystemSpecific2,
6103 IN PVOID SystemSpecific3)
6104{
6105}
6106
6107/*
6108 ==========================================================================
6109 Description:
6110 Gives CCK TX rate 2 more dB TX power.
6111 This routine works only in LINK UP in INFRASTRUCTURE mode.
6112
6113 calculate desired Tx power in RF R3.Tx0~5, should consider -
6114 0. if current radio is a noisy environment (pAd->DrsCounters.fNoisyEnvironment)
6115 1. TxPowerPercentage
6116 2. auto calibration based on TSSI feedback
6117 3. extra 2 db for CCK
6118 4. -10 db upon very-short distance (AvgRSSI >= -40db) to AP
6119
6120 NOTE: Since this routine requires the value of (pAd->DrsCounters.fNoisyEnvironment),
6121 it should be called AFTER MlmeDynamicTxRatSwitching()
6122 ==========================================================================
6123 */
6124VOID AsicAdjustTxPower(
6125 IN PRTMP_ADAPTER pAd)
6126{
6127 INT i, j;
6128 CHAR DeltaPwr = 0;
6129 BOOLEAN bAutoTxAgc = FALSE;
6130 UCHAR TssiRef, *pTssiMinusBoundary, *pTssiPlusBoundary, TxAgcStep;
6131 UCHAR BbpR1 = 0, BbpR49 = 0, idx;
6132 PCHAR pTxAgcCompensate;
6133 ULONG TxPwr[5];
6134 CHAR Value;
6135
6136#ifdef RT2860
6137 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)
6138 || (pAd->bPCIclkOff == TRUE)
6139 || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)
6140 || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
6141 return;
6142#endif
6143
6144 if (pAd->CommonCfg.BBPCurrentBW == BW_40)
6145 {
6146 if (pAd->CommonCfg.CentralChannel > 14)
6147 {
6148 TxPwr[0] = pAd->Tx40MPwrCfgABand[0];
6149 TxPwr[1] = pAd->Tx40MPwrCfgABand[1];
6150 TxPwr[2] = pAd->Tx40MPwrCfgABand[2];
6151 TxPwr[3] = pAd->Tx40MPwrCfgABand[3];
6152 TxPwr[4] = pAd->Tx40MPwrCfgABand[4];
6153 }
6154 else
6155 {
6156 TxPwr[0] = pAd->Tx40MPwrCfgGBand[0];
6157 TxPwr[1] = pAd->Tx40MPwrCfgGBand[1];
6158 TxPwr[2] = pAd->Tx40MPwrCfgGBand[2];
6159 TxPwr[3] = pAd->Tx40MPwrCfgGBand[3];
6160 TxPwr[4] = pAd->Tx40MPwrCfgGBand[4];
6161 }
6162 }
6163 else
6164 {
6165 if (pAd->CommonCfg.Channel > 14)
6166 {
6167 TxPwr[0] = pAd->Tx20MPwrCfgABand[0];
6168 TxPwr[1] = pAd->Tx20MPwrCfgABand[1];
6169 TxPwr[2] = pAd->Tx20MPwrCfgABand[2];
6170 TxPwr[3] = pAd->Tx20MPwrCfgABand[3];
6171 TxPwr[4] = pAd->Tx20MPwrCfgABand[4];
6172 }
6173 else
6174 {
6175 TxPwr[0] = pAd->Tx20MPwrCfgGBand[0];
6176 TxPwr[1] = pAd->Tx20MPwrCfgGBand[1];
6177 TxPwr[2] = pAd->Tx20MPwrCfgGBand[2];
6178 TxPwr[3] = pAd->Tx20MPwrCfgGBand[3];
6179 TxPwr[4] = pAd->Tx20MPwrCfgGBand[4];
6180 }
6181 }
6182
6183 // TX power compensation for temperature variation based on TSSI. try every 4 second
6184 if (pAd->Mlme.OneSecPeriodicRound % 4 == 0)
6185 {
6186 if (pAd->CommonCfg.Channel <= 14)
6187 {
6188 /* bg channel */
6189 bAutoTxAgc = pAd->bAutoTxAgcG;
6190 TssiRef = pAd->TssiRefG;
6191 pTssiMinusBoundary = &pAd->TssiMinusBoundaryG[0];
6192 pTssiPlusBoundary = &pAd->TssiPlusBoundaryG[0];
6193 TxAgcStep = pAd->TxAgcStepG;
6194 pTxAgcCompensate = &pAd->TxAgcCompensateG;
6195 }
6196 else
6197 {
6198 /* a channel */
6199 bAutoTxAgc = pAd->bAutoTxAgcA;
6200 TssiRef = pAd->TssiRefA;
6201 pTssiMinusBoundary = &pAd->TssiMinusBoundaryA[0];
6202 pTssiPlusBoundary = &pAd->TssiPlusBoundaryA[0];
6203 TxAgcStep = pAd->TxAgcStepA;
6204 pTxAgcCompensate = &pAd->TxAgcCompensateA;
6205 }
6206
6207 if (bAutoTxAgc)
6208 {
6209 /* BbpR1 is unsigned char */
6210 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpR49);
6211
6212 /* (p) TssiPlusBoundaryG[0] = 0 = (m) TssiMinusBoundaryG[0] */
6213 /* compensate: +4 +3 +2 +1 0 -1 -2 -3 -4 * steps */
6214 /* step value is defined in pAd->TxAgcStepG for tx power value */
6215
6216 /* [4]+1+[4] p4 p3 p2 p1 o1 m1 m2 m3 m4 */
6217 /* ex: 0x00 0x15 0x25 0x45 0x88 0xA0 0xB5 0xD0 0xF0
6218 above value are examined in mass factory production */
6219 /* [4] [3] [2] [1] [0] [1] [2] [3] [4] */
6220
6221 /* plus (+) is 0x00 ~ 0x45, minus (-) is 0xa0 ~ 0xf0 */
6222 /* if value is between p1 ~ o1 or o1 ~ s1, no need to adjust tx power */
6223 /* if value is 0xa5, tx power will be -= TxAgcStep*(2-1) */
6224
6225 if (BbpR49 > pTssiMinusBoundary[1])
6226 {
6227 // Reading is larger than the reference value
6228 // check for how large we need to decrease the Tx power
6229 for (idx = 1; idx < 5; idx++)
6230 {
6231 if (BbpR49 <= pTssiMinusBoundary[idx]) // Found the range
6232 break;
6233 }
6234 // The index is the step we should decrease, idx = 0 means there is nothing to compensate
6235 *pTxAgcCompensate = -(TxAgcStep * (idx-1));
6236
6237 DeltaPwr += (*pTxAgcCompensate);
6238 DBGPRINT(RT_DEBUG_TRACE, ("-- Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = -%d\n",
6239 BbpR49, TssiRef, TxAgcStep, idx-1));
6240 }
6241 else if (BbpR49 < pTssiPlusBoundary[1])
6242 {
6243 // Reading is smaller than the reference value
6244 // check for how large we need to increase the Tx power
6245 for (idx = 1; idx < 5; idx++)
6246 {
6247 if (BbpR49 >= pTssiPlusBoundary[idx]) // Found the range
6248 break;
6249 }
6250 // The index is the step we should increase, idx = 0 means there is nothing to compensate
6251 *pTxAgcCompensate = TxAgcStep * (idx-1);
6252 DeltaPwr += (*pTxAgcCompensate);
6253 DBGPRINT(RT_DEBUG_TRACE, ("++ Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
6254 BbpR49, TssiRef, TxAgcStep, idx-1));
6255 }
6256 else
6257 {
6258 *pTxAgcCompensate = 0;
6259 DBGPRINT(RT_DEBUG_TRACE, (" Tx Power, BBP R49=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
6260 BbpR49, TssiRef, TxAgcStep, 0));
6261 }
6262 }
6263 }
6264 else
6265 {
6266 if (pAd->CommonCfg.Channel <= 14)
6267 {
6268 bAutoTxAgc = pAd->bAutoTxAgcG;
6269 pTxAgcCompensate = &pAd->TxAgcCompensateG;
6270 }
6271 else
6272 {
6273 bAutoTxAgc = pAd->bAutoTxAgcA;
6274 pTxAgcCompensate = &pAd->TxAgcCompensateA;
6275 }
6276
6277 if (bAutoTxAgc)
6278 DeltaPwr += (*pTxAgcCompensate);
6279 }
6280
6281 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpR1);
6282 BbpR1 &= 0xFC;
6283
6284 /* calculate delta power based on the percentage specified from UI */
6285 // E2PROM setting is calibrated for maximum TX power (i.e. 100%)
6286 // We lower TX power here according to the percentage specified from UI
6287 if (pAd->CommonCfg.TxPowerPercentage == 0xffffffff) // AUTO TX POWER control
6288 ;
6289 else if (pAd->CommonCfg.TxPowerPercentage > 90) // 91 ~ 100% & AUTO, treat as 100% in terms of mW
6290 ;
6291 else if (pAd->CommonCfg.TxPowerPercentage > 60) // 61 ~ 90%, treat as 75% in terms of mW // DeltaPwr -= 1;
6292 {
6293 DeltaPwr -= 1;
6294 }
6295 else if (pAd->CommonCfg.TxPowerPercentage > 30) // 31 ~ 60%, treat as 50% in terms of mW // DeltaPwr -= 3;
6296 {
6297 DeltaPwr -= 3;
6298 }
6299 else if (pAd->CommonCfg.TxPowerPercentage > 15) // 16 ~ 30%, treat as 25% in terms of mW // DeltaPwr -= 6;
6300 {
6301 BbpR1 |= 0x01;
6302 }
6303 else if (pAd->CommonCfg.TxPowerPercentage > 9) // 10 ~ 15%, treat as 12.5% in terms of mW // DeltaPwr -= 9;
6304 {
6305 BbpR1 |= 0x01;
6306 DeltaPwr -= 3;
6307 }
6308 else // 0 ~ 9 %, treat as MIN(~3%) in terms of mW // DeltaPwr -= 12;
6309 {
6310 BbpR1 |= 0x02;
6311 }
6312
6313 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpR1);
6314
6315 /* reset different new tx power for different TX rate */
6316 for(i=0; i<5; i++)
6317 {
6318 if (TxPwr[i] != 0xffffffff)
6319 {
6320 for (j=0; j<8; j++)
6321 {
6322 Value = (CHAR)((TxPwr[i] >> j*4) & 0x0F); /* 0 ~ 15 */
6323
6324 if ((Value + DeltaPwr) < 0)
6325 {
6326 Value = 0; /* min */
6327 }
6328 else if ((Value + DeltaPwr) > 0xF)
6329 {
6330 Value = 0xF; /* max */
6331 }
6332 else
6333 {
6334 Value += DeltaPwr; /* temperature compensation */
6335 }
6336
6337 /* fill new value to CSR offset */
6338 TxPwr[i] = (TxPwr[i] & ~(0x0000000F << j*4)) | (Value << j*4);
6339 }
6340
6341 /* write tx power value to CSR */
6342 /* TX_PWR_CFG_0 (8 tx rate) for TX power for OFDM 12M/18M
6343 TX power for OFDM 6M/9M
6344 TX power for CCK5.5M/11M
6345 TX power for CCK1M/2M */
6346 /* TX_PWR_CFG_1 ~ TX_PWR_CFG_4 */
6347 RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, TxPwr[i]);
6348 }
6349 }
6350
6351}
6352
6353/*
6354 ==========================================================================
6355 Description:
6356 put PHY to sleep here, and set next wakeup timer. PHY doesn't not wakeup
6357 automatically. Instead, MCU will issue a TwakeUpInterrupt to host after
6358 the wakeup timer timeout. Driver has to issue a separate command to wake
6359 PHY up.
6360
6361 IRQL = DISPATCH_LEVEL
6362
6363 ==========================================================================
6364 */
6365VOID AsicSleepThenAutoWakeup(
6366 IN PRTMP_ADAPTER pAd,
6367 IN USHORT TbttNumToNextWakeUp)
6368{
6369 RT28XX_STA_SLEEP_THEN_AUTO_WAKEUP(pAd, TbttNumToNextWakeUp);
6370}
6371
6372/*
6373 ==========================================================================
6374 Description:
6375 AsicForceWakeup() is used whenever manual wakeup is required
6376 AsicForceSleep() should only be used when not in INFRA BSS. When
6377 in INFRA BSS, we should use AsicSleepThenAutoWakeup() instead.
6378 ==========================================================================
6379 */
6380VOID AsicForceSleep(
6381 IN PRTMP_ADAPTER pAd)
6382{
6383
6384}
6385
6386/*
6387 ==========================================================================
6388 Description:
6389 AsicForceWakeup() is used whenever Twakeup timer (set via AsicSleepThenAutoWakeup)
6390 expired.
6391
6392 IRQL = PASSIVE_LEVEL
6393 IRQL = DISPATCH_LEVEL
6394 ==========================================================================
6395 */
6396VOID AsicForceWakeup(
6397 IN PRTMP_ADAPTER pAd,
6398#ifdef RT2860
6399 IN UCHAR Level)
6400#endif
6401#ifdef RT2870
6402 IN BOOLEAN bFromTx)
6403#endif
6404{
6405 DBGPRINT(RT_DEBUG_TRACE, ("--> AsicForceWakeup \n"));
6406#ifdef RT2860
6407 RT28XX_STA_FORCE_WAKEUP(pAd, Level);
6408#endif
6409#ifdef RT2870
6410 RT28XX_STA_FORCE_WAKEUP(pAd, bFromTx);
6411#endif
6412}
6413
6414/*
6415 ==========================================================================
6416 Description:
6417 Set My BSSID
6418
6419 IRQL = DISPATCH_LEVEL
6420
6421 ==========================================================================
6422 */
6423VOID AsicSetBssid(
6424 IN PRTMP_ADAPTER pAd,
6425 IN PUCHAR pBssid)
6426{
6427 ULONG Addr4;
6428 DBGPRINT(RT_DEBUG_TRACE, ("==============> AsicSetBssid %x:%x:%x:%x:%x:%x\n",
6429 pBssid[0],pBssid[1],pBssid[2],pBssid[3], pBssid[4],pBssid[5]));
6430
6431 Addr4 = (ULONG)(pBssid[0]) |
6432 (ULONG)(pBssid[1] << 8) |
6433 (ULONG)(pBssid[2] << 16) |
6434 (ULONG)(pBssid[3] << 24);
6435 RTMP_IO_WRITE32(pAd, MAC_BSSID_DW0, Addr4);
6436
6437 Addr4 = 0;
6438 // always one BSSID in STA mode
6439 Addr4 = (ULONG)(pBssid[4]) | (ULONG)(pBssid[5] << 8);
6440
6441 RTMP_IO_WRITE32(pAd, MAC_BSSID_DW1, Addr4);
6442}
6443
6444VOID AsicSetMcastWC(
6445 IN PRTMP_ADAPTER pAd)
6446{
6447 MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[MCAST_WCID];
6448 USHORT offset;
6449
6450 pEntry->Sst = SST_ASSOC;
6451 pEntry->Aid = MCAST_WCID; // Softap supports 1 BSSID and use WCID=0 as multicast Wcid index
6452 pEntry->PsMode = PWR_ACTIVE;
6453 pEntry->CurrTxRate = pAd->CommonCfg.MlmeRate;
6454 offset = MAC_WCID_BASE + BSS0Mcast_WCID * HW_WCID_ENTRY_SIZE;
6455}
6456
6457/*
6458 ==========================================================================
6459 Description:
6460
6461 IRQL = DISPATCH_LEVEL
6462
6463 ==========================================================================
6464 */
6465VOID AsicDelWcidTab(
6466 IN PRTMP_ADAPTER pAd,
6467 IN UCHAR Wcid)
6468{
6469 ULONG Addr0 = 0x0, Addr1 = 0x0;
6470 ULONG offset;
6471
6472 DBGPRINT(RT_DEBUG_TRACE, ("AsicDelWcidTab==>Wcid = 0x%x\n",Wcid));
6473 offset = MAC_WCID_BASE + Wcid * HW_WCID_ENTRY_SIZE;
6474 RTMP_IO_WRITE32(pAd, offset, Addr0);
6475 offset += 4;
6476 RTMP_IO_WRITE32(pAd, offset, Addr1);
6477}
6478
6479/*
6480 ==========================================================================
6481 Description:
6482
6483 IRQL = DISPATCH_LEVEL
6484
6485 ==========================================================================
6486 */
6487VOID AsicEnableRDG(
6488 IN PRTMP_ADAPTER pAd)
6489{
6490 TX_LINK_CFG_STRUC TxLinkCfg;
6491 UINT32 Data = 0;
6492
6493 RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word);
6494 TxLinkCfg.field.TxRDGEn = 1;
6495 RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word);
6496
6497 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
6498 Data &= 0xFFFFFF00;
6499 Data |= 0x80;
6500 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
6501
6502 //OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
6503}
6504
6505/*
6506 ==========================================================================
6507 Description:
6508
6509 IRQL = DISPATCH_LEVEL
6510
6511 ==========================================================================
6512 */
6513VOID AsicDisableRDG(
6514 IN PRTMP_ADAPTER pAd)
6515{
6516 TX_LINK_CFG_STRUC TxLinkCfg;
6517 UINT32 Data = 0;
6518
6519
6520 RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word);
6521 TxLinkCfg.field.TxRDGEn = 0;
6522 RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word);
6523
6524 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
6525
6526 Data &= 0xFFFFFF00;
6527 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_DYNAMIC_BE_TXOP_ACTIVE)
6528 && (pAd->MacTab.fAnyStationMIMOPSDynamic == FALSE)
6529 )
6530 {
6531 // For CWC test, change txop from 0x30 to 0x20 in TxBurst mode
6532 if (pAd->CommonCfg.bEnableTxBurst)
6533 Data |= 0x20;
6534 }
6535 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
6536}
6537
6538/*
6539 ==========================================================================
6540 Description:
6541
6542 IRQL = PASSIVE_LEVEL
6543 IRQL = DISPATCH_LEVEL
6544
6545 ==========================================================================
6546 */
6547VOID AsicDisableSync(
6548 IN PRTMP_ADAPTER pAd)
6549{
6550 BCN_TIME_CFG_STRUC csr;
6551
6552 DBGPRINT(RT_DEBUG_TRACE, ("--->Disable TSF synchronization\n"));
6553
6554 // 2003-12-20 disable TSF and TBTT while NIC in power-saving have side effect
6555 // that NIC will never wakes up because TSF stops and no more
6556 // TBTT interrupts
6557 pAd->TbttTickCount = 0;
6558 RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
6559 csr.field.bBeaconGen = 0;
6560 csr.field.bTBTTEnable = 0;
6561 csr.field.TsfSyncMode = 0;
6562 csr.field.bTsfTicking = 0;
6563 RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
6564
6565}
6566
6567/*
6568 ==========================================================================
6569 Description:
6570
6571 IRQL = DISPATCH_LEVEL
6572
6573 ==========================================================================
6574 */
6575VOID AsicEnableBssSync(
6576 IN PRTMP_ADAPTER pAd)
6577{
6578 BCN_TIME_CFG_STRUC csr;
6579
6580 DBGPRINT(RT_DEBUG_TRACE, ("--->AsicEnableBssSync(INFRA mode)\n"));
6581
6582 RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
6583
6584 {
6585 csr.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4; // ASIC register in units of 1/16 TU
6586 csr.field.bTsfTicking = 1;
6587 csr.field.TsfSyncMode = 1; // sync TSF in INFRASTRUCTURE mode
6588 csr.field.bBeaconGen = 0; // do NOT generate BEACON
6589 csr.field.bTBTTEnable = 1;
6590 }
6591
6592 RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
6593}
6594
6595/*
6596 ==========================================================================
6597 Description:
6598 Note:
6599 BEACON frame in shared memory should be built ok before this routine
6600 can be called. Otherwise, a garbage frame maybe transmitted out every
6601 Beacon period.
6602
6603 IRQL = DISPATCH_LEVEL
6604
6605 ==========================================================================
6606 */
6607VOID AsicEnableIbssSync(
6608 IN PRTMP_ADAPTER pAd)
6609{
6610 BCN_TIME_CFG_STRUC csr9;
6611 PUCHAR ptr;
6612 UINT i;
6613
6614 DBGPRINT(RT_DEBUG_TRACE, ("--->AsicEnableIbssSync(ADHOC mode. MPDUtotalByteCount = %d)\n", pAd->BeaconTxWI.MPDUtotalByteCount));
6615
6616 RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr9.word);
6617 csr9.field.bBeaconGen = 0;
6618 csr9.field.bTBTTEnable = 0;
6619 csr9.field.bTsfTicking = 0;
6620 RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word);
6621
6622#ifdef RT2860
6623 // move BEACON TXD and frame content to on-chip memory
6624 ptr = (PUCHAR)&pAd->BeaconTxWI;
6625 for (i=0; i<TXWI_SIZE; i+=4) // 16-byte TXWI field
6626 {
6627 UINT32 longptr = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
6628 RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + i, longptr);
6629 ptr += 4;
6630 }
6631
6632 // start right after the 16-byte TXWI field
6633 ptr = pAd->BeaconBuf;
6634 for (i=0; i< pAd->BeaconTxWI.MPDUtotalByteCount; i+=4)
6635 {
6636 UINT32 longptr = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
6637 RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, longptr);
6638 ptr +=4;
6639 }
6640#endif
6641#ifdef RT2870
6642 // move BEACON TXD and frame content to on-chip memory
6643 ptr = (PUCHAR)&pAd->BeaconTxWI;
6644 for (i=0; i<TXWI_SIZE; i+=2) // 16-byte TXWI field
6645 {
6646 RTUSBMultiWrite(pAd, HW_BEACON_BASE0 + i, ptr, 2);
6647 ptr += 2;
6648 }
6649
6650 // start right after the 16-byte TXWI field
6651 ptr = pAd->BeaconBuf;
6652 for (i=0; i< pAd->BeaconTxWI.MPDUtotalByteCount; i+=2)
6653 {
6654 RTUSBMultiWrite(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, ptr, 2);
6655 ptr +=2;
6656 }
6657#endif // RT2870 //
6658
6659 // start sending BEACON
6660 csr9.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4; // ASIC register in units of 1/16 TU
6661 csr9.field.bTsfTicking = 1;
6662 csr9.field.TsfSyncMode = 2; // sync TSF in IBSS mode
6663 csr9.field.bTBTTEnable = 1;
6664 csr9.field.bBeaconGen = 1;
6665 RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word);
6666}
6667
6668/*
6669 ==========================================================================
6670 Description:
6671
6672 IRQL = PASSIVE_LEVEL
6673 IRQL = DISPATCH_LEVEL
6674
6675 ==========================================================================
6676 */
6677VOID AsicSetEdcaParm(
6678 IN PRTMP_ADAPTER pAd,
6679 IN PEDCA_PARM pEdcaParm)
6680{
6681 EDCA_AC_CFG_STRUC Ac0Cfg, Ac1Cfg, Ac2Cfg, Ac3Cfg;
6682 AC_TXOP_CSR0_STRUC csr0;
6683 AC_TXOP_CSR1_STRUC csr1;
6684 AIFSN_CSR_STRUC AifsnCsr;
6685 CWMIN_CSR_STRUC CwminCsr;
6686 CWMAX_CSR_STRUC CwmaxCsr;
6687 int i;
6688
6689 Ac0Cfg.word = 0;
6690 Ac1Cfg.word = 0;
6691 Ac2Cfg.word = 0;
6692 Ac3Cfg.word = 0;
6693 if ((pEdcaParm == NULL) || (pEdcaParm->bValid == FALSE))
6694 {
6695 DBGPRINT(RT_DEBUG_TRACE,("AsicSetEdcaParm\n"));
6696 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_WMM_INUSED);
6697 for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
6698 {
6699 if (pAd->MacTab.Content[i].ValidAsCLI || pAd->MacTab.Content[i].ValidAsApCli)
6700 CLIENT_STATUS_CLEAR_FLAG(&pAd->MacTab.Content[i], fCLIENT_STATUS_WMM_CAPABLE);
6701 }
6702
6703 //========================================================
6704 // MAC Register has a copy .
6705 //========================================================
6706 if( pAd->CommonCfg.bEnableTxBurst )
6707 {
6708 // For CWC test, change txop from 0x30 to 0x20 in TxBurst mode
6709 Ac0Cfg.field.AcTxop = 0x20; // Suggest by John for TxBurst in HT Mode
6710 }
6711 else
6712 Ac0Cfg.field.AcTxop = 0; // QID_AC_BE
6713 Ac0Cfg.field.Cwmin = CW_MIN_IN_BITS;
6714 Ac0Cfg.field.Cwmax = CW_MAX_IN_BITS;
6715 Ac0Cfg.field.Aifsn = 2;
6716 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Ac0Cfg.word);
6717
6718 Ac1Cfg.field.AcTxop = 0; // QID_AC_BK
6719 Ac1Cfg.field.Cwmin = CW_MIN_IN_BITS;
6720 Ac1Cfg.field.Cwmax = CW_MAX_IN_BITS;
6721 Ac1Cfg.field.Aifsn = 2;
6722 RTMP_IO_WRITE32(pAd, EDCA_AC1_CFG, Ac1Cfg.word);
6723
6724 if (pAd->CommonCfg.PhyMode == PHY_11B)
6725 {
6726 Ac2Cfg.field.AcTxop = 192; // AC_VI: 192*32us ~= 6ms
6727 Ac3Cfg.field.AcTxop = 96; // AC_VO: 96*32us ~= 3ms
6728 }
6729 else
6730 {
6731 Ac2Cfg.field.AcTxop = 96; // AC_VI: 96*32us ~= 3ms
6732 Ac3Cfg.field.AcTxop = 48; // AC_VO: 48*32us ~= 1.5ms
6733 }
6734 Ac2Cfg.field.Cwmin = CW_MIN_IN_BITS;
6735 Ac2Cfg.field.Cwmax = CW_MAX_IN_BITS;
6736 Ac2Cfg.field.Aifsn = 2;
6737 RTMP_IO_WRITE32(pAd, EDCA_AC2_CFG, Ac2Cfg.word);
6738 Ac3Cfg.field.Cwmin = CW_MIN_IN_BITS;
6739 Ac3Cfg.field.Cwmax = CW_MAX_IN_BITS;
6740 Ac3Cfg.field.Aifsn = 2;
6741 RTMP_IO_WRITE32(pAd, EDCA_AC3_CFG, Ac3Cfg.word);
6742
6743 //========================================================
6744 // DMA Register has a copy too.
6745 //========================================================
6746 csr0.field.Ac0Txop = 0; // QID_AC_BE
6747 csr0.field.Ac1Txop = 0; // QID_AC_BK
6748 RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word);
6749 if (pAd->CommonCfg.PhyMode == PHY_11B)
6750 {
6751 csr1.field.Ac2Txop = 192; // AC_VI: 192*32us ~= 6ms
6752 csr1.field.Ac3Txop = 96; // AC_VO: 96*32us ~= 3ms
6753 }
6754 else
6755 {
6756 csr1.field.Ac2Txop = 96; // AC_VI: 96*32us ~= 3ms
6757 csr1.field.Ac3Txop = 48; // AC_VO: 48*32us ~= 1.5ms
6758 }
6759 RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr1.word);
6760
6761 CwminCsr.word = 0;
6762 CwminCsr.field.Cwmin0 = CW_MIN_IN_BITS;
6763 CwminCsr.field.Cwmin1 = CW_MIN_IN_BITS;
6764 CwminCsr.field.Cwmin2 = CW_MIN_IN_BITS;
6765 CwminCsr.field.Cwmin3 = CW_MIN_IN_BITS;
6766 RTMP_IO_WRITE32(pAd, WMM_CWMIN_CFG, CwminCsr.word);
6767
6768 CwmaxCsr.word = 0;
6769 CwmaxCsr.field.Cwmax0 = CW_MAX_IN_BITS;
6770 CwmaxCsr.field.Cwmax1 = CW_MAX_IN_BITS;
6771 CwmaxCsr.field.Cwmax2 = CW_MAX_IN_BITS;
6772 CwmaxCsr.field.Cwmax3 = CW_MAX_IN_BITS;
6773 RTMP_IO_WRITE32(pAd, WMM_CWMAX_CFG, CwmaxCsr.word);
6774
6775 RTMP_IO_WRITE32(pAd, WMM_AIFSN_CFG, 0x00002222);
6776
6777 NdisZeroMemory(&pAd->CommonCfg.APEdcaParm, sizeof(EDCA_PARM));
6778 }
6779 else
6780 {
6781 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_WMM_INUSED);
6782 //========================================================
6783 // MAC Register has a copy.
6784 //========================================================
6785 //
6786 // Modify Cwmin/Cwmax/Txop on queue[QID_AC_VI], Recommend by Jerry 2005/07/27
6787 // To degrade our VIDO Queue's throughput for WiFi WMM S3T07 Issue.
6788 //
6789 //pEdcaParm->Txop[QID_AC_VI] = pEdcaParm->Txop[QID_AC_VI] * 7 / 10; // rt2860c need this
6790
6791 Ac0Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BE];
6792 Ac0Cfg.field.Cwmin= pEdcaParm->Cwmin[QID_AC_BE];
6793 Ac0Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_BE];
6794 Ac0Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BE]; //+1;
6795
6796 Ac1Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BK];
6797 Ac1Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_BK]; //+2;
6798 Ac1Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_BK];
6799 Ac1Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BK]; //+1;
6800
6801 Ac2Cfg.field.AcTxop = (pEdcaParm->Txop[QID_AC_VI] * 6) / 10;
6802 Ac2Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VI];
6803 Ac2Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VI];
6804 Ac2Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VI];
6805
6806 {
6807 // Tuning for Wi-Fi WMM S06
6808 if (pAd->CommonCfg.bWiFiTest &&
6809 pEdcaParm->Aifsn[QID_AC_VI] == 10)
6810 Ac2Cfg.field.Aifsn -= 1;
6811
6812 // Tuning for TGn Wi-Fi 5.2.32
6813 // STA TestBed changes in this item: connexant legacy sta ==> broadcom 11n sta
6814 if (STA_TGN_WIFI_ON(pAd) &&
6815 pEdcaParm->Aifsn[QID_AC_VI] == 10)
6816 {
6817 Ac0Cfg.field.Aifsn = 3;
6818 Ac2Cfg.field.AcTxop = 5;
6819 }
6820
6821#ifdef RT2870
6822 if (pAd->RfIcType == RFIC_3020 || pAd->RfIcType == RFIC_2020)
6823 {
6824 // Tuning for WiFi WMM S3-T07: connexant legacy sta ==> broadcom 11n sta.
6825 Ac2Cfg.field.Aifsn = 5;
6826 }
6827#endif
6828 }
6829
6830 Ac3Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_VO];
6831 Ac3Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VO];
6832 Ac3Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VO];
6833 Ac3Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VO];
6834
6835//#ifdef WIFI_TEST
6836 if (pAd->CommonCfg.bWiFiTest)
6837 {
6838 if (Ac3Cfg.field.AcTxop == 102)
6839 {
6840 Ac0Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BE] ? pEdcaParm->Txop[QID_AC_BE] : 10;
6841 Ac0Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BE]-1; /* AIFSN must >= 1 */
6842 Ac1Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BK];
6843 Ac1Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BK];
6844 Ac2Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_VI];
6845 } /* End of if */
6846 }
6847//#endif // WIFI_TEST //
6848
6849 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Ac0Cfg.word);
6850 RTMP_IO_WRITE32(pAd, EDCA_AC1_CFG, Ac1Cfg.word);
6851 RTMP_IO_WRITE32(pAd, EDCA_AC2_CFG, Ac2Cfg.word);
6852 RTMP_IO_WRITE32(pAd, EDCA_AC3_CFG, Ac3Cfg.word);
6853
6854
6855 //========================================================
6856 // DMA Register has a copy too.
6857 //========================================================
6858 csr0.field.Ac0Txop = Ac0Cfg.field.AcTxop;
6859 csr0.field.Ac1Txop = Ac1Cfg.field.AcTxop;
6860 RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word);
6861
6862 csr1.field.Ac2Txop = Ac2Cfg.field.AcTxop;
6863 csr1.field.Ac3Txop = Ac3Cfg.field.AcTxop;
6864 RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr1.word);
6865
6866 CwminCsr.word = 0;
6867 CwminCsr.field.Cwmin0 = pEdcaParm->Cwmin[QID_AC_BE];
6868 CwminCsr.field.Cwmin1 = pEdcaParm->Cwmin[QID_AC_BK];
6869 CwminCsr.field.Cwmin2 = pEdcaParm->Cwmin[QID_AC_VI];
6870
6871 CwminCsr.field.Cwmin3 = pEdcaParm->Cwmin[QID_AC_VO] - 1; //for TGn wifi test
6872
6873 RTMP_IO_WRITE32(pAd, WMM_CWMIN_CFG, CwminCsr.word);
6874
6875 CwmaxCsr.word = 0;
6876 CwmaxCsr.field.Cwmax0 = pEdcaParm->Cwmax[QID_AC_BE];
6877 CwmaxCsr.field.Cwmax1 = pEdcaParm->Cwmax[QID_AC_BK];
6878 CwmaxCsr.field.Cwmax2 = pEdcaParm->Cwmax[QID_AC_VI];
6879 CwmaxCsr.field.Cwmax3 = pEdcaParm->Cwmax[QID_AC_VO];
6880 RTMP_IO_WRITE32(pAd, WMM_CWMAX_CFG, CwmaxCsr.word);
6881
6882 AifsnCsr.word = 0;
6883 AifsnCsr.field.Aifsn0 = Ac0Cfg.field.Aifsn; //pEdcaParm->Aifsn[QID_AC_BE];
6884 AifsnCsr.field.Aifsn1 = Ac1Cfg.field.Aifsn; //pEdcaParm->Aifsn[QID_AC_BK];
6885 AifsnCsr.field.Aifsn2 = Ac2Cfg.field.Aifsn; //pEdcaParm->Aifsn[QID_AC_VI];
6886
6887 {
6888 // Tuning for Wi-Fi WMM S06
6889 if (pAd->CommonCfg.bWiFiTest &&
6890 pEdcaParm->Aifsn[QID_AC_VI] == 10)
6891 AifsnCsr.field.Aifsn2 = Ac2Cfg.field.Aifsn - 4;
6892
6893 // Tuning for TGn Wi-Fi 5.2.32
6894 // STA TestBed changes in this item: connexant legacy sta ==> broadcom 11n sta
6895 if (STA_TGN_WIFI_ON(pAd) &&
6896 pEdcaParm->Aifsn[QID_AC_VI] == 10)
6897 {
6898 AifsnCsr.field.Aifsn0 = 3;
6899 AifsnCsr.field.Aifsn2 = 7;
6900 }
6901#ifdef RT2870
6902 if (INFRA_ON(pAd))
6903 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_WMM_CAPABLE);
6904#endif
6905 }
6906
6907 AifsnCsr.field.Aifsn3 = Ac3Cfg.field.Aifsn - 1; //pEdcaParm->Aifsn[QID_AC_VO]; //for TGn wifi test
6908#ifdef RT2870
6909 if (pAd->RfIcType == RFIC_3020 || pAd->RfIcType == RFIC_2020)
6910 AifsnCsr.field.Aifsn2 = 0x2; //pEdcaParm->Aifsn[QID_AC_VI]; //for WiFi WMM S4-T04.
6911#endif
6912 RTMP_IO_WRITE32(pAd, WMM_AIFSN_CFG, AifsnCsr.word);
6913
6914 NdisMoveMemory(&pAd->CommonCfg.APEdcaParm, pEdcaParm, sizeof(EDCA_PARM));
6915 if (!ADHOC_ON(pAd))
6916 {
6917 DBGPRINT(RT_DEBUG_TRACE,("EDCA [#%d]: AIFSN CWmin CWmax TXOP(us) ACM\n", pEdcaParm->EdcaUpdateCount));
6918 DBGPRINT(RT_DEBUG_TRACE,(" AC_BE %2d %2d %2d %4d %d\n",
6919 pEdcaParm->Aifsn[0],
6920 pEdcaParm->Cwmin[0],
6921 pEdcaParm->Cwmax[0],
6922 pEdcaParm->Txop[0]<<5,
6923 pEdcaParm->bACM[0]));
6924 DBGPRINT(RT_DEBUG_TRACE,(" AC_BK %2d %2d %2d %4d %d\n",
6925 pEdcaParm->Aifsn[1],
6926 pEdcaParm->Cwmin[1],
6927 pEdcaParm->Cwmax[1],
6928 pEdcaParm->Txop[1]<<5,
6929 pEdcaParm->bACM[1]));
6930 DBGPRINT(RT_DEBUG_TRACE,(" AC_VI %2d %2d %2d %4d %d\n",
6931 pEdcaParm->Aifsn[2],
6932 pEdcaParm->Cwmin[2],
6933 pEdcaParm->Cwmax[2],
6934 pEdcaParm->Txop[2]<<5,
6935 pEdcaParm->bACM[2]));
6936 DBGPRINT(RT_DEBUG_TRACE,(" AC_VO %2d %2d %2d %4d %d\n",
6937 pEdcaParm->Aifsn[3],
6938 pEdcaParm->Cwmin[3],
6939 pEdcaParm->Cwmax[3],
6940 pEdcaParm->Txop[3]<<5,
6941 pEdcaParm->bACM[3]));
6942 }
6943 }
6944}
6945
6946/*
6947 ==========================================================================
6948 Description:
6949
6950 IRQL = PASSIVE_LEVEL
6951 IRQL = DISPATCH_LEVEL
6952
6953 ==========================================================================
6954 */
6955VOID AsicSetSlotTime(
6956 IN PRTMP_ADAPTER pAd,
6957 IN BOOLEAN bUseShortSlotTime)
6958{
6959 ULONG SlotTime;
6960 UINT32 RegValue = 0;
6961
6962 if (pAd->CommonCfg.Channel > 14)
6963 bUseShortSlotTime = TRUE;
6964
6965 if (bUseShortSlotTime)
6966 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
6967 else
6968 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
6969
6970 SlotTime = (bUseShortSlotTime)? 9 : 20;
6971
6972 {
6973 // force using short SLOT time for FAE to demo performance when TxBurst is ON
6974 if (((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED)))
6975 || ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE) && (pAd->CommonCfg.BACapability.field.Policy == BA_NOTUSE))
6976 )
6977 {
6978 // In this case, we will think it is doing Wi-Fi test
6979 // And we will not set to short slot when bEnableTxBurst is TRUE.
6980 }
6981 else if (pAd->CommonCfg.bEnableTxBurst)
6982 SlotTime = 9;
6983 }
6984
6985 //
6986 // For some reasons, always set it to short slot time.
6987 //
6988 // ToDo: Should consider capability with 11B
6989 //
6990 if (pAd->StaCfg.BssType == BSS_ADHOC)
6991 SlotTime = 20;
6992
6993 RTMP_IO_READ32(pAd, BKOFF_SLOT_CFG, &RegValue);
6994 RegValue = RegValue & 0xFFFFFF00;
6995
6996 RegValue |= SlotTime;
6997
6998 RTMP_IO_WRITE32(pAd, BKOFF_SLOT_CFG, RegValue);
6999}
7000
7001/*
7002 ========================================================================
7003 Description:
7004 Add Shared key information into ASIC.
7005 Update shared key, TxMic and RxMic to Asic Shared key table
7006 Update its cipherAlg to Asic Shared key Mode.
7007
7008 Return:
7009 ========================================================================
7010*/
7011VOID AsicAddSharedKeyEntry(
7012 IN PRTMP_ADAPTER pAd,
7013 IN UCHAR BssIndex,
7014 IN UCHAR KeyIdx,
7015 IN UCHAR CipherAlg,
7016 IN PUCHAR pKey,
7017 IN PUCHAR pTxMic,
7018 IN PUCHAR pRxMic)
7019{
7020 ULONG offset; //, csr0;
7021 SHAREDKEY_MODE_STRUC csr1;
7022#ifdef RT2860
7023 INT i;
7024#endif
7025
7026 DBGPRINT(RT_DEBUG_TRACE, ("AsicAddSharedKeyEntry BssIndex=%d, KeyIdx=%d\n", BssIndex,KeyIdx));
7027//============================================================================================
7028
7029 DBGPRINT(RT_DEBUG_TRACE,("AsicAddSharedKeyEntry: %s key #%d\n", CipherName[CipherAlg], BssIndex*4 + KeyIdx));
7030 DBGPRINT_RAW(RT_DEBUG_TRACE, (" Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
7031 pKey[0],pKey[1],pKey[2],pKey[3],pKey[4],pKey[5],pKey[6],pKey[7],pKey[8],pKey[9],pKey[10],pKey[11],pKey[12],pKey[13],pKey[14],pKey[15]));
7032 if (pRxMic)
7033 {
7034 DBGPRINT_RAW(RT_DEBUG_TRACE, (" Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
7035 pRxMic[0],pRxMic[1],pRxMic[2],pRxMic[3],pRxMic[4],pRxMic[5],pRxMic[6],pRxMic[7]));
7036 }
7037 if (pTxMic)
7038 {
7039 DBGPRINT_RAW(RT_DEBUG_TRACE, (" Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
7040 pTxMic[0],pTxMic[1],pTxMic[2],pTxMic[3],pTxMic[4],pTxMic[5],pTxMic[6],pTxMic[7]));
7041 }
7042//============================================================================================
7043 //
7044 // fill key material - key + TX MIC + RX MIC
7045 //
7046
7047 offset = SHARED_KEY_TABLE_BASE + (4*BssIndex + KeyIdx)*HW_KEY_ENTRY_SIZE;
7048#ifdef RT2860
7049 for (i=0; i<MAX_LEN_OF_SHARE_KEY; i++)
7050 {
7051 RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
7052 }
7053#endif
7054#ifdef RT2870
7055 RTUSBMultiWrite(pAd, offset, pKey, MAX_LEN_OF_SHARE_KEY);
7056#endif
7057 offset += MAX_LEN_OF_SHARE_KEY;
7058 if (pTxMic)
7059 {
7060#ifdef RT2860
7061 for (i=0; i<8; i++)
7062 {
7063 RTMP_IO_WRITE8(pAd, offset + i, pTxMic[i]);
7064 }
7065#endif
7066#ifdef RT2870
7067 RTUSBMultiWrite(pAd, offset, pTxMic, 8);
7068#endif
7069 }
7070
7071 offset += 8;
7072 if (pRxMic)
7073 {
7074#ifdef RT2860
7075 for (i=0; i<8; i++)
7076 {
7077 RTMP_IO_WRITE8(pAd, offset + i, pRxMic[i]);
7078 }
7079#endif
7080#ifdef RT2870
7081 RTUSBMultiWrite(pAd, offset, pRxMic, 8);
7082#endif
7083 }
7084
7085
7086 //
7087 // Update cipher algorithm. WSTA always use BSS0
7088 //
7089 RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), &csr1.word);
7090 DBGPRINT(RT_DEBUG_TRACE,("Read: SHARED_KEY_MODE_BASE at this Bss[%d] KeyIdx[%d]= 0x%x \n", BssIndex,KeyIdx, csr1.word));
7091 if ((BssIndex%2) == 0)
7092 {
7093 if (KeyIdx == 0)
7094 csr1.field.Bss0Key0CipherAlg = CipherAlg;
7095 else if (KeyIdx == 1)
7096 csr1.field.Bss0Key1CipherAlg = CipherAlg;
7097 else if (KeyIdx == 2)
7098 csr1.field.Bss0Key2CipherAlg = CipherAlg;
7099 else
7100 csr1.field.Bss0Key3CipherAlg = CipherAlg;
7101 }
7102 else
7103 {
7104 if (KeyIdx == 0)
7105 csr1.field.Bss1Key0CipherAlg = CipherAlg;
7106 else if (KeyIdx == 1)
7107 csr1.field.Bss1Key1CipherAlg = CipherAlg;
7108 else if (KeyIdx == 2)
7109 csr1.field.Bss1Key2CipherAlg = CipherAlg;
7110 else
7111 csr1.field.Bss1Key3CipherAlg = CipherAlg;
7112 }
7113 DBGPRINT(RT_DEBUG_TRACE,("Write: SHARED_KEY_MODE_BASE at this Bss[%d] = 0x%x \n", BssIndex, csr1.word));
7114 RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), csr1.word);
7115
7116}
7117
7118// IRQL = DISPATCH_LEVEL
7119VOID AsicRemoveSharedKeyEntry(
7120 IN PRTMP_ADAPTER pAd,
7121 IN UCHAR BssIndex,
7122 IN UCHAR KeyIdx)
7123{
7124 //ULONG SecCsr0;
7125 SHAREDKEY_MODE_STRUC csr1;
7126
7127 DBGPRINT(RT_DEBUG_TRACE,("AsicRemoveSharedKeyEntry: #%d \n", BssIndex*4 + KeyIdx));
7128
7129 RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), &csr1.word);
7130 if ((BssIndex%2) == 0)
7131 {
7132 if (KeyIdx == 0)
7133 csr1.field.Bss0Key0CipherAlg = 0;
7134 else if (KeyIdx == 1)
7135 csr1.field.Bss0Key1CipherAlg = 0;
7136 else if (KeyIdx == 2)
7137 csr1.field.Bss0Key2CipherAlg = 0;
7138 else
7139 csr1.field.Bss0Key3CipherAlg = 0;
7140 }
7141 else
7142 {
7143 if (KeyIdx == 0)
7144 csr1.field.Bss1Key0CipherAlg = 0;
7145 else if (KeyIdx == 1)
7146 csr1.field.Bss1Key1CipherAlg = 0;
7147 else if (KeyIdx == 2)
7148 csr1.field.Bss1Key2CipherAlg = 0;
7149 else
7150 csr1.field.Bss1Key3CipherAlg = 0;
7151 }
7152 DBGPRINT(RT_DEBUG_TRACE,("Write: SHARED_KEY_MODE_BASE at this Bss[%d] = 0x%x \n", BssIndex, csr1.word));
7153 RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), csr1.word);
7154 ASSERT(BssIndex < 4);
7155 ASSERT(KeyIdx < 4);
7156
7157}
7158
7159
7160VOID AsicUpdateWCIDAttribute(
7161 IN PRTMP_ADAPTER pAd,
7162 IN USHORT WCID,
7163 IN UCHAR BssIndex,
7164 IN UCHAR CipherAlg,
7165 IN BOOLEAN bUsePairewiseKeyTable)
7166{
7167 ULONG WCIDAttri = 0, offset;
7168
7169 //
7170 // Update WCID attribute.
7171 // Only TxKey could update WCID attribute.
7172 //
7173 offset = MAC_WCID_ATTRIBUTE_BASE + (WCID * HW_WCID_ATTRI_SIZE);
7174 WCIDAttri = (BssIndex << 4) | (CipherAlg << 1) | (bUsePairewiseKeyTable);
7175 RTMP_IO_WRITE32(pAd, offset, WCIDAttri);
7176}
7177
7178VOID AsicUpdateWCIDIVEIV(
7179 IN PRTMP_ADAPTER pAd,
7180 IN USHORT WCID,
7181 IN ULONG uIV,
7182 IN ULONG uEIV)
7183{
7184 ULONG offset;
7185
7186 offset = MAC_IVEIV_TABLE_BASE + (WCID * HW_IVEIV_ENTRY_SIZE);
7187
7188 RTMP_IO_WRITE32(pAd, offset, uIV);
7189 RTMP_IO_WRITE32(pAd, offset + 4, uEIV);
7190}
7191
7192VOID AsicUpdateRxWCIDTable(
7193 IN PRTMP_ADAPTER pAd,
7194 IN USHORT WCID,
7195 IN PUCHAR pAddr)
7196{
7197 ULONG offset;
7198 ULONG Addr;
7199
7200 offset = MAC_WCID_BASE + (WCID * HW_WCID_ENTRY_SIZE);
7201 Addr = pAddr[0] + (pAddr[1] << 8) +(pAddr[2] << 16) +(pAddr[3] << 24);
7202 RTMP_IO_WRITE32(pAd, offset, Addr);
7203 Addr = pAddr[4] + (pAddr[5] << 8);
7204 RTMP_IO_WRITE32(pAd, offset + 4, Addr);
7205}
7206
7207
7208/*
7209 ========================================================================
7210
7211 Routine Description:
7212 Set Cipher Key, Cipher algorithm, IV/EIV to Asic
7213
7214 Arguments:
7215 pAd Pointer to our adapter
7216 WCID WCID Entry number.
7217 BssIndex BSSID index, station or none multiple BSSID support
7218 this value should be 0.
7219 KeyIdx This KeyIdx will set to IV's KeyID if bTxKey enabled
7220 pCipherKey Pointer to Cipher Key.
7221 bUsePairewiseKeyTable TRUE means saved the key in SharedKey table,
7222 otherwise PairewiseKey table
7223 bTxKey This is the transmit key if enabled.
7224
7225 Return Value:
7226 None
7227
7228 Note:
7229 This routine will set the relative key stuff to Asic including WCID attribute,
7230 Cipher Key, Cipher algorithm and IV/EIV.
7231
7232 IV/EIV will be update if this CipherKey is the transmission key because
7233 ASIC will base on IV's KeyID value to select Cipher Key.
7234
7235 If bTxKey sets to FALSE, this is not the TX key, but it could be
7236 RX key
7237
7238 For AP mode bTxKey must be always set to TRUE.
7239 ========================================================================
7240*/
7241VOID AsicAddKeyEntry(
7242 IN PRTMP_ADAPTER pAd,
7243 IN USHORT WCID,
7244 IN UCHAR BssIndex,
7245 IN UCHAR KeyIdx,
7246 IN PCIPHER_KEY pCipherKey,
7247 IN BOOLEAN bUsePairewiseKeyTable,
7248 IN BOOLEAN bTxKey)
7249{
7250 ULONG offset;
7251 UCHAR IV4 = 0;
7252 PUCHAR pKey = pCipherKey->Key;
7253 PUCHAR pTxMic = pCipherKey->TxMic;
7254 PUCHAR pRxMic = pCipherKey->RxMic;
7255 PUCHAR pTxtsc = pCipherKey->TxTsc;
7256 UCHAR CipherAlg = pCipherKey->CipherAlg;
7257 SHAREDKEY_MODE_STRUC csr1;
7258#ifdef RT2860
7259 UCHAR i;
7260#endif
7261
7262 DBGPRINT(RT_DEBUG_TRACE, ("==> AsicAddKeyEntry\n"));
7263 //
7264 // 1.) decide key table offset
7265 //
7266 if (bUsePairewiseKeyTable)
7267 offset = PAIRWISE_KEY_TABLE_BASE + (WCID * HW_KEY_ENTRY_SIZE);
7268 else
7269 offset = SHARED_KEY_TABLE_BASE + (4 * BssIndex + KeyIdx) * HW_KEY_ENTRY_SIZE;
7270
7271 //
7272 // 2.) Set Key to Asic
7273 //
7274 //for (i = 0; i < KeyLen; i++)
7275#ifdef RT2860
7276 for (i = 0; i < MAX_LEN_OF_PEER_KEY; i++)
7277 {
7278 RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
7279 }
7280#endif
7281#ifdef RT2870
7282 RTUSBMultiWrite(pAd, offset, pKey, MAX_LEN_OF_PEER_KEY);
7283#endif
7284 offset += MAX_LEN_OF_PEER_KEY;
7285
7286 //
7287 // 3.) Set MIC key if available
7288 //
7289 if (pTxMic)
7290 {
7291#ifdef RT2860
7292 for (i = 0; i < 8; i++)
7293 {
7294 RTMP_IO_WRITE8(pAd, offset + i, pTxMic[i]);
7295 }
7296#endif
7297#ifdef RT2870
7298 RTUSBMultiWrite(pAd, offset, pTxMic, 8);
7299#endif
7300 }
7301 offset += LEN_TKIP_TXMICK;
7302
7303 if (pRxMic)
7304 {
7305#ifdef RT2860
7306 for (i = 0; i < 8; i++)
7307 {
7308 RTMP_IO_WRITE8(pAd, offset + i, pRxMic[i]);
7309 }
7310#endif
7311#ifdef RT2870
7312 RTUSBMultiWrite(pAd, offset, pRxMic, 8);
7313#endif
7314 }
7315
7316
7317 //
7318 // 4.) Modify IV/EIV if needs
7319 // This will force Asic to use this key ID by setting IV.
7320 //
7321 if (bTxKey)
7322 {
7323#ifdef RT2860
7324 offset = MAC_IVEIV_TABLE_BASE + (WCID * HW_IVEIV_ENTRY_SIZE);
7325 //
7326 // Write IV
7327 //
7328 RTMP_IO_WRITE8(pAd, offset, pTxtsc[1]);
7329 RTMP_IO_WRITE8(pAd, offset + 1, ((pTxtsc[1] | 0x20) & 0x7f));
7330 RTMP_IO_WRITE8(pAd, offset + 2, pTxtsc[0]);
7331
7332 IV4 = (KeyIdx << 6);
7333 if ((CipherAlg == CIPHER_TKIP) || (CipherAlg == CIPHER_TKIP_NO_MIC) ||(CipherAlg == CIPHER_AES))
7334 IV4 |= 0x20; // turn on extension bit means EIV existence
7335
7336 RTMP_IO_WRITE8(pAd, offset + 3, IV4);
7337
7338 //
7339 // Write EIV
7340 //
7341 offset += 4;
7342 for (i = 0; i < 4; i++)
7343 {
7344 RTMP_IO_WRITE8(pAd, offset + i, pTxtsc[i + 2]);
7345 }
7346
7347#endif
7348#ifdef RT2870
7349 UINT32 tmpVal;
7350
7351 //
7352 // Write IV
7353 //
7354 IV4 = (KeyIdx << 6);
7355 if ((CipherAlg == CIPHER_TKIP) || (CipherAlg == CIPHER_TKIP_NO_MIC) ||(CipherAlg == CIPHER_AES))
7356 IV4 |= 0x20; // turn on extension bit means EIV existence
7357
7358 tmpVal = pTxtsc[1] + (((pTxtsc[1] | 0x20) & 0x7f) << 8) + (pTxtsc[0] << 16) + (IV4 << 24);
7359 RTMP_IO_WRITE32(pAd, offset, tmpVal);
7360
7361 //
7362 // Write EIV
7363 //
7364 offset += 4;
7365 RTMP_IO_WRITE32(pAd, offset, *(PUINT32)&pCipherKey->TxTsc[2]);
7366#endif // RT2870 //
7367 AsicUpdateWCIDAttribute(pAd, WCID, BssIndex, CipherAlg, bUsePairewiseKeyTable);
7368 }
7369
7370 if (!bUsePairewiseKeyTable)
7371 {
7372 //
7373 // Only update the shared key security mode
7374 //
7375 RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2), &csr1.word);
7376 if ((BssIndex % 2) == 0)
7377 {
7378 if (KeyIdx == 0)
7379 csr1.field.Bss0Key0CipherAlg = CipherAlg;
7380 else if (KeyIdx == 1)
7381 csr1.field.Bss0Key1CipherAlg = CipherAlg;
7382 else if (KeyIdx == 2)
7383 csr1.field.Bss0Key2CipherAlg = CipherAlg;
7384 else
7385 csr1.field.Bss0Key3CipherAlg = CipherAlg;
7386 }
7387 else
7388 {
7389 if (KeyIdx == 0)
7390 csr1.field.Bss1Key0CipherAlg = CipherAlg;
7391 else if (KeyIdx == 1)
7392 csr1.field.Bss1Key1CipherAlg = CipherAlg;
7393 else if (KeyIdx == 2)
7394 csr1.field.Bss1Key2CipherAlg = CipherAlg;
7395 else
7396 csr1.field.Bss1Key3CipherAlg = CipherAlg;
7397 }
7398 RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2), csr1.word);
7399 }
7400
7401 DBGPRINT(RT_DEBUG_TRACE, ("<== AsicAddKeyEntry\n"));
7402}
7403
7404
7405/*
7406 ========================================================================
7407 Description:
7408 Add Pair-wise key material into ASIC.
7409 Update pairwise key, TxMic and RxMic to Asic Pair-wise key table
7410
7411 Return:
7412 ========================================================================
7413*/
7414VOID AsicAddPairwiseKeyEntry(
7415 IN PRTMP_ADAPTER pAd,
7416 IN PUCHAR pAddr,
7417 IN UCHAR WCID,
7418 IN CIPHER_KEY *pCipherKey)
7419{
7420 INT i;
7421 ULONG offset;
7422 PUCHAR pKey = pCipherKey->Key;
7423 PUCHAR pTxMic = pCipherKey->TxMic;
7424 PUCHAR pRxMic = pCipherKey->RxMic;
7425#ifdef DBG
7426 UCHAR CipherAlg = pCipherKey->CipherAlg;
7427#endif // DBG //
7428
7429 // EKEY
7430 offset = PAIRWISE_KEY_TABLE_BASE + (WCID * HW_KEY_ENTRY_SIZE);
7431#ifdef RT2860
7432 for (i=0; i<MAX_LEN_OF_PEER_KEY; i++)
7433 {
7434 RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
7435 }
7436#endif
7437#ifdef RT2870
7438 RTUSBMultiWrite(pAd, offset, &pCipherKey->Key[0], MAX_LEN_OF_PEER_KEY);
7439#endif // RT2870 //
7440 for (i=0; i<MAX_LEN_OF_PEER_KEY; i+=4)
7441 {
7442 UINT32 Value;
7443 RTMP_IO_READ32(pAd, offset + i, &Value);
7444 }
7445
7446 offset += MAX_LEN_OF_PEER_KEY;
7447
7448 // MIC KEY
7449 if (pTxMic)
7450 {
7451#ifdef RT2860
7452 for (i=0; i<8; i++)
7453 {
7454 RTMP_IO_WRITE8(pAd, offset+i, pTxMic[i]);
7455 }
7456#endif
7457#ifdef RT2870
7458 RTUSBMultiWrite(pAd, offset, &pCipherKey->TxMic[0], 8);
7459#endif // RT2870 //
7460 }
7461 offset += 8;
7462 if (pRxMic)
7463 {
7464#ifdef RT2860
7465 for (i=0; i<8; i++)
7466 {
7467 RTMP_IO_WRITE8(pAd, offset+i, pRxMic[i]);
7468 }
7469#endif
7470#ifdef RT2870
7471 RTUSBMultiWrite(pAd, offset, &pCipherKey->RxMic[0], 8);
7472#endif // RT2870 //
7473 }
7474
7475 DBGPRINT(RT_DEBUG_TRACE,("AsicAddPairwiseKeyEntry: WCID #%d Alg=%s\n",WCID, CipherName[CipherAlg]));
7476 DBGPRINT(RT_DEBUG_TRACE,(" Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
7477 pKey[0],pKey[1],pKey[2],pKey[3],pKey[4],pKey[5],pKey[6],pKey[7],pKey[8],pKey[9],pKey[10],pKey[11],pKey[12],pKey[13],pKey[14],pKey[15]));
7478 if (pRxMic)
7479 {
7480 DBGPRINT(RT_DEBUG_TRACE, (" Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
7481 pRxMic[0],pRxMic[1],pRxMic[2],pRxMic[3],pRxMic[4],pRxMic[5],pRxMic[6],pRxMic[7]));
7482 }
7483 if (pTxMic)
7484 {
7485 DBGPRINT(RT_DEBUG_TRACE, (" Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
7486 pTxMic[0],pTxMic[1],pTxMic[2],pTxMic[3],pTxMic[4],pTxMic[5],pTxMic[6],pTxMic[7]));
7487 }
7488}
7489/*
7490 ========================================================================
7491 Description:
7492 Remove Pair-wise key material from ASIC.
7493
7494 Return:
7495 ========================================================================
7496*/
7497VOID AsicRemovePairwiseKeyEntry(
7498 IN PRTMP_ADAPTER pAd,
7499 IN UCHAR BssIdx,
7500 IN UCHAR Wcid)
7501{
7502 ULONG WCIDAttri;
7503 USHORT offset;
7504
7505 // re-set the entry's WCID attribute as OPEN-NONE.
7506 offset = MAC_WCID_ATTRIBUTE_BASE + (Wcid * HW_WCID_ATTRI_SIZE);
7507 WCIDAttri = (BssIdx<<4) | PAIRWISEKEYTABLE;
7508 RTMP_IO_WRITE32(pAd, offset, WCIDAttri);
7509}
7510
7511BOOLEAN AsicSendCommandToMcu(
7512 IN PRTMP_ADAPTER pAd,
7513 IN UCHAR Command,
7514 IN UCHAR Token,
7515 IN UCHAR Arg0,
7516 IN UCHAR Arg1)
7517{
7518 HOST_CMD_CSR_STRUC H2MCmd;
7519 H2M_MAILBOX_STRUC H2MMailbox;
7520 ULONG i = 0;
7521
7522 do
7523 {
7524 RTMP_IO_READ32(pAd, H2M_MAILBOX_CSR, &H2MMailbox.word);
7525 if (H2MMailbox.field.Owner == 0)
7526 break;
7527
7528 RTMPusecDelay(2);
7529 } while(i++ < 100);
7530
7531 if (i > 100)
7532 {
7533 {
7534#ifdef RT2860
7535 UINT32 Data;
7536
7537 // Reset DMA
7538 RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data);
7539 Data |= 0x2;
7540 RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
7541
7542 // After Reset DMA, DMA index will become Zero. So Driver need to reset all ring indexs too.
7543 // Reset DMA/CPU ring index
7544 RTMPRingCleanUp(pAd, QID_AC_BK);
7545 RTMPRingCleanUp(pAd, QID_AC_BE);
7546 RTMPRingCleanUp(pAd, QID_AC_VI);
7547 RTMPRingCleanUp(pAd, QID_AC_VO);
7548 RTMPRingCleanUp(pAd, QID_HCCA);
7549 RTMPRingCleanUp(pAd, QID_MGMT);
7550 RTMPRingCleanUp(pAd, QID_RX);
7551
7552 // Clear Reset
7553 RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data);
7554 Data &= 0xfffffffd;
7555 RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
7556#endif /* RT2860 */
7557 DBGPRINT_ERR(("H2M_MAILBOX still hold by MCU. command fail\n"));
7558 }
7559 //return FALSE;
7560#ifdef RT2870
7561 return FALSE;
7562#endif
7563 }
7564
7565 H2MMailbox.field.Owner = 1; // pass ownership to MCU
7566 H2MMailbox.field.CmdToken = Token;
7567 H2MMailbox.field.HighByte = Arg1;
7568 H2MMailbox.field.LowByte = Arg0;
7569 RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CSR, H2MMailbox.word);
7570
7571 H2MCmd.word = 0;
7572 H2MCmd.field.HostCommand = Command;
7573 RTMP_IO_WRITE32(pAd, HOST_CMD_CSR, H2MCmd.word);
7574
7575 if (Command != 0x80)
7576 {
7577 }
7578
7579 return TRUE;
7580}
7581
7582#ifdef RT2860
7583BOOLEAN AsicCheckCommanOk(
7584 IN PRTMP_ADAPTER pAd,
7585 IN UCHAR Command)
7586{
7587 UINT32 CmdStatus = 0, CID = 0, i;
7588 UINT32 ThisCIDMask = 0;
7589
7590 i = 0;
7591 do
7592 {
7593 RTMP_IO_READ32(pAd, H2M_MAILBOX_CID, &CID);
7594 // Find where the command is. Because this is randomly specified by firmware.
7595 if ((CID & CID0MASK) == Command)
7596 {
7597 ThisCIDMask = CID0MASK;
7598 break;
7599 }
7600 else if ((((CID & CID1MASK)>>8) & 0xff) == Command)
7601 {
7602 ThisCIDMask = CID1MASK;
7603 break;
7604 }
7605 else if ((((CID & CID2MASK)>>16) & 0xff) == Command)
7606 {
7607 ThisCIDMask = CID2MASK;
7608 break;
7609 }
7610 else if ((((CID & CID3MASK)>>24) & 0xff) == Command)
7611 {
7612 ThisCIDMask = CID3MASK;
7613 break;
7614 }
7615
7616 RTMPusecDelay(100);
7617 i++;
7618 }while (i < 200);
7619
7620 // Get CommandStatus Value
7621 RTMP_IO_READ32(pAd, H2M_MAILBOX_STATUS, &CmdStatus);
7622
7623 // This command's status is at the same position as command. So AND command position's bitmask to read status.
7624 if (i < 200)
7625 {
7626 // If Status is 1, the comamnd is success.
7627 if (((CmdStatus & ThisCIDMask) == 0x1) || ((CmdStatus & ThisCIDMask) == 0x100)
7628 || ((CmdStatus & ThisCIDMask) == 0x10000) || ((CmdStatus & ThisCIDMask) == 0x1000000))
7629 {
7630 DBGPRINT(RT_DEBUG_TRACE, ("--> AsicCheckCommanOk CID = 0x%x, CmdStatus= 0x%x \n", CID, CmdStatus));
7631 RTMP_IO_WRITE32(pAd, H2M_MAILBOX_STATUS, 0xffffffff);
7632 RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CID, 0xffffffff);
7633 return TRUE;
7634 }
7635 DBGPRINT(RT_DEBUG_TRACE, ("--> AsicCheckCommanFail1 CID = 0x%x, CmdStatus= 0x%x \n", CID, CmdStatus));
7636 }
7637 else
7638 {
7639 DBGPRINT(RT_DEBUG_TRACE, ("--> AsicCheckCommanFail2 Timeout Command = %d, CmdStatus= 0x%x \n", Command, CmdStatus));
7640 }
7641 // Clear Command and Status.
7642 RTMP_IO_WRITE32(pAd, H2M_MAILBOX_STATUS, 0xffffffff);
7643 RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CID, 0xffffffff);
7644
7645 return FALSE;
7646}
7647#endif /* RT8260 */
7648 5122
7649/* 5123/*
7650 ======================================================================== 5124 ========================================================================
@@ -7993,55 +5467,6 @@ CHAR RTMPMaxRssi(
7993 return larger; 5467 return larger;
7994} 5468}
7995 5469
7996#ifdef RT2870
7997// Antenna divesity use GPIO3 and EESK pin for control
7998// Antenna and EEPROM access are both using EESK pin,
7999// Therefor we should avoid accessing EESK at the same time
8000// Then restore antenna after EEPROM access
8001VOID AsicSetRxAnt(
8002 IN PRTMP_ADAPTER pAd,
8003 IN UCHAR Ant)
8004{
8005 UINT32 Value;
8006 UINT32 x;
8007
8008 if ((pAd->EepromAccess) ||
8009 (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) ||
8010 (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) ||
8011 (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) ||
8012 (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
8013 {
8014 return;
8015 }
8016
8017 // the antenna selection is through firmware and MAC register(GPIO3)
8018 if (Ant == 0)
8019 {
8020 // Main antenna
8021 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
8022 x |= (EESK);
8023 RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
8024
8025 RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &Value);
8026 Value &= ~(0x0808);
8027 RTMP_IO_WRITE32(pAd, GPIO_CTRL_CFG, Value);
8028 DBGPRINT_RAW(RT_DEBUG_TRACE, ("AsicSetRxAnt, switch to main antenna\n"));
8029 }
8030 else
8031 {
8032 // Aux antenna
8033 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
8034 x &= ~(EESK);
8035 RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
8036
8037 RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &Value);
8038 Value &= ~(0x0808);
8039 Value |= 0x08;
8040 RTMP_IO_WRITE32(pAd, GPIO_CTRL_CFG, Value);
8041 DBGPRINT_RAW(RT_DEBUG_TRACE, ("AsicSetRxAnt, switch to aux antenna\n"));
8042 }
8043}
8044#endif
8045 5470
8046/* 5471/*
8047 ======================================================================== 5472 ========================================================================
@@ -8065,39 +5490,21 @@ VOID AsicEvaluateRxAnt(
8065 fRTMP_ADAPTER_HALT_IN_PROGRESS | 5490 fRTMP_ADAPTER_HALT_IN_PROGRESS |
8066 fRTMP_ADAPTER_RADIO_OFF | 5491 fRTMP_ADAPTER_RADIO_OFF |
8067 fRTMP_ADAPTER_NIC_NOT_EXIST | 5492 fRTMP_ADAPTER_NIC_NOT_EXIST |
8068 fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS) 5493 fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS) ||
8069 || OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) 5494 OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)
8070#ifdef RT2870 5495#ifdef RT30xx
8071 || (pAd->EepromAccess) 5496 || (pAd->EepromAccess)
8072#endif 5497#endif // RT30xx //
8073 ) 5498 )
8074 return; 5499 return;
8075 5500
8076#ifdef RT30xx
8077 // two antenna selection mechanism- one is antenna diversity, the other is failed antenna remove
8078 // one is antenna diversity:there is only one antenna can rx and tx
8079 // the other is failed antenna remove:two physical antenna can rx and tx
8080 if (pAd->NicConfig2.field.AntDiversity)
8081 {
8082 DBGPRINT(RT_DEBUG_TRACE,("AntDiv - before evaluate Pair1-Ant (%d,%d)\n",
8083 pAd->RxAnt.Pair1PrimaryRxAnt, pAd->RxAnt.Pair1SecondaryRxAnt));
8084 5501
8085 AsicSetRxAnt(pAd, pAd->RxAnt.Pair1SecondaryRxAnt); 5502 {
8086 5503 //if (pAd->StaCfg.Psm == PWR_SAVE)
8087 pAd->RxAnt.EvaluatePeriod = 1; // 1:Means switch to SecondaryRxAnt, 0:Means switch to Pair1PrimaryRxAnt 5504 // return;
8088 pAd->RxAnt.FirstPktArrivedWhenEvaluate = FALSE;
8089 pAd->RxAnt.RcvPktNumWhenEvaluate = 0;
8090 5505
8091 // a one-shot timer to end the evalution
8092 // dynamic adjust antenna evaluation period according to the traffic
8093 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
8094 RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 100);
8095 else
8096 RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 300);
8097 }
8098 else
8099#endif
8100 { 5506 {
5507
8101 if (pAd->StaCfg.Psm == PWR_SAVE) 5508 if (pAd->StaCfg.Psm == PWR_SAVE)
8102 return; 5509 return;
8103 5510
@@ -8116,12 +5523,9 @@ VOID AsicEvaluateRxAnt(
8116 BBPR3 |= (0x0); 5523 BBPR3 |= (0x0);
8117 } 5524 }
8118 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3); 5525 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
8119 5526#ifdef RTMP_MAC_PCI
8120#ifdef RT2860
8121 pAd->StaCfg.BBPR3 = BBPR3; 5527 pAd->StaCfg.BBPR3 = BBPR3;
8122#endif 5528#endif // RTMP_MAC_PCI //
8123 }
8124
8125 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) 5529 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
8126 ) 5530 )
8127 { 5531 {
@@ -8141,6 +5545,11 @@ VOID AsicEvaluateRxAnt(
8141 pAd->Mlme.bLowThroughput = TRUE; 5545 pAd->Mlme.bLowThroughput = TRUE;
8142 } 5546 }
8143 } 5547 }
5548 }
5549
5550 }
5551
5552
8144} 5553}
8145 5554
8146/* 5555/*
@@ -8169,48 +5578,17 @@ VOID AsicRxAntEvalTimeout(
8169 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS | 5578 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS |
8170 fRTMP_ADAPTER_HALT_IN_PROGRESS | 5579 fRTMP_ADAPTER_HALT_IN_PROGRESS |
8171 fRTMP_ADAPTER_RADIO_OFF | 5580 fRTMP_ADAPTER_RADIO_OFF |
8172 fRTMP_ADAPTER_NIC_NOT_EXIST) 5581 fRTMP_ADAPTER_NIC_NOT_EXIST) ||
8173 || OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) 5582 OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)
8174#ifdef RT2870 5583#ifdef RT30xx
8175 || (pAd->EepromAccess) 5584 || (pAd->EepromAccess)
8176#endif 5585#endif // RT30xx //
8177 ) 5586 )
8178 return; 5587 return;
8179 5588
8180 { 5589 {
8181#ifdef RT30xx 5590 //if (pAd->StaCfg.Psm == PWR_SAVE)
8182 if (pAd->NicConfig2.field.AntDiversity) 5591 // return;
8183 {
8184 if ((pAd->RxAnt.RcvPktNumWhenEvaluate != 0) && (pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1SecondaryRxAnt] >= pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1PrimaryRxAnt]))
8185 {
8186 UCHAR temp;
8187
8188 //
8189 // select PrimaryRxAntPair
8190 // Role change, Used Pair1SecondaryRxAnt as PrimaryRxAntPair.
8191 // Since Pair1SecondaryRxAnt Quality good than Pair1PrimaryRxAnt
8192 //
8193 temp = pAd->RxAnt.Pair1PrimaryRxAnt;
8194 pAd->RxAnt.Pair1PrimaryRxAnt = pAd->RxAnt.Pair1SecondaryRxAnt;
8195 pAd->RxAnt.Pair1SecondaryRxAnt = temp;
8196
8197 pAd->RxAnt.Pair1LastAvgRssi = (pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1SecondaryRxAnt] >> 3);
8198 pAd->RxAnt.EvaluateStableCnt = 0;
8199 }
8200 else
8201 {
8202 // if the evaluated antenna is not better than original, switch back to original antenna
8203 AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
8204 pAd->RxAnt.EvaluateStableCnt ++;
8205 }
8206
8207 pAd->RxAnt.EvaluatePeriod = 0; // 1:Means switch to SecondaryRxAnt, 0:Means switch to Pair1PrimaryRxAnt
8208
8209 DBGPRINT(RT_DEBUG_TRACE,("AsicRxAntEvalAction::After Eval(fix in #%d), <%d, %d>, RcvPktNumWhenEvaluate=%ld\n",
8210 pAd->RxAnt.Pair1PrimaryRxAnt, (pAd->RxAnt.Pair1AvgRssi[0] >> 3), (pAd->RxAnt.Pair1AvgRssi[1] >> 3), pAd->RxAnt.RcvPktNumWhenEvaluate));
8211 }
8212 else
8213#endif
8214 { 5592 {
8215 if (pAd->StaCfg.Psm == PWR_SAVE) 5593 if (pAd->StaCfg.Psm == PWR_SAVE)
8216 return; 5594 return;
@@ -8261,13 +5639,16 @@ VOID AsicRxAntEvalTimeout(
8261 BBPR3 |= (0x0); 5639 BBPR3 |= (0x0);
8262 } 5640 }
8263 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3); 5641 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
8264#ifdef RT2860 5642#ifdef RTMP_MAC_PCI
8265 pAd->StaCfg.BBPR3 = BBPR3; 5643 pAd->StaCfg.BBPR3 = BBPR3;
8266#endif 5644#endif // RTMP_MAC_PCI //
8267 } 5645 }
8268 } 5646 }
5647
5648
8269} 5649}
8270 5650
5651
8271VOID APSDPeriodicExec( 5652VOID APSDPeriodicExec(
8272 IN PVOID SystemSpecific1, 5653 IN PVOID SystemSpecific1,
8273 IN PVOID FunctionContext, 5654 IN PVOID FunctionContext,
@@ -8281,6 +5662,18 @@ VOID APSDPeriodicExec(
8281 5662
8282 pAd->CommonCfg.TriggerTimerCount++; 5663 pAd->CommonCfg.TriggerTimerCount++;
8283 5664
5665// Driver should not send trigger frame, it should be send by application layer
5666/*
5667 if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable
5668 && (pAd->CommonCfg.bNeedSendTriggerFrame ||
5669 (((pAd->CommonCfg.TriggerTimerCount%20) == 19) && (!pAd->CommonCfg.bAPSDAC_BE || !pAd->CommonCfg.bAPSDAC_BK || !pAd->CommonCfg.bAPSDAC_VI || !pAd->CommonCfg.bAPSDAC_VO))))
5670 {
5671 DBGPRINT(RT_DEBUG_TRACE,("Sending trigger frame and enter service period when support APSD\n"));
5672 RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
5673 pAd->CommonCfg.bNeedSendTriggerFrame = FALSE;
5674 pAd->CommonCfg.TriggerTimerCount = 0;
5675 pAd->CommonCfg.bInServicePeriod = TRUE;
5676 }*/
8284} 5677}
8285 5678
8286/* 5679/*
@@ -8347,9 +5740,10 @@ BOOLEAN RTMPCheckEntryEnableAutoRateSwitch(
8347BOOLEAN RTMPAutoRateSwitchCheck( 5740BOOLEAN RTMPAutoRateSwitchCheck(
8348 IN PRTMP_ADAPTER pAd) 5741 IN PRTMP_ADAPTER pAd)
8349{ 5742{
5743 {
8350 if (pAd->StaCfg.bAutoTxRateSwitch) 5744 if (pAd->StaCfg.bAutoTxRateSwitch)
8351 return TRUE; 5745 return TRUE;
8352 5746 }
8353 return FALSE; 5747 return FALSE;
8354} 5748}
8355 5749
@@ -8375,7 +5769,9 @@ UCHAR RTMPStaFixedTxMode(
8375{ 5769{
8376 UCHAR tx_mode = FIXED_TXMODE_HT; 5770 UCHAR tx_mode = FIXED_TXMODE_HT;
8377 5771
5772 {
8378 tx_mode = (UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode; 5773 tx_mode = (UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode;
5774 }
8379 5775
8380 return tx_mode; 5776 return tx_mode;
8381} 5777}
@@ -8462,12 +5858,10 @@ VOID AsicStaBbpTuning(
8462 && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) 5858 && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
8463 ) 5859 )
8464 && !(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) 5860 && !(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
8465#ifdef RT2860 5861#ifdef RTMP_MAC_PCI
8466 && (pAd->bPCIclkOff == FALSE)) 5862 && (pAd->bPCIclkOff == FALSE)
8467#endif 5863#endif // RTMP_MAC_PCI //
8468#ifdef RT2870
8469 ) 5864 )
8470#endif
8471 { 5865 {
8472 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &OrigR66Value); 5866 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &OrigR66Value);
8473 R66 = OrigR66Value; 5867 R66 = OrigR66Value;
@@ -8479,26 +5873,31 @@ VOID AsicStaBbpTuning(
8479 5873
8480 if (pAd->LatchRfRegs.Channel <= 14) 5874 if (pAd->LatchRfRegs.Channel <= 14)
8481 { //BG band 5875 { //BG band
8482#ifdef RT2870 5876#ifdef RT30xx
8483 // RT3070 is a no LNA solution, it should have different control regarding to AGC gain control 5877 // RT3070 is a no LNA solution, it should have different control regarding to AGC gain control
8484 // Otherwise, it will have some throughput side effect when low RSSI 5878 // Otherwise, it will have some throughput side effect when low RSSI
8485 if (IS_RT30xx(pAd)) 5879
5880 if (IS_RT3070(pAd)||IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
8486 { 5881 {
8487 if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY) 5882 if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY)
8488 { 5883 {
8489 R66 = 0x1C + 2*GET_LNA_GAIN(pAd) + 0x20; 5884 R66 = 0x1C + 2*GET_LNA_GAIN(pAd) + 0x20;
8490 if (OrigR66Value != R66) 5885 if (OrigR66Value != R66)
5886 {
8491 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66); 5887 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
8492 } 5888 }
5889 }
8493 else 5890 else
8494 { 5891 {
8495 R66 = 0x1C + 2*GET_LNA_GAIN(pAd); 5892 R66 = 0x1C + 2*GET_LNA_GAIN(pAd);
8496 if (OrigR66Value != R66) 5893 if (OrigR66Value != R66)
5894 {
8497 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66); 5895 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
8498 } 5896 }
8499 } 5897 }
5898 }
8500 else 5899 else
8501#endif // RT2870 // 5900#endif // RT30xx //
8502 { 5901 {
8503 if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY) 5902 if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY)
8504 { 5903 {
@@ -8564,108 +5963,6 @@ VOID AsicStaBbpTuning(
8564 } 5963 }
8565} 5964}
8566 5965
8567#ifdef RT2860
8568VOID AsicResetFromDMABusy(
8569 IN PRTMP_ADAPTER pAd)
8570{
8571 UINT32 Data;
8572 BOOLEAN bCtrl = FALSE;
8573
8574 DBGPRINT(RT_DEBUG_TRACE, ("---> AsicResetFromDMABusy !!!!!!!!!!!!!!!!!!!!!!! \n"));
8575
8576 // Be sure restore link control value so we can write register.
8577 RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
8578 if (RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND))
8579 {
8580 DBGPRINT(RT_DEBUG_TRACE,("AsicResetFromDMABusy==>\n"));
8581 RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_HALT);
8582 RTMPusecDelay(6000);
8583 pAd->bPCIclkOff = FALSE;
8584 bCtrl = TRUE;
8585 }
8586 // Reset DMA
8587 RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data);
8588 Data |= 0x2;
8589 RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
8590
8591 // After Reset DMA, DMA index will become Zero. So Driver need to reset all ring indexs too.
8592 // Reset DMA/CPU ring index
8593 RTMPRingCleanUp(pAd, QID_AC_BK);
8594 RTMPRingCleanUp(pAd, QID_AC_BE);
8595 RTMPRingCleanUp(pAd, QID_AC_VI);
8596 RTMPRingCleanUp(pAd, QID_AC_VO);
8597 RTMPRingCleanUp(pAd, QID_HCCA);
8598 RTMPRingCleanUp(pAd, QID_MGMT);
8599 RTMPRingCleanUp(pAd, QID_RX);
8600
8601 // Clear Reset
8602 RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data);
8603 Data &= 0xfffffffd;
8604 RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
8605
8606 // If in Radio off, should call RTMPPCIePowerLinkCtrl again.
8607 if ((bCtrl == TRUE) && (pAd->StaCfg.bRadio == FALSE))
8608 RTMPPCIeLinkCtrlSetting(pAd, 3);
8609
8610 RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
8611 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS);
8612 DBGPRINT(RT_DEBUG_TRACE, ("<--- AsicResetFromDMABusy !!!!!!!!!!!!!!!!!!!!!!! \n"));
8613}
8614
8615VOID AsicResetBBP(
8616 IN PRTMP_ADAPTER pAd)
8617{
8618 DBGPRINT(RT_DEBUG_TRACE, ("---> Asic HardReset BBP !!!!!!!!!!!!!!!!!!!!!!! \n"));
8619
8620 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x0);
8621 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x2);
8622 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0xc);
8623
8624 // After hard-reset BBP, initialize all BBP values.
8625 NICRestoreBBPValue(pAd);
8626 DBGPRINT(RT_DEBUG_TRACE, ("<--- Asic HardReset BBP !!!!!!!!!!!!!!!!!!!!!!! \n"));
8627}
8628
8629VOID AsicResetMAC(
8630 IN PRTMP_ADAPTER pAd)
8631{
8632 ULONG Data;
8633
8634 DBGPRINT(RT_DEBUG_TRACE, ("---> AsicResetMAC !!!! \n"));
8635 RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data);
8636 Data |= 0x4;
8637 RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
8638 Data &= 0xfffffffb;
8639 RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
8640
8641 DBGPRINT(RT_DEBUG_TRACE, ("<--- AsicResetMAC !!!! \n"));
8642}
8643
8644VOID AsicResetPBF(
8645 IN PRTMP_ADAPTER pAd)
8646{
8647 ULONG Value1, Value2;
8648 ULONG Data;
8649
8650 RTMP_IO_READ32(pAd, TXRXQ_PCNT, &Value1);
8651 RTMP_IO_READ32(pAd, PBF_DBG, &Value2);
8652
8653 Value2 &= 0xff;
8654 // sum should be equals to 0xff, which is the total buffer size.
8655 if ((Value1 + Value2) < 0xff)
8656 {
8657 DBGPRINT(RT_DEBUG_TRACE, ("---> Asic HardReset PBF !!!! \n"));
8658 RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data);
8659 Data |= 0x8;
8660 RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
8661 Data &= 0xfffffff7;
8662 RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
8663
8664 DBGPRINT(RT_DEBUG_TRACE, ("<--- Asic HardReset PBF !!!! \n"));
8665 }
8666}
8667#endif /* RT2860 */
8668
8669VOID RTMPSetAGCInitValue( 5966VOID RTMPSetAGCInitValue(
8670 IN PRTMP_ADAPTER pAd, 5967 IN PRTMP_ADAPTER pAd,
8671 IN UCHAR BandWidth) 5968 IN UCHAR BandWidth)
@@ -8674,11 +5971,24 @@ VOID RTMPSetAGCInitValue(
8674 5971
8675 if (pAd->LatchRfRegs.Channel <= 14) 5972 if (pAd->LatchRfRegs.Channel <= 14)
8676 { // BG band 5973 { // BG band
5974#ifdef RT30xx
5975 /* Gary was verified Amazon AP and find that RT307x has BBP_R66 invalid default value */
5976
5977 if (IS_RT3070(pAd)||IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
5978 {
5979 R66 = 0x1C + 2*GET_LNA_GAIN(pAd);
5980 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
5981 }
5982 else
5983#endif // RT30xx //
5984 {
8677 R66 = 0x2E + GET_LNA_GAIN(pAd); 5985 R66 = 0x2E + GET_LNA_GAIN(pAd);
8678 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66); 5986 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
8679 } 5987 }
5988 }
8680 else 5989 else
8681 { //A band 5990 { //A band
5991 {
8682 if (BandWidth == BW_20) 5992 if (BandWidth == BW_20)
8683 { 5993 {
8684 R66 = (UCHAR)(0x32 + (GET_LNA_GAIN(pAd)*5)/3); 5994 R66 = (UCHAR)(0x32 + (GET_LNA_GAIN(pAd)*5)/3);
@@ -8690,133 +6000,7 @@ VOID RTMPSetAGCInitValue(
8690 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66); 6000 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
8691 } 6001 }
8692 } 6002 }
8693
8694}
8695
8696VOID AsicTurnOffRFClk(
8697 IN PRTMP_ADAPTER pAd,
8698 IN UCHAR Channel)
8699{
8700
8701 // RF R2 bit 18 = 0
8702 UINT32 R1 = 0, R2 = 0, R3 = 0;
8703 UCHAR index;
8704 RTMP_RF_REGS *RFRegTable;
8705
8706 // The RF programming sequence is difference between 3xxx and 2xxx
8707 if (IS_RT3090(pAd))
8708 {
8709 RT30xxLoadRFSleepModeSetup(pAd); // add by johnli, RF power sequence setup, load RF sleep-mode setup
8710 return;
8711 }
8712
8713 RFRegTable = RF2850RegTable;
8714
8715 switch (pAd->RfIcType)
8716 {
8717 case RFIC_2820:
8718 case RFIC_2850:
8719 case RFIC_2720:
8720 case RFIC_2750:
8721
8722 for (index = 0; index < NUM_OF_2850_CHNL; index++)
8723 {
8724 if (Channel == RFRegTable[index].Channel)
8725 {
8726 R1 = RFRegTable[index].R1 & 0xffffdfff;
8727 R2 = RFRegTable[index].R2 & 0xfffbffff;
8728 R3 = RFRegTable[index].R3 & 0xfff3ffff;
8729
8730 RTMP_RF_IO_WRITE32(pAd, R1);
8731 RTMP_RF_IO_WRITE32(pAd, R2);
8732
8733 // Program R1b13 to 1, R3/b18,19 to 0, R2b18 to 0.
8734 // Set RF R2 bit18=0, R3 bit[18:19]=0
8735 //if (pAd->StaCfg.bRadio == FALSE)
8736 if (1)
8737 {
8738 RTMP_RF_IO_WRITE32(pAd, R3);
8739
8740 DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x, R3 = 0x%08x \n",
8741 Channel, pAd->RfIcType, R2, R3));
8742 }
8743 else
8744 DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x \n",
8745 Channel, pAd->RfIcType, R2));
8746 break;
8747 }
8748 }
8749 break;
8750
8751 default:
8752 break;
8753 }
8754}
8755
8756
8757VOID AsicTurnOnRFClk(
8758 IN PRTMP_ADAPTER pAd,
8759 IN UCHAR Channel)
8760{
8761
8762 // RF R2 bit 18 = 0
8763 UINT32 R1 = 0, R2 = 0, R3 = 0;
8764 UCHAR index;
8765 RTMP_RF_REGS *RFRegTable;
8766
8767 // The RF programming sequence is difference between 3xxx and 2xxx
8768 if (IS_RT3090(pAd))
8769 return;
8770
8771 RFRegTable = RF2850RegTable;
8772
8773 switch (pAd->RfIcType)
8774 {
8775 case RFIC_2820:
8776 case RFIC_2850:
8777 case RFIC_2720:
8778 case RFIC_2750:
8779
8780 for (index = 0; index < NUM_OF_2850_CHNL; index++)
8781 {
8782 if (Channel == RFRegTable[index].Channel)
8783 {
8784 R3 = pAd->LatchRfRegs.R3;
8785 R3 &= 0xfff3ffff;
8786 R3 |= 0x00080000;
8787 RTMP_RF_IO_WRITE32(pAd, R3);
8788
8789 R1 = RFRegTable[index].R1;
8790 RTMP_RF_IO_WRITE32(pAd, R1);
8791
8792 R2 = RFRegTable[index].R2;
8793 if (pAd->Antenna.field.TxPath == 1)
8794 {
8795 R2 |= 0x4000; // If TXpath is 1, bit 14 = 1;
8796 }
8797
8798 if (pAd->Antenna.field.RxPath == 2)
8799 {
8800 R2 |= 0x40; // write 1 to off Rxpath.
8801 }
8802 else if (pAd->Antenna.field.RxPath == 1)
8803 {
8804 R2 |= 0x20040; // write 1 to off RxPath
8805 }
8806 RTMP_RF_IO_WRITE32(pAd, R2);
8807
8808 break;
8809 }
8810 }
8811 break;
8812
8813 default:
8814 break;
8815 } 6003 }
8816 6004
8817 DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOnRFClk#%d(RF=%d, ) , R2=0x%08x\n",
8818 Channel,
8819 pAd->RfIcType,
8820 R2));
8821} 6005}
8822 6006
diff --git a/drivers/staging/rt2860/common/rt_channel.c b/drivers/staging/rt2860/common/rt_channel.c
new file mode 100644
index 00000000000..06b51a01289
--- /dev/null
+++ b/drivers/staging/rt2860/common/rt_channel.c
@@ -0,0 +1,1280 @@
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
29
30CH_FREQ_MAP CH_HZ_ID_MAP[]=
31 {
32 {1, 2412},
33 {2, 2417},
34 {3, 2422},
35 {4, 2427},
36 {5, 2432},
37 {6, 2437},
38 {7, 2442},
39 {8, 2447},
40 {9, 2452},
41 {10, 2457},
42 {11, 2462},
43 {12, 2467},
44 {13, 2472},
45 {14, 2484},
46
47 /* UNII */
48 {36, 5180},
49 {40, 5200},
50 {44, 5220},
51 {48, 5240},
52 {52, 5260},
53 {56, 5280},
54 {60, 5300},
55 {64, 5320},
56 {149, 5745},
57 {153, 5765},
58 {157, 5785},
59 {161, 5805},
60 {165, 5825},
61 {167, 5835},
62 {169, 5845},
63 {171, 5855},
64 {173, 5865},
65
66 /* HiperLAN2 */
67 {100, 5500},
68 {104, 5520},
69 {108, 5540},
70 {112, 5560},
71 {116, 5580},
72 {120, 5600},
73 {124, 5620},
74 {128, 5640},
75 {132, 5660},
76 {136, 5680},
77 {140, 5700},
78
79 /* Japan MMAC */
80 {34, 5170},
81 {38, 5190},
82 {42, 5210},
83 {46, 5230},
84
85 /* Japan */
86 {184, 4920},
87 {188, 4940},
88 {192, 4960},
89 {196, 4980},
90
91 {208, 5040}, /* Japan, means J08 */
92 {212, 5060}, /* Japan, means J12 */
93 {216, 5080}, /* Japan, means J16 */
94};
95
96INT CH_HZ_ID_MAP_NUM = (sizeof(CH_HZ_ID_MAP)/sizeof(CH_FREQ_MAP));
97
98CH_REGION ChRegion[] =
99{
100 { // Antigua and Berbuda
101 "AG",
102 CE,
103 {
104 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
105 { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
106 { 52, 4, 23, BOTH, FALSE}, // 5G, ch 52~64
107 { 100, 11, 30, BOTH, FALSE}, // 5G, ch 100~140
108 { 0}, // end
109 }
110 },
111
112 { // Argentina
113 "AR",
114 CE,
115 {
116 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
117 { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
118 { 149, 4, 30, BOTH, FALSE}, // 5G, ch 149~161
119 { 0}, // end
120 }
121 },
122
123 { // Aruba
124 "AW",
125 CE,
126 {
127 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
128 { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
129 { 52, 4, 23, BOTH, FALSE}, // 5G, ch 52~64
130 { 100, 11, 30, BOTH, FALSE}, // 5G, ch 100~140
131 { 0}, // end
132 }
133 },
134
135 { // Australia
136 "AU",
137 CE,
138 {
139 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
140 { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
141 { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
142 { 149, 5, 30, BOTH, FALSE}, // 5G, ch 149~165
143 { 0}, // end
144 }
145 },
146
147 { // Austria
148 "AT",
149 CE,
150 {
151 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
152 { 36, 4, 23, IDOR, TRUE}, // 5G, ch 36~48
153 { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
154 { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
155 { 0}, // end
156 }
157 },
158
159 { // Bahamas
160 "BS",
161 CE,
162 {
163 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
164 { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
165 { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
166 { 149, 5, 30, BOTH, FALSE}, // 5G, ch 149~165
167 { 0}, // end
168 }
169 },
170
171 { // Barbados
172 "BB",
173 CE,
174 {
175 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
176 { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
177 { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
178 { 100, 11, 30, BOTH, FALSE}, // 5G, ch 100~140
179 { 0}, // end
180 }
181 },
182
183 { // Bermuda
184 "BM",
185 CE,
186 {
187 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
188 { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
189 { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
190 { 100, 11, 30, BOTH, FALSE}, // 5G, ch 100~140
191 { 0}, // end
192 }
193 },
194
195 { // Brazil
196 "BR",
197 CE,
198 {
199 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
200 { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
201 { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
202 { 100, 11, 24, BOTH, FALSE}, // 5G, ch 100~140
203 { 149, 5, 30, BOTH, FALSE}, // 5G, ch 100~140
204 { 0}, // end
205 }
206 },
207
208 { // Belgium
209 "BE",
210 CE,
211 {
212 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
213 { 36, 4, 18, IDOR, FALSE}, // 5G, ch 36~48
214 { 52, 4, 18, IDOR, FALSE}, // 5G, ch 52~64
215 { 0}, // end
216 }
217 },
218
219 { // Bulgaria
220 "BG",
221 CE,
222 {
223 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
224 { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
225 { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
226 { 100, 11, 30, ODOR, TRUE}, // 5G, ch 100~140
227 { 0}, // end
228 }
229 },
230
231 { // Canada
232 "CA",
233 CE,
234 {
235 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
236 { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
237 { 52, 4, 23, BOTH, FALSE}, // 5G, ch 52~64
238 { 149, 5, 30, BOTH, FALSE}, // 5G, ch 149~165
239 { 0}, // end
240 }
241 },
242
243 { // Cayman IsLands
244 "KY",
245 CE,
246 {
247 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
248 { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
249 { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
250 { 100, 11, 30, BOTH, FALSE}, // 5G, ch 100~140
251 { 0}, // end
252 }
253 },
254
255 { // Chile
256 "CL",
257 CE,
258 {
259 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
260 { 36, 4, 20, BOTH, FALSE}, // 5G, ch 36~48
261 { 52, 4, 20, BOTH, FALSE}, // 5G, ch 52~64
262 { 149, 5, 20, BOTH, FALSE}, // 5G, ch 149~165
263 { 0}, // end
264 }
265 },
266
267 { // China
268 "CN",
269 CE,
270 {
271 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
272 { 149, 4, 27, BOTH, FALSE}, // 5G, ch 149~161
273 { 0}, // end
274 }
275 },
276
277 { // Colombia
278 "CO",
279 CE,
280 {
281 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
282 { 36, 4, 17, BOTH, FALSE}, // 5G, ch 36~48
283 { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
284 { 100, 11, 30, BOTH, FALSE}, // 5G, ch 100~140
285 { 149, 5, 30, BOTH, FALSE}, // 5G, ch 149~165
286 { 0}, // end
287 }
288 },
289
290 { // Costa Rica
291 "CR",
292 CE,
293 {
294 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
295 { 36, 4, 17, BOTH, FALSE}, // 5G, ch 36~48
296 { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
297 { 149, 4, 30, BOTH, FALSE}, // 5G, ch 149~161
298 { 0}, // end
299 }
300 },
301
302 { // Cyprus
303 "CY",
304 CE,
305 {
306 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
307 { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
308 { 52, 4, 24, IDOR, TRUE}, // 5G, ch 52~64
309 { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
310 { 0}, // end
311 }
312 },
313
314 { // Czech_Republic
315 "CZ",
316 CE,
317 {
318 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
319 { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
320 { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
321 { 0}, // end
322 }
323 },
324
325 { // Denmark
326 "DK",
327 CE,
328 {
329 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
330 { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
331 { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
332 { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
333 { 0}, // end
334 }
335 },
336
337 { // Dominican Republic
338 "DO",
339 CE,
340 {
341 { 1, 0, 20, BOTH, FALSE}, // 2.4 G, ch 0
342 { 149, 4, 20, BOTH, FALSE}, // 5G, ch 149~161
343 { 0}, // end
344 }
345 },
346
347 { // Equador
348 "EC",
349 CE,
350 {
351 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
352 { 100, 11, 27, BOTH, FALSE}, // 5G, ch 100~140
353 { 0}, // end
354 }
355 },
356
357 { // El Salvador
358 "SV",
359 CE,
360 {
361 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
362 { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
363 { 52, 4, 30, BOTH, TRUE}, // 5G, ch 52~64
364 { 149, 4, 36, BOTH, TRUE}, // 5G, ch 149~165
365 { 0}, // end
366 }
367 },
368
369 { // Finland
370 "FI",
371 CE,
372 {
373 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
374 { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
375 { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
376 { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
377 { 0}, // end
378 }
379 },
380
381 { // France
382 "FR",
383 CE,
384 {
385 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
386 { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
387 { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
388 { 0}, // end
389 }
390 },
391
392 { // Germany
393 "DE",
394 CE,
395 {
396 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
397 { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
398 { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
399 { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
400 { 0}, // end
401 }
402 },
403
404 { // Greece
405 "GR",
406 CE,
407 {
408 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
409 { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
410 { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
411 { 100, 11, 30, ODOR, TRUE}, // 5G, ch 100~140
412 { 0}, // end
413 }
414 },
415
416 { // Guam
417 "GU",
418 CE,
419 {
420 { 1, 11, 20, BOTH, FALSE}, // 2.4 G, ch 1~11
421 { 36, 4, 17, BOTH, FALSE}, // 5G, ch 36~48
422 { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
423 { 100, 11, 30, BOTH, FALSE}, // 5G, ch 100~140
424 { 149, 5, 30, BOTH, FALSE}, // 5G, ch 149~165
425 { 0}, // end
426 }
427 },
428
429 { // Guatemala
430 "GT",
431 CE,
432 {
433 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
434 { 36, 4, 17, BOTH, FALSE}, // 5G, ch 36~48
435 { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
436 { 149, 4, 30, BOTH, FALSE}, // 5G, ch 149~161
437 { 0}, // end
438 }
439 },
440
441 { // Haiti
442 "HT",
443 CE,
444 {
445 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
446 { 36, 4, 17, BOTH, FALSE}, // 5G, ch 36~48
447 { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
448 { 149, 4, 30, BOTH, FALSE}, // 5G, ch 149~161
449 { 0}, // end
450 }
451 },
452
453 { // Honduras
454 "HN",
455 CE,
456 {
457 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
458 { 149, 4, 27, BOTH, FALSE}, // 5G, ch 149~161
459 { 0}, // end
460 }
461 },
462
463 { // Hong Kong
464 "HK",
465 CE,
466 {
467 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
468 { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
469 { 52, 4, 23, IDOR, FALSE}, // 5G, ch 52~64
470 { 149, 4, 30, BOTH, FALSE}, // 5G, ch 149~161
471 { 0}, // end
472 }
473 },
474
475 { // Hungary
476 "HU",
477 CE,
478 {
479 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
480 { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
481 { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
482 { 0}, // end
483 }
484 },
485
486 { // Iceland
487 "IS",
488 CE,
489 {
490 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
491 { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
492 { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
493 { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
494 { 0}, // end
495 }
496 },
497
498 { // India
499 "IN",
500 CE,
501 {
502 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
503 { 149, 4, 24, IDOR, FALSE}, // 5G, ch 149~161
504 { 0}, // end
505 }
506 },
507
508 { // Indonesia
509 "ID",
510 CE,
511 {
512 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
513 { 149, 4, 27, BOTH, FALSE}, // 5G, ch 149~161
514 { 0}, // end
515 }
516 },
517
518 { // Ireland
519 "IE",
520 CE,
521 {
522 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
523 { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
524 { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
525 { 100, 11, 30, ODOR, TRUE}, // 5G, ch 100~140
526 { 0}, // end
527 }
528 },
529
530 { // Israel
531 "IL",
532 CE,
533 {
534 { 1, 3, 20, IDOR, FALSE}, // 2.4 G, ch 1~3
535 { 4, 6, 20, BOTH, FALSE}, // 2.4 G, ch 4~9
536 { 10, 4, 20, IDOR, FALSE}, // 2.4 G, ch 10~13
537 { 0}, // end
538 }
539 },
540
541 { // Italy
542 "IT",
543 CE,
544 {
545 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
546 { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
547 { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
548 { 100, 11, 30, ODOR, TRUE}, // 5G, ch 100~140
549 { 0}, // end
550 }
551 },
552
553 { // Japan
554 "JP",
555 JAP,
556 {
557 { 1, 14, 20, BOTH, FALSE}, // 2.4 G, ch 1~14
558 { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
559 { 0}, // end
560 }
561 },
562
563 { // Jordan
564 "JO",
565 CE,
566 {
567 { 1, 13, 20, IDOR, FALSE}, // 2.4 G, ch 1~13
568 { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
569 { 149, 4, 23, IDOR, FALSE}, // 5G, ch 149~161
570 { 0}, // end
571 }
572 },
573
574 { // Latvia
575 "LV",
576 CE,
577 {
578 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
579 { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
580 { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
581 { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
582 { 0}, // end
583 }
584 },
585
586 { // Liechtenstein
587 "LI",
588 CE,
589 {
590 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
591 { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
592 { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
593 { 0}, // end
594 }
595 },
596
597 { // Lithuania
598 "LT",
599 CE,
600 {
601 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
602 { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
603 { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
604 { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
605 { 0}, // end
606 }
607 },
608
609 { // Luxemburg
610 "LU",
611 CE,
612 {
613 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
614 { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
615 { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
616 { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
617 { 0}, // end
618 }
619 },
620
621 { // Malaysia
622 "MY",
623 CE,
624 {
625 { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
626 { 52, 4, 23, BOTH, FALSE}, // 5G, ch 52~64
627 { 149, 5, 20, BOTH, FALSE}, // 5G, ch 149~165
628 { 0}, // end
629 }
630 },
631
632 { // Malta
633 "MT",
634 CE,
635 {
636 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
637 { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
638 { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
639 { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
640 { 0}, // end
641 }
642 },
643
644 { // Marocco
645 "MA",
646 CE,
647 {
648 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
649 { 36, 4, 24, IDOR, FALSE}, // 5G, ch 36~48
650 { 0}, // end
651 }
652 },
653
654 { // Mexico
655 "MX",
656 CE,
657 {
658 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
659 { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
660 { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
661 { 149, 5, 30, IDOR, FALSE}, // 5G, ch 149~165
662 { 0}, // end
663 }
664 },
665
666 { // Netherlands
667 "NL",
668 CE,
669 {
670 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
671 { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
672 { 52, 4, 24, IDOR, TRUE}, // 5G, ch 52~64
673 { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
674 { 0}, // end
675 }
676 },
677
678 { // New Zealand
679 "NZ",
680 CE,
681 {
682 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
683 { 36, 4, 24, BOTH, FALSE}, // 5G, ch 36~48
684 { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
685 { 149, 4, 30, BOTH, FALSE}, // 5G, ch 149~161
686 { 0}, // end
687 }
688 },
689
690 { // Norway
691 "NO",
692 CE,
693 {
694 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
695 { 36, 4, 24, IDOR, FALSE}, // 5G, ch 36~48
696 { 52, 4, 24, IDOR, TRUE}, // 5G, ch 52~64
697 { 100, 11, 30, BOTH, TRUE}, // 5G, ch 149~161
698 { 0}, // end
699 }
700 },
701
702 { // Peru
703 "PE",
704 CE,
705 {
706 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
707 { 149, 4, 27, BOTH, FALSE}, // 5G, ch 149~161
708 { 0}, // end
709 }
710 },
711
712 { // Portugal
713 "PT",
714 CE,
715 {
716 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
717 { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
718 { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
719 { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
720 { 0}, // end
721 }
722 },
723
724 { // Poland
725 "PL",
726 CE,
727 {
728 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
729 { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
730 { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
731 { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
732 { 0}, // end
733 }
734 },
735
736 { // Romania
737 "RO",
738 CE,
739 {
740 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
741 { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
742 { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
743 { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
744 { 0}, // end
745 }
746 },
747
748 { // Russia
749 "RU",
750 CE,
751 {
752 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
753 { 149, 4, 20, IDOR, FALSE}, // 5G, ch 149~161
754 { 0}, // end
755 }
756 },
757
758 { // Saudi Arabia
759 "SA",
760 CE,
761 {
762 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
763 { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
764 { 52, 4, 23, BOTH, FALSE}, // 5G, ch 52~64
765 { 149, 4, 23, BOTH, FALSE}, // 5G, ch 149~161
766 { 0}, // end
767 }
768 },
769
770 { // Serbia_and_Montenegro
771 "CS",
772 CE,
773 {
774 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
775 { 0}, // end
776 }
777 },
778
779 { // Singapore
780 "SG",
781 CE,
782 {
783 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
784 { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
785 { 52, 4, 23, BOTH, FALSE}, // 5G, ch 52~64
786 { 149, 4, 20, BOTH, FALSE}, // 5G, ch 149~161
787 { 0}, // end
788 }
789 },
790
791 { // Slovakia
792 "SK",
793 CE,
794 {
795 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
796 { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
797 { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
798 { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
799 { 0}, // end
800 }
801 },
802
803 { // Slovenia
804 "SI",
805 CE,
806 {
807 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
808 { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
809 { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
810 { 0}, // end
811 }
812 },
813
814 { // South Africa
815 "ZA",
816 CE,
817 {
818 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
819 { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
820 { 52, 4, 23, IDOR, FALSE}, // 5G, ch 52~64
821 { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
822 { 149, 4, 30, BOTH, FALSE}, // 5G, ch 149~161
823 { 0}, // end
824 }
825 },
826
827 { // South Korea
828 "KR",
829 CE,
830 {
831 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
832 { 36, 4, 20, BOTH, FALSE}, // 5G, ch 36~48
833 { 52, 4, 20, BOTH, FALSE}, // 5G, ch 52~64
834 { 100, 8, 20, BOTH, FALSE}, // 5G, ch 100~128
835 { 149, 4, 20, BOTH, FALSE}, // 5G, ch 149~161
836 { 0}, // end
837 }
838 },
839
840 { // Spain
841 "ES",
842 CE,
843 {
844 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
845 { 36, 4, 17, IDOR, FALSE}, // 5G, ch 36~48
846 { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
847 { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
848 { 0}, // end
849 }
850 },
851
852 { // Sweden
853 "SE",
854 CE,
855 {
856 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
857 { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
858 { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
859 { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
860 { 0}, // end
861 }
862 },
863
864 { // Switzerland
865 "CH",
866 CE,
867 {
868 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
869 { 36, 4, 23, IDOR, TRUE}, // 5G, ch 36~48
870 { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
871 { 0}, // end
872 }
873 },
874
875 { // Taiwan
876 "TW",
877 CE,
878 {
879 { 1, 11, 30, BOTH, FALSE}, // 2.4 G, ch 1~11
880 { 52, 4, 23, IDOR, FALSE}, // 5G, ch 52~64
881 { 0}, // end
882 }
883 },
884
885 { // Turkey
886 "TR",
887 CE,
888 {
889 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~11
890 { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
891 { 52, 4, 23, BOTH, FALSE}, // 5G, ch 52~64
892 { 0}, // end
893 }
894 },
895
896 { // UK
897 "GB",
898 CE,
899 {
900 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~11
901 { 36, 4, 23, IDOR, FALSE}, // 5G, ch 52~64
902 { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
903 { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
904 { 0}, // end
905 }
906 },
907
908 { // Ukraine
909 "UA",
910 CE,
911 {
912 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~11
913 { 0}, // end
914 }
915 },
916
917 { // United_Arab_Emirates
918 "AE",
919 CE,
920 {
921 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~11
922 { 0}, // end
923 }
924 },
925
926 { // United_States
927 "US",
928 CE,
929 {
930 { 1, 11, 30, BOTH, FALSE}, // 2.4 G, ch 1~11
931 { 36, 4, 17, IDOR, FALSE}, // 5G, ch 52~64
932 { 52, 4, 24, BOTH, TRUE}, // 5G, ch 52~64
933 { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
934 { 149, 5, 30, BOTH, FALSE}, // 5G, ch 149~165
935 { 0}, // end
936 }
937 },
938
939 { // Venezuela
940 "VE",
941 CE,
942 {
943 { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~11
944 { 149, 4, 27, BOTH, FALSE}, // 5G, ch 149~161
945 { 0}, // end
946 }
947 },
948
949 { // Default
950 "",
951 CE,
952 {
953 { 1, 11, 20, BOTH, FALSE}, // 2.4 G, ch 1~11
954 { 36, 4, 20, BOTH, FALSE}, // 5G, ch 52~64
955 { 52, 4, 20, BOTH, FALSE}, // 5G, ch 52~64
956 { 100, 11, 20, BOTH, FALSE}, // 5G, ch 100~140
957 { 149, 5, 20, BOTH, FALSE}, // 5G, ch 149~165
958 { 0}, // end
959 }
960 },
961};
962
963
964static PCH_REGION GetChRegion(
965 IN PUCHAR CntryCode)
966{
967 INT loop = 0;
968 PCH_REGION pChRegion = NULL;
969
970 while (strcmp((PSTRING) ChRegion[loop].CountReg, "") != 0)
971 {
972 if (strncmp((PSTRING) ChRegion[loop].CountReg, (PSTRING) CntryCode, 2) == 0)
973 {
974 pChRegion = &ChRegion[loop];
975 break;
976 }
977 loop++;
978 }
979
980 if (pChRegion == NULL)
981 pChRegion = &ChRegion[loop];
982 return pChRegion;
983}
984
985static VOID ChBandCheck(
986 IN UCHAR PhyMode,
987 OUT PUCHAR pChType)
988{
989 switch(PhyMode)
990 {
991 case PHY_11A:
992 case PHY_11AN_MIXED:
993 *pChType = BAND_5G;
994 break;
995 case PHY_11ABG_MIXED:
996 case PHY_11AGN_MIXED:
997 case PHY_11ABGN_MIXED:
998 *pChType = BAND_BOTH;
999 break;
1000
1001 default:
1002 *pChType = BAND_24G;
1003 break;
1004 }
1005}
1006
1007static UCHAR FillChList(
1008 IN PRTMP_ADAPTER pAd,
1009 IN PCH_DESP pChDesp,
1010 IN UCHAR Offset,
1011 IN UCHAR increment)
1012{
1013 INT i, j, l;
1014 UCHAR channel;
1015
1016 j = Offset;
1017 for (i = 0; i < pChDesp->NumOfCh; i++)
1018 {
1019 channel = pChDesp->FirstChannel + i * increment;
1020 for (l=0; l<MAX_NUM_OF_CHANNELS; l++)
1021 {
1022 if (channel == pAd->TxPower[l].Channel)
1023 {
1024 pAd->ChannelList[j].Power = pAd->TxPower[l].Power;
1025 pAd->ChannelList[j].Power2 = pAd->TxPower[l].Power2;
1026 break;
1027 }
1028 }
1029 if (l == MAX_NUM_OF_CHANNELS)
1030 continue;
1031
1032 pAd->ChannelList[j].Channel = pChDesp->FirstChannel + i * increment;
1033 pAd->ChannelList[j].MaxTxPwr = pChDesp->MaxTxPwr;
1034 pAd->ChannelList[j].DfsReq = pChDesp->DfsReq;
1035 j++;
1036 }
1037 pAd->ChannelListNum = j;
1038
1039 return j;
1040}
1041
1042
1043static inline VOID CreateChList(
1044 IN PRTMP_ADAPTER pAd,
1045 IN PCH_REGION pChRegion,
1046 IN UCHAR Geography)
1047{
1048 INT i;
1049 UCHAR offset = 0;
1050 PCH_DESP pChDesp;
1051 UCHAR ChType;
1052 UCHAR increment;
1053
1054 if (pChRegion == NULL)
1055 return;
1056
1057 ChBandCheck(pAd->CommonCfg.PhyMode, &ChType);
1058
1059 for (i=0; i<10; i++)
1060 {
1061 pChDesp = &pChRegion->ChDesp[i];
1062 if (pChDesp->FirstChannel == 0)
1063 break;
1064
1065 if (ChType == BAND_5G)
1066 {
1067 if (pChDesp->FirstChannel <= 14)
1068 continue;
1069 }
1070 else if (ChType == BAND_24G)
1071 {
1072 if (pChDesp->FirstChannel > 14)
1073 continue;
1074 }
1075
1076 if ((pChDesp->Geography == BOTH)
1077 || (pChDesp->Geography == Geography))
1078 {
1079 if (pChDesp->FirstChannel > 14)
1080 increment = 4;
1081 else
1082 increment = 1;
1083 offset = FillChList(pAd, pChDesp, offset, increment);
1084 }
1085 }
1086}
1087
1088
1089VOID BuildChannelListEx(
1090 IN PRTMP_ADAPTER pAd)
1091{
1092 PCH_REGION pChReg;
1093
1094 pChReg = GetChRegion(pAd->CommonCfg.CountryCode);
1095 CreateChList(pAd, pChReg, pAd->CommonCfg.Geography);
1096}
1097
1098
1099VOID BuildBeaconChList(
1100 IN PRTMP_ADAPTER pAd,
1101 OUT PUCHAR pBuf,
1102 OUT PULONG pBufLen)
1103{
1104 INT i;
1105 ULONG TmpLen;
1106 PCH_REGION pChRegion;
1107 PCH_DESP pChDesp;
1108 UCHAR ChType;
1109
1110 pChRegion = GetChRegion(pAd->CommonCfg.CountryCode);
1111
1112 if (pChRegion == NULL)
1113 return;
1114
1115 ChBandCheck(pAd->CommonCfg.PhyMode, &ChType);
1116 *pBufLen = 0;
1117
1118 for (i=0; i<10; i++)
1119 {
1120 pChDesp = &pChRegion->ChDesp[i];
1121 if (pChDesp->FirstChannel == 0)
1122 break;
1123
1124 if (ChType == BAND_5G)
1125 {
1126 if (pChDesp->FirstChannel <= 14)
1127 continue;
1128 }
1129 else if (ChType == BAND_24G)
1130 {
1131 if (pChDesp->FirstChannel > 14)
1132 continue;
1133 }
1134
1135 if ((pChDesp->Geography == BOTH)
1136 || (pChDesp->Geography == pAd->CommonCfg.Geography))
1137 {
1138 MakeOutgoingFrame(pBuf + *pBufLen, &TmpLen,
1139 1, &pChDesp->FirstChannel,
1140 1, &pChDesp->NumOfCh,
1141 1, &pChDesp->MaxTxPwr,
1142 END_OF_ARGS);
1143 *pBufLen += TmpLen;
1144 }
1145 }
1146}
1147
1148
1149static BOOLEAN IsValidChannel(
1150 IN PRTMP_ADAPTER pAd,
1151 IN UCHAR channel)
1152
1153{
1154 INT i;
1155
1156 for (i = 0; i < pAd->ChannelListNum; i++)
1157 {
1158 if (pAd->ChannelList[i].Channel == channel)
1159 break;
1160 }
1161
1162 if (i == pAd->ChannelListNum)
1163 return FALSE;
1164 else
1165 return TRUE;
1166}
1167
1168
1169static UCHAR GetExtCh(
1170 IN UCHAR Channel,
1171 IN UCHAR Direction)
1172{
1173 CHAR ExtCh;
1174
1175 if (Direction == EXTCHA_ABOVE)
1176 ExtCh = Channel + 4;
1177 else
1178 ExtCh = (Channel - 4) > 0 ? (Channel - 4) : 0;
1179
1180 return ExtCh;
1181}
1182
1183
1184VOID N_ChannelCheck(
1185 IN PRTMP_ADAPTER pAd)
1186{
1187 //UCHAR ChannelNum = pAd->ChannelListNum;
1188 UCHAR Channel = pAd->CommonCfg.Channel;
1189
1190 if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) && (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40))
1191 {
1192 if (Channel > 14)
1193 {
1194 if ((Channel == 36) || (Channel == 44) || (Channel == 52) || (Channel == 60) || (Channel == 100) || (Channel == 108) ||
1195 (Channel == 116) || (Channel == 124) || (Channel == 132) || (Channel == 149) || (Channel == 157))
1196 {
1197 pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_ABOVE;
1198 }
1199 else if ((Channel == 40) || (Channel == 48) || (Channel == 56) || (Channel == 64) || (Channel == 104) || (Channel == 112) ||
1200 (Channel == 120) || (Channel == 128) || (Channel == 136) || (Channel == 153) || (Channel == 161))
1201 {
1202 pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_BELOW;
1203 }
1204 else
1205 {
1206 pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
1207 }
1208 }
1209 else
1210 {
1211 do
1212 {
1213 UCHAR ExtCh;
1214 UCHAR Dir = pAd->CommonCfg.RegTransmitSetting.field.EXTCHA;
1215 ExtCh = GetExtCh(Channel, Dir);
1216 if (IsValidChannel(pAd, ExtCh))
1217 break;
1218
1219 Dir = (Dir == EXTCHA_ABOVE) ? EXTCHA_BELOW : EXTCHA_ABOVE;
1220 ExtCh = GetExtCh(Channel, Dir);
1221 if (IsValidChannel(pAd, ExtCh))
1222 {
1223 pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = Dir;
1224 break;
1225 }
1226 pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
1227 } while(FALSE);
1228
1229 if (Channel == 14)
1230 {
1231 pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
1232 //pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_NONE; // We didn't set the ExtCh as NONE due to it'll set in RTMPSetHT()
1233 }
1234 }
1235 }
1236
1237
1238}
1239
1240
1241VOID N_SetCenCh(
1242 IN PRTMP_ADAPTER pAd)
1243{
1244 if (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40)
1245 {
1246 if (pAd->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_ABOVE)
1247 {
1248 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel + 2;
1249 }
1250 else
1251 {
1252 if (pAd->CommonCfg.Channel == 14)
1253 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 1;
1254 else
1255 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 2;
1256 }
1257 }
1258 else
1259 {
1260 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
1261 }
1262}
1263
1264
1265UINT8 GetCuntryMaxTxPwr(
1266 IN PRTMP_ADAPTER pAd,
1267 IN UINT8 channel)
1268{
1269 int i;
1270 for (i = 0; i < pAd->ChannelListNum; i++)
1271 {
1272 if (pAd->ChannelList[i].Channel == channel)
1273 break;
1274 }
1275
1276 if (i == pAd->ChannelListNum)
1277 return 0xff;
1278 else
1279 return pAd->ChannelList[i].MaxTxPwr;
1280}
diff --git a/drivers/staging/rt2860/common/rt_rf.c b/drivers/staging/rt2860/common/rt_rf.c
new file mode 100644
index 00000000000..34a6fcae120
--- /dev/null
+++ b/drivers/staging/rt2860/common/rt_rf.c
@@ -0,0 +1,194 @@
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
39#include "../rt_config.h"
40
41
42#ifdef RTMP_RF_RW_SUPPORT
43/*
44 ========================================================================
45
46 Routine Description: Write RT30xx RF register through MAC
47
48 Arguments:
49
50 Return Value:
51
52 IRQL =
53
54 Note:
55
56 ========================================================================
57*/
58NDIS_STATUS RT30xxWriteRFRegister(
59 IN PRTMP_ADAPTER pAd,
60 IN UCHAR regID,
61 IN UCHAR value)
62{
63 RF_CSR_CFG_STRUC rfcsr;
64 UINT i = 0;
65
66 do
67 {
68 RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word);
69
70 if (!rfcsr.field.RF_CSR_KICK)
71 break;
72 i++;
73 }
74 while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
75
76 if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
77 {
78 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n"));
79 return STATUS_UNSUCCESSFUL;
80 }
81
82 rfcsr.field.RF_CSR_WR = 1;
83 rfcsr.field.RF_CSR_KICK = 1;
84 rfcsr.field.TESTCSR_RFACC_REGNUM = regID;
85 rfcsr.field.RF_CSR_DATA = value;
86
87 RTMP_IO_WRITE32(pAd, RF_CSR_CFG, rfcsr.word);
88
89 return NDIS_STATUS_SUCCESS;
90}
91
92
93/*
94 ========================================================================
95
96 Routine Description: Read RT30xx RF register through MAC
97
98 Arguments:
99
100 Return Value:
101
102 IRQL =
103
104 Note:
105
106 ========================================================================
107*/
108NDIS_STATUS RT30xxReadRFRegister(
109 IN PRTMP_ADAPTER pAd,
110 IN UCHAR regID,
111 IN PUCHAR pValue)
112{
113 RF_CSR_CFG_STRUC rfcsr;
114 UINT i=0, k=0;
115
116 for (i=0; i<MAX_BUSY_COUNT; i++)
117 {
118 RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word);
119
120 if (rfcsr.field.RF_CSR_KICK == BUSY)
121 {
122 continue;
123 }
124 rfcsr.word = 0;
125 rfcsr.field.RF_CSR_WR = 0;
126 rfcsr.field.RF_CSR_KICK = 1;
127 rfcsr.field.TESTCSR_RFACC_REGNUM = regID;
128 RTMP_IO_WRITE32(pAd, RF_CSR_CFG, rfcsr.word);
129 for (k=0; k<MAX_BUSY_COUNT; k++)
130 {
131 RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word);
132
133 if (rfcsr.field.RF_CSR_KICK == IDLE)
134 break;
135 }
136 if ((rfcsr.field.RF_CSR_KICK == IDLE) &&
137 (rfcsr.field.TESTCSR_RFACC_REGNUM == regID))
138 {
139 *pValue = (UCHAR)rfcsr.field.RF_CSR_DATA;
140 break;
141 }
142 }
143 if (rfcsr.field.RF_CSR_KICK == BUSY)
144 {
145 DBGPRINT_ERR(("RF read R%d=0x%x fail, i[%d], k[%d]\n", regID, rfcsr.word,i,k));
146 return STATUS_UNSUCCESSFUL;
147 }
148
149 return STATUS_SUCCESS;
150}
151
152
153VOID NICInitRFRegisters(
154 IN RTMP_ADAPTER *pAd)
155{
156 if (pAd->chipOps.AsicRfInit)
157 pAd->chipOps.AsicRfInit(pAd);
158}
159
160
161VOID RtmpChipOpsRFHook(
162 IN RTMP_ADAPTER *pAd)
163{
164 RTMP_CHIP_OP *pChipOps = &pAd->chipOps;
165
166 pChipOps->pRFRegTable = NULL;
167 pChipOps->AsicRfInit = NULL;
168 pChipOps->AsicRfTurnOn = NULL;
169 pChipOps->AsicRfTurnOff = NULL;
170 pChipOps->AsicReverseRfFromSleepMode = NULL;
171 pChipOps->AsicHaltAction = NULL;
172 /* We depends on RfICType and MACVersion to assign the corresponding operation callbacks. */
173
174#ifdef RT30xx
175 if (IS_RT30xx(pAd))
176 {
177 pChipOps->pRFRegTable = RT30xx_RFRegTable;
178 pChipOps->AsicHaltAction = RT30xxHaltAction;
179#ifdef RT3070
180 if((IS_RT3070(pAd) || IS_RT3071(pAd)) && (pAd->infType == RTMP_DEV_INF_USB))
181 {
182 pChipOps->AsicRfInit = NICInitRT3070RFRegisters;
183 if (IS_RT3071(pAd))
184 {
185 pChipOps->AsicRfTurnOff = RT30xxLoadRFSleepModeSetup;
186 pChipOps->AsicReverseRfFromSleepMode = RT30xxReverseRFSleepModeSetup;
187 }
188 }
189#endif // RT3070 //
190 }
191#endif // RT30xx //
192}
193
194#endif // RTMP_RF_RW_SUPPORT //
diff --git a/drivers/staging/rt2860/common/rtmp_init.c b/drivers/staging/rt2860/common/rtmp_init.c
index 20c2ce26bc9..1dd4c829291 100644
--- a/drivers/staging/rt2860/common/rtmp_init.c
+++ b/drivers/staging/rt2860/common/rtmp_init.c
@@ -33,30 +33,10 @@
33 Revision History: 33 Revision History:
34 Who When What 34 Who When What
35 -------- ---------- ---------------------------------------------- 35 -------- ---------- ----------------------------------------------
36 Paul Lin 2002-08-01 created
37 John Chang 2004-08-20 RT2561/2661 use scatter-gather scheme
38 Jan Lee 2006-09-15 RT2860. Change for 802.11n , EEPROM, Led, BA, HT.
39*/ 36*/
40#include "../rt_config.h" 37#include "../rt_config.h"
41#ifdef RT2860
42#include "firmware.h"
43#include <linux/bitrev.h>
44#endif
45#ifdef RT2870
46/* New firmware handles both RT2870 and RT3070. */
47#include "../../rt3070/firmware.h"
48#endif
49 38
50UCHAR BIT8[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80}; 39UCHAR BIT8[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
51ULONG BIT32[] = {0x00000001, 0x00000002, 0x00000004, 0x00000008,
52 0x00000010, 0x00000020, 0x00000040, 0x00000080,
53 0x00000100, 0x00000200, 0x00000400, 0x00000800,
54 0x00001000, 0x00002000, 0x00004000, 0x00008000,
55 0x00010000, 0x00020000, 0x00040000, 0x00080000,
56 0x00100000, 0x00200000, 0x00400000, 0x00800000,
57 0x01000000, 0x02000000, 0x04000000, 0x08000000,
58 0x10000000, 0x20000000, 0x40000000, 0x80000000};
59
60char* CipherName[] = {"none","wep64","wep128","TKIP","AES","CKIP64","CKIP128"}; 40char* CipherName[] = {"none","wep64","wep128","TKIP","AES","CKIP64","CKIP128"};
61 41
62// 42//
@@ -77,36 +57,10 @@ REG_PAIR BBPRegTable[] = {
77 {BBP_R92, 0x00}, // middle range issue, Rory @2008-01-28 57 {BBP_R92, 0x00}, // middle range issue, Rory @2008-01-28
78 {BBP_R103, 0x00}, // near range high-power issue, requested from Gary @2008-0528 58 {BBP_R103, 0x00}, // near range high-power issue, requested from Gary @2008-0528
79 {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. 59 {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.
60 {BBP_R106, 0x35}, // for ShortGI throughput
80}; 61};
81#define NUM_BBP_REG_PARMS (sizeof(BBPRegTable) / sizeof(REG_PAIR)) 62#define NUM_BBP_REG_PARMS (sizeof(BBPRegTable) / sizeof(REG_PAIR))
82 63
83//
84// RF register initialization set
85//
86#ifdef RT2870
87REG_PAIR RT30xx_RFRegTable[] = {
88 {RF_R04, 0x40},
89 {RF_R05, 0x03},
90 {RF_R06, 0x02},
91 {RF_R07, 0x70},
92 {RF_R09, 0x0F},
93 {RF_R10, 0x41},
94 {RF_R11, 0x21},
95 {RF_R12, 0x7B},
96 {RF_R14, 0x90},
97 {RF_R15, 0x58},
98 {RF_R16, 0xB3},
99 {RF_R17, 0x92},
100 {RF_R18, 0x2C},
101 {RF_R19, 0x02},
102 {RF_R20, 0xBA},
103 {RF_R21, 0xDB},
104 {RF_R24, 0x16},
105 {RF_R25, 0x01},
106 {RF_R29, 0x1F},
107};
108#define NUM_RF_REG_PARMS (sizeof(RT30xx_RFRegTable) / sizeof(REG_PAIR))
109#endif // RT2870 //
110 64
111// 65//
112// ASIC register initialization sets 66// ASIC register initialization sets
@@ -128,32 +82,37 @@ RTMP_REG_PAIR MACRegTable[] = {
128 {MAC_SYS_CTRL, 0x00}, // 0x1004, , default Disable RX 82 {MAC_SYS_CTRL, 0x00}, // 0x1004, , default Disable RX
129 {RX_FILTR_CFG, 0x17f97}, //0x1400 , RX filter control, 83 {RX_FILTR_CFG, 0x17f97}, //0x1400 , RX filter control,
130 {BKOFF_SLOT_CFG, 0x209}, // default set short slot time, CC_DELAY_TIME should be 2 84 {BKOFF_SLOT_CFG, 0x209}, // default set short slot time, CC_DELAY_TIME should be 2
85 //{TX_SW_CFG0, 0x40a06}, // Gary,2006-08-23
131 {TX_SW_CFG0, 0x0}, // Gary,2008-05-21 for CWC test 86 {TX_SW_CFG0, 0x0}, // Gary,2008-05-21 for CWC test
132 {TX_SW_CFG1, 0x80606}, // Gary,2006-08-23 87 {TX_SW_CFG1, 0x80606}, // Gary,2006-08-23
133 {TX_LINK_CFG, 0x1020}, // Gary,2006-08-23 88 {TX_LINK_CFG, 0x1020}, // Gary,2006-08-23
89 //{TX_TIMEOUT_CFG, 0x00182090}, // CCK has some problem. So increase timieout value. 2006-10-09// MArvek RT
134 {TX_TIMEOUT_CFG, 0x000a2090}, // CCK has some problem. So increase timieout value. 2006-10-09// MArvek RT , Modify for 2860E ,2007-08-01 90 {TX_TIMEOUT_CFG, 0x000a2090}, // CCK has some problem. So increase timieout value. 2006-10-09// MArvek RT , Modify for 2860E ,2007-08-01
135 {MAX_LEN_CFG, MAX_AGGREGATION_SIZE | 0x00001000}, // 0x3018, MAX frame length. Max PSDU = 16kbytes. 91 {MAX_LEN_CFG, MAX_AGGREGATION_SIZE | 0x00001000}, // 0x3018, MAX frame length. Max PSDU = 16kbytes.
136 {LED_CFG, 0x7f031e46}, // Gary, 2006-08-23 92 {LED_CFG, 0x7f031e46}, // Gary, 2006-08-23
93
137 {PBF_MAX_PCNT, 0x1F3FBF9F}, //0x1F3f7f9f}, //Jan, 2006/04/20 94 {PBF_MAX_PCNT, 0x1F3FBF9F}, //0x1F3f7f9f}, //Jan, 2006/04/20
95
138 {TX_RTY_CFG, 0x47d01f0f}, // Jan, 2006/11/16, Set TxWI->ACK =0 in Probe Rsp Modify for 2860E ,2007-08-03 96 {TX_RTY_CFG, 0x47d01f0f}, // Jan, 2006/11/16, Set TxWI->ACK =0 in Probe Rsp Modify for 2860E ,2007-08-03
97
139 {AUTO_RSP_CFG, 0x00000013}, // Initial Auto_Responder, because QA will turn off Auto-Responder 98 {AUTO_RSP_CFG, 0x00000013}, // Initial Auto_Responder, because QA will turn off Auto-Responder
140 {CCK_PROT_CFG, 0x05740003 /*0x01740003*/}, // Initial Auto_Responder, because QA will turn off Auto-Responder. And RTS threshold is enabled. 99 {CCK_PROT_CFG, 0x05740003 /*0x01740003*/}, // Initial Auto_Responder, because QA will turn off Auto-Responder. And RTS threshold is enabled.
141 {OFDM_PROT_CFG, 0x05740003 /*0x01740003*/}, // Initial Auto_Responder, because QA will turn off Auto-Responder. And RTS threshold is enabled. 100 {OFDM_PROT_CFG, 0x05740003 /*0x01740003*/}, // Initial Auto_Responder, because QA will turn off Auto-Responder. And RTS threshold is enabled.
142//PS packets use Tx1Q (for HCCA) when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA) 101#ifdef RTMP_MAC_USB
143#ifdef RT2870
144 {PBF_CFG, 0xf40006}, // Only enable Queue 2 102 {PBF_CFG, 0xf40006}, // Only enable Queue 2
145 {MM40_PROT_CFG, 0x3F44084}, // Initial Auto_Responder, because QA will turn off Auto-Responder 103 {MM40_PROT_CFG, 0x3F44084}, // Initial Auto_Responder, because QA will turn off Auto-Responder
146 {WPDMA_GLO_CFG, 0x00000030}, 104 {WPDMA_GLO_CFG, 0x00000030},
147#endif // RT2870 // 105#endif // RTMP_MAC_USB //
148 {GF20_PROT_CFG, 0x01744004}, // set 19:18 --> Short NAV for MIMO PS 106 {GF20_PROT_CFG, 0x01744004}, // set 19:18 --> Short NAV for MIMO PS
149 {GF40_PROT_CFG, 0x03F44084}, 107 {GF40_PROT_CFG, 0x03F44084},
150 {MM20_PROT_CFG, 0x01744004}, 108 {MM20_PROT_CFG, 0x01744004},
151#ifdef RT2860 109#ifdef RTMP_MAC_PCI
152 {MM40_PROT_CFG, 0x03F54084}, 110 {MM40_PROT_CFG, 0x03F54084},
153#endif 111#endif // RTMP_MAC_PCI //
154 {TXOP_CTRL_CFG, 0x0000583f, /*0x0000243f*/ /*0x000024bf*/}, //Extension channel backoff. 112 {TXOP_CTRL_CFG, 0x0000583f, /*0x0000243f*/ /*0x000024bf*/}, //Extension channel backoff.
155 {TX_RTS_CFG, 0x00092b20}, 113 {TX_RTS_CFG, 0x00092b20},
156 {EXP_ACK_TIME, 0x002400ca}, // default value 114 {EXP_ACK_TIME, 0x002400ca}, // default value
115
157 {TXOP_HLDR_ET, 0x00000002}, 116 {TXOP_HLDR_ET, 0x00000002},
158 117
159 /* Jerry comments 2008/01/16: we use SIFS = 10us in CCK defaultly, but it seems that 10us 118 /* Jerry comments 2008/01/16: we use SIFS = 10us in CCK defaultly, but it seems that 10us
@@ -173,26 +132,6 @@ RTMP_REG_PAIR STAMACRegTable[] = {
173#define NUM_MAC_REG_PARMS (sizeof(MACRegTable) / sizeof(RTMP_REG_PAIR)) 132#define NUM_MAC_REG_PARMS (sizeof(MACRegTable) / sizeof(RTMP_REG_PAIR))
174#define NUM_STA_MAC_REG_PARMS (sizeof(STAMACRegTable) / sizeof(RTMP_REG_PAIR)) 133#define NUM_STA_MAC_REG_PARMS (sizeof(STAMACRegTable) / sizeof(RTMP_REG_PAIR))
175 134
176#ifdef RT2870
177//
178// RT2870 Firmware Spec only used 1 oct for version expression
179//
180#define FIRMWARE_MINOR_VERSION 7
181
182#endif // RT2870 //
183
184// New 8k byte firmware size for RT3071/RT3072
185#define FIRMWAREIMAGE_MAX_LENGTH 0x2000
186#define FIRMWAREIMAGE_LENGTH (sizeof (FirmwareImage) / sizeof(UCHAR))
187#define FIRMWARE_MAJOR_VERSION 0
188
189#define FIRMWAREIMAGEV1_LENGTH 0x1000
190#define FIRMWAREIMAGEV2_LENGTH 0x1000
191
192#ifdef RT2860
193#define FIRMWARE_MINOR_VERSION 2
194#endif
195
196 135
197/* 136/*
198 ======================================================================== 137 ========================================================================
@@ -236,6 +175,7 @@ NDIS_STATUS RTMPAllocAdapterBlock(
236 DBGPRINT_ERR(("Failed to allocate memory - BeaconBuf!\n")); 175 DBGPRINT_ERR(("Failed to allocate memory - BeaconBuf!\n"));
237 break; 176 break;
238 } 177 }
178 NdisZeroMemory(pBeaconBuf, MAX_BEACON_SIZE);
239 179
240 Status = AdapterBlockAllocateMemory(handle, (PVOID *)&pAd); 180 Status = AdapterBlockAllocateMemory(handle, (PVOID *)&pAd);
241 if (Status != NDIS_STATUS_SUCCESS) 181 if (Status != NDIS_STATUS_SUCCESS)
@@ -244,14 +184,14 @@ NDIS_STATUS RTMPAllocAdapterBlock(
244 break; 184 break;
245 } 185 }
246 pAd->BeaconBuf = pBeaconBuf; 186 pAd->BeaconBuf = pBeaconBuf;
247 printk("\n\n=== pAd = %p, size = %d ===\n\n", pAd, (UINT32)sizeof(RTMP_ADAPTER)); 187 DBGPRINT(RT_DEBUG_OFF, ("\n\n=== pAd = %p, size = %d ===\n\n", pAd, (UINT32)sizeof(RTMP_ADAPTER)));
248 188
249 189
250 // Init spin locks 190 // Init spin locks
251 NdisAllocateSpinLock(&pAd->MgmtRingLock); 191 NdisAllocateSpinLock(&pAd->MgmtRingLock);
252#ifdef RT2860 192#ifdef RTMP_MAC_PCI
253 NdisAllocateSpinLock(&pAd->RxRingLock); 193 NdisAllocateSpinLock(&pAd->RxRingLock);
254#endif 194#endif // RTMP_MAC_PCI //
255 195
256 for (index =0 ; index < NUM_OF_TX_RING; index++) 196 for (index =0 ; index < NUM_OF_TX_RING; index++)
257 { 197 {
@@ -298,7 +238,7 @@ VOID RTMPReadTxPwrPerRate(
298 USHORT i, value, value2; 238 USHORT i, value, value2;
299 INT Apwrdelta, Gpwrdelta; 239 INT Apwrdelta, Gpwrdelta;
300 UCHAR t1,t2,t3,t4; 240 UCHAR t1,t2,t3,t4;
301 BOOLEAN bValid, bApwrdeltaMinus = TRUE, bGpwrdeltaMinus = TRUE; 241 BOOLEAN bApwrdeltaMinus = TRUE, bGpwrdeltaMinus = TRUE;
302 242
303 // 243 //
304 // Get power delta for 20MHz and 40MHz. 244 // Get power delta for 20MHz and 40MHz.
@@ -481,325 +421,16 @@ VOID RTMPReadTxPwrPerRate(
481 Gdata |= ((t1<<16) + (t2<<20) + (t3<<24) + (t4<<28)); 421 Gdata |= ((t1<<16) + (t2<<20) + (t3<<24) + (t4<<28));
482 data |= (value<<16); 422 data |= (value<<16);
483 423
484 pAd->Tx20MPwrCfgABand[i] = pAd->Tx40MPwrCfgABand[i] = Adata; 424 /* For 20M/40M Power Delta issue */
485 pAd->Tx20MPwrCfgGBand[i] = pAd->Tx40MPwrCfgGBand[i] = Gdata; 425 pAd->Tx20MPwrCfgABand[i] = data;
426 pAd->Tx20MPwrCfgGBand[i] = data;
427 pAd->Tx40MPwrCfgABand[i] = Adata;
428 pAd->Tx40MPwrCfgGBand[i] = Gdata;
486 429
487 if (data != 0xffffffff) 430 if (data != 0xffffffff)
488 RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, data); 431 RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, data);
489 DBGPRINT_RAW(RT_DEBUG_TRACE, ("20MHz BW, 2.4G band-%lx, Adata = %lx, Gdata = %lx \n", data, Adata, Gdata)); 432 DBGPRINT_RAW(RT_DEBUG_TRACE, ("20MHz BW, 2.4G band-%lx, Adata = %lx, Gdata = %lx \n", data, Adata, Gdata));
490 } 433 }
491
492 //
493 // Check this block is valid for 40MHz in 2.4G. If invalid, use parameter for 20MHz in 2.4G
494 //
495 bValid = TRUE;
496 for (i=0; i<6; i++)
497 {
498 RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_40MHZ_2_4G + 2 + i*2, value);
499 if (((value & 0x00FF) == 0x00FF) || ((value & 0xFF00) == 0xFF00))
500 {
501 bValid = FALSE;
502 break;
503 }
504 }
505
506 //
507 // Get Txpower per MCS for 40MHz in 2.4G.
508 //
509 if (bValid)
510 {
511 for (i=0; i<4; i++)
512 {
513 RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_40MHZ_2_4G + i*4, value);
514 if (bGpwrdeltaMinus == FALSE)
515 {
516 t1 = (value&0xf)+(Gpwrdelta);
517 if (t1 > 0xf)
518 t1 = 0xf;
519 t2 = ((value&0xf0)>>4)+(Gpwrdelta);
520 if (t2 > 0xf)
521 t2 = 0xf;
522 t3 = ((value&0xf00)>>8)+(Gpwrdelta);
523 if (t3 > 0xf)
524 t3 = 0xf;
525 t4 = ((value&0xf000)>>12)+(Gpwrdelta);
526 if (t4 > 0xf)
527 t4 = 0xf;
528 }
529 else
530 {
531 if ((value&0xf) > Gpwrdelta)
532 t1 = (value&0xf)-(Gpwrdelta);
533 else
534 t1 = 0;
535 if (((value&0xf0)>>4) > Gpwrdelta)
536 t2 = ((value&0xf0)>>4)-(Gpwrdelta);
537 else
538 t2 = 0;
539 if (((value&0xf00)>>8) > Gpwrdelta)
540 t3 = ((value&0xf00)>>8)-(Gpwrdelta);
541 else
542 t3 = 0;
543 if (((value&0xf000)>>12) > Gpwrdelta)
544 t4 = ((value&0xf000)>>12)-(Gpwrdelta);
545 else
546 t4 = 0;
547 }
548 Gdata = t1 + (t2<<4) + (t3<<8) + (t4<<12);
549
550 RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_40MHZ_2_4G + i*4 + 2, value);
551 if (bGpwrdeltaMinus == FALSE)
552 {
553 t1 = (value&0xf)+(Gpwrdelta);
554 if (t1 > 0xf)
555 t1 = 0xf;
556 t2 = ((value&0xf0)>>4)+(Gpwrdelta);
557 if (t2 > 0xf)
558 t2 = 0xf;
559 t3 = ((value&0xf00)>>8)+(Gpwrdelta);
560 if (t3 > 0xf)
561 t3 = 0xf;
562 t4 = ((value&0xf000)>>12)+(Gpwrdelta);
563 if (t4 > 0xf)
564 t4 = 0xf;
565 }
566 else
567 {
568 if ((value&0xf) > Gpwrdelta)
569 t1 = (value&0xf)-(Gpwrdelta);
570 else
571 t1 = 0;
572 if (((value&0xf0)>>4) > Gpwrdelta)
573 t2 = ((value&0xf0)>>4)-(Gpwrdelta);
574 else
575 t2 = 0;
576 if (((value&0xf00)>>8) > Gpwrdelta)
577 t3 = ((value&0xf00)>>8)-(Gpwrdelta);
578 else
579 t3 = 0;
580 if (((value&0xf000)>>12) > Gpwrdelta)
581 t4 = ((value&0xf000)>>12)-(Gpwrdelta);
582 else
583 t4 = 0;
584 }
585 Gdata |= ((t1<<16) + (t2<<20) + (t3<<24) + (t4<<28));
586
587 if (i == 0)
588 pAd->Tx40MPwrCfgGBand[i+1] = (pAd->Tx40MPwrCfgGBand[i+1] & 0x0000FFFF) | (Gdata & 0xFFFF0000);
589 else
590 pAd->Tx40MPwrCfgGBand[i+1] = Gdata;
591
592 DBGPRINT_RAW(RT_DEBUG_TRACE, ("40MHz BW, 2.4G band, Gdata = %lx \n", Gdata));
593 }
594 }
595
596 //
597 // Check this block is valid for 20MHz in 5G. If invalid, use parameter for 20MHz in 2.4G
598 //
599 bValid = TRUE;
600 for (i=0; i<8; i++)
601 {
602 RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_20MHZ_5G + 2 + i*2, value);
603 if (((value & 0x00FF) == 0x00FF) || ((value & 0xFF00) == 0xFF00))
604 {
605 bValid = FALSE;
606 break;
607 }
608 }
609
610 //
611 // Get Txpower per MCS for 20MHz in 5G.
612 //
613 if (bValid)
614 {
615 for (i=0; i<5; i++)
616 {
617 RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_20MHZ_5G + i*4, value);
618 if (bApwrdeltaMinus == FALSE)
619 {
620 t1 = (value&0xf)+(Apwrdelta);
621 if (t1 > 0xf)
622 t1 = 0xf;
623 t2 = ((value&0xf0)>>4)+(Apwrdelta);
624 if (t2 > 0xf)
625 t2 = 0xf;
626 t3 = ((value&0xf00)>>8)+(Apwrdelta);
627 if (t3 > 0xf)
628 t3 = 0xf;
629 t4 = ((value&0xf000)>>12)+(Apwrdelta);
630 if (t4 > 0xf)
631 t4 = 0xf;
632 }
633 else
634 {
635 if ((value&0xf) > Apwrdelta)
636 t1 = (value&0xf)-(Apwrdelta);
637 else
638 t1 = 0;
639 if (((value&0xf0)>>4) > Apwrdelta)
640 t2 = ((value&0xf0)>>4)-(Apwrdelta);
641 else
642 t2 = 0;
643 if (((value&0xf00)>>8) > Apwrdelta)
644 t3 = ((value&0xf00)>>8)-(Apwrdelta);
645 else
646 t3 = 0;
647 if (((value&0xf000)>>12) > Apwrdelta)
648 t4 = ((value&0xf000)>>12)-(Apwrdelta);
649 else
650 t4 = 0;
651 }
652 Adata = t1 + (t2<<4) + (t3<<8) + (t4<<12);
653
654 RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_20MHZ_5G + i*4 + 2, value);
655 if (bApwrdeltaMinus == FALSE)
656 {
657 t1 = (value&0xf)+(Apwrdelta);
658 if (t1 > 0xf)
659 t1 = 0xf;
660 t2 = ((value&0xf0)>>4)+(Apwrdelta);
661 if (t2 > 0xf)
662 t2 = 0xf;
663 t3 = ((value&0xf00)>>8)+(Apwrdelta);
664 if (t3 > 0xf)
665 t3 = 0xf;
666 t4 = ((value&0xf000)>>12)+(Apwrdelta);
667 if (t4 > 0xf)
668 t4 = 0xf;
669 }
670 else
671 {
672 if ((value&0xf) > Apwrdelta)
673 t1 = (value&0xf)-(Apwrdelta);
674 else
675 t1 = 0;
676 if (((value&0xf0)>>4) > Apwrdelta)
677 t2 = ((value&0xf0)>>4)-(Apwrdelta);
678 else
679 t2 = 0;
680 if (((value&0xf00)>>8) > Apwrdelta)
681 t3 = ((value&0xf00)>>8)-(Apwrdelta);
682 else
683 t3 = 0;
684 if (((value&0xf000)>>12) > Apwrdelta)
685 t4 = ((value&0xf000)>>12)-(Apwrdelta);
686 else
687 t4 = 0;
688 }
689 Adata |= ((t1<<16) + (t2<<20) + (t3<<24) + (t4<<28));
690
691 if (i == 0)
692 pAd->Tx20MPwrCfgABand[i] = (pAd->Tx20MPwrCfgABand[i] & 0x0000FFFF) | (Adata & 0xFFFF0000);
693 else
694 pAd->Tx20MPwrCfgABand[i] = Adata;
695
696 DBGPRINT_RAW(RT_DEBUG_TRACE, ("20MHz BW, 5GHz band, Adata = %lx \n", Adata));
697 }
698 }
699
700 //
701 // Check this block is valid for 40MHz in 5G. If invalid, use parameter for 20MHz in 2.4G
702 //
703 bValid = TRUE;
704 for (i=0; i<6; i++)
705 {
706 RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_40MHZ_5G + 2 + i*2, value);
707 if (((value & 0x00FF) == 0x00FF) || ((value & 0xFF00) == 0xFF00))
708 {
709 bValid = FALSE;
710 break;
711 }
712 }
713
714 //
715 // Get Txpower per MCS for 40MHz in 5G.
716 //
717 if (bValid)
718 {
719 for (i=0; i<4; i++)
720 {
721 RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_40MHZ_5G + i*4, value);
722 if (bApwrdeltaMinus == FALSE)
723 {
724 t1 = (value&0xf)+(Apwrdelta);
725 if (t1 > 0xf)
726 t1 = 0xf;
727 t2 = ((value&0xf0)>>4)+(Apwrdelta);
728 if (t2 > 0xf)
729 t2 = 0xf;
730 t3 = ((value&0xf00)>>8)+(Apwrdelta);
731 if (t3 > 0xf)
732 t3 = 0xf;
733 t4 = ((value&0xf000)>>12)+(Apwrdelta);
734 if (t4 > 0xf)
735 t4 = 0xf;
736 }
737 else
738 {
739 if ((value&0xf) > Apwrdelta)
740 t1 = (value&0xf)-(Apwrdelta);
741 else
742 t1 = 0;
743 if (((value&0xf0)>>4) > Apwrdelta)
744 t2 = ((value&0xf0)>>4)-(Apwrdelta);
745 else
746 t2 = 0;
747 if (((value&0xf00)>>8) > Apwrdelta)
748 t3 = ((value&0xf00)>>8)-(Apwrdelta);
749 else
750 t3 = 0;
751 if (((value&0xf000)>>12) > Apwrdelta)
752 t4 = ((value&0xf000)>>12)-(Apwrdelta);
753 else
754 t4 = 0;
755 }
756 Adata = t1 + (t2<<4) + (t3<<8) + (t4<<12);
757
758 RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_40MHZ_5G + i*4 + 2, value);
759 if (bApwrdeltaMinus == FALSE)
760 {
761 t1 = (value&0xf)+(Apwrdelta);
762 if (t1 > 0xf)
763 t1 = 0xf;
764 t2 = ((value&0xf0)>>4)+(Apwrdelta);
765 if (t2 > 0xf)
766 t2 = 0xf;
767 t3 = ((value&0xf00)>>8)+(Apwrdelta);
768 if (t3 > 0xf)
769 t3 = 0xf;
770 t4 = ((value&0xf000)>>12)+(Apwrdelta);
771 if (t4 > 0xf)
772 t4 = 0xf;
773 }
774 else
775 {
776 if ((value&0xf) > Apwrdelta)
777 t1 = (value&0xf)-(Apwrdelta);
778 else
779 t1 = 0;
780 if (((value&0xf0)>>4) > Apwrdelta)
781 t2 = ((value&0xf0)>>4)-(Apwrdelta);
782 else
783 t2 = 0;
784 if (((value&0xf00)>>8) > Apwrdelta)
785 t3 = ((value&0xf00)>>8)-(Apwrdelta);
786 else
787 t3 = 0;
788 if (((value&0xf000)>>12) > Apwrdelta)
789 t4 = ((value&0xf000)>>12)-(Apwrdelta);
790 else
791 t4 = 0;
792 }
793 Adata |= ((t1<<16) + (t2<<20) + (t3<<24) + (t4<<28));
794
795 if (i == 0)
796 pAd->Tx40MPwrCfgABand[i+1] = (pAd->Tx40MPwrCfgABand[i+1] & 0x0000FFFF) | (Adata & 0xFFFF0000);
797 else
798 pAd->Tx40MPwrCfgABand[i+1] = Adata;
799
800 DBGPRINT_RAW(RT_DEBUG_TRACE, ("40MHz BW, 5GHz band, Adata = %lx \n", Adata));
801 }
802 }
803} 434}
804 435
805 436
@@ -939,10 +570,11 @@ VOID RTMPReadChannelPwr(
939 pAd->TxPower[i * 2 + choffset + 1].Power2 = Power2.field.Byte1; 570 pAd->TxPower[i * 2 + choffset + 1].Power2 = Power2.field.Byte1;
940 } 571 }
941 572
942 // 3. U-NII upper band: 149, 151, 153; 157, 159, 161; 165 (including central frequency in BW 40MHz) 573 // 3. U-NII upper band: 149, 151, 153; 157, 159, 161; 165, 167, 169; 171, 173 (including central frequency in BW 40MHz)
943 // 3.1 Fill up channel 574 // 3.1 Fill up channel
944 choffset = 14 + 12 + 16; 575 choffset = 14 + 12 + 16;
945 for (i = 0; i < 2; i++) 576 /*for (i = 0; i < 2; i++)*/
577 for (i = 0; i < 3; i++)
946 { 578 {
947 pAd->TxPower[3 * i + choffset + 0].Channel = 149 + i * 8 + 0; 579 pAd->TxPower[3 * i + choffset + 0].Channel = 149 + i * 8 + 0;
948 pAd->TxPower[3 * i + choffset + 0].Power = DEFAULT_RF_TX_POWER; 580 pAd->TxPower[3 * i + choffset + 0].Power = DEFAULT_RF_TX_POWER;
@@ -956,12 +588,17 @@ VOID RTMPReadChannelPwr(
956 pAd->TxPower[3 * i + choffset + 2].Power = DEFAULT_RF_TX_POWER; 588 pAd->TxPower[3 * i + choffset + 2].Power = DEFAULT_RF_TX_POWER;
957 pAd->TxPower[3 * i + choffset + 2].Power2 = DEFAULT_RF_TX_POWER; 589 pAd->TxPower[3 * i + choffset + 2].Power2 = DEFAULT_RF_TX_POWER;
958 } 590 }
959 pAd->TxPower[3 * 2 + choffset + 0].Channel = 165; 591 pAd->TxPower[3 * 3 + choffset + 0].Channel = 171;
960 pAd->TxPower[3 * 2 + choffset + 0].Power = DEFAULT_RF_TX_POWER; 592 pAd->TxPower[3 * 3 + choffset + 0].Power = DEFAULT_RF_TX_POWER;
961 pAd->TxPower[3 * 2 + choffset + 0].Power2 = DEFAULT_RF_TX_POWER; 593 pAd->TxPower[3 * 3 + choffset + 0].Power2 = DEFAULT_RF_TX_POWER;
594
595 pAd->TxPower[3 * 3 + choffset + 1].Channel = 173;
596 pAd->TxPower[3 * 3 + choffset + 1].Power = DEFAULT_RF_TX_POWER;
597 pAd->TxPower[3 * 3 + choffset + 1].Power2 = DEFAULT_RF_TX_POWER;
962 598
963 // 3.2 Fill up power 599 // 3.2 Fill up power
964 for (i = 0; i < 4; i++) 600 /*for (i = 0; i < 4; i++)*/
601 for (i = 0; i < 6; i++)
965 { 602 {
966 RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX_PWR_OFFSET + (choffset - 14) + i * 2, Power.word); 603 RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX_PWR_OFFSET + (choffset - 14) + i * 2, Power.word);
967 RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX2_PWR_OFFSET + (choffset - 14) + i * 2, Power2.word); 604 RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX2_PWR_OFFSET + (choffset - 14) + i * 2, Power2.word);
@@ -980,7 +617,10 @@ VOID RTMPReadChannelPwr(
980 } 617 }
981 618
982 // 4. Print and Debug 619 // 4. Print and Debug
983 choffset = 14 + 12 + 16 + 7; 620 /*choffset = 14 + 12 + 16 + 7;*/
621 choffset = 14 + 12 + 16 + 11;
622
623
984} 624}
985 625
986/* 626/*
@@ -1017,267 +657,6 @@ NDIS_STATUS NICReadRegParameters(
1017} 657}
1018 658
1019 659
1020#ifdef RT2870
1021/*
1022 ========================================================================
1023
1024 Routine Description:
1025 For RF filter calibration purpose
1026
1027 Arguments:
1028 pAd Pointer to our adapter
1029
1030 Return Value:
1031 None
1032
1033 IRQL = PASSIVE_LEVEL
1034
1035 ========================================================================
1036*/
1037VOID RTMPFilterCalibration(
1038 IN PRTMP_ADAPTER pAd)
1039{
1040 UCHAR R55x = 0, value, FilterTarget = 0x1E, BBPValue=0;
1041 UINT loop = 0, count = 0, loopcnt = 0, ReTry = 0;
1042 UCHAR RF_R24_Value = 0;
1043
1044 // Give bbp filter initial value
1045#ifndef RT2870
1046 pAd->Mlme.CaliBW20RfR24 = 0x16;
1047 pAd->Mlme.CaliBW40RfR24 = 0x36; //Bit[5] must be 1 for BW 40
1048#else
1049 pAd->Mlme.CaliBW20RfR24 = 0x1F;
1050 pAd->Mlme.CaliBW40RfR24 = 0x2F; //Bit[5] must be 1 for BW 40
1051#endif
1052 do
1053 {
1054 if (loop == 1) //BandWidth = 40 MHz
1055 {
1056 // Write 0x27 to RF_R24 to program filter
1057 RF_R24_Value = 0x27;
1058 RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
1059 if (IS_RT3090(pAd))
1060 FilterTarget = 0x15;
1061 else
1062 FilterTarget = 0x19;
1063
1064 // when calibrate BW40, BBP mask must set to BW40.
1065 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
1066 BBPValue&= (~0x18);
1067 BBPValue|= (0x10);
1068 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
1069#ifdef RT2870
1070 // set to BW40
1071 RT30xxReadRFRegister(pAd, RF_R31, &value);
1072 value |= 0x20;
1073 RT30xxWriteRFRegister(pAd, RF_R31, value);
1074#endif
1075 }
1076 else //BandWidth = 20 MHz
1077 {
1078 // Write 0x07 to RF_R24 to program filter
1079 RF_R24_Value = 0x07;
1080 RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
1081 if (IS_RT3090(pAd))
1082 FilterTarget = 0x13;
1083 else
1084 FilterTarget = 0x16;
1085#ifdef RT2870
1086 // set to BW20
1087 RT30xxReadRFRegister(pAd, RF_R31, &value);
1088 value &= (~0x20);
1089 RT30xxWriteRFRegister(pAd, RF_R31, value);
1090#endif
1091 }
1092
1093 // Write 0x01 to RF_R22 to enable baseband loopback mode
1094 RT30xxReadRFRegister(pAd, RF_R22, &value);
1095 value |= 0x01;
1096 RT30xxWriteRFRegister(pAd, RF_R22, value);
1097
1098 // Write 0x00 to BBP_R24 to set power & frequency of passband test tone
1099 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0);
1100
1101 do
1102 {
1103 // Write 0x90 to BBP_R25 to transmit test tone
1104 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R25, 0x90);
1105
1106 RTMPusecDelay(1000);
1107 // Read BBP_R55[6:0] for received power, set R55x = BBP_R55[6:0]
1108 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R55, &value);
1109 R55x = value & 0xFF;
1110
1111 } while ((ReTry++ < 100) && (R55x == 0));
1112
1113 // Write 0x06 to BBP_R24 to set power & frequency of stopband test tone
1114 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0x06);
1115
1116 while(TRUE)
1117 {
1118 // Write 0x90 to BBP_R25 to transmit test tone
1119 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R25, 0x90);
1120
1121 //We need to wait for calibration
1122 RTMPusecDelay(1000);
1123 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R55, &value);
1124 value &= 0xFF;
1125 if ((R55x - value) < FilterTarget)
1126 {
1127 RF_R24_Value ++;
1128 }
1129 else if ((R55x - value) == FilterTarget)
1130 {
1131 RF_R24_Value ++;
1132 count ++;
1133 }
1134 else
1135 {
1136 break;
1137 }
1138
1139 // prevent infinite loop cause driver hang.
1140 if (loopcnt++ > 100)
1141 {
1142 DBGPRINT(RT_DEBUG_ERROR, ("RTMPFilterCalibration - can't find a valid value, loopcnt=%d stop calibrating", loopcnt));
1143 break;
1144 }
1145
1146 // Write RF_R24 to program filter
1147 RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
1148 }
1149
1150 if (count > 0)
1151 {
1152 RF_R24_Value = RF_R24_Value - ((count) ? (1) : (0));
1153 }
1154
1155 // Store for future usage
1156 if (loopcnt < 100)
1157 {
1158 if (loop++ == 0)
1159 {
1160 //BandWidth = 20 MHz
1161 pAd->Mlme.CaliBW20RfR24 = (UCHAR)RF_R24_Value;
1162 }
1163 else
1164 {
1165 //BandWidth = 40 MHz
1166 pAd->Mlme.CaliBW40RfR24 = (UCHAR)RF_R24_Value;
1167 break;
1168 }
1169 }
1170 else
1171 break;
1172
1173 RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
1174
1175 // reset count
1176 count = 0;
1177 } while(TRUE);
1178
1179 //
1180 // Set back to initial state
1181 //
1182 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0);
1183
1184 RT30xxReadRFRegister(pAd, RF_R22, &value);
1185 value &= ~(0x01);
1186 RT30xxWriteRFRegister(pAd, RF_R22, value);
1187
1188 // set BBP back to BW20
1189 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
1190 BBPValue&= (~0x18);
1191 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
1192
1193 DBGPRINT(RT_DEBUG_TRACE, ("RTMPFilterCalibration - CaliBW20RfR24=0x%x, CaliBW40RfR24=0x%x\n", pAd->Mlme.CaliBW20RfR24, pAd->Mlme.CaliBW40RfR24));
1194}
1195
1196VOID NICInitRT30xxRFRegisters(IN PRTMP_ADAPTER pAd)
1197{
1198 INT i;
1199 // Driver must read EEPROM to get RfIcType before initial RF registers
1200 // Initialize RF register to default value
1201 if (IS_RT3070(pAd) || IS_RT3071(pAd))
1202 {
1203 // Init RF calibration
1204 // Driver should toggle RF R30 bit7 before init RF registers
1205 UINT32 RfReg = 0;
1206 UINT32 data;
1207
1208 RT30xxReadRFRegister(pAd, RF_R30, (PUCHAR)&RfReg);
1209 RfReg |= 0x80;
1210 RT30xxWriteRFRegister(pAd, RF_R30, (UCHAR)RfReg);
1211 RTMPusecDelay(1000);
1212 RfReg &= 0x7F;
1213 RT30xxWriteRFRegister(pAd, RF_R30, (UCHAR)RfReg);
1214
1215 // Initialize RF register to default value
1216 for (i = 0; i < NUM_RF_REG_PARMS; i++)
1217 {
1218 RT30xxWriteRFRegister(pAd, RT30xx_RFRegTable[i].Register, RT30xx_RFRegTable[i].Value);
1219 }
1220
1221 if (IS_RT3070(pAd))
1222 {
1223 // Update MAC 0x05D4 from 01xxxxxx to 0Dxxxxxx (voltage 1.2V to 1.35V) for RT3070 to improve yield rate
1224 RTUSBReadMACRegister(pAd, LDO_CFG0, &data);
1225 data = ((data & 0xF0FFFFFF) | 0x0D000000);
1226 RTUSBWriteMACRegister(pAd, LDO_CFG0, data);
1227 }
1228 else if (IS_RT3071(pAd))
1229 {
1230 // Driver should set RF R6 bit6 on before init RF registers
1231 RT30xxReadRFRegister(pAd, RF_R06, (PUCHAR)&RfReg);
1232 RfReg |= 0x40;
1233 RT30xxWriteRFRegister(pAd, RF_R06, (UCHAR)RfReg);
1234
1235 // init R31
1236 RT30xxWriteRFRegister(pAd, RF_R31, 0x14);
1237
1238 // RT3071 version E has fixed this issue
1239 if ((pAd->NicConfig2.field.DACTestBit == 1) && ((pAd->MACVersion & 0xffff) < 0x0211))
1240 {
1241 // patch tx EVM issue temporarily
1242 RTUSBReadMACRegister(pAd, LDO_CFG0, &data);
1243 data = ((data & 0xE0FFFFFF) | 0x0D000000);
1244 RTUSBWriteMACRegister(pAd, LDO_CFG0, data);
1245 }
1246 else
1247 {
1248 RTMP_IO_READ32(pAd, LDO_CFG0, &data);
1249 data = ((data & 0xE0FFFFFF) | 0x01000000);
1250 RTMP_IO_WRITE32(pAd, LDO_CFG0, data);
1251 }
1252
1253 // patch LNA_PE_G1 failed issue
1254 RTUSBReadMACRegister(pAd, GPIO_SWITCH, &data);
1255 data &= ~(0x20);
1256 RTUSBWriteMACRegister(pAd, GPIO_SWITCH, data);
1257 }
1258
1259 //For RF filter Calibration
1260 RTMPFilterCalibration(pAd);
1261
1262 // Initialize RF R27 register, set RF R27 must be behind RTMPFilterCalibration()
1263 if ((pAd->MACVersion & 0xffff) < 0x0211)
1264 RT30xxWriteRFRegister(pAd, RF_R27, 0x3);
1265
1266 // set led open drain enable
1267 RTUSBReadMACRegister(pAd, OPT_14, &data);
1268 data |= 0x01;
1269 RTUSBWriteMACRegister(pAd, OPT_14, data);
1270
1271 if (IS_RT3071(pAd))
1272 {
1273 // add by johnli, RF power sequence setup, load RF normal operation-mode setup
1274 RT30xxLoadRFNormalModeSetup(pAd);
1275 }
1276 }
1277}
1278#endif // RT2870 //
1279
1280
1281/* 660/*
1282 ======================================================================== 661 ========================================================================
1283 662
@@ -1310,6 +689,18 @@ VOID NICReadEEPROMParameters(
1310 689
1311 DBGPRINT(RT_DEBUG_TRACE, ("--> NICReadEEPROMParameters\n")); 690 DBGPRINT(RT_DEBUG_TRACE, ("--> NICReadEEPROMParameters\n"));
1312 691
692 if (pAd->chipOps.eeinit)
693 pAd->chipOps.eeinit(pAd);
694#ifdef RTMP_EFUSE_SUPPORT
695#ifdef RT30xx
696 if(!pAd->bFroceEEPROMBuffer && pAd->bEEPROMFile)
697 {
698 DBGPRINT(RT_DEBUG_TRACE, ("--> NICReadEEPROMParameters::(Efuse)Load to EEPROM Buffer Mode\n"));
699 eFuseLoadEEPROM(pAd);
700 }
701#endif // RT30xx //
702#endif // RTMP_EFUSE_SUPPORT //
703
1313 // Init EEPROM Address Number, before access EEPROM; if 93c46, EEPROMAddressNum=6, else if 93c66, EEPROMAddressNum=8 704 // Init EEPROM Address Number, before access EEPROM; if 93c46, EEPROMAddressNum=6, else if 93c66, EEPROMAddressNum=8
1314 RTMP_IO_READ32(pAd, E2PROM_CSR, &data); 705 RTMP_IO_READ32(pAd, E2PROM_CSR, &data);
1315 DBGPRINT(RT_DEBUG_TRACE, ("--> E2PROM_CSR = 0x%x\n", data)); 706 DBGPRINT(RT_DEBUG_TRACE, ("--> E2PROM_CSR = 0x%x\n", data));
@@ -1325,7 +716,7 @@ VOID NICReadEEPROMParameters(
1325 // RT2860 MAC no longer auto load MAC address from E2PROM. Driver has to intialize 716 // RT2860 MAC no longer auto load MAC address from E2PROM. Driver has to intialize
1326 // MAC address registers according to E2PROM setting 717 // MAC address registers according to E2PROM setting
1327 if (mac_addr == NULL || 718 if (mac_addr == NULL ||
1328 strlen(mac_addr) != 17 || 719 strlen((PSTRING) mac_addr) != 17 ||
1329 mac_addr[2] != ':' || mac_addr[5] != ':' || mac_addr[8] != ':' || 720 mac_addr[2] != ':' || mac_addr[5] != ':' || mac_addr[8] != ':' ||
1330 mac_addr[11] != ':' || mac_addr[14] != ':') 721 mac_addr[11] != ':' || mac_addr[14] != ':')
1331 { 722 {
@@ -1347,9 +738,9 @@ VOID NICReadEEPROMParameters(
1347 else 738 else
1348 { 739 {
1349 INT j; 740 INT j;
1350 PUCHAR macptr; 741 PSTRING macptr;
1351 742
1352 macptr = mac_addr; 743 macptr = (PSTRING) mac_addr;
1353 744
1354 for (j=0; j<MAC_ADDR_LEN; j++) 745 for (j=0; j<MAC_ADDR_LEN; j++)
1355 { 746 {
@@ -1389,9 +780,7 @@ VOID NICReadEEPROMParameters(
1389 csr3.field.U2MeMask = 0xff; 780 csr3.field.U2MeMask = 0xff;
1390 RTMP_IO_WRITE32(pAd, MAC_ADDR_DW1, csr3.word); 781 RTMP_IO_WRITE32(pAd, MAC_ADDR_DW1, csr3.word);
1391 DBGPRINT_RAW(RT_DEBUG_TRACE,("E2PROM MAC: =%02x:%02x:%02x:%02x:%02x:%02x\n", 782 DBGPRINT_RAW(RT_DEBUG_TRACE,("E2PROM MAC: =%02x:%02x:%02x:%02x:%02x:%02x\n",
1392 pAd->PermanentAddress[0], pAd->PermanentAddress[1], 783 PRINT_MAC(pAd->PermanentAddress)));
1393 pAd->PermanentAddress[2], pAd->PermanentAddress[3],
1394 pAd->PermanentAddress[4], pAd->PermanentAddress[5]));
1395 } 784 }
1396 } 785 }
1397 786
@@ -1450,7 +839,8 @@ VOID NICReadEEPROMParameters(
1450 Antenna.word = pAd->EEPROMDefaultValue[0]; 839 Antenna.word = pAd->EEPROMDefaultValue[0];
1451 if (Antenna.word == 0xFFFF) 840 if (Antenna.word == 0xFFFF)
1452 { 841 {
1453 if(IS_RT3090(pAd)) 842#ifdef RT30xx
843 if(IS_RT3090(pAd)|| IS_RT3390(pAd))
1454 { 844 {
1455 Antenna.word = 0; 845 Antenna.word = 0;
1456 Antenna.field.RfIcType = RFIC_3020; 846 Antenna.field.RfIcType = RFIC_3020;
@@ -1458,7 +848,9 @@ VOID NICReadEEPROMParameters(
1458 Antenna.field.RxPath = 1; 848 Antenna.field.RxPath = 1;
1459 } 849 }
1460 else 850 else
851#endif // RT30xx //
1461 { 852 {
853
1462 Antenna.word = 0; 854 Antenna.word = 0;
1463 Antenna.field.RfIcType = RFIC_2820; 855 Antenna.field.RfIcType = RFIC_2820;
1464 Antenna.field.TxPath = 1; 856 Antenna.field.TxPath = 1;
@@ -1514,11 +906,26 @@ VOID NICReadEEPROMParameters(
1514 // Save the antenna for future use 906 // Save the antenna for future use
1515 pAd->Antenna.word = Antenna.word; 907 pAd->Antenna.word = Antenna.word;
1516 908
909 // Set the RfICType here, then we can initialize RFIC related operation callbacks
910 pAd->Mlme.RealRxPath = (UCHAR) Antenna.field.RxPath;
911 pAd->RfIcType = (UCHAR) Antenna.field.RfIcType;
912
913#ifdef RTMP_RF_RW_SUPPORT
914 RtmpChipOpsRFHook(pAd);
915#endif // RTMP_RF_RW_SUPPORT //
916
917#ifdef RTMP_MAC_PCI
918 sprintf((PSTRING) pAd->nickname, "RT2860STA");
919#endif // RTMP_MAC_PCI //
920
921
1517 // 922 //
1518 // Reset PhyMode if we don't support 802.11a 923 // Reset PhyMode if we don't support 802.11a
1519 // Only RFIC_2850 & RFIC_2750 support 802.11a 924 // Only RFIC_2850 & RFIC_2750 support 802.11a
1520 // 925 //
1521 if ((Antenna.field.RfIcType != RFIC_2850) && (Antenna.field.RfIcType != RFIC_2750)) 926 if ((Antenna.field.RfIcType != RFIC_2850)
927 && (Antenna.field.RfIcType != RFIC_2750)
928 && (Antenna.field.RfIcType != RFIC_3052))
1522 { 929 {
1523 if ((pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED) || 930 if ((pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED) ||
1524 (pAd->CommonCfg.PhyMode == PHY_11A)) 931 (pAd->CommonCfg.PhyMode == PHY_11A))
@@ -1671,11 +1078,31 @@ VOID NICReadEEPROMParameters(
1671 if ((pAd->ARssiOffset2 < -10) || (pAd->ARssiOffset2 > 10)) 1078 if ((pAd->ARssiOffset2 < -10) || (pAd->ARssiOffset2 > 10))
1672 pAd->ARssiOffset2 = 0; 1079 pAd->ARssiOffset2 = 0;
1673 1080
1081#ifdef RT30xx
1082 //
1083 // Get TX mixer gain setting
1084 // 0xff are invalid value
1085 // Note: RT30xX default value is 0x00 and will program to RF_R17 only when this value is not zero.
1086 // RT359X default value is 0x02
1087 //
1088 if (IS_RT30xx(pAd) || IS_RT3572(pAd))
1089 {
1090 RT28xx_EEPROM_READ16(pAd, EEPROM_TXMIXER_GAIN_2_4G, value);
1091 pAd->TxMixerGain24G = 0;
1092 value &= 0x00ff;
1093 if (value != 0xff)
1094 {
1095 value &= 0x07;
1096 pAd->TxMixerGain24G = (UCHAR)value;
1097 }
1098 }
1099#endif // RT30xx //
1100
1674 // 1101 //
1675 // Get LED Setting. 1102 // Get LED Setting.
1676 // 1103 //
1677 RT28xx_EEPROM_READ16(pAd, 0x3a, value); 1104 RT28xx_EEPROM_READ16(pAd, 0x3a, value);
1678 pAd->LedCntl.word = (value&0xff00) >> 8; 1105 pAd->LedCntl.word = (value>>8);
1679 RT28xx_EEPROM_READ16(pAd, EEPROM_LED1_OFFSET, value); 1106 RT28xx_EEPROM_READ16(pAd, EEPROM_LED1_OFFSET, value);
1680 pAd->Led1 = value; 1107 pAd->Led1 = value;
1681 RT28xx_EEPROM_READ16(pAd, EEPROM_LED2_OFFSET, value); 1108 RT28xx_EEPROM_READ16(pAd, EEPROM_LED2_OFFSET, value);
@@ -1685,6 +1112,12 @@ VOID NICReadEEPROMParameters(
1685 1112
1686 RTMPReadTxPwrPerRate(pAd); 1113 RTMPReadTxPwrPerRate(pAd);
1687 1114
1115#ifdef RT30xx
1116#ifdef RTMP_EFUSE_SUPPORT
1117 RtmpEfuseSupportCheck(pAd);
1118#endif // RTMP_EFUSE_SUPPORT //
1119#endif // RT30xx //
1120
1688 DBGPRINT(RT_DEBUG_TRACE, ("<-- NICReadEEPROMParameters\n")); 1121 DBGPRINT(RT_DEBUG_TRACE, ("<-- NICReadEEPROMParameters\n"));
1689} 1122}
1690 1123
@@ -1712,7 +1145,7 @@ VOID NICInitAsicFromEEPROM(
1712 UINT32 data = 0; 1145 UINT32 data = 0;
1713 UCHAR BBPR1 = 0; 1146 UCHAR BBPR1 = 0;
1714 USHORT i; 1147 USHORT i;
1715 EEPROM_ANTENNA_STRUC Antenna; 1148// EEPROM_ANTENNA_STRUC Antenna;
1716 EEPROM_NIC_CONFIG2_STRUC NicConfig2; 1149 EEPROM_NIC_CONFIG2_STRUC NicConfig2;
1717 UCHAR BBPR3 = 0; 1150 UCHAR BBPR3 = 0;
1718 1151
@@ -1729,28 +1162,9 @@ VOID NICInitAsicFromEEPROM(
1729 } 1162 }
1730 } 1163 }
1731 1164
1732#ifndef RT2870
1733 Antenna.word = pAd->Antenna.word;
1734#else
1735 Antenna.word = pAd->EEPROMDefaultValue[0];
1736 if (Antenna.word == 0xFFFF)
1737 {
1738 DBGPRINT(RT_DEBUG_ERROR, ("E2PROM error, hard code as 0x%04x\n", Antenna.word));
1739 BUG_ON(Antenna.word == 0xFFFF);
1740 }
1741#endif
1742 pAd->Mlme.RealRxPath = (UCHAR) Antenna.field.RxPath;
1743 pAd->RfIcType = (UCHAR) Antenna.field.RfIcType;
1744
1745#ifdef RT2870
1746 DBGPRINT(RT_DEBUG_WARN, ("pAd->RfIcType = %d, RealRxPath=%d, TxPath = %d\n", pAd->RfIcType, pAd->Mlme.RealRxPath,Antenna.field.TxPath));
1747 1165
1748 // Save the antenna for future use
1749 pAd->Antenna.word = Antenna.word;
1750#endif
1751 NicConfig2.word = pAd->EEPROMDefaultValue[1]; 1166 NicConfig2.word = pAd->EEPROMDefaultValue[1];
1752 1167
1753#ifdef RT2870
1754 { 1168 {
1755 if ((NicConfig2.word & 0x00ff) == 0xff) 1169 if ((NicConfig2.word & 0x00ff) == 0xff)
1756 { 1170 {
@@ -1762,15 +1176,16 @@ VOID NICInitAsicFromEEPROM(
1762 NicConfig2.word &= 0x00ff; 1176 NicConfig2.word &= 0x00ff;
1763 } 1177 }
1764 } 1178 }
1765#endif 1179
1766 // Save the antenna for future use 1180 // Save the antenna for future use
1767 pAd->NicConfig2.word = NicConfig2.word; 1181 pAd->NicConfig2.word = NicConfig2.word;
1768 1182
1769#ifdef RT2870 1183#ifdef RT30xx
1770 // set default antenna as main 1184 // set default antenna as main
1771 if (pAd->RfIcType == RFIC_3020) 1185 if (pAd->RfIcType == RFIC_3020)
1772 AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt); 1186 AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
1773#endif 1187#endif // RT30xx //
1188
1774 // 1189 //
1775 // Send LED Setting to MCU. 1190 // Send LED Setting to MCU.
1776 // 1191 //
@@ -1779,19 +1194,21 @@ VOID NICInitAsicFromEEPROM(
1779 pAd->LedCntl.word = 0x01; 1194 pAd->LedCntl.word = 0x01;
1780 pAd->Led1 = 0x5555; 1195 pAd->Led1 = 0x5555;
1781 pAd->Led2 = 0x2221; 1196 pAd->Led2 = 0x2221;
1782#ifdef RT2860
1783 pAd->Led3 = 0xA9F8;
1784#endif
1785 1197
1786#ifdef RT2870 1198#ifdef RTMP_MAC_PCI
1199 pAd->Led3 = 0xA9F8;
1200#endif // RTMP_MAC_PCI //
1201#ifdef RTMP_MAC_USB
1787 pAd->Led3 = 0x5627; 1202 pAd->Led3 = 0x5627;
1788#endif // RT2870 // 1203#endif // RTMP_MAC_USB //
1789 } 1204 }
1790 1205
1791 AsicSendCommandToMcu(pAd, 0x52, 0xff, (UCHAR)pAd->Led1, (UCHAR)(pAd->Led1 >> 8)); 1206 AsicSendCommandToMcu(pAd, 0x52, 0xff, (UCHAR)pAd->Led1, (UCHAR)(pAd->Led1 >> 8));
1792 AsicSendCommandToMcu(pAd, 0x53, 0xff, (UCHAR)pAd->Led2, (UCHAR)(pAd->Led2 >> 8)); 1207 AsicSendCommandToMcu(pAd, 0x53, 0xff, (UCHAR)pAd->Led2, (UCHAR)(pAd->Led2 >> 8));
1793 AsicSendCommandToMcu(pAd, 0x54, 0xff, (UCHAR)pAd->Led3, (UCHAR)(pAd->Led3 >> 8)); 1208 AsicSendCommandToMcu(pAd, 0x54, 0xff, (UCHAR)pAd->Led3, (UCHAR)(pAd->Led3 >> 8));
1794 pAd->LedIndicatorStregth = 0xFF; 1209 AsicSendCommandToMcu(pAd, 0x51, 0xff, 0, pAd->LedCntl.field.Polarity);
1210
1211 pAd->LedIndicatorStrength = 0xFF;
1795 RTMPSetSignalLED(pAd, -100); // Force signal strength Led to be turned off, before link up 1212 RTMPSetSignalLED(pAd, -100); // Force signal strength Led to be turned off, before link up
1796 1213
1797 { 1214 {
@@ -1806,6 +1223,7 @@ VOID NICInitAsicFromEEPROM(
1806 { 1223 {
1807 pAd->StaCfg.bHwRadio = FALSE; 1224 pAd->StaCfg.bHwRadio = FALSE;
1808 pAd->StaCfg.bRadio = FALSE; 1225 pAd->StaCfg.bRadio = FALSE;
1226// RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0x00001818);
1809 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF); 1227 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
1810 } 1228 }
1811 } 1229 }
@@ -1819,26 +1237,29 @@ VOID NICInitAsicFromEEPROM(
1819 else 1237 else
1820 { 1238 {
1821 RTMPSetLED(pAd, LED_RADIO_ON); 1239 RTMPSetLED(pAd, LED_RADIO_ON);
1822#ifdef RT2860 1240#ifdef RTMP_MAC_PCI
1823 AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02); 1241 AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02);
1824 AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00, 0x00); 1242 AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00, 0x00);
1825 // 2-1. wait command ok. 1243 // 2-1. wait command ok.
1826 AsicCheckCommanOk(pAd, PowerWakeCID); 1244 AsicCheckCommanOk(pAd, PowerWakeCID);
1827#endif 1245#endif // RTMP_MAC_PCI //
1828 } 1246 }
1829 } 1247 }
1830 1248
1831 // Turn off patching for cardbus controller 1249 // Turn off patching for cardbus controller
1832 if (NicConfig2.field.CardbusAcceleration == 1) 1250 if (NicConfig2.field.CardbusAcceleration == 1)
1833 { 1251 {
1252// pAd->bTest1 = TRUE;
1834 } 1253 }
1835 1254
1836 if (NicConfig2.field.DynamicTxAgcControl == 1) 1255 if (NicConfig2.field.DynamicTxAgcControl == 1)
1837 pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = TRUE; 1256 pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = TRUE;
1838 else 1257 else
1839 pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = FALSE; 1258 pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = FALSE;
1840 1259 //
1841 /* BBP has been programmed so reset to UNKNOWN_BAND */ 1260 // Since BBP has been progamed, to make sure BBP setting will be
1261 // upate inside of AsicAntennaSelect, so reset to UNKNOWN_BAND!!
1262 //
1842 pAd->CommonCfg.BandState = UNKNOWN_BAND; 1263 pAd->CommonCfg.BandState = UNKNOWN_BAND;
1843 1264
1844 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPR3); 1265 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPR3);
@@ -1866,10 +1287,53 @@ VOID NICInitAsicFromEEPROM(
1866 } 1287 }
1867 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BBPR1); 1288 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BBPR1);
1868 1289
1869 DBGPRINT(RT_DEBUG_TRACE, ("Use Hw Radio Control Pin=%d; if used Pin=%d;\n", pAd->CommonCfg.bHardwareRadio, pAd->CommonCfg.bHardwareRadio)); 1290 DBGPRINT(RT_DEBUG_TRACE, ("Use Hw Radio Control Pin=%d; if used Pin=%d;\n",
1291 pAd->CommonCfg.bHardwareRadio, pAd->CommonCfg.bHardwareRadio));
1870 } 1292 }
1871 1293
1872 DBGPRINT(RT_DEBUG_TRACE, ("TxPath = %d, RxPath = %d, RFIC=%d, Polar+LED mode=%x\n", pAd->Antenna.field.TxPath, pAd->Antenna.field.RxPath, pAd->RfIcType, pAd->LedCntl.word)); 1294#ifdef RTMP_MAC_USB
1295#ifdef RT30xx
1296 // update registers from EEPROM for RT3071 or later(3572/3592).
1297
1298 if (IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
1299 {
1300 UCHAR RegIdx, RegValue;
1301 USHORT value;
1302
1303 // after RT3071, write BBP from EEPROM 0xF0 to 0x102
1304 for (i = 0xF0; i <= 0x102; i = i+2)
1305 {
1306 value = 0xFFFF;
1307 RT28xx_EEPROM_READ16(pAd, i, value);
1308 if ((value != 0xFFFF) && (value != 0))
1309 {
1310 RegIdx = (UCHAR)(value >> 8);
1311 RegValue = (UCHAR)(value & 0xff);
1312 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, RegIdx, RegValue);
1313 DBGPRINT(RT_DEBUG_TRACE, ("Update BBP Registers from EEPROM(0x%0x), BBP(0x%x) = 0x%x\n", i, RegIdx, RegValue));
1314 }
1315 }
1316
1317 // after RT3071, write RF from EEPROM 0x104 to 0x116
1318 for (i = 0x104; i <= 0x116; i = i+2)
1319 {
1320 value = 0xFFFF;
1321 RT28xx_EEPROM_READ16(pAd, i, value);
1322 if ((value != 0xFFFF) && (value != 0))
1323 {
1324 RegIdx = (UCHAR)(value >> 8);
1325 RegValue = (UCHAR)(value & 0xff);
1326 RT30xxWriteRFRegister(pAd, RegIdx, RegValue);
1327 DBGPRINT(RT_DEBUG_TRACE, ("Update RF Registers from EEPROM0x%x), BBP(0x%x) = 0x%x\n", i, RegIdx, RegValue));
1328 }
1329 }
1330 }
1331#endif // RT30xx //
1332#endif // RTMP_MAC_USB //
1333
1334 DBGPRINT(RT_DEBUG_TRACE, ("TxPath = %d, RxPath = %d, RFIC=%d, Polar+LED mode=%x\n",
1335 pAd->Antenna.field.TxPath, pAd->Antenna.field.RxPath,
1336 pAd->RfIcType, pAd->LedCntl.word));
1873 DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitAsicFromEEPROM\n")); 1337 DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitAsicFromEEPROM\n"));
1874} 1338}
1875 1339
@@ -1897,10 +1361,11 @@ NDIS_STATUS NICInitializeAdapter(
1897{ 1361{
1898 NDIS_STATUS Status = NDIS_STATUS_SUCCESS; 1362 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
1899 WPDMA_GLO_CFG_STRUC GloCfg; 1363 WPDMA_GLO_CFG_STRUC GloCfg;
1900#ifdef RT2860 1364#ifdef RTMP_MAC_PCI
1901 UINT32 Value; 1365 UINT32 Value;
1902 DELAY_INT_CFG_STRUC IntCfg; 1366 DELAY_INT_CFG_STRUC IntCfg;
1903#endif 1367#endif // RTMP_MAC_PCI //
1368// INT_MASK_CSR_STRUC IntMask;
1904 ULONG i =0, j=0; 1369 ULONG i =0, j=0;
1905 AC_TXOP_CSR0_STRUC csr0; 1370 AC_TXOP_CSR0_STRUC csr0;
1906 1371
@@ -1939,11 +1404,11 @@ retry:
1939 1404
1940 // asic simulation sequence put this ahead before loading firmware. 1405 // asic simulation sequence put this ahead before loading firmware.
1941 // pbf hardware reset 1406 // pbf hardware reset
1942#ifdef RT2860 1407#ifdef RTMP_MAC_PCI
1943 RTMP_IO_WRITE32(pAd, WPDMA_RST_IDX, 0x1003f); // 0x10000 for reset rx, 0x3f resets all 6 tx rings. 1408 RTMP_IO_WRITE32(pAd, WPDMA_RST_IDX, 0x1003f); // 0x10000 for reset rx, 0x3f resets all 6 tx rings.
1944 RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0xe1f); 1409 RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0xe1f);
1945 RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0xe00); 1410 RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0xe00);
1946#endif 1411#endif // RTMP_MAC_PCI //
1947 1412
1948 // Initialze ASIC for TX & Rx operation 1413 // Initialze ASIC for TX & Rx operation
1949 if (NICInitializeAsic(pAd , bHardReset) != NDIS_STATUS_SUCCESS) 1414 if (NICInitializeAsic(pAd , bHardReset) != NDIS_STATUS_SUCCESS)
@@ -1957,7 +1422,7 @@ retry:
1957 } 1422 }
1958 1423
1959 1424
1960#ifdef RT2860 1425#ifdef RTMP_MAC_PCI
1961 // Write AC_BK base address register 1426 // Write AC_BK base address register
1962 Value = RTMP_GetPhysicalAddressLow(pAd->TxRing[QID_AC_BK].Cell[0].AllocPa); 1427 Value = RTMP_GetPhysicalAddressLow(pAd->TxRing[QID_AC_BK].Cell[0].AllocPa);
1963 RTMP_IO_WRITE32(pAd, TX_BASE_PTR1, Value); 1428 RTMP_IO_WRITE32(pAd, TX_BASE_PTR1, Value);
@@ -2030,7 +1495,7 @@ retry:
2030 // Write RX_RING_CSR register 1495 // Write RX_RING_CSR register
2031 Value = RX_RING_SIZE; 1496 Value = RX_RING_SIZE;
2032 RTMP_IO_WRITE32(pAd, RX_MAX_CNT, Value); 1497 RTMP_IO_WRITE32(pAd, RX_MAX_CNT, Value);
2033#endif /* RT2860 */ 1498#endif // RTMP_MAC_PCI //
2034 1499
2035 1500
2036 // WMM parameter 1501 // WMM parameter
@@ -2049,7 +1514,7 @@ retry:
2049 RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr0.word); 1514 RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr0.word);
2050 1515
2051 1516
2052#ifdef RT2860 1517#ifdef RTMP_MAC_PCI
2053 // 3. Set DMA global configuration except TX_DMA_EN and RX_DMA_EN bits: 1518 // 3. Set DMA global configuration except TX_DMA_EN and RX_DMA_EN bits:
2054 i = 0; 1519 i = 0;
2055 do 1520 do
@@ -2068,7 +1533,7 @@ retry:
2068 1533
2069 IntCfg.word = 0; 1534 IntCfg.word = 0;
2070 RTMP_IO_WRITE32(pAd, DELAY_INT_CFG, IntCfg.word); 1535 RTMP_IO_WRITE32(pAd, DELAY_INT_CFG, IntCfg.word);
2071#endif 1536#endif // RTMP_MAC_PCI //
2072 1537
2073 1538
2074 // reset action 1539 // reset action
@@ -2104,26 +1569,44 @@ NDIS_STATUS NICInitializeAsic(
2104 ULONG Index = 0; 1569 ULONG Index = 0;
2105 UCHAR R0 = 0xff; 1570 UCHAR R0 = 0xff;
2106 UINT32 MacCsr12 = 0, Counter = 0; 1571 UINT32 MacCsr12 = 0, Counter = 0;
2107#ifdef RT2870 1572#ifdef RTMP_MAC_USB
2108 UINT32 MacCsr0 = 0; 1573 UINT32 MacCsr0 = 0;
2109 NTSTATUS Status; 1574 NTSTATUS Status;
2110 UCHAR Value = 0xff; 1575 UCHAR Value = 0xff;
2111 UINT32 eFuseCtrl; 1576#endif // RTMP_MAC_USB //
2112#endif 1577#ifdef RT30xx
1578 UCHAR bbpreg=0;
1579 UCHAR RFValue=0;
1580#endif // RT30xx //
2113 USHORT KeyIdx; 1581 USHORT KeyIdx;
2114 INT i,apidx; 1582 INT i,apidx;
2115 1583
2116 DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitializeAsic\n")); 1584 DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitializeAsic\n"));
2117 1585
2118#ifdef RT2860 1586#ifdef RTMP_MAC_PCI
1587 RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0x3); // To fix driver disable/enable hang issue when radio off
2119 if (bHardReset == TRUE) 1588 if (bHardReset == TRUE)
2120 { 1589 {
2121 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x3); 1590 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x3);
2122 } 1591 }
2123 else 1592 else
2124 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x1); 1593 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x1);
2125#endif 1594
2126#ifdef RT2870 1595 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x0);
1596 // Initialize MAC register to default value
1597 for (Index = 0; Index < NUM_MAC_REG_PARMS; Index++)
1598 {
1599 RTMP_IO_WRITE32(pAd, MACRegTable[Index].Register, MACRegTable[Index].Value);
1600 }
1601
1602 {
1603 for (Index = 0; Index < NUM_STA_MAC_REG_PARMS; Index++)
1604 {
1605 RTMP_IO_WRITE32(pAd, STAMACRegTable[Index].Register, STAMACRegTable[Index].Value);
1606 }
1607 }
1608#endif // RTMP_MAC_PCI //
1609#ifdef RTMP_MAC_USB
2127 // 1610 //
2128 // Make sure MAC gets ready after NICLoadFirmware(). 1611 // Make sure MAC gets ready after NICLoadFirmware().
2129 // 1612 //
@@ -2151,44 +1634,32 @@ NDIS_STATUS NICInitializeAsic(
2151 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x3); 1634 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x3);
2152 RTMP_IO_WRITE32(pAd, USB_DMA_CFG, 0x0); 1635 RTMP_IO_WRITE32(pAd, USB_DMA_CFG, 0x0);
2153 Status = RTUSBVenderReset(pAd); 1636 Status = RTUSBVenderReset(pAd);
2154#endif
2155 1637
2156 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x0); 1638 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x0);
2157 1639
2158 // Initialize MAC register to default value 1640 // Initialize MAC register to default value
2159#ifdef RT2860
2160 for (Index = 0; Index < NUM_MAC_REG_PARMS; Index++)
2161 {
2162 RTMP_IO_WRITE32(pAd, MACRegTable[Index].Register, MACRegTable[Index].Value);
2163 }
2164#endif
2165#ifdef RT2870
2166 for(Index=0; Index<NUM_MAC_REG_PARMS; Index++) 1641 for(Index=0; Index<NUM_MAC_REG_PARMS; Index++)
2167 { 1642 {
2168#ifdef RT3070 1643#ifdef RT30xx
2169 if ((MACRegTable[Index].Register == TX_SW_CFG0) && (IS_RT3070(pAd) || IS_RT3071(pAd))) 1644 if ((MACRegTable[Index].Register == TX_SW_CFG0) && (IS_RT3070(pAd) || IS_RT3071(pAd) || IS_RT3572(pAd)))
2170 { 1645 {
2171 MACRegTable[Index].Value = 0x00000400; 1646 MACRegTable[Index].Value = 0x00000400;
2172 } 1647 }
2173#endif // RT3070 // 1648#endif // RT30xx //
2174 RTMP_IO_WRITE32(pAd, (USHORT)MACRegTable[Index].Register, MACRegTable[Index].Value); 1649 RTMP_IO_WRITE32(pAd, (USHORT)MACRegTable[Index].Register, MACRegTable[Index].Value);
2175 } 1650 }
2176#endif // RT2870 //
2177 1651
2178 { 1652 {
2179 for (Index = 0; Index < NUM_STA_MAC_REG_PARMS; Index++) 1653 for (Index = 0; Index < NUM_STA_MAC_REG_PARMS; Index++)
2180 { 1654 {
2181#ifdef RT2860
2182 RTMP_IO_WRITE32(pAd, STAMACRegTable[Index].Register, STAMACRegTable[Index].Value);
2183#endif
2184#ifdef RT2870
2185 RTMP_IO_WRITE32(pAd, (USHORT)STAMACRegTable[Index].Register, STAMACRegTable[Index].Value); 1655 RTMP_IO_WRITE32(pAd, (USHORT)STAMACRegTable[Index].Register, STAMACRegTable[Index].Value);
2186#endif
2187 } 1656 }
2188 } 1657 }
1658#endif // RTMP_MAC_USB //
2189 1659
2190 // Initialize RT3070 serial MAc registers which is different from RT2870 serial 1660#ifdef RT30xx
2191 if (IS_RT3090(pAd)) 1661 // Initialize RT3070 serial MAC registers which is different from RT2870 serial
1662 if (IS_RT3090(pAd) || IS_RT3572(pAd)||IS_RT3390(pAd))
2192 { 1663 {
2193 RTMP_IO_WRITE32(pAd, TX_SW_CFG1, 0); 1664 RTMP_IO_WRITE32(pAd, TX_SW_CFG1, 0);
2194 1665
@@ -2197,7 +1668,7 @@ NDIS_STATUS NICInitializeAsic(
2197 { 1668 {
2198 if (pAd->NicConfig2.field.DACTestBit == 1) 1669 if (pAd->NicConfig2.field.DACTestBit == 1)
2199 { 1670 {
2200 RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x1F); // To fix throughput drop drastically 1671 RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x2C); // To fix throughput drop drastically
2201 } 1672 }
2202 else 1673 else
2203 { 1674 {
@@ -2209,11 +1680,17 @@ NDIS_STATUS NICInitializeAsic(
2209 RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x0); 1680 RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x0);
2210 } 1681 }
2211 } 1682 }
2212#ifdef RT2870
2213 else if (IS_RT3070(pAd)) 1683 else if (IS_RT3070(pAd))
2214 { 1684 {
1685 if (((pAd->MACVersion & 0xffff) < 0x0201))
1686 {
2215 RTMP_IO_WRITE32(pAd, TX_SW_CFG1, 0); 1687 RTMP_IO_WRITE32(pAd, TX_SW_CFG1, 0);
2216 RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x1F); // To fix throughput drop drastically 1688 RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x2C); // To fix throughput drop drastically
1689 }
1690 else
1691 {
1692 RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0);
1693 }
2217 } 1694 }
2218#endif // RT30xx // 1695#endif // RT30xx //
2219 1696
@@ -2256,28 +1733,42 @@ NDIS_STATUS NICInitializeAsic(
2256 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBPRegTable[Index].Register, BBPRegTable[Index].Value); 1733 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBPRegTable[Index].Register, BBPRegTable[Index].Value);
2257 } 1734 }
2258 1735
2259#ifndef RT2870 1736#ifdef RTMP_MAC_PCI
2260 // for rt2860E and after, init BBP_R84 with 0x19. This is for extension channel overlapping IOT. 1737 // TODO: shiang, check MACVersion, currently, rbus-based chip use this.
2261 if ((pAd->MACVersion&0xffff) != 0x0101) 1738 if (pAd->MACVersion == 0x28720200)
2262 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R84, 0x19); 1739 {
2263#else 1740 //UCHAR value;
1741 ULONG value2;
1742
1743 //disable MLD by Bruce 20080704
1744 //BBP_IO_READ8_BY_REG_ID(pAd, BBP_R105, &value);
1745 //BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R105, value | 4);
1746
1747 //Maximum PSDU length from 16K to 32K bytes
1748 RTMP_IO_READ32(pAd, MAX_LEN_CFG, &value2);
1749 value2 &= ~(0x3<<12);
1750 value2 |= (0x2<<12);
1751 RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, value2);
1752 }
1753#endif // RTMP_MAC_PCI //
1754
2264 // for rt2860E and after, init BBP_R84 with 0x19. This is for extension channel overlapping IOT. 1755 // for rt2860E and after, init BBP_R84 with 0x19. This is for extension channel overlapping IOT.
2265 // RT3090 should not program BBP R84 to 0x19, otherwise TX will block. 1756 // RT3090 should not program BBP R84 to 0x19, otherwise TX will block.
2266 if (((pAd->MACVersion&0xffff) != 0x0101) && (!IS_RT30xx(pAd))) 1757 //3070/71/72,3090,3090A( are included in RT30xx),3572,3390
1758 if (((pAd->MACVersion & 0xffff) != 0x0101) && !(IS_RT30xx(pAd)|| IS_RT3572(pAd) || IS_RT3390(pAd)))
2267 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R84, 0x19); 1759 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R84, 0x19);
2268 1760
1761#ifdef RT30xx
2269// add by johnli, RF power sequence setup 1762// add by johnli, RF power sequence setup
2270 if (IS_RT30xx(pAd)) 1763 if (IS_RT30xx(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
2271 { //update for RT3070/71/72/90/91/92. 1764 { //update for RT3070/71/72/90/91/92,3572,3390.
2272 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R79, 0x13); 1765 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R79, 0x13);
2273 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R80, 0x05); 1766 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R80, 0x05);
2274 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R81, 0x33); 1767 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R81, 0x33);
2275 } 1768 }
2276 1769
2277 if (IS_RT3090(pAd)) 1770 if (IS_RT3090(pAd)||IS_RT3390(pAd)) // RT309x, RT3071/72
2278 { 1771 {
2279 UCHAR bbpreg=0;
2280
2281 // enable DC filter 1772 // enable DC filter
2282 if ((pAd->MACVersion & 0xffff) >= 0x0211) 1773 if ((pAd->MACVersion & 0xffff) >= 0x0211)
2283 { 1774 {
@@ -2307,7 +1798,38 @@ NDIS_STATUS NICInitializeAsic(
2307 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R31, bbpreg); 1798 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R31, bbpreg);
2308 } 1799 }
2309 } 1800 }
2310#endif 1801 else if (IS_RT3070(pAd))
1802 {
1803 if ((pAd->MACVersion & 0xffff) >= 0x0201)
1804 {
1805 // enable DC filter
1806 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R103, 0xc0);
1807
1808 // improve power consumption in RT3070 Ver.F
1809 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R31, &bbpreg);
1810 bbpreg &= (~0x3);
1811 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R31, bbpreg);
1812 }
1813
1814 // TX_LO1_en, RF R17 register Bit 3 to 0
1815 RT30xxReadRFRegister(pAd, RF_R17, &RFValue);
1816 RFValue &= (~0x08);
1817 // to fix rx long range issue
1818 if (pAd->NicConfig2.field.ExternalLNAForG == 0)
1819 {
1820 RFValue |= 0x20;
1821 }
1822 // set RF_R17_bit[2:0] equal to EEPROM setting at 0x48h
1823 if (pAd->TxMixerGain24G >= 1)
1824 {
1825 RFValue &= (~0x7); // clean bit [2:0]
1826 RFValue |= pAd->TxMixerGain24G;
1827 }
1828 RT30xxWriteRFRegister(pAd, RF_R17, RFValue);
1829 }
1830// end johnli
1831#endif // RT30xx //
1832
2311 if (pAd->MACVersion == 0x28600100) 1833 if (pAd->MACVersion == 0x28600100)
2312 { 1834 {
2313 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16); 1835 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
@@ -2324,7 +1846,7 @@ NDIS_STATUS NICInitializeAsic(
2324 RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, csr); 1846 RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, csr);
2325 } 1847 }
2326 1848
2327#ifdef RT2870 1849#ifdef RTMP_MAC_USB
2328{ 1850{
2329 UCHAR MAC_Value[]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0,0}; 1851 UCHAR MAC_Value[]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0,0};
2330 1852
@@ -2335,7 +1857,7 @@ NDIS_STATUS NICInitializeAsic(
2335 RTUSBMultiWrite(pAd, (USHORT)(MAC_WCID_BASE + Index * 8), MAC_Value, 8); 1857 RTUSBMultiWrite(pAd, (USHORT)(MAC_WCID_BASE + Index * 8), MAC_Value, 8);
2336 } 1858 }
2337} 1859}
2338#endif // RT2870 // 1860#endif // RTMP_MAC_USB //
2339 1861
2340 // Add radio off control 1862 // Add radio off control
2341 { 1863 {
@@ -2356,7 +1878,7 @@ NDIS_STATUS NICInitializeAsic(
2356 RTMP_IO_READ32(pAd, TX_STA_CNT2, &Counter); 1878 RTMP_IO_READ32(pAd, TX_STA_CNT2, &Counter);
2357 1879
2358 // ASIC will keep garbage value after boot 1880 // ASIC will keep garbage value after boot
2359 // Clear all seared key table when initial 1881 // Clear all shared key table when initial
2360 // This routine can be ignored in radio-ON/OFF operation. 1882 // This routine can be ignored in radio-ON/OFF operation.
2361 if (bHardReset) 1883 if (bHardReset)
2362 { 1884 {
@@ -2372,6 +1894,9 @@ NDIS_STATUS NICInitializeAsic(
2372 } 1894 }
2373 } 1895 }
2374 1896
1897 // assert HOST ready bit
1898// RTMP_IO_WRITE32(pAd, MAC_CSR1, 0x0); // 2004-09-14 asked by Mark
1899// RTMP_IO_WRITE32(pAd, MAC_CSR1, 0x4);
2375 1900
2376 // It isn't necessary to clear this space when not hard reset. 1901 // It isn't necessary to clear this space when not hard reset.
2377 if (bHardReset == TRUE) 1902 if (bHardReset == TRUE)
@@ -2383,7 +1908,8 @@ NDIS_STATUS NICInitializeAsic(
2383 RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[apidx] + i, 0x00); 1908 RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[apidx] + i, 0x00);
2384 } 1909 }
2385 } 1910 }
2386#ifdef RT2870 1911
1912#ifdef RTMP_MAC_USB
2387 AsicDisableSync(pAd); 1913 AsicDisableSync(pAd);
2388 // Clear raw counters 1914 // Clear raw counters
2389 RTMP_IO_READ32(pAd, RX_STA_CNT0, &Counter); 1915 RTMP_IO_READ32(pAd, RX_STA_CNT0, &Counter);
@@ -2397,19 +1923,7 @@ NDIS_STATUS NICInitializeAsic(
2397 Counter&=0xffffff00; 1923 Counter&=0xffffff00;
2398 Counter|=0x000001e; 1924 Counter|=0x000001e;
2399 RTMP_IO_WRITE32(pAd, USB_CYC_CFG, Counter); 1925 RTMP_IO_WRITE32(pAd, USB_CYC_CFG, Counter);
2400 1926#endif // RTMP_MAC_USB //
2401 pAd->bUseEfuse=FALSE;
2402 RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrl);
2403 pAd->bUseEfuse = ( (eFuseCtrl & 0x80000000) == 0x80000000) ? 1 : 0;
2404 if(pAd->bUseEfuse)
2405 {
2406 DBGPRINT(RT_DEBUG_TRACE, ("NVM is Efuse\n"));
2407 }
2408 else
2409 {
2410 DBGPRINT(RT_DEBUG_TRACE, ("NVM is EEPROM\n"));
2411 }
2412#endif
2413 1927
2414 { 1928 {
2415 // for rt2860E and after, init TXOP_CTRL_CFG with 0x583f. This is for extension channel overlapping IOT. 1929 // for rt2860E and after, init TXOP_CTRL_CFG with 0x583f. This is for extension channel overlapping IOT.
@@ -2421,133 +1935,6 @@ NDIS_STATUS NICInitializeAsic(
2421 return NDIS_STATUS_SUCCESS; 1935 return NDIS_STATUS_SUCCESS;
2422} 1936}
2423 1937
2424
2425#ifdef RT2860
2426VOID NICRestoreBBPValue(
2427 IN PRTMP_ADAPTER pAd)
2428{
2429 UCHAR index;
2430 UCHAR Value = 0;
2431 ULONG Data;
2432
2433 DBGPRINT(RT_DEBUG_TRACE, ("---> NICRestoreBBPValue !!!!!!!!!!!!!!!!!!!!!!! \n"));
2434 // Initialize BBP register to default value (rtmp_init.c)
2435 for (index = 0; index < NUM_BBP_REG_PARMS; index++)
2436 {
2437 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBPRegTable[index].Register, BBPRegTable[index].Value);
2438 }
2439 // copy from (rtmp_init.c)
2440 if (pAd->MACVersion == 0x28600100)
2441 {
2442 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
2443 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x12);
2444 }
2445
2446 // copy from (connect.c LinkUp function)
2447 if (INFRA_ON(pAd))
2448 {
2449 // Change to AP channel
2450 if ((pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
2451 {
2452 // Must using 40MHz.
2453 pAd->CommonCfg.BBPCurrentBW = BW_40;
2454 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
2455 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
2456
2457 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
2458 Value &= (~0x18);
2459 Value |= 0x10;
2460 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
2461
2462 // RX : control channel at lower
2463 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
2464 Value &= (~0x20);
2465 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
2466 // Record BBPR3 setting, But don't keep R Antenna # information.
2467 pAd->StaCfg.BBPR3 = Value;
2468
2469 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
2470 Data &= 0xfffffffe;
2471 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
2472
2473 if (pAd->MACVersion == 0x28600100)
2474 {
2475 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
2476 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
2477 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
2478 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
2479 }
2480
2481 DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Lower LINK UP !!! Control Channel at Below. Central = %d \n", pAd->CommonCfg.CentralChannel ));
2482 }
2483 else if ((pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
2484 {
2485 // Must using 40MHz.
2486 pAd->CommonCfg.BBPCurrentBW = BW_40;
2487 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
2488 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
2489
2490 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
2491 Value &= (~0x18);
2492 Value |= 0x10;
2493 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
2494
2495 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
2496 Data |= 0x1;
2497 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
2498
2499 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
2500 Value |= (0x20);
2501 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
2502 // Record BBPR3 setting, But don't keep R Antenna # information.
2503 pAd->StaCfg.BBPR3 = Value;
2504
2505 if (pAd->MACVersion == 0x28600100)
2506 {
2507 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
2508 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
2509 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
2510 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
2511 }
2512
2513 DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Upper LINK UP !!! Control Channel at UpperCentral = %d \n", pAd->CommonCfg.CentralChannel ));
2514 }
2515 else
2516 {
2517 pAd->CommonCfg.BBPCurrentBW = BW_20;
2518 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
2519 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
2520
2521 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
2522 Value &= (~0x18);
2523 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
2524
2525 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
2526 Data &= 0xfffffffe;
2527 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
2528
2529 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
2530 Value &= (~0x20);
2531 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
2532 // Record BBPR3 setting, But don't keep R Antenna # information.
2533 pAd->StaCfg.BBPR3 = Value;
2534
2535 if (pAd->MACVersion == 0x28600100)
2536 {
2537 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
2538 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x08);
2539 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x11);
2540 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
2541 }
2542
2543 DBGPRINT(RT_DEBUG_TRACE, ("!!!20MHz LINK UP !!! \n" ));
2544 }
2545 }
2546
2547 DBGPRINT(RT_DEBUG_TRACE, ("<--- NICRestoreBBPValue !!!!!!!!!!!!!!!!!!!!!!! \n"));
2548}
2549#endif /* RT2860 */
2550
2551/* 1938/*
2552 ======================================================================== 1939 ========================================================================
2553 1940
@@ -2573,6 +1960,9 @@ VOID NICIssueReset(
2573 UINT32 Value = 0; 1960 UINT32 Value = 0;
2574 DBGPRINT(RT_DEBUG_TRACE, ("--> NICIssueReset\n")); 1961 DBGPRINT(RT_DEBUG_TRACE, ("--> NICIssueReset\n"));
2575 1962
1963 // Abort Tx, prevent ASIC from writing to Host memory
1964 //RTMP_IO_WRITE32(pAd, TX_CNTL_CSR, 0x001f0000);
1965
2576 // Disable Rx, register value supposed will remain after reset 1966 // Disable Rx, register value supposed will remain after reset
2577 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value); 1967 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
2578 Value &= (0xfffffff3); 1968 Value &= (0xfffffff3);
@@ -2644,10 +2034,6 @@ VOID NICUpdateFifoStaCounters(
2644 if (StaFifo.field.TxBF) // 3*3 2034 if (StaFifo.field.TxBF) // 3*3
2645 pEntry->TxBFCount++; 2035 pEntry->TxBFCount++;
2646 2036
2647#ifdef UAPSD_AP_SUPPORT
2648 UAPSD_SP_AUE_Handle(pAd, pEntry, StaFifo.field.TxSuccess);
2649#endif // UAPSD_AP_SUPPORT //
2650
2651 if (!StaFifo.field.TxSuccess) 2037 if (!StaFifo.field.TxSuccess)
2652 { 2038 {
2653 pEntry->FIFOCount++; 2039 pEntry->FIFOCount++;
@@ -2676,7 +2062,9 @@ VOID NICUpdateFifoStaCounters(
2676 pEntry->FIFOCount = 0; 2062 pEntry->FIFOCount = 0;
2677 pEntry->ContinueTxFailCnt = 0; 2063 pEntry->ContinueTxFailCnt = 0;
2678 } 2064 }
2065 //pEntry->FIFOCount = 0;
2679 } 2066 }
2067 //pEntry->bSendBAR = TRUE;
2680 } 2068 }
2681 else 2069 else
2682 { 2070 {
@@ -2752,7 +2140,9 @@ VOID NICUpdateFifoStaCounters(
2752VOID NICUpdateRawCounters( 2140VOID NICUpdateRawCounters(
2753 IN PRTMP_ADAPTER pAd) 2141 IN PRTMP_ADAPTER pAd)
2754{ 2142{
2755 UINT32 OldValue; 2143 UINT32 OldValue;//, Value2;
2144 //ULONG PageSum, OneSecTransmitCount;
2145 //ULONG TxErrorRatio, Retry, Fail;
2756 RX_STA_CNT0_STRUC RxStaCnt0; 2146 RX_STA_CNT0_STRUC RxStaCnt0;
2757 RX_STA_CNT1_STRUC RxStaCnt1; 2147 RX_STA_CNT1_STRUC RxStaCnt1;
2758 RX_STA_CNT2_STRUC RxStaCnt2; 2148 RX_STA_CNT2_STRUC RxStaCnt2;
@@ -2768,6 +2158,10 @@ VOID NICUpdateRawCounters(
2768 TX_AGG_CNT5_STRUC TxAggCnt5; 2158 TX_AGG_CNT5_STRUC TxAggCnt5;
2769 TX_AGG_CNT6_STRUC TxAggCnt6; 2159 TX_AGG_CNT6_STRUC TxAggCnt6;
2770 TX_AGG_CNT7_STRUC TxAggCnt7; 2160 TX_AGG_CNT7_STRUC TxAggCnt7;
2161 COUNTER_RALINK *pRalinkCounters;
2162
2163
2164 pRalinkCounters = &pAd->RalinkCounters;
2771 2165
2772 RTMP_IO_READ32(pAd, RX_STA_CNT0, &RxStaCnt0.word); 2166 RTMP_IO_READ32(pAd, RX_STA_CNT0, &RxStaCnt0.word);
2773 RTMP_IO_READ32(pAd, RX_STA_CNT2, &RxStaCnt2.word); 2167 RTMP_IO_READ32(pAd, RX_STA_CNT2, &RxStaCnt2.word);
@@ -2787,22 +2181,23 @@ VOID NICUpdateRawCounters(
2787 pAd->WlanCounters.FCSErrorCount.u.HighPart++; 2181 pAd->WlanCounters.FCSErrorCount.u.HighPart++;
2788 2182
2789 // Add FCS error count to private counters 2183 // Add FCS error count to private counters
2790 pAd->RalinkCounters.OneSecRxFcsErrCnt += RxStaCnt0.field.CrcErr; 2184 pRalinkCounters->OneSecRxFcsErrCnt += RxStaCnt0.field.CrcErr;
2791 OldValue = pAd->RalinkCounters.RealFcsErrCount.u.LowPart; 2185 OldValue = pRalinkCounters->RealFcsErrCount.u.LowPart;
2792 pAd->RalinkCounters.RealFcsErrCount.u.LowPart += RxStaCnt0.field.CrcErr; 2186 pRalinkCounters->RealFcsErrCount.u.LowPart += RxStaCnt0.field.CrcErr;
2793 if (pAd->RalinkCounters.RealFcsErrCount.u.LowPart < OldValue) 2187 if (pRalinkCounters->RealFcsErrCount.u.LowPart < OldValue)
2794 pAd->RalinkCounters.RealFcsErrCount.u.HighPart++; 2188 pRalinkCounters->RealFcsErrCount.u.HighPart++;
2795 2189
2796 // Update Duplicate Rcv check 2190 // Update Duplicate Rcv check
2797 pAd->RalinkCounters.DuplicateRcv += RxStaCnt2.field.RxDupliCount; 2191 pRalinkCounters->DuplicateRcv += RxStaCnt2.field.RxDupliCount;
2798 pAd->WlanCounters.FrameDuplicateCount.u.LowPart += RxStaCnt2.field.RxDupliCount; 2192 pAd->WlanCounters.FrameDuplicateCount.u.LowPart += RxStaCnt2.field.RxDupliCount;
2799 // Update RX Overflow counter 2193 // Update RX Overflow counter
2800 pAd->Counters8023.RxNoBuffer += (RxStaCnt2.field.RxFifoOverflowCount); 2194 pAd->Counters8023.RxNoBuffer += (RxStaCnt2.field.RxFifoOverflowCount);
2801 2195
2802#ifdef RT2870 2196 //pAd->RalinkCounters.RxCount = 0;
2803 if (pAd->RalinkCounters.RxCount != pAd->watchDogRxCnt) 2197#ifdef RTMP_MAC_USB
2198 if (pRalinkCounters->RxCount != pAd->watchDogRxCnt)
2804 { 2199 {
2805 pAd->watchDogRxCnt = pAd->RalinkCounters.RxCount; 2200 pAd->watchDogRxCnt = pRalinkCounters->RxCount;
2806 pAd->watchDogRxOverFlowCnt = 0; 2201 pAd->watchDogRxOverFlowCnt = 0;
2807 } 2202 }
2808 else 2203 else
@@ -2812,24 +2207,28 @@ VOID NICUpdateRawCounters(
2812 else 2207 else
2813 pAd->watchDogRxOverFlowCnt = 0; 2208 pAd->watchDogRxOverFlowCnt = 0;
2814 } 2209 }
2815#endif // RT2870 // 2210#endif // RTMP_MAC_USB //
2816 2211
2817 2212
2213 //if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED) ||
2214 // (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED) && (pAd->MacTab.Size != 1)))
2818 if (!pAd->bUpdateBcnCntDone) 2215 if (!pAd->bUpdateBcnCntDone)
2819 { 2216 {
2820 // Update BEACON sent count 2217 // Update BEACON sent count
2821 RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word); 2218 RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word);
2822 RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word); 2219 RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word);
2823 RTMP_IO_READ32(pAd, TX_STA_CNT2, &StaTx2.word); 2220 RTMP_IO_READ32(pAd, TX_STA_CNT2, &StaTx2.word);
2824 pAd->RalinkCounters.OneSecBeaconSentCnt += TxStaCnt0.field.TxBeaconCount; 2221 pRalinkCounters->OneSecBeaconSentCnt += TxStaCnt0.field.TxBeaconCount;
2825 pAd->RalinkCounters.OneSecTxRetryOkCount += StaTx1.field.TxRetransmit; 2222 pRalinkCounters->OneSecTxRetryOkCount += StaTx1.field.TxRetransmit;
2826 pAd->RalinkCounters.OneSecTxNoRetryOkCount += StaTx1.field.TxSuccess; 2223 pRalinkCounters->OneSecTxNoRetryOkCount += StaTx1.field.TxSuccess;
2827 pAd->RalinkCounters.OneSecTxFailCount += TxStaCnt0.field.TxFailCount; 2224 pRalinkCounters->OneSecTxFailCount += TxStaCnt0.field.TxFailCount;
2828 pAd->WlanCounters.TransmittedFragmentCount.u.LowPart += StaTx1.field.TxSuccess; 2225 pAd->WlanCounters.TransmittedFragmentCount.u.LowPart += StaTx1.field.TxSuccess;
2829 pAd->WlanCounters.RetryCount.u.LowPart += StaTx1.field.TxRetransmit; 2226 pAd->WlanCounters.RetryCount.u.LowPart += StaTx1.field.TxRetransmit;
2830 pAd->WlanCounters.FailedCount.u.LowPart += TxStaCnt0.field.TxFailCount; 2227 pAd->WlanCounters.FailedCount.u.LowPart += TxStaCnt0.field.TxFailCount;
2831 } 2228 }
2832 2229
2230
2231 //if (pAd->bStaFifoTest == TRUE)
2833 { 2232 {
2834 RTMP_IO_READ32(pAd, TX_AGG_CNT, &TxAggCnt.word); 2233 RTMP_IO_READ32(pAd, TX_AGG_CNT, &TxAggCnt.word);
2835 RTMP_IO_READ32(pAd, TX_AGG_CNT0, &TxAggCnt0.word); 2234 RTMP_IO_READ32(pAd, TX_AGG_CNT0, &TxAggCnt0.word);
@@ -2840,53 +2239,53 @@ VOID NICUpdateRawCounters(
2840 RTMP_IO_READ32(pAd, TX_AGG_CNT5, &TxAggCnt5.word); 2239 RTMP_IO_READ32(pAd, TX_AGG_CNT5, &TxAggCnt5.word);
2841 RTMP_IO_READ32(pAd, TX_AGG_CNT6, &TxAggCnt6.word); 2240 RTMP_IO_READ32(pAd, TX_AGG_CNT6, &TxAggCnt6.word);
2842 RTMP_IO_READ32(pAd, TX_AGG_CNT7, &TxAggCnt7.word); 2241 RTMP_IO_READ32(pAd, TX_AGG_CNT7, &TxAggCnt7.word);
2843 pAd->RalinkCounters.TxAggCount += TxAggCnt.field.AggTxCount; 2242 pRalinkCounters->TxAggCount += TxAggCnt.field.AggTxCount;
2844 pAd->RalinkCounters.TxNonAggCount += TxAggCnt.field.NonAggTxCount; 2243 pRalinkCounters->TxNonAggCount += TxAggCnt.field.NonAggTxCount;
2845 pAd->RalinkCounters.TxAgg1MPDUCount += TxAggCnt0.field.AggSize1Count; 2244 pRalinkCounters->TxAgg1MPDUCount += TxAggCnt0.field.AggSize1Count;
2846 pAd->RalinkCounters.TxAgg2MPDUCount += TxAggCnt0.field.AggSize2Count; 2245 pRalinkCounters->TxAgg2MPDUCount += TxAggCnt0.field.AggSize2Count;
2847 2246
2848 pAd->RalinkCounters.TxAgg3MPDUCount += TxAggCnt1.field.AggSize3Count; 2247 pRalinkCounters->TxAgg3MPDUCount += TxAggCnt1.field.AggSize3Count;
2849 pAd->RalinkCounters.TxAgg4MPDUCount += TxAggCnt1.field.AggSize4Count; 2248 pRalinkCounters->TxAgg4MPDUCount += TxAggCnt1.field.AggSize4Count;
2850 pAd->RalinkCounters.TxAgg5MPDUCount += TxAggCnt2.field.AggSize5Count; 2249 pRalinkCounters->TxAgg5MPDUCount += TxAggCnt2.field.AggSize5Count;
2851 pAd->RalinkCounters.TxAgg6MPDUCount += TxAggCnt2.field.AggSize6Count; 2250 pRalinkCounters->TxAgg6MPDUCount += TxAggCnt2.field.AggSize6Count;
2852 2251
2853 pAd->RalinkCounters.TxAgg7MPDUCount += TxAggCnt3.field.AggSize7Count; 2252 pRalinkCounters->TxAgg7MPDUCount += TxAggCnt3.field.AggSize7Count;
2854 pAd->RalinkCounters.TxAgg8MPDUCount += TxAggCnt3.field.AggSize8Count; 2253 pRalinkCounters->TxAgg8MPDUCount += TxAggCnt3.field.AggSize8Count;
2855 pAd->RalinkCounters.TxAgg9MPDUCount += TxAggCnt4.field.AggSize9Count; 2254 pRalinkCounters->TxAgg9MPDUCount += TxAggCnt4.field.AggSize9Count;
2856 pAd->RalinkCounters.TxAgg10MPDUCount += TxAggCnt4.field.AggSize10Count; 2255 pRalinkCounters->TxAgg10MPDUCount += TxAggCnt4.field.AggSize10Count;
2857 2256
2858 pAd->RalinkCounters.TxAgg11MPDUCount += TxAggCnt5.field.AggSize11Count; 2257 pRalinkCounters->TxAgg11MPDUCount += TxAggCnt5.field.AggSize11Count;
2859 pAd->RalinkCounters.TxAgg12MPDUCount += TxAggCnt5.field.AggSize12Count; 2258 pRalinkCounters->TxAgg12MPDUCount += TxAggCnt5.field.AggSize12Count;
2860 pAd->RalinkCounters.TxAgg13MPDUCount += TxAggCnt6.field.AggSize13Count; 2259 pRalinkCounters->TxAgg13MPDUCount += TxAggCnt6.field.AggSize13Count;
2861 pAd->RalinkCounters.TxAgg14MPDUCount += TxAggCnt6.field.AggSize14Count; 2260 pRalinkCounters->TxAgg14MPDUCount += TxAggCnt6.field.AggSize14Count;
2862 2261
2863 pAd->RalinkCounters.TxAgg15MPDUCount += TxAggCnt7.field.AggSize15Count; 2262 pRalinkCounters->TxAgg15MPDUCount += TxAggCnt7.field.AggSize15Count;
2864 pAd->RalinkCounters.TxAgg16MPDUCount += TxAggCnt7.field.AggSize16Count; 2263 pRalinkCounters->TxAgg16MPDUCount += TxAggCnt7.field.AggSize16Count;
2865 2264
2866 // Calculate the transmitted A-MPDU count 2265 // Calculate the transmitted A-MPDU count
2867 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += TxAggCnt0.field.AggSize1Count; 2266 pRalinkCounters->TransmittedAMPDUCount.u.LowPart += TxAggCnt0.field.AggSize1Count;
2868 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt0.field.AggSize2Count / 2); 2267 pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt0.field.AggSize2Count / 2);
2869 2268
2870 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt1.field.AggSize3Count / 3); 2269 pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt1.field.AggSize3Count / 3);
2871 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt1.field.AggSize4Count / 4); 2270 pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt1.field.AggSize4Count / 4);
2872 2271
2873 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt2.field.AggSize5Count / 5); 2272 pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt2.field.AggSize5Count / 5);
2874 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt2.field.AggSize6Count / 6); 2273 pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt2.field.AggSize6Count / 6);
2875 2274
2876 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt3.field.AggSize7Count / 7); 2275 pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt3.field.AggSize7Count / 7);
2877 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt3.field.AggSize8Count / 8); 2276 pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt3.field.AggSize8Count / 8);
2878 2277
2879 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt4.field.AggSize9Count / 9); 2278 pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt4.field.AggSize9Count / 9);
2880 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt4.field.AggSize10Count / 10); 2279 pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt4.field.AggSize10Count / 10);
2881 2280
2882 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt5.field.AggSize11Count / 11); 2281 pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt5.field.AggSize11Count / 11);
2883 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt5.field.AggSize12Count / 12); 2282 pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt5.field.AggSize12Count / 12);
2884 2283
2885 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt6.field.AggSize13Count / 13); 2284 pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt6.field.AggSize13Count / 13);
2886 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt6.field.AggSize14Count / 14); 2285 pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt6.field.AggSize14Count / 14);
2887 2286
2888 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt7.field.AggSize15Count / 15); 2287 pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt7.field.AggSize15Count / 15);
2889 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt7.field.AggSize16Count / 16); 2288 pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt7.field.AggSize16Count / 16);
2890 } 2289 }
2891 2290
2892 2291
@@ -2932,112 +2331,38 @@ VOID NICResetFromError(
2932 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel); 2331 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
2933} 2332}
2934 2333
2935/*
2936 ========================================================================
2937
2938 Routine Description:
2939 erase 8051 firmware image in MAC ASIC
2940
2941 Arguments:
2942 Adapter Pointer to our adapter
2943
2944 IRQL = PASSIVE_LEVEL
2945 2334
2946 ======================================================================== 2335NDIS_STATUS NICLoadFirmware(
2947*/
2948VOID NICEraseFirmware(
2949 IN PRTMP_ADAPTER pAd) 2336 IN PRTMP_ADAPTER pAd)
2950{ 2337{
2951 ULONG i; 2338 NDIS_STATUS status = NDIS_STATUS_SUCCESS;
2339 if (pAd->chipOps.loadFirmware)
2340 status = pAd->chipOps.loadFirmware(pAd);
2952 2341
2953 for(i=0; i<MAX_FIRMWARE_IMAGE_SIZE; i+=4) 2342 return status;
2954 RTMP_IO_WRITE32(pAd, FIRMWARE_IMAGE_BASE + i, 0); 2343}
2955 2344
2956}/* End of NICEraseFirmware */
2957 2345
2958/* 2346/*
2959 ======================================================================== 2347 ========================================================================
2960 2348
2961 Routine Description: 2349 Routine Description:
2962 Load 8051 firmware RT2561.BIN file into MAC ASIC 2350 erase 8051 firmware image in MAC ASIC
2963 2351
2964 Arguments: 2352 Arguments:
2965 Adapter Pointer to our adapter 2353 Adapter Pointer to our adapter
2966 2354
2967 Return Value:
2968 NDIS_STATUS_SUCCESS firmware image load ok
2969 NDIS_STATUS_FAILURE image not found
2970
2971 IRQL = PASSIVE_LEVEL 2355 IRQL = PASSIVE_LEVEL
2972 2356
2973 ======================================================================== 2357 ========================================================================
2974*/ 2358*/
2975NDIS_STATUS NICLoadFirmware( 2359VOID NICEraseFirmware(
2976 IN PRTMP_ADAPTER pAd) 2360 IN PRTMP_ADAPTER pAd)
2977{ 2361{
2978 NDIS_STATUS Status = NDIS_STATUS_SUCCESS; 2362 if (pAd->chipOps.eraseFirmware)
2979 PUCHAR pFirmwareImage; 2363 pAd->chipOps.eraseFirmware(pAd);
2980 ULONG FileLength, Index;
2981 //ULONG firm;
2982 UINT32 MacReg = 0;
2983#ifdef RT2870
2984 UINT32 Version = (pAd->MACVersion >> 16);
2985#endif // RT2870 //
2986
2987 pFirmwareImage = FirmwareImage;
2988 FileLength = sizeof(FirmwareImage);
2989#ifdef RT2870
2990 // New 8k byte firmware size for RT3071/RT3072
2991 //printk("Usb Chip\n");
2992 if (FIRMWAREIMAGE_LENGTH == FIRMWAREIMAGE_MAX_LENGTH)
2993 //The firmware image consists of two parts. One is the origianl and the other is the new.
2994 //Use Second Part
2995 {
2996 if ((Version != 0x2860) && (Version != 0x2872) && (Version != 0x3070))
2997 { // Use Firmware V2.
2998 //printk("KH:Use New Version,part2\n");
2999 pFirmwareImage = (PUCHAR)&FirmwareImage[FIRMWAREIMAGEV1_LENGTH];
3000 FileLength = FIRMWAREIMAGEV2_LENGTH;
3001 }
3002 else
3003 {
3004 //printk("KH:Use New Version,part1\n");
3005 pFirmwareImage = FirmwareImage;
3006 FileLength = FIRMWAREIMAGEV1_LENGTH;
3007 }
3008 }
3009 else
3010 {
3011 DBGPRINT(RT_DEBUG_ERROR, ("KH: bin file should be 8KB.\n"));
3012 Status = NDIS_STATUS_FAILURE;
3013 }
3014 2364
3015#endif // RT2870 // 2365}/* End of NICEraseFirmware */
3016
3017 RT28XX_WRITE_FIRMWARE(pAd, pFirmwareImage, FileLength);
3018
3019 /* check if MCU is ready */
3020 Index = 0;
3021 do
3022 {
3023 RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &MacReg);
3024
3025 if (MacReg & 0x80)
3026 break;
3027
3028 RTMPusecDelay(1000);
3029 } while (Index++ < 1000);
3030
3031 if (Index > 1000)
3032 {
3033 Status = NDIS_STATUS_FAILURE;
3034 DBGPRINT(RT_DEBUG_ERROR, ("NICLoadFirmware: MCU is not ready\n\n\n"));
3035 } /* End of if */
3036
3037 DBGPRINT(RT_DEBUG_TRACE,
3038 ("<=== %s (status=%d)\n", __func__, Status));
3039 return Status;
3040} /* End of NICLoadFirmware */
3041 2366
3042 2367
3043/* 2368/*
@@ -3067,52 +2392,6 @@ NDIS_STATUS NICLoadRateSwitchingParams(
3067 return NDIS_STATUS_SUCCESS; 2392 return NDIS_STATUS_SUCCESS;
3068} 2393}
3069 2394
3070/*
3071 ========================================================================
3072
3073 Routine Description:
3074 if pSrc1 all zero with length Length, return 0.
3075 If not all zero, return 1
3076
3077 Arguments:
3078 pSrc1
3079
3080 Return Value:
3081 1: not all zero
3082 0: all zero
3083
3084 IRQL = DISPATCH_LEVEL
3085
3086 Note:
3087
3088 ========================================================================
3089*/
3090ULONG RTMPNotAllZero(
3091 IN PVOID pSrc1,
3092 IN ULONG Length)
3093{
3094 PUCHAR pMem1;
3095 ULONG Index = 0;
3096
3097 pMem1 = (PUCHAR) pSrc1;
3098
3099 for (Index = 0; Index < Length; Index++)
3100 {
3101 if (pMem1[Index] != 0x0)
3102 {
3103 break;
3104 }
3105 }
3106
3107 if (Index == Length)
3108 {
3109 return (0);
3110 }
3111 else
3112 {
3113 return (1);
3114 }
3115}
3116 2395
3117/* 2396/*
3118 ======================================================================== 2397 ========================================================================
@@ -3194,21 +2473,6 @@ VOID RTMPZeroMemory(
3194 } 2473 }
3195} 2474}
3196 2475
3197VOID RTMPFillMemory(
3198 IN PVOID pSrc,
3199 IN ULONG Length,
3200 IN UCHAR Fill)
3201{
3202 PUCHAR pMem;
3203 ULONG Index = 0;
3204
3205 pMem = (PUCHAR) pSrc;
3206
3207 for (Index = 0; Index < Length; Index++)
3208 {
3209 pMem[Index] = Fill;
3210 }
3211}
3212 2476
3213/* 2477/*
3214 ======================================================================== 2478 ========================================================================
@@ -3279,7 +2543,7 @@ VOID UserCfgInit(
3279 // 2543 //
3280 // part I. intialize common configuration 2544 // part I. intialize common configuration
3281 // 2545 //
3282#ifdef RT2870 2546#ifdef RTMP_MAC_USB
3283 pAd->BulkOutReq = 0; 2547 pAd->BulkOutReq = 0;
3284 2548
3285 pAd->BulkOutComplete = 0; 2549 pAd->BulkOutComplete = 0;
@@ -3294,7 +2558,7 @@ VOID UserCfgInit(
3294 pAd->bUsbTxBulkAggre = 0; 2558 pAd->bUsbTxBulkAggre = 0;
3295 2559
3296 // init as unsed value to ensure driver will set to MCU once. 2560 // init as unsed value to ensure driver will set to MCU once.
3297 pAd->LedIndicatorStregth = 0xFF; 2561 pAd->LedIndicatorStrength = 0xFF;
3298 2562
3299 pAd->CommonCfg.MaxPktOneTxBulk = 2; 2563 pAd->CommonCfg.MaxPktOneTxBulk = 2;
3300 pAd->CommonCfg.TxBulkFactor = 1; 2564 pAd->CommonCfg.TxBulkFactor = 1;
@@ -3303,7 +2567,7 @@ VOID UserCfgInit(
3303 pAd->CommonCfg.TxPower = 100; //mW 2567 pAd->CommonCfg.TxPower = 100; //mW
3304 2568
3305 NdisZeroMemory(&pAd->CommonCfg.IOTestParm, sizeof(pAd->CommonCfg.IOTestParm)); 2569 NdisZeroMemory(&pAd->CommonCfg.IOTestParm, sizeof(pAd->CommonCfg.IOTestParm));
3306#endif // RT2870 // 2570#endif // RTMP_MAC_USB //
3307 2571
3308 for(key_index=0; key_index<SHARE_KEY_NUM; key_index++) 2572 for(key_index=0; key_index<SHARE_KEY_NUM; key_index++)
3309 { 2573 {
@@ -3314,19 +2578,17 @@ VOID UserCfgInit(
3314 } 2578 }
3315 } 2579 }
3316 2580
3317#ifdef RT2870
3318 pAd->EepromAccess = FALSE; 2581 pAd->EepromAccess = FALSE;
3319#endif 2582
3320 pAd->Antenna.word = 0; 2583 pAd->Antenna.word = 0;
3321 pAd->CommonCfg.BBPCurrentBW = BW_20; 2584 pAd->CommonCfg.BBPCurrentBW = BW_20;
3322 2585
3323 pAd->LedCntl.word = 0; 2586 pAd->LedCntl.word = 0;
3324#ifdef RT2860 2587#ifdef RTMP_MAC_PCI
3325 pAd->LedIndicatorStregth = 0; 2588 pAd->LedIndicatorStrength = 0;
3326 pAd->RLnkCtrlOffset = 0; 2589 pAd->RLnkCtrlOffset = 0;
3327 pAd->HostLnkCtrlOffset = 0; 2590 pAd->HostLnkCtrlOffset = 0;
3328 pAd->CheckDmaBusyCount = 0; 2591#endif // RTMP_MAC_PCI //
3329#endif
3330 2592
3331 pAd->bAutoTxAgcA = FALSE; // Default is OFF 2593 pAd->bAutoTxAgcA = FALSE; // Default is OFF
3332 pAd->bAutoTxAgcG = FALSE; // Default is OFF 2594 pAd->bAutoTxAgcG = FALSE; // Default is OFF
@@ -3355,6 +2617,10 @@ VOID UserCfgInit(
3355 pAd->CommonCfg.RadarDetect.CSPeriod = 10; 2617 pAd->CommonCfg.RadarDetect.CSPeriod = 10;
3356 pAd->CommonCfg.RadarDetect.CSCount = 0; 2618 pAd->CommonCfg.RadarDetect.CSCount = 0;
3357 pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE; 2619 pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE;
2620
2621
2622
2623
3358 pAd->CommonCfg.RadarDetect.ChMovingTime = 65; 2624 pAd->CommonCfg.RadarDetect.ChMovingTime = 65;
3359 pAd->CommonCfg.RadarDetect.LongPulseRadarTh = 3; 2625 pAd->CommonCfg.RadarDetect.LongPulseRadarTh = 3;
3360 pAd->CommonCfg.bAPSDCapable = FALSE; 2626 pAd->CommonCfg.bAPSDCapable = FALSE;
@@ -3386,10 +2652,18 @@ VOID UserCfgInit(
3386 pAd->CommonCfg.bExtChannelSwitchAnnouncement = 1; 2652 pAd->CommonCfg.bExtChannelSwitchAnnouncement = 1;
3387 pAd->CommonCfg.bHTProtect = 1; 2653 pAd->CommonCfg.bHTProtect = 1;
3388 pAd->CommonCfg.bMIMOPSEnable = TRUE; 2654 pAd->CommonCfg.bMIMOPSEnable = TRUE;
2655 //2008/11/05:KH add to support Antenna power-saving of AP<--
2656 pAd->CommonCfg.bGreenAPEnable=FALSE;
2657 //2008/11/05:KH add to support Antenna power-saving of AP-->
3389 pAd->CommonCfg.bBADecline = FALSE; 2658 pAd->CommonCfg.bBADecline = FALSE;
3390 pAd->CommonCfg.bDisableReordering = FALSE; 2659 pAd->CommonCfg.bDisableReordering = FALSE;
3391 2660
2661 if (pAd->MACVersion == 0x28720200)
2662 {
2663 pAd->CommonCfg.TxBASize = 13; //by Jerry recommend
2664 }else{
3392 pAd->CommonCfg.TxBASize = 7; 2665 pAd->CommonCfg.TxBASize = 7;
2666 }
3393 2667
3394 pAd->CommonCfg.REGBACapability.word = pAd->CommonCfg.BACapability.word; 2668 pAd->CommonCfg.REGBACapability.word = pAd->CommonCfg.BACapability.word;
3395 2669
@@ -3467,12 +2741,6 @@ VOID UserCfgInit(
3467 // Patch for Ndtest 2741 // Patch for Ndtest
3468 pAd->StaCfg.ScanCnt = 0; 2742 pAd->StaCfg.ScanCnt = 0;
3469 2743
3470 // CCX 2.0 control flag init
3471 pAd->StaCfg.CCXEnable = FALSE;
3472 pAd->StaCfg.CCXReqType = MSRN_TYPE_UNUSED;
3473 pAd->StaCfg.CCXQosECWMin = 4;
3474 pAd->StaCfg.CCXQosECWMax = 10;
3475
3476 pAd->StaCfg.bHwRadio = TRUE; // Default Hardware Radio status is On 2744 pAd->StaCfg.bHwRadio = TRUE; // Default Hardware Radio status is On
3477 pAd->StaCfg.bSwRadio = TRUE; // Default Software Radio status is On 2745 pAd->StaCfg.bSwRadio = TRUE; // Default Software Radio status is On
3478 pAd->StaCfg.bRadio = TRUE; // bHwRadio && bSwRadio 2746 pAd->StaCfg.bRadio = TRUE; // bHwRadio && bSwRadio
@@ -3484,14 +2752,31 @@ VOID UserCfgInit(
3484 2752
3485 // Save the init time as last scan time, the system should do scan after 2 seconds. 2753 // Save the init time as last scan time, the system should do scan after 2 seconds.
3486 // This patch is for driver wake up from standby mode, system will do scan right away. 2754 // This patch is for driver wake up from standby mode, system will do scan right away.
3487 pAd->StaCfg.LastScanTime = 0; 2755 NdisGetSystemUpTime(&pAd->StaCfg.LastScanTime);
2756 if (pAd->StaCfg.LastScanTime > 10 * OS_HZ)
2757 pAd->StaCfg.LastScanTime -= (10 * OS_HZ);
2758
3488 NdisZeroMemory(pAd->nickname, IW_ESSID_MAX_SIZE+1); 2759 NdisZeroMemory(pAd->nickname, IW_ESSID_MAX_SIZE+1);
3489 sprintf(pAd->nickname, "%s", STA_NIC_DEVICE_NAME); 2760#ifdef RTMP_MAC_USB
2761 sprintf((PSTRING) pAd->nickname, "RT2870STA");
2762#endif // RTMP_MAC_USB //
3490 RTMPInitTimer(pAd, &pAd->StaCfg.WpaDisassocAndBlockAssocTimer, GET_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc), pAd, FALSE); 2763 RTMPInitTimer(pAd, &pAd->StaCfg.WpaDisassocAndBlockAssocTimer, GET_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc), pAd, FALSE);
3491 pAd->StaCfg.IEEE8021X = FALSE; 2764 pAd->StaCfg.IEEE8021X = FALSE;
3492 pAd->StaCfg.IEEE8021x_required_keys = FALSE; 2765 pAd->StaCfg.IEEE8021x_required_keys = FALSE;
3493 pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_DISABLE; 2766 pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_DISABLE;
2767 pAd->StaCfg.bRSN_IE_FromWpaSupplicant = FALSE;
3494 pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_ENABLE; 2768 pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_ENABLE;
2769 pAd->StaCfg.bLostAp = FALSE;
2770
2771 NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8);
2772
2773
2774 pAd->StaCfg.bAutoConnectByBssid = FALSE;
2775 pAd->StaCfg.BeaconLostTime = BEACON_LOST_TIME;
2776 NdisZeroMemory(pAd->StaCfg.WpaPassPhrase, 64);
2777 pAd->StaCfg.WpaPassPhraseLen = 0;
2778 pAd->StaCfg.bAutoRoaming = FALSE;
2779 pAd->StaCfg.bForceTxBurst = FALSE;
3495 } 2780 }
3496 2781
3497 // Default for extra information is not valid 2782 // Default for extra information is not valid
@@ -3524,22 +2809,30 @@ VOID UserCfgInit(
3524 pAd->Bbp94 = BBPR94_DEFAULT; 2809 pAd->Bbp94 = BBPR94_DEFAULT;
3525 pAd->BbpForCCK = FALSE; 2810 pAd->BbpForCCK = FALSE;
3526 2811
2812 // Default is FALSE for test bit 1
2813 //pAd->bTest1 = FALSE;
2814
3527 // initialize MAC table and allocate spin lock 2815 // initialize MAC table and allocate spin lock
3528 NdisZeroMemory(&pAd->MacTab, sizeof(MAC_TABLE)); 2816 NdisZeroMemory(&pAd->MacTab, sizeof(MAC_TABLE));
3529 InitializeQueueHeader(&pAd->MacTab.McastPsQueue); 2817 InitializeQueueHeader(&pAd->MacTab.McastPsQueue);
3530 NdisAllocateSpinLock(&pAd->MacTabLock); 2818 NdisAllocateSpinLock(&pAd->MacTabLock);
3531 2819
2820 //RTMPInitTimer(pAd, &pAd->RECBATimer, RECBATimerTimeout, pAd, TRUE);
2821 //RTMPSetTimer(&pAd->RECBATimer, REORDER_EXEC_INTV);
2822
2823
2824
3532 pAd->CommonCfg.bWiFiTest = FALSE; 2825 pAd->CommonCfg.bWiFiTest = FALSE;
3533#ifdef RT2860 2826#ifdef RTMP_MAC_PCI
3534 pAd->bPCIclkOff = FALSE; 2827 pAd->bPCIclkOff = FALSE;
2828#endif // RTMP_MAC_PCI //
3535 2829
3536 RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP); 2830RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
3537#endif
3538 DBGPRINT(RT_DEBUG_TRACE, ("<-- UserCfgInit\n")); 2831 DBGPRINT(RT_DEBUG_TRACE, ("<-- UserCfgInit\n"));
3539} 2832}
3540 2833
3541// IRQL = PASSIVE_LEVEL 2834// IRQL = PASSIVE_LEVEL
3542UCHAR BtoH(char ch) 2835UCHAR BtoH(STRING ch)
3543{ 2836{
3544 if (ch >= '0' && ch <= '9') return (ch - '0'); // Handle numerals 2837 if (ch >= '0' && ch <= '9') return (ch - '0'); // Handle numerals
3545 if (ch >= 'A' && ch <= 'F') return (ch - 'A' + 0xA); // Handle capitol hex digits 2838 if (ch >= 'A' && ch <= 'F') return (ch - 'A' + 0xA); // Handle capitol hex digits
@@ -3564,9 +2857,9 @@ UCHAR BtoH(char ch)
3564// 2857//
3565// IRQL = PASSIVE_LEVEL 2858// IRQL = PASSIVE_LEVEL
3566 2859
3567void AtoH(char * src, UCHAR * dest, int destlen) 2860void AtoH(PSTRING src, PUCHAR dest, int destlen)
3568{ 2861{
3569 char * srcptr; 2862 PSTRING srcptr;
3570 PUCHAR destTemp; 2863 PUCHAR destTemp;
3571 2864
3572 srcptr = src; 2865 srcptr = src;
@@ -3580,24 +2873,10 @@ void AtoH(char * src, UCHAR * dest, int destlen)
3580 } 2873 }
3581} 2874}
3582 2875
3583VOID RTMPPatchMacBbpBug(
3584 IN PRTMP_ADAPTER pAd)
3585{
3586 ULONG Index;
3587 2876
3588 // Initialize BBP register to default value 2877//+++Mark by shiang, not use now, need to remove after confirm
3589 for (Index = 0; Index < NUM_BBP_REG_PARMS; Index++) 2878//---Mark by shiang, not use now, need to remove after confirm
3590 {
3591 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBPRegTable[Index].Register, (UCHAR)BBPRegTable[Index].Value);
3592 }
3593 2879
3594 // Initialize RF register to default value
3595 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
3596 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
3597
3598 // Re-init BBP register from EEPROM value
3599 NICInitAsicFromEEPROM(pAd);
3600}
3601 2880
3602/* 2881/*
3603 ======================================================================== 2882 ========================================================================
@@ -3636,9 +2915,9 @@ VOID RTMPInitTimer(
3636 pTimer->State = FALSE; 2915 pTimer->State = FALSE;
3637 pTimer->cookie = (ULONG) pData; 2916 pTimer->cookie = (ULONG) pData;
3638 2917
3639#ifdef RT2870 2918#ifdef RTMP_TIMER_TASK_SUPPORT
3640 pTimer->pAd = pAd; 2919 pTimer->pAd = pAd;
3641#endif // RT2870 // 2920#endif // RTMP_TIMER_TASK_SUPPORT //
3642 2921
3643 RTMP_OS_Init_Timer(pAd, &pTimer->TimerObj, pTimerFunc, (PVOID) pTimer); 2922 RTMP_OS_Init_Timer(pAd, &pTimer->TimerObj, pTimerFunc, (PVOID) pTimer);
3644} 2923}
@@ -3760,24 +3039,20 @@ VOID RTMPCancelTimer(
3760 { 3039 {
3761 if (pTimer->State == FALSE) 3040 if (pTimer->State == FALSE)
3762 pTimer->Repeat = FALSE; 3041 pTimer->Repeat = FALSE;
3042
3763 RTMP_OS_Del_Timer(&pTimer->TimerObj, pCancelled); 3043 RTMP_OS_Del_Timer(&pTimer->TimerObj, pCancelled);
3764 3044
3765 if (*pCancelled == TRUE) 3045 if (*pCancelled == TRUE)
3766 pTimer->State = TRUE; 3046 pTimer->State = TRUE;
3767 3047
3768#ifdef RT2870 3048#ifdef RTMP_TIMER_TASK_SUPPORT
3769 // We need to go-through the TimerQ to findout this timer handler and remove it if 3049 // We need to go-through the TimerQ to findout this timer handler and remove it if
3770 // it's still waiting for execution. 3050 // it's still waiting for execution.
3771 3051 RtmpTimerQRemove(pTimer->pAd, pTimer);
3772 RT2870_TimerQ_Remove(pTimer->pAd, pTimer); 3052#endif // RTMP_TIMER_TASK_SUPPORT //
3773#endif // RT2870 //
3774 } 3053 }
3775 else 3054 else
3776 { 3055 {
3777 //
3778 // NdisMCancelTimer just canced the timer and not mean release the timer.
3779 // And don't set the "Valid" to False. So that we can use this timer again.
3780 //
3781 DBGPRINT_ERR(("RTMPCancelTimer failed, Timer hasn't been initialize!\n")); 3056 DBGPRINT_ERR(("RTMPCancelTimer failed, Timer hasn't been initialize!\n"));
3782 } 3057 }
3783} 3058}
@@ -3816,7 +3091,7 @@ VOID RTMPSetLED(
3816 case LED_LINK_DOWN: 3091 case LED_LINK_DOWN:
3817 HighByte = 0x20; 3092 HighByte = 0x20;
3818 AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte); 3093 AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
3819 pAd->LedIndicatorStregth = 0; 3094 pAd->LedIndicatorStrength = 0;
3820 break; 3095 break;
3821 case LED_LINK_UP: 3096 case LED_LINK_UP:
3822 if (pAd->CommonCfg.Channel > 14) 3097 if (pAd->CommonCfg.Channel > 14)
@@ -3895,14 +3170,8 @@ VOID RTMPSetSignalLED(
3895{ 3170{
3896 UCHAR nLed = 0; 3171 UCHAR nLed = 0;
3897 3172
3898 // 3173 if (pAd->LedCntl.field.LedMode == LED_MODE_SIGNAL_STREGTH)
3899 // if not Signal Stregth, then do nothing.
3900 //
3901 if (pAd->LedCntl.field.LedMode != LED_MODE_SIGNAL_STREGTH)
3902 { 3174 {
3903 return;
3904 }
3905
3906 if (Dbm <= -90) 3175 if (Dbm <= -90)
3907 nLed = 0; 3176 nLed = 0;
3908 else if (Dbm <= -81) 3177 else if (Dbm <= -81)
@@ -3919,10 +3188,11 @@ VOID RTMPSetSignalLED(
3919 // 3188 //
3920 // Update Signal Stregth to firmware if changed. 3189 // Update Signal Stregth to firmware if changed.
3921 // 3190 //
3922 if (pAd->LedIndicatorStregth != nLed) 3191 if (pAd->LedIndicatorStrength != nLed)
3923 { 3192 {
3924 AsicSendCommandToMcu(pAd, 0x51, 0xff, nLed, pAd->LedCntl.field.Polarity); 3193 AsicSendCommandToMcu(pAd, 0x51, 0xff, nLed, pAd->LedCntl.field.Polarity);
3925 pAd->LedIndicatorStregth = nLed; 3194 pAd->LedIndicatorStrength = nLed;
3195 }
3926 } 3196 }
3927} 3197}
3928 3198
@@ -3947,6 +3217,10 @@ VOID RTMPSetSignalLED(
3947VOID RTMPEnableRxTx( 3217VOID RTMPEnableRxTx(
3948 IN PRTMP_ADAPTER pAd) 3218 IN PRTMP_ADAPTER pAd)
3949{ 3219{
3220// WPDMA_GLO_CFG_STRUC GloCfg;
3221// ULONG i = 0;
3222 UINT32 rx_filter_flag;
3223
3950 DBGPRINT(RT_DEBUG_TRACE, ("==> RTMPEnableRxTx\n")); 3224 DBGPRINT(RT_DEBUG_TRACE, ("==> RTMPEnableRxTx\n"));
3951 3225
3952 // Enable Rx DMA. 3226 // Enable Rx DMA.
@@ -3955,14 +3229,18 @@ VOID RTMPEnableRxTx(
3955 // enable RX of MAC block 3229 // enable RX of MAC block
3956 if (pAd->OpMode == OPMODE_AP) 3230 if (pAd->OpMode == OPMODE_AP)
3957 { 3231 {
3958 UINT32 rx_filter_flag = APNORMAL; 3232 rx_filter_flag = APNORMAL;
3959 3233
3960 3234
3961 RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, rx_filter_flag); // enable RX of DMA block 3235 RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, rx_filter_flag); // enable RX of DMA block
3962 } 3236 }
3963 else 3237 else
3964 { 3238 {
3965 RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, STANORMAL); // Staion not drop control frame will fail WiFi Certification. 3239 if (pAd->CommonCfg.PSPXlink)
3240 rx_filter_flag = PSPXLINK;
3241 else
3242 rx_filter_flag = STANORMAL; // Staion not drop control frame will fail WiFi Certification.
3243 RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, rx_filter_flag);
3966 } 3244 }
3967 3245
3968 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0xc); 3246 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0xc);
@@ -3970,3 +3248,380 @@ VOID RTMPEnableRxTx(
3970} 3248}
3971 3249
3972 3250
3251//+++Add by shiang, move from os/linux/rt_main_dev.c
3252void CfgInitHook(PRTMP_ADAPTER pAd)
3253{
3254 pAd->bBroadComHT = TRUE;
3255}
3256
3257
3258int rt28xx_init(
3259 IN PRTMP_ADAPTER pAd,
3260 IN PSTRING pDefaultMac,
3261 IN PSTRING pHostName)
3262{
3263 UINT index;
3264 UCHAR TmpPhy;
3265 NDIS_STATUS Status;
3266 UINT32 MacCsr0 = 0;
3267
3268
3269#ifdef RTMP_MAC_PCI
3270 {
3271 // If dirver doesn't wake up firmware here,
3272 // NICLoadFirmware will hang forever when interface is up again.
3273 // RT2860 PCI
3274 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) &&
3275 OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
3276 {
3277 AUTO_WAKEUP_STRUC AutoWakeupCfg;
3278 AsicForceWakeup(pAd, TRUE);
3279 AutoWakeupCfg.word = 0;
3280 RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
3281 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
3282 }
3283 }
3284#endif // RTMP_MAC_PCI //
3285
3286
3287 // reset Adapter flags
3288 RTMP_CLEAR_FLAGS(pAd);
3289
3290 // Init BssTab & ChannelInfo tabbles for auto channel select.
3291
3292 // Allocate BA Reordering memory
3293 ba_reordering_resource_init(pAd, MAX_REORDERING_MPDU_NUM);
3294
3295 // Make sure MAC gets ready.
3296 index = 0;
3297 do
3298 {
3299 RTMP_IO_READ32(pAd, MAC_CSR0, &MacCsr0);
3300 pAd->MACVersion = MacCsr0;
3301
3302 if ((pAd->MACVersion != 0x00) && (pAd->MACVersion != 0xFFFFFFFF))
3303 break;
3304
3305 RTMPusecDelay(10);
3306 } while (index++ < 100);
3307 DBGPRINT(RT_DEBUG_TRACE, ("MAC_CSR0 [ Ver:Rev=0x%08x]\n", pAd->MACVersion));
3308
3309#ifdef RTMP_MAC_PCI
3310
3311 // To fix driver disable/enable hang issue when radio off
3312 RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0x2);
3313#endif // RTMP_MAC_PCI //
3314
3315 // Disable DMA
3316 RT28XXDMADisable(pAd);
3317
3318
3319 // Load 8051 firmware
3320 Status = NICLoadFirmware(pAd);
3321 if (Status != NDIS_STATUS_SUCCESS)
3322 {
3323 DBGPRINT_ERR(("NICLoadFirmware failed, Status[=0x%08x]\n", Status));
3324 goto err1;
3325 }
3326
3327 NICLoadRateSwitchingParams(pAd);
3328
3329 // Disable interrupts here which is as soon as possible
3330 // This statement should never be true. We might consider to remove it later
3331#ifdef RTMP_MAC_PCI
3332 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE))
3333 {
3334 RTMP_ASIC_INTERRUPT_DISABLE(pAd);
3335 }
3336#endif // RTMP_MAC_PCI //
3337
3338 Status = RTMPAllocTxRxRingMemory(pAd);
3339 if (Status != NDIS_STATUS_SUCCESS)
3340 {
3341 DBGPRINT_ERR(("RTMPAllocDMAMemory failed, Status[=0x%08x]\n", Status));
3342 goto err1;
3343 }
3344
3345 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE);
3346
3347 // initialize MLME
3348 //
3349
3350 Status = RtmpMgmtTaskInit(pAd);
3351 if (Status != NDIS_STATUS_SUCCESS)
3352 goto err2;
3353
3354 Status = MlmeInit(pAd);
3355 if (Status != NDIS_STATUS_SUCCESS)
3356 {
3357 DBGPRINT_ERR(("MlmeInit failed, Status[=0x%08x]\n", Status));
3358 goto err2;
3359 }
3360
3361 // Initialize pAd->StaCfg, pAd->ApCfg, pAd->CommonCfg to manufacture default
3362 //
3363 UserCfgInit(pAd);
3364 Status = RtmpNetTaskInit(pAd);
3365 if (Status != NDIS_STATUS_SUCCESS)
3366 goto err3;
3367
3368// COPY_MAC_ADDR(pAd->ApCfg.MBSSID[apidx].Bssid, netif->hwaddr);
3369// pAd->bForcePrintTX = TRUE;
3370
3371 CfgInitHook(pAd);
3372
3373 NdisAllocateSpinLock(&pAd->MacTabLock);
3374
3375 MeasureReqTabInit(pAd);
3376 TpcReqTabInit(pAd);
3377
3378 //
3379 // Init the hardware, we need to init asic before read registry, otherwise mac register will be reset
3380 //
3381 Status = NICInitializeAdapter(pAd, TRUE);
3382 if (Status != NDIS_STATUS_SUCCESS)
3383 {
3384 DBGPRINT_ERR(("NICInitializeAdapter failed, Status[=0x%08x]\n", Status));
3385 if (Status != NDIS_STATUS_SUCCESS)
3386 goto err3;
3387 }
3388
3389 // Read parameters from Config File
3390 Status = RTMPReadParametersHook(pAd);
3391
3392 DBGPRINT(RT_DEBUG_OFF, ("1. Phy Mode = %d\n", pAd->CommonCfg.PhyMode));
3393 if (Status != NDIS_STATUS_SUCCESS)
3394 {
3395 DBGPRINT_ERR(("NICReadRegParameters failed, Status[=0x%08x]\n",Status));
3396// goto err4;
3397 Status = 0;
3398 }
3399
3400#ifdef RTMP_MAC_USB
3401 pAd->CommonCfg.bMultipleIRP = FALSE;
3402
3403 if (pAd->CommonCfg.bMultipleIRP)
3404 pAd->CommonCfg.NumOfBulkInIRP = RX_RING_SIZE;
3405 else
3406 pAd->CommonCfg.NumOfBulkInIRP = 1;
3407#endif // RTMP_MAC_USB //
3408
3409 //Init Ba Capability parameters.
3410// RT28XX_BA_INIT(pAd);
3411 pAd->CommonCfg.DesiredHtPhy.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity;
3412 pAd->CommonCfg.DesiredHtPhy.AmsduEnable = (USHORT)pAd->CommonCfg.BACapability.field.AmsduEnable;
3413 pAd->CommonCfg.DesiredHtPhy.AmsduSize = (USHORT)pAd->CommonCfg.BACapability.field.AmsduSize;
3414 pAd->CommonCfg.DesiredHtPhy.MimoPs = (USHORT)pAd->CommonCfg.BACapability.field.MMPSmode;
3415 // UPdata to HT IE
3416 pAd->CommonCfg.HtCapability.HtCapInfo.MimoPs = (USHORT)pAd->CommonCfg.BACapability.field.MMPSmode;
3417 pAd->CommonCfg.HtCapability.HtCapInfo.AMsduSize = (USHORT)pAd->CommonCfg.BACapability.field.AmsduSize;
3418 pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity;
3419
3420 // after reading Registry, we now know if in AP mode or STA mode
3421
3422 // Load 8051 firmware; crash when FW image not existent
3423 // Status = NICLoadFirmware(pAd);
3424 // if (Status != NDIS_STATUS_SUCCESS)
3425 // break;
3426
3427 DBGPRINT(RT_DEBUG_OFF, ("2. Phy Mode = %d\n", pAd->CommonCfg.PhyMode));
3428
3429 // We should read EEPROM for all cases. rt2860b
3430 NICReadEEPROMParameters(pAd, (PUCHAR)pDefaultMac);
3431
3432 DBGPRINT(RT_DEBUG_OFF, ("3. Phy Mode = %d\n", pAd->CommonCfg.PhyMode));
3433
3434 NICInitAsicFromEEPROM(pAd); //rt2860b
3435
3436 // Set PHY to appropriate mode
3437 TmpPhy = pAd->CommonCfg.PhyMode;
3438 pAd->CommonCfg.PhyMode = 0xff;
3439 RTMPSetPhyMode(pAd, TmpPhy);
3440 SetCommonHT(pAd);
3441
3442 // No valid channels.
3443 if (pAd->ChannelListNum == 0)
3444 {
3445 DBGPRINT(RT_DEBUG_ERROR, ("Wrong configuration. No valid channel found. Check \"ContryCode\" and \"ChannelGeography\" setting.\n"));
3446 goto err4;
3447 }
3448
3449 DBGPRINT(RT_DEBUG_OFF, ("MCS Set = %02x %02x %02x %02x %02x\n", pAd->CommonCfg.HtCapability.MCSSet[0],
3450 pAd->CommonCfg.HtCapability.MCSSet[1], pAd->CommonCfg.HtCapability.MCSSet[2],
3451 pAd->CommonCfg.HtCapability.MCSSet[3], pAd->CommonCfg.HtCapability.MCSSet[4]));
3452
3453#ifdef RTMP_RF_RW_SUPPORT
3454 //Init RT30xx RFRegisters after read RFIC type from EEPROM
3455 NICInitRFRegisters(pAd);
3456#endif // RTMP_RF_RW_SUPPORT //
3457
3458// APInitialize(pAd);
3459
3460
3461 //
3462 // Initialize RF register to default value
3463 //
3464 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
3465 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
3466
3467 // 8051 firmware require the signal during booting time.
3468 //2008/11/28:KH marked the following codes to patch Frequency offset bug
3469 //AsicSendCommandToMcu(pAd, 0x72, 0xFF, 0x00, 0x00);
3470
3471 if (pAd && (Status != NDIS_STATUS_SUCCESS))
3472 {
3473 //
3474 // Undo everything if it failed
3475 //
3476 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
3477 {
3478// NdisMDeregisterInterrupt(&pAd->Interrupt);
3479 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE);
3480 }
3481// RTMPFreeAdapter(pAd); // we will free it in disconnect()
3482 }
3483 else if (pAd)
3484 {
3485 // Microsoft HCT require driver send a disconnect event after driver initialization.
3486 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
3487// pAd->IndicateMediaState = NdisMediaStateDisconnected;
3488 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE);
3489
3490 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event B!\n"));
3491
3492#ifdef RTMP_MAC_USB
3493 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS);
3494 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS);
3495
3496 //
3497 // Support multiple BulkIn IRP,
3498 // the value on pAd->CommonCfg.NumOfBulkInIRP may be large than 1.
3499 //
3500 for(index=0; index<pAd->CommonCfg.NumOfBulkInIRP; index++)
3501 {
3502 RTUSBBulkReceive(pAd);
3503 DBGPRINT(RT_DEBUG_TRACE, ("RTUSBBulkReceive!\n" ));
3504 }
3505#endif // RTMP_MAC_USB //
3506 }// end of else
3507
3508
3509 // Set up the Mac address
3510 RtmpOSNetDevAddrSet(pAd->net_dev, &pAd->CurrentAddress[0]);
3511
3512 DBGPRINT_S(Status, ("<==== rt28xx_init, Status=%x\n", Status));
3513
3514 return TRUE;
3515
3516
3517err4:
3518err3:
3519 MlmeHalt(pAd);
3520err2:
3521 RTMPFreeTxRxRingMemory(pAd);
3522err1:
3523
3524 os_free_mem(pAd, pAd->mpdu_blk_pool.mem); // free BA pool
3525
3526 // shall not set priv to NULL here because the priv didn't been free yet.
3527 //net_dev->ml_priv = 0;
3528#ifdef ST
3529err0:
3530#endif // ST //
3531
3532 DBGPRINT(RT_DEBUG_ERROR, ("!!! rt28xx Initialized fail !!!\n"));
3533 return FALSE;
3534}
3535//---Add by shiang, move from os/linux/rt_main_dev.c
3536
3537
3538static INT RtmpChipOpsRegister(
3539 IN RTMP_ADAPTER *pAd,
3540 IN INT infType)
3541{
3542 RTMP_CHIP_OP *pChipOps = &pAd->chipOps;
3543 int status;
3544
3545 memset(pChipOps, 0, sizeof(RTMP_CHIP_OP));
3546
3547 /* set eeprom related hook functions */
3548 status = RtmpChipOpsEepromHook(pAd, infType);
3549
3550 /* set mcu related hook functions */
3551 switch(infType)
3552 {
3553#ifdef RTMP_PCI_SUPPORT
3554 case RTMP_DEV_INF_PCI:
3555 pChipOps->loadFirmware = RtmpAsicLoadFirmware;
3556 pChipOps->eraseFirmware = RtmpAsicEraseFirmware;
3557 pChipOps->sendCommandToMcu = RtmpAsicSendCommandToMcu;
3558 break;
3559#endif // RTMP_PCI_SUPPORT //
3560#ifdef RTMP_USB_SUPPORT
3561 case RTMP_DEV_INF_USB:
3562 pChipOps->loadFirmware = RtmpAsicLoadFirmware;
3563 pChipOps->sendCommandToMcu = RtmpAsicSendCommandToMcu;
3564 break;
3565#endif // RTMP_USB_SUPPORT //
3566 default:
3567 break;
3568 }
3569
3570 return status;
3571}
3572
3573
3574INT RtmpRaDevCtrlInit(
3575 IN RTMP_ADAPTER *pAd,
3576 IN RTMP_INF_TYPE infType)
3577{
3578 //VOID *handle;
3579
3580 // Assign the interface type. We need use it when do register/EEPROM access.
3581 pAd->infType = infType;
3582
3583
3584 pAd->OpMode = OPMODE_STA;
3585 DBGPRINT(RT_DEBUG_TRACE, ("STA Driver version-%s\n", STA_DRIVER_VERSION));
3586
3587#ifdef RTMP_MAC_USB
3588 init_MUTEX(&(pAd->UsbVendorReq_semaphore));
3589 os_alloc_mem(pAd, (PUCHAR)&pAd->UsbVendorReqBuf, MAX_PARAM_BUFFER_SIZE - 1);
3590 if (pAd->UsbVendorReqBuf == NULL)
3591 {
3592 DBGPRINT(RT_DEBUG_ERROR, ("Allocate vendor request temp buffer failed!\n"));
3593 return FALSE;
3594 }
3595#endif // RTMP_MAC_USB //
3596
3597 RtmpChipOpsRegister(pAd, infType);
3598
3599
3600 return 0;
3601}
3602
3603
3604BOOLEAN RtmpRaDevCtrlExit(IN RTMP_ADAPTER *pAd)
3605{
3606
3607
3608 RTMPFreeAdapter(pAd);
3609
3610 return TRUE;
3611}
3612
3613
3614// not yet support MBSS
3615PNET_DEV get_netdev_from_bssid(
3616 IN PRTMP_ADAPTER pAd,
3617 IN UCHAR FromWhichBSSID)
3618{
3619 PNET_DEV dev_p = NULL;
3620
3621 {
3622 dev_p = pAd->net_dev;
3623 }
3624
3625 ASSERT(dev_p);
3626 return dev_p; /* return one of MBSS */
3627}
diff --git a/drivers/staging/rt2860/common/rtmp_mcu.c b/drivers/staging/rt2860/common/rtmp_mcu.c
new file mode 100644
index 00000000000..24531c58f90
--- /dev/null
+++ b/drivers/staging/rt2860/common/rtmp_mcu.c
@@ -0,0 +1,233 @@
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
39#include "../rt_config.h"
40
41#ifdef RT2860
42#include "firmware.h"
43#endif
44#ifdef RT2870
45#include "../../rt3070/firmware.h"
46#include "firmware_3070.h"
47#endif
48
49#include <linux/bitrev.h>
50
51//#define BIN_IN_FILE /* use *.bin firmware */
52
53#ifdef RTMP_MAC_USB
54//
55// RT2870 Firmware Spec only used 1 oct for version expression
56//
57#define FIRMWARE_MINOR_VERSION 7
58#endif // RTMP_MAC_USB //
59
60// New 8k byte firmware size for RT3071/RT3072
61#define FIRMWAREIMAGE_MAX_LENGTH 0x2000
62#define FIRMWAREIMAGE_LENGTH (sizeof (FirmwareImage) / sizeof(UCHAR))
63#define FIRMWARE_MAJOR_VERSION 0
64
65#define FIRMWAREIMAGEV1_LENGTH 0x1000
66#define FIRMWAREIMAGEV2_LENGTH 0x1000
67
68#ifdef RTMP_MAC_PCI
69#define FIRMWARE_MINOR_VERSION 2
70#endif // RTMP_MAC_PCI //
71
72/*
73 ========================================================================
74
75 Routine Description:
76 erase 8051 firmware image in MAC ASIC
77
78 Arguments:
79 Adapter Pointer to our adapter
80
81 IRQL = PASSIVE_LEVEL
82
83 ========================================================================
84*/
85INT RtmpAsicEraseFirmware(
86 IN PRTMP_ADAPTER pAd)
87{
88 ULONG 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
96/*
97 ========================================================================
98
99 Routine Description:
100 Load 8051 firmware file into MAC ASIC
101
102 Arguments:
103 Adapter Pointer to our adapter
104
105 Return Value:
106 NDIS_STATUS_SUCCESS firmware image load ok
107 NDIS_STATUS_FAILURE image not found
108
109 IRQL = PASSIVE_LEVEL
110
111 ========================================================================
112*/
113NDIS_STATUS RtmpAsicLoadFirmware(
114 IN PRTMP_ADAPTER pAd)
115{
116
117 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
118 PUCHAR pFirmwareImage;
119 ULONG FileLength, Index;
120 //ULONG firm;
121 UINT32 MacReg = 0;
122 UINT32 Version = (pAd->MACVersion >> 16);
123
124// pFirmwareImage = FirmwareImage;
125// FileLength = sizeof(FirmwareImage);
126
127 // New 8k byte firmware size for RT3071/RT3072
128 {
129#ifdef RTMP_MAC_PCI
130 if ((Version == 0x2860) || (Version == 0x3572) || IS_RT3090(pAd))
131 {
132 pFirmwareImage = FirmwareImage_2860;
133 FileLength = FIRMWAREIMAGE_MAX_LENGTH;
134 }
135#endif // RTMP_MAC_PCI //
136#ifdef RTMP_MAC_USB
137 /* the firmware image consists of two parts */
138 if ((Version != 0x2860) && (Version != 0x2872) && (Version != 0x3070))
139 { /* use the second part */
140 //printk("KH:Use New Version,part2\n");
141 pFirmwareImage = (PUCHAR)&FirmwareImage_3070[FIRMWAREIMAGEV1_LENGTH];
142 FileLength = FIRMWAREIMAGEV2_LENGTH;
143 }
144 else
145 {
146 //printk("KH:Use New Version,part1\n");
147 if (Version == 0x3070)
148 pFirmwareImage = FirmwareImage_3070;
149 else
150 pFirmwareImage = FirmwareImage_2870;
151 FileLength = FIRMWAREIMAGEV1_LENGTH;
152 }
153#endif // RTMP_MAC_USB //
154 }
155
156 RTMP_WRITE_FIRMWARE(pAd, pFirmwareImage, FileLength);
157
158
159 /* check if MCU is ready */
160 Index = 0;
161 do
162 {
163 RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &MacReg);
164
165 if (MacReg & 0x80)
166 break;
167
168 RTMPusecDelay(1000);
169 } while (Index++ < 1000);
170
171 if (Index > 1000)
172 {
173 DBGPRINT(RT_DEBUG_ERROR, ("NICLoadFirmware: MCU is not ready\n\n\n"));
174 Status = NDIS_STATUS_FAILURE;
175 }
176
177 DBGPRINT(RT_DEBUG_TRACE, ("<=== %s (status=%d)\n", __func__, Status));
178
179 return Status;
180}
181
182
183INT RtmpAsicSendCommandToMcu(
184 IN PRTMP_ADAPTER pAd,
185 IN UCHAR Command,
186 IN UCHAR Token,
187 IN UCHAR Arg0,
188 IN UCHAR Arg1)
189{
190 HOST_CMD_CSR_STRUC H2MCmd;
191 H2M_MAILBOX_STRUC H2MMailbox;
192 ULONG i = 0;
193#ifdef RTMP_MAC_PCI
194#endif // RTMP_MAC_PCI //
195
196 do
197 {
198 RTMP_IO_READ32(pAd, H2M_MAILBOX_CSR, &H2MMailbox.word);
199 if (H2MMailbox.field.Owner == 0)
200 break;
201
202 RTMPusecDelay(2);
203 } while(i++ < 100);
204
205 if (i > 100)
206 {
207#ifdef RTMP_MAC_PCI
208#endif // RTMP_MAC_PCI //
209 {
210 DBGPRINT_ERR(("H2M_MAILBOX still hold by MCU. command fail\n"));
211 }
212 return FALSE;
213 }
214
215#ifdef RTMP_MAC_PCI
216#endif // RTMP_MAC_PCI //
217
218 H2MMailbox.field.Owner = 1; // pass ownership to MCU
219 H2MMailbox.field.CmdToken = Token;
220 H2MMailbox.field.HighByte = Arg1;
221 H2MMailbox.field.LowByte = Arg0;
222 RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CSR, H2MMailbox.word);
223
224 H2MCmd.word = 0;
225 H2MCmd.field.HostCommand = Command;
226 RTMP_IO_WRITE32(pAd, HOST_CMD_CSR, H2MCmd.word);
227
228 if (Command != 0x80)
229 {
230 }
231
232 return TRUE;
233}
diff --git a/drivers/staging/rt2860/common/rtmp_timer.c b/drivers/staging/rt2860/common/rtmp_timer.c
new file mode 100644
index 00000000000..258ab1bb0f0
--- /dev/null
+++ b/drivers/staging/rt2860/common/rtmp_timer.c
@@ -0,0 +1,323 @@
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
43
44BUILD_TIMER_FUNCTION(MlmePeriodicExec);
45//BUILD_TIMER_FUNCTION(MlmeRssiReportExec);
46BUILD_TIMER_FUNCTION(AsicRxAntEvalTimeout);
47BUILD_TIMER_FUNCTION(APSDPeriodicExec);
48BUILD_TIMER_FUNCTION(AsicRfTuningExec);
49#ifdef RTMP_MAC_USB
50BUILD_TIMER_FUNCTION(BeaconUpdateExec);
51#endif // RTMP_MAC_USB //
52
53BUILD_TIMER_FUNCTION(BeaconTimeout);
54BUILD_TIMER_FUNCTION(ScanTimeout);
55BUILD_TIMER_FUNCTION(AuthTimeout);
56BUILD_TIMER_FUNCTION(AssocTimeout);
57BUILD_TIMER_FUNCTION(ReassocTimeout);
58BUILD_TIMER_FUNCTION(DisassocTimeout);
59BUILD_TIMER_FUNCTION(LinkDownExec);
60BUILD_TIMER_FUNCTION(StaQuickResponeForRateUpExec);
61BUILD_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc);
62#ifdef RTMP_PCI_SUPPORT
63BUILD_TIMER_FUNCTION(PsPollWakeExec);
64BUILD_TIMER_FUNCTION(RadioOnExec);
65#endif // RTMP_PCI_SUPPORT //
66#ifdef RTMP_MAC_USB
67BUILD_TIMER_FUNCTION(RtmpUsbStaAsicForceWakeupTimeout);
68#endif // RTMP_MAC_USB //
69
70#if defined(AP_LED) || defined(STA_LED)
71extern void LedCtrlMain(
72 IN PVOID SystemSpecific1,
73 IN PVOID FunctionContext,
74 IN PVOID SystemSpecific2,
75 IN PVOID SystemSpecific3);
76BUILD_TIMER_FUNCTION(LedCtrlMain);
77#endif
78
79
80#ifdef RTMP_TIMER_TASK_SUPPORT
81static void RtmpTimerQHandle(RTMP_ADAPTER *pAd)
82{
83#ifndef KTHREAD_SUPPORT
84 int status;
85#endif
86 RALINK_TIMER_STRUCT *pTimer;
87 RTMP_TIMER_TASK_ENTRY *pEntry;
88 unsigned long irqFlag;
89 RTMP_OS_TASK *pTask;
90
91
92 pTask = &pAd->timerTask;
93 while(!pTask->task_killed)
94 {
95 pTimer = NULL;
96
97#ifdef KTHREAD_SUPPORT
98 RTMP_WAIT_EVENT_INTERRUPTIBLE(pAd, pTask);
99#else
100 RTMP_SEM_EVENT_WAIT(&(pTask->taskSema), status);
101#endif
102
103 if (pAd->TimerQ.status == RTMP_TASK_STAT_STOPED)
104 break;
105
106 // event happened.
107 while(pAd->TimerQ.pQHead)
108 {
109 RTMP_INT_LOCK(&pAd->TimerQLock, irqFlag);
110 pEntry = pAd->TimerQ.pQHead;
111 if (pEntry)
112 {
113 pTimer = pEntry->pRaTimer;
114
115 // update pQHead
116 pAd->TimerQ.pQHead = pEntry->pNext;
117 if (pEntry == pAd->TimerQ.pQTail)
118 pAd->TimerQ.pQTail = NULL;
119
120 // return this queue entry to timerQFreeList.
121 pEntry->pNext = pAd->TimerQ.pQPollFreeList;
122 pAd->TimerQ.pQPollFreeList = pEntry;
123 }
124 RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlag);
125
126 if (pTimer)
127 {
128 if ((pTimer->handle != NULL) && (!pAd->PM_FlgSuspend))
129 pTimer->handle(NULL, (PVOID) pTimer->cookie, NULL, pTimer);
130 if ((pTimer->Repeat) && (pTimer->State == FALSE))
131 RTMP_OS_Add_Timer(&pTimer->TimerObj, pTimer->TimerValue);
132 }
133 }
134
135#ifndef KTHREAD_SUPPORT
136 if (status != 0)
137 {
138 pAd->TimerQ.status = RTMP_TASK_STAT_STOPED;
139 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
140 break;
141 }
142#endif
143 }
144}
145
146
147INT RtmpTimerQThread(
148 IN OUT PVOID Context)
149{
150 RTMP_OS_TASK *pTask;
151 PRTMP_ADAPTER pAd;
152
153
154 pTask = (RTMP_OS_TASK *)Context;
155 pAd = (PRTMP_ADAPTER)pTask->priv;
156
157 RtmpOSTaskCustomize(pTask);
158
159 RtmpTimerQHandle(pAd);
160
161 DBGPRINT(RT_DEBUG_TRACE,( "<---%s\n",__func__));
162#ifndef KTHREAD_SUPPORT
163 pTask->taskPID = THREAD_PID_INIT_VALUE;
164#endif
165 /* notify the exit routine that we're actually exiting now
166 *
167 * complete()/wait_for_completion() is similar to up()/down(),
168 * except that complete() is safe in the case where the structure
169 * is getting deleted in a parallel mode of execution (i.e. just
170 * after the down() -- that's necessary for the thread-shutdown
171 * case.
172 *
173 * complete_and_exit() goes even further than this -- it is safe in
174 * the case that the thread of the caller is going away (not just
175 * the structure) -- this is necessary for the module-remove case.
176 * This is important in preemption kernels, which transfer the flow
177 * of execution immediately upon a complete().
178 */
179 RtmpOSTaskNotifyToExit(pTask);
180
181 return 0;
182
183}
184
185
186RTMP_TIMER_TASK_ENTRY *RtmpTimerQInsert(
187 IN RTMP_ADAPTER *pAd,
188 IN RALINK_TIMER_STRUCT *pTimer)
189{
190 RTMP_TIMER_TASK_ENTRY *pQNode = NULL, *pQTail;
191 unsigned long irqFlags;
192 RTMP_OS_TASK *pTask = &pAd->timerTask;
193
194 RTMP_INT_LOCK(&pAd->TimerQLock, irqFlags);
195 if (pAd->TimerQ.status & RTMP_TASK_CAN_DO_INSERT)
196 {
197 if(pAd->TimerQ.pQPollFreeList)
198 {
199 pQNode = pAd->TimerQ.pQPollFreeList;
200 pAd->TimerQ.pQPollFreeList = pQNode->pNext;
201
202 pQNode->pRaTimer = pTimer;
203 pQNode->pNext = NULL;
204
205 pQTail = pAd->TimerQ.pQTail;
206 if (pAd->TimerQ.pQTail != NULL)
207 pQTail->pNext = pQNode;
208 pAd->TimerQ.pQTail = pQNode;
209 if (pAd->TimerQ.pQHead == NULL)
210 pAd->TimerQ.pQHead = pQNode;
211 }
212 }
213 RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlags);
214
215 if (pQNode)
216 {
217#ifdef KTHREAD_SUPPORT
218 WAKE_UP(pTask);
219#else
220 RTMP_SEM_EVENT_UP(&pTask->taskSema);
221#endif
222 }
223
224 return pQNode;
225}
226
227
228BOOLEAN RtmpTimerQRemove(
229 IN RTMP_ADAPTER *pAd,
230 IN RALINK_TIMER_STRUCT *pTimer)
231{
232 RTMP_TIMER_TASK_ENTRY *pNode, *pPrev = NULL;
233 unsigned long irqFlags;
234
235 RTMP_INT_LOCK(&pAd->TimerQLock, irqFlags);
236 if (pAd->TimerQ.status >= RTMP_TASK_STAT_INITED)
237 {
238 pNode = pAd->TimerQ.pQHead;
239 while (pNode)
240 {
241 if (pNode->pRaTimer == pTimer)
242 break;
243 pPrev = pNode;
244 pNode = pNode->pNext;
245 }
246
247 // Now move it to freeList queue.
248 if (pNode)
249 {
250 if (pNode == pAd->TimerQ.pQHead)
251 pAd->TimerQ.pQHead = pNode->pNext;
252 if (pNode == pAd->TimerQ.pQTail)
253 pAd->TimerQ.pQTail = pPrev;
254 if (pPrev != NULL)
255 pPrev->pNext = pNode->pNext;
256
257 // return this queue entry to timerQFreeList.
258 pNode->pNext = pAd->TimerQ.pQPollFreeList;
259 pAd->TimerQ.pQPollFreeList = pNode;
260 }
261 }
262 RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlags);
263
264 return TRUE;
265}
266
267
268void RtmpTimerQExit(RTMP_ADAPTER *pAd)
269{
270 RTMP_TIMER_TASK_ENTRY *pTimerQ;
271 unsigned long irqFlags;
272
273 RTMP_INT_LOCK(&pAd->TimerQLock, irqFlags);
274 while (pAd->TimerQ.pQHead)
275 {
276 pTimerQ = pAd->TimerQ.pQHead;
277 pAd->TimerQ.pQHead = pTimerQ->pNext;
278 // remove the timeQ
279 }
280 pAd->TimerQ.pQPollFreeList = NULL;
281 os_free_mem(pAd, pAd->TimerQ.pTimerQPoll);
282 pAd->TimerQ.pQTail = NULL;
283 pAd->TimerQ.pQHead = NULL;
284#ifndef KTHREAD_SUPPORT
285 pAd->TimerQ.status = RTMP_TASK_STAT_STOPED;
286#endif
287 RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlags);
288
289}
290
291
292void RtmpTimerQInit(RTMP_ADAPTER *pAd)
293{
294 int i;
295 RTMP_TIMER_TASK_ENTRY *pQNode, *pEntry;
296 unsigned long irqFlags;
297
298 NdisAllocateSpinLock(&pAd->TimerQLock);
299
300 NdisZeroMemory(&pAd->TimerQ, sizeof(pAd->TimerQ));
301
302 os_alloc_mem(pAd, &pAd->TimerQ.pTimerQPoll, sizeof(RTMP_TIMER_TASK_ENTRY) * TIMER_QUEUE_SIZE_MAX);
303 if (pAd->TimerQ.pTimerQPoll)
304 {
305 pEntry = NULL;
306 pQNode = (RTMP_TIMER_TASK_ENTRY *)pAd->TimerQ.pTimerQPoll;
307 NdisZeroMemory(pAd->TimerQ.pTimerQPoll, sizeof(RTMP_TIMER_TASK_ENTRY) * TIMER_QUEUE_SIZE_MAX);
308
309 RTMP_INT_LOCK(&pAd->TimerQLock, irqFlags);
310 for (i = 0 ;i <TIMER_QUEUE_SIZE_MAX; i++)
311 {
312 pQNode->pNext = pEntry;
313 pEntry = pQNode;
314 pQNode++;
315 }
316 pAd->TimerQ.pQPollFreeList = pEntry;
317 pAd->TimerQ.pQHead = NULL;
318 pAd->TimerQ.pQTail = NULL;
319 pAd->TimerQ.status = RTMP_TASK_STAT_INITED;
320 RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlags);
321 }
322}
323#endif // RTMP_TIMER_TASK_SUPPORT //
diff --git a/drivers/staging/rt2860/common/spectrum.c b/drivers/staging/rt2860/common/spectrum.c
index c658bf3082c..7fd715ad39b 100644
--- a/drivers/staging/rt2860/common/spectrum.c
+++ b/drivers/staging/rt2860/common/spectrum.c
@@ -40,6 +40,239 @@
40#include "../rt_config.h" 40#include "../rt_config.h"
41#include "action.h" 41#include "action.h"
42 42
43
44/* The regulatory information in the USA (US) */
45DOT11_REGULATORY_INFORMATION USARegulatoryInfo[] =
46{
47/* "regulatory class" "number of channels" "Max Tx Pwr" "channel list" */
48 {0, {0, 0, {0}}}, // Invlid entry
49 {1, {4, 16, {36, 40, 44, 48}}},
50 {2, {4, 23, {52, 56, 60, 64}}},
51 {3, {4, 29, {149, 153, 157, 161}}},
52 {4, {11, 23, {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}}},
53 {5, {5, 30, {149, 153, 157, 161, 165}}},
54 {6, {10, 14, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}},
55 {7, {10, 27, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}},
56 {8, {5, 17, {11, 13, 15, 17, 19}}},
57 {9, {5, 30, {11, 13, 15, 17, 19}}},
58 {10, {2, 20, {21, 25}}},
59 {11, {2, 33, {21, 25}}},
60 {12, {11, 30, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}}}
61};
62#define USA_REGULATORY_INFO_SIZE (sizeof(USARegulatoryInfo) / sizeof(DOT11_REGULATORY_INFORMATION))
63
64
65/* The regulatory information in Europe */
66DOT11_REGULATORY_INFORMATION EuropeRegulatoryInfo[] =
67{
68/* "regulatory class" "number of channels" "Max Tx Pwr" "channel list" */
69 {0, {0, 0, {0}}}, // Invalid entry
70 {1, {4, 20, {36, 40, 44, 48}}},
71 {2, {4, 20, {52, 56, 60, 64}}},
72 {3, {11, 30, {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}}},
73 {4, {13, 20, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}}}
74};
75#define EU_REGULATORY_INFO_SIZE (sizeof(EuropeRegulatoryInfo) / sizeof(DOT11_REGULATORY_INFORMATION))
76
77
78/* The regulatory information in Japan */
79DOT11_REGULATORY_INFORMATION JapanRegulatoryInfo[] =
80{
81/* "regulatory class" "number of channels" "Max Tx Pwr" "channel list" */
82 {0, {0, 0, {0}}}, // Invalid entry
83 {1, {4, 22, {34, 38, 42, 46}}},
84 {2, {3, 24, {8, 12, 16}}},
85 {3, {3, 24, {8, 12, 16}}},
86 {4, {3, 24, {8, 12, 16}}},
87 {5, {3, 24, {8, 12, 16}}},
88 {6, {3, 22, {8, 12, 16}}},
89 {7, {4, 24, {184, 188, 192, 196}}},
90 {8, {4, 24, {184, 188, 192, 196}}},
91 {9, {4, 24, {184, 188, 192, 196}}},
92 {10, {4, 24, {184, 188, 192, 196}}},
93 {11, {4, 22, {184, 188, 192, 196}}},
94 {12, {4, 24, {7, 8, 9, 11}}},
95 {13, {4, 24, {7, 8, 9, 11}}},
96 {14, {4, 24, {7, 8, 9, 11}}},
97 {15, {4, 24, {7, 8, 9, 11}}},
98 {16, {6, 24, {183, 184, 185, 187, 188, 189}}},
99 {17, {6, 24, {183, 184, 185, 187, 188, 189}}},
100 {18, {6, 24, {183, 184, 185, 187, 188, 189}}},
101 {19, {6, 24, {183, 184, 185, 187, 188, 189}}},
102 {20, {6, 17, {183, 184, 185, 187, 188, 189}}},
103 {21, {6, 24, {6, 7, 8, 9, 10, 11}}},
104 {22, {6, 24, {6, 7, 8, 9, 10, 11}}},
105 {23, {6, 24, {6, 7, 8, 9, 10, 11}}},
106 {24, {6, 24, {6, 7, 8, 9, 10, 11}}},
107 {25, {8, 24, {182, 183, 184, 185, 186, 187, 188, 189}}},
108 {26, {8, 24, {182, 183, 184, 185, 186, 187, 188, 189}}},
109 {27, {8, 24, {182, 183, 184, 185, 186, 187, 188, 189}}},
110 {28, {8, 24, {182, 183, 184, 185, 186, 187, 188, 189}}},
111 {29, {8, 17, {182, 183, 184, 185, 186, 187, 188, 189}}},
112 {30, {13, 23, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}}},
113 {31, {1, 23, {14}}},
114 {32, {4, 22, {52, 56, 60, 64}}}
115};
116#define JP_REGULATORY_INFO_SIZE (sizeof(JapanRegulatoryInfo) / sizeof(DOT11_REGULATORY_INFORMATION))
117
118
119CHAR RTMP_GetTxPwr(
120 IN PRTMP_ADAPTER pAd,
121 IN HTTRANSMIT_SETTING HTTxMode)
122{
123typedef struct __TX_PWR_CFG
124{
125 UINT8 Mode;
126 UINT8 MCS;
127 UINT16 req;
128 UINT8 shift;
129 UINT32 BitMask;
130} TX_PWR_CFG;
131
132 UINT32 Value;
133 INT Idx;
134 UINT8 PhyMode;
135 CHAR CurTxPwr;
136 UINT8 TxPwrRef = 0;
137 CHAR DaltaPwr;
138 ULONG TxPwr[5];
139
140
141 TX_PWR_CFG TxPwrCfg[] = {
142 {MODE_CCK, 0, 0, 4, 0x000000f0},
143 {MODE_CCK, 1, 0, 0, 0x0000000f},
144 {MODE_CCK, 2, 0, 12, 0x0000f000},
145 {MODE_CCK, 3, 0, 8, 0x00000f00},
146
147 {MODE_OFDM, 0, 0, 20, 0x00f00000},
148 {MODE_OFDM, 1, 0, 16, 0x000f0000},
149 {MODE_OFDM, 2, 0, 28, 0xf0000000},
150 {MODE_OFDM, 3, 0, 24, 0x0f000000},
151 {MODE_OFDM, 4, 1, 4, 0x000000f0},
152 {MODE_OFDM, 5, 1, 0, 0x0000000f},
153 {MODE_OFDM, 6, 1, 12, 0x0000f000},
154 {MODE_OFDM, 7, 1, 8, 0x00000f00}
155 ,{MODE_HTMIX, 0, 1, 20, 0x00f00000},
156 {MODE_HTMIX, 1, 1, 16, 0x000f0000},
157 {MODE_HTMIX, 2, 1, 28, 0xf0000000},
158 {MODE_HTMIX, 3, 1, 24, 0x0f000000},
159 {MODE_HTMIX, 4, 2, 4, 0x000000f0},
160 {MODE_HTMIX, 5, 2, 0, 0x0000000f},
161 {MODE_HTMIX, 6, 2, 12, 0x0000f000},
162 {MODE_HTMIX, 7, 2, 8, 0x00000f00},
163 {MODE_HTMIX, 8, 2, 20, 0x00f00000},
164 {MODE_HTMIX, 9, 2, 16, 0x000f0000},
165 {MODE_HTMIX, 10, 2, 28, 0xf0000000},
166 {MODE_HTMIX, 11, 2, 24, 0x0f000000},
167 {MODE_HTMIX, 12, 3, 4, 0x000000f0},
168 {MODE_HTMIX, 13, 3, 0, 0x0000000f},
169 {MODE_HTMIX, 14, 3, 12, 0x0000f000},
170 {MODE_HTMIX, 15, 3, 8, 0x00000f00}
171 };
172#define MAX_TXPWR_TAB_SIZE (sizeof(TxPwrCfg) / sizeof(TX_PWR_CFG))
173
174 CurTxPwr = 19;
175
176 /* check Tx Power setting from UI. */
177 if (pAd->CommonCfg.TxPowerPercentage > 90)
178 ;
179 else if (pAd->CommonCfg.TxPowerPercentage > 60) /* reduce Pwr for 1 dB. */
180 CurTxPwr -= 1;
181 else if (pAd->CommonCfg.TxPowerPercentage > 30) /* reduce Pwr for 3 dB. */
182 CurTxPwr -= 3;
183 else if (pAd->CommonCfg.TxPowerPercentage > 15) /* reduce Pwr for 6 dB. */
184 CurTxPwr -= 6;
185 else if (pAd->CommonCfg.TxPowerPercentage > 9) /* reduce Pwr for 9 dB. */
186 CurTxPwr -= 9;
187 else /* reduce Pwr for 12 dB. */
188 CurTxPwr -= 12;
189
190 if (pAd->CommonCfg.BBPCurrentBW == BW_40)
191 {
192 if (pAd->CommonCfg.CentralChannel > 14)
193 {
194 TxPwr[0] = pAd->Tx40MPwrCfgABand[0];
195 TxPwr[1] = pAd->Tx40MPwrCfgABand[1];
196 TxPwr[2] = pAd->Tx40MPwrCfgABand[2];
197 TxPwr[3] = pAd->Tx40MPwrCfgABand[3];
198 TxPwr[4] = pAd->Tx40MPwrCfgABand[4];
199 }
200 else
201 {
202 TxPwr[0] = pAd->Tx40MPwrCfgGBand[0];
203 TxPwr[1] = pAd->Tx40MPwrCfgGBand[1];
204 TxPwr[2] = pAd->Tx40MPwrCfgGBand[2];
205 TxPwr[3] = pAd->Tx40MPwrCfgGBand[3];
206 TxPwr[4] = pAd->Tx40MPwrCfgGBand[4];
207 }
208 }
209 else
210 {
211 if (pAd->CommonCfg.Channel > 14)
212 {
213 TxPwr[0] = pAd->Tx20MPwrCfgABand[0];
214 TxPwr[1] = pAd->Tx20MPwrCfgABand[1];
215 TxPwr[2] = pAd->Tx20MPwrCfgABand[2];
216 TxPwr[3] = pAd->Tx20MPwrCfgABand[3];
217 TxPwr[4] = pAd->Tx20MPwrCfgABand[4];
218 }
219 else
220 {
221 TxPwr[0] = pAd->Tx20MPwrCfgGBand[0];
222 TxPwr[1] = pAd->Tx20MPwrCfgGBand[1];
223 TxPwr[2] = pAd->Tx20MPwrCfgGBand[2];
224 TxPwr[3] = pAd->Tx20MPwrCfgGBand[3];
225 TxPwr[4] = pAd->Tx20MPwrCfgGBand[4];
226 }
227 }
228
229
230 switch(HTTxMode.field.MODE)
231 {
232 case MODE_CCK:
233 case MODE_OFDM:
234 Value = TxPwr[1];
235 TxPwrRef = (Value & 0x00000f00) >> 8;
236
237 break;
238
239 case MODE_HTMIX:
240 case MODE_HTGREENFIELD:
241 if (pAd->CommonCfg.TxStream == 1)
242 {
243 Value = TxPwr[2];
244 TxPwrRef = (Value & 0x00000f00) >> 8;
245 }
246 else if (pAd->CommonCfg.TxStream == 2)
247 {
248 Value = TxPwr[3];
249 TxPwrRef = (Value & 0x00000f00) >> 8;
250 }
251 break;
252 }
253
254 PhyMode =
255 (HTTxMode.field.MODE == MODE_HTGREENFIELD)
256 ? MODE_HTMIX :
257 HTTxMode.field.MODE;
258
259 for (Idx = 0; Idx < MAX_TXPWR_TAB_SIZE; Idx++)
260 {
261 if ((TxPwrCfg[Idx].Mode == PhyMode)
262 && (TxPwrCfg[Idx].MCS == HTTxMode.field.MCS))
263 {
264 Value = TxPwr[TxPwrCfg[Idx].req];
265 DaltaPwr = TxPwrRef - (CHAR)((Value & TxPwrCfg[Idx].BitMask)
266 >> TxPwrCfg[Idx].shift);
267 CurTxPwr -= DaltaPwr;
268 break;
269 }
270 }
271
272 return CurTxPwr;
273}
274
275
43VOID MeasureReqTabInit( 276VOID MeasureReqTabInit(
44 IN PRTMP_ADAPTER pAd) 277 IN PRTMP_ADAPTER pAd)
45{ 278{
@@ -57,7 +290,7 @@ VOID MeasureReqTabInit(
57VOID MeasureReqTabExit( 290VOID MeasureReqTabExit(
58 IN PRTMP_ADAPTER pAd) 291 IN PRTMP_ADAPTER pAd)
59{ 292{
60 NdisFreeSpinLock(pAd->CommonCfg.MeasureReqTabLock); 293 NdisFreeSpinLock(&pAd->CommonCfg.MeasureReqTabLock);
61 294
62 if (pAd->CommonCfg.pMeasureReqTab) 295 if (pAd->CommonCfg.pMeasureReqTab)
63 kfree(pAd->CommonCfg.pMeasureReqTab); 296 kfree(pAd->CommonCfg.pMeasureReqTab);
@@ -66,7 +299,7 @@ VOID MeasureReqTabExit(
66 return; 299 return;
67} 300}
68 301
69static PMEASURE_REQ_ENTRY MeasureReqLookUp( 302PMEASURE_REQ_ENTRY MeasureReqLookUp(
70 IN PRTMP_ADAPTER pAd, 303 IN PRTMP_ADAPTER pAd,
71 IN UINT8 DialogToken) 304 IN UINT8 DialogToken)
72{ 305{
@@ -102,7 +335,7 @@ static PMEASURE_REQ_ENTRY MeasureReqLookUp(
102 return pEntry; 335 return pEntry;
103} 336}
104 337
105static PMEASURE_REQ_ENTRY MeasureReqInsert( 338PMEASURE_REQ_ENTRY MeasureReqInsert(
106 IN PRTMP_ADAPTER pAd, 339 IN PRTMP_ADAPTER pAd,
107 IN UINT8 DialogToken) 340 IN UINT8 DialogToken)
108{ 341{
@@ -201,7 +434,7 @@ static PMEASURE_REQ_ENTRY MeasureReqInsert(
201 return pEntry; 434 return pEntry;
202} 435}
203 436
204static VOID MeasureReqDelete( 437VOID MeasureReqDelete(
205 IN PRTMP_ADAPTER pAd, 438 IN PRTMP_ADAPTER pAd,
206 IN UINT8 DialogToken) 439 IN UINT8 DialogToken)
207{ 440{
@@ -275,7 +508,7 @@ VOID TpcReqTabInit(
275VOID TpcReqTabExit( 508VOID TpcReqTabExit(
276 IN PRTMP_ADAPTER pAd) 509 IN PRTMP_ADAPTER pAd)
277{ 510{
278 NdisFreeSpinLock(pAd->CommonCfg.TpcReqTabLock); 511 NdisFreeSpinLock(&pAd->CommonCfg.TpcReqTabLock);
279 512
280 if (pAd->CommonCfg.pTpcReqTab) 513 if (pAd->CommonCfg.pTpcReqTab)
281 kfree(pAd->CommonCfg.pTpcReqTab); 514 kfree(pAd->CommonCfg.pTpcReqTab);
@@ -514,6 +747,72 @@ static UINT8 GetCurTxPwr(
514/* 747/*
515 ========================================================================== 748 ==========================================================================
516 Description: 749 Description:
750 Get Current Transmit Power.
751
752 Parametrs:
753
754 Return : Current Time Stamp.
755 ==========================================================================
756 */
757VOID InsertChannelRepIE(
758 IN PRTMP_ADAPTER pAd,
759 OUT PUCHAR pFrameBuf,
760 OUT PULONG pFrameLen,
761 IN PSTRING pCountry,
762 IN UINT8 RegulatoryClass)
763{
764 ULONG TempLen;
765 UINT8 Len;
766 UINT8 IEId = IE_AP_CHANNEL_REPORT;
767 PUCHAR pChListPtr = NULL;
768
769 Len = 1;
770 if (strncmp(pCountry, "US", 2) == 0)
771 {
772 if (RegulatoryClass >= USA_REGULATORY_INFO_SIZE)
773 {
774 DBGPRINT(RT_DEBUG_ERROR, ("%s: USA Unknow Requlatory class (%d)\n",
775 __func__, RegulatoryClass));
776 return;
777 }
778
779 Len += USARegulatoryInfo[RegulatoryClass].ChannelSet.NumberOfChannels;
780 pChListPtr = USARegulatoryInfo[RegulatoryClass].ChannelSet.ChannelList;
781 }
782 else if (strncmp(pCountry, "JP", 2) == 0)
783 {
784 if (RegulatoryClass >= JP_REGULATORY_INFO_SIZE)
785 {
786 DBGPRINT(RT_DEBUG_ERROR, ("%s: JP Unknow Requlatory class (%d)\n",
787 __func__, RegulatoryClass));
788 return;
789 }
790
791 Len += JapanRegulatoryInfo[RegulatoryClass].ChannelSet.NumberOfChannels;
792 pChListPtr = JapanRegulatoryInfo[RegulatoryClass].ChannelSet.ChannelList;
793 }
794 else
795 {
796 DBGPRINT(RT_DEBUG_ERROR, ("%s: Unknow Country (%s)\n",
797 __func__, pCountry));
798 return;
799 }
800
801 MakeOutgoingFrame(pFrameBuf, &TempLen,
802 1, &IEId,
803 1, &Len,
804 1, &RegulatoryClass,
805 Len -1, pChListPtr,
806 END_OF_ARGS);
807
808 *pFrameLen = *pFrameLen + TempLen;
809
810 return;
811}
812
813/*
814 ==========================================================================
815 Description:
517 Insert Dialog Token into frame. 816 Insert Dialog Token into frame.
518 817
519 Parametrs: 818 Parametrs:
@@ -524,7 +823,7 @@ static UINT8 GetCurTxPwr(
524 Return : None. 823 Return : None.
525 ========================================================================== 824 ==========================================================================
526 */ 825 */
527static VOID InsertDialogToken( 826VOID InsertDialogToken(
528 IN PRTMP_ADAPTER pAd, 827 IN PRTMP_ADAPTER pAd,
529 OUT PUCHAR pFrameBuf, 828 OUT PUCHAR pFrameBuf,
530 OUT PULONG pFrameLen, 829 OUT PULONG pFrameLen,
@@ -585,7 +884,7 @@ static VOID InsertDialogToken(
585 Return : None. 884 Return : None.
586 ========================================================================== 885 ==========================================================================
587 */ 886 */
588 static VOID InsertTpcReportIE( 887VOID InsertTpcReportIE(
589 IN PRTMP_ADAPTER pAd, 888 IN PRTMP_ADAPTER pAd,
590 OUT PUCHAR pFrameBuf, 889 OUT PUCHAR pFrameBuf,
591 OUT PULONG pFrameLen, 890 OUT PULONG pFrameLen,
@@ -679,16 +978,16 @@ static VOID InsertMeasureReqIE(
679 IN PRTMP_ADAPTER pAd, 978 IN PRTMP_ADAPTER pAd,
680 OUT PUCHAR pFrameBuf, 979 OUT PUCHAR pFrameBuf,
681 OUT PULONG pFrameLen, 980 OUT PULONG pFrameLen,
981 IN UINT8 Len,
682 IN PMEASURE_REQ_INFO pMeasureReqIE) 982 IN PMEASURE_REQ_INFO pMeasureReqIE)
683{ 983{
684 ULONG TempLen; 984 ULONG TempLen;
685 UINT8 Len = sizeof(MEASURE_REQ_INFO);
686 UINT8 ElementID = IE_MEASUREMENT_REQUEST; 985 UINT8 ElementID = IE_MEASUREMENT_REQUEST;
687 986
688 MakeOutgoingFrame(pFrameBuf, &TempLen, 987 MakeOutgoingFrame(pFrameBuf, &TempLen,
689 1, &ElementID, 988 1, &ElementID,
690 1, &Len, 989 1, &Len,
691 Len, pMeasureReqIE, 990 sizeof(MEASURE_REQ_INFO), pMeasureReqIE,
692 END_OF_ARGS); 991 END_OF_ARGS);
693 992
694 *pFrameLen = *pFrameLen + TempLen; 993 *pFrameLen = *pFrameLen + TempLen;
@@ -758,53 +1057,43 @@ static VOID InsertMeasureReportIE(
758 Return : None. 1057 Return : None.
759 ========================================================================== 1058 ==========================================================================
760 */ 1059 */
761VOID EnqueueMeasurementReq( 1060VOID MakeMeasurementReqFrame(
762 IN PRTMP_ADAPTER pAd, 1061 IN PRTMP_ADAPTER pAd,
763 IN PUCHAR pDA, 1062 OUT PUCHAR pOutBuffer,
1063 OUT PULONG pFrameLen,
1064 IN UINT8 TotalLen,
1065 IN UINT8 Category,
1066 IN UINT8 Action,
764 IN UINT8 MeasureToken, 1067 IN UINT8 MeasureToken,
765 IN UINT8 MeasureReqMode, 1068 IN UINT8 MeasureReqMode,
766 IN UINT8 MeasureReqType, 1069 IN UINT8 MeasureReqType,
767 IN UINT8 MeasureCh, 1070 IN UINT8 NumOfRepetitions)
768 IN UINT16 MeasureDuration)
769{ 1071{
770 PUCHAR pOutBuffer = NULL; 1072 ULONG TempLen;
771 NDIS_STATUS NStatus;
772 ULONG FrameLen;
773 HEADER_802_11 ActHdr;
774 MEASURE_REQ_INFO MeasureReqIE; 1073 MEASURE_REQ_INFO MeasureReqIE;
775 UINT8 RmReqDailogToken = RandomByte(pAd);
776 UINT64 MeasureStartTime = GetCurrentTimeStamp(pAd);
777 1074
778 // build action frame header. 1075 InsertActField(pAd, (pOutBuffer + *pFrameLen), pFrameLen, Category, Action);
779 MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
780 pAd->CurrentAddress);
781 1076
782 NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); //Get an unused nonpaged memory 1077 // fill Dialog Token
783 if(NStatus != NDIS_STATUS_SUCCESS) 1078 InsertDialogToken(pAd, (pOutBuffer + *pFrameLen), pFrameLen, MeasureToken);
784 {
785 DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __func__));
786 return;
787 }
788 NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11));
789 FrameLen = sizeof(HEADER_802_11);
790 1079
791 InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_SPECTRUM, SPEC_MRQ); 1080 /* fill Number of repetitions. */
1081 if (Category == CATEGORY_RM)
1082 {
1083 MakeOutgoingFrame((pOutBuffer+*pFrameLen), &TempLen,
1084 2, &NumOfRepetitions,
1085 END_OF_ARGS);
792 1086
793 // fill Dialog Token 1087 *pFrameLen += TempLen;
794 InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, MeasureToken); 1088 }
795 1089
796 // prepare Measurement IE. 1090 // prepare Measurement IE.
797 NdisZeroMemory(&MeasureReqIE, sizeof(MEASURE_REQ_INFO)); 1091 NdisZeroMemory(&MeasureReqIE, sizeof(MEASURE_REQ_INFO));
798 MeasureReqIE.Token = RmReqDailogToken; 1092 MeasureReqIE.Token = MeasureToken;
799 MeasureReqIE.ReqMode.word = MeasureReqMode; 1093 MeasureReqIE.ReqMode.word = MeasureReqMode;
800 MeasureReqIE.ReqType = MeasureReqType; 1094 MeasureReqIE.ReqType = MeasureReqType;
801 MeasureReqIE.MeasureReq.ChNum = MeasureCh; 1095 InsertMeasureReqIE(pAd, (pOutBuffer+*pFrameLen), pFrameLen,
802 MeasureReqIE.MeasureReq.MeasureStartTime = cpu2le64(MeasureStartTime); 1096 TotalLen, &MeasureReqIE);
803 MeasureReqIE.MeasureReq.MeasureDuration = cpu2le16(MeasureDuration);
804 InsertMeasureReqIE(pAd, (pOutBuffer + FrameLen), &FrameLen, &MeasureReqIE);
805
806 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
807 MlmeFreeMemory(pAd, pOutBuffer);
808 1097
809 return; 1098 return;
810} 1099}
@@ -858,7 +1147,7 @@ VOID EnqueueMeasurementRep(
858 // prepare Measurement IE. 1147 // prepare Measurement IE.
859 NdisZeroMemory(&MeasureRepIE, sizeof(MEASURE_REPORT_INFO)); 1148 NdisZeroMemory(&MeasureRepIE, sizeof(MEASURE_REPORT_INFO));
860 MeasureRepIE.Token = MeasureToken; 1149 MeasureRepIE.Token = MeasureToken;
861 MeasureRepIE.ReportMode.word = MeasureReqMode; 1150 MeasureRepIE.ReportMode = MeasureReqMode;
862 MeasureRepIE.ReportType = MeasureReqType; 1151 MeasureRepIE.ReportType = MeasureReqType;
863 InsertMeasureReportIE(pAd, (pOutBuffer + FrameLen), &FrameLen, &MeasureRepIE, ReportInfoLen, pReportInfo); 1152 InsertMeasureReportIE(pAd, (pOutBuffer + FrameLen), &FrameLen, &MeasureRepIE, ReportInfoLen, pReportInfo);
864 1153
@@ -1159,7 +1448,8 @@ static BOOLEAN PeerMeasureReqSanity(
1159 IN VOID *pMsg, 1448 IN VOID *pMsg,
1160 IN ULONG MsgLen, 1449 IN ULONG MsgLen,
1161 OUT PUINT8 pDialogToken, 1450 OUT PUINT8 pDialogToken,
1162 OUT PMEASURE_REQ_INFO pMeasureReqInfo) 1451 OUT PMEASURE_REQ_INFO pMeasureReqInfo,
1452 OUT PMEASURE_REQ pMeasureReq)
1163{ 1453{
1164 PFRAME_802_11 Fr = (PFRAME_802_11)pMsg; 1454 PFRAME_802_11 Fr = (PFRAME_802_11)pMsg;
1165 PUCHAR pFramePtr = Fr->Octet; 1455 PUCHAR pFramePtr = Fr->Octet;
@@ -1192,12 +1482,12 @@ static BOOLEAN PeerMeasureReqSanity(
1192 NdisMoveMemory(&pMeasureReqInfo->Token, eid_ptr->Octet, 1); 1482 NdisMoveMemory(&pMeasureReqInfo->Token, eid_ptr->Octet, 1);
1193 NdisMoveMemory(&pMeasureReqInfo->ReqMode.word, eid_ptr->Octet + 1, 1); 1483 NdisMoveMemory(&pMeasureReqInfo->ReqMode.word, eid_ptr->Octet + 1, 1);
1194 NdisMoveMemory(&pMeasureReqInfo->ReqType, eid_ptr->Octet + 2, 1); 1484 NdisMoveMemory(&pMeasureReqInfo->ReqType, eid_ptr->Octet + 2, 1);
1195 ptr = eid_ptr->Octet + 3; 1485 ptr = (PUCHAR)(eid_ptr->Octet + 3);
1196 NdisMoveMemory(&pMeasureReqInfo->MeasureReq.ChNum, ptr, 1); 1486 NdisMoveMemory(&pMeasureReq->ChNum, ptr, 1);
1197 NdisMoveMemory(&MeasureStartTime, ptr + 1, 8); 1487 NdisMoveMemory(&MeasureStartTime, ptr + 1, 8);
1198 pMeasureReqInfo->MeasureReq.MeasureStartTime = SWAP64(MeasureStartTime); 1488 pMeasureReq->MeasureStartTime = SWAP64(MeasureStartTime);
1199 NdisMoveMemory(&MeasureDuration, ptr + 9, 2); 1489 NdisMoveMemory(&MeasureDuration, ptr + 9, 2);
1200 pMeasureReqInfo->MeasureReq.MeasureDuration = SWAP16(MeasureDuration); 1490 pMeasureReq->MeasureDuration = SWAP16(MeasureDuration);
1201 1491
1202 result = TRUE; 1492 result = TRUE;
1203 break; 1493 break;
@@ -1285,7 +1575,7 @@ static BOOLEAN PeerMeasureReportSanity(
1285 if (pMeasureReportInfo->ReportType == RM_BASIC) 1575 if (pMeasureReportInfo->ReportType == RM_BASIC)
1286 { 1576 {
1287 PMEASURE_BASIC_REPORT pReport = (PMEASURE_BASIC_REPORT)pReportBuf; 1577 PMEASURE_BASIC_REPORT pReport = (PMEASURE_BASIC_REPORT)pReportBuf;
1288 ptr = eid_ptr->Octet + 3; 1578 ptr = (PUCHAR)(eid_ptr->Octet + 3);
1289 NdisMoveMemory(&pReport->ChNum, ptr, 1); 1579 NdisMoveMemory(&pReport->ChNum, ptr, 1);
1290 NdisMoveMemory(&pReport->MeasureStartTime, ptr + 1, 8); 1580 NdisMoveMemory(&pReport->MeasureStartTime, ptr + 1, 8);
1291 NdisMoveMemory(&pReport->MeasureDuration, ptr + 9, 2); 1581 NdisMoveMemory(&pReport->MeasureDuration, ptr + 9, 2);
@@ -1295,7 +1585,7 @@ static BOOLEAN PeerMeasureReportSanity(
1295 else if (pMeasureReportInfo->ReportType == RM_CCA) 1585 else if (pMeasureReportInfo->ReportType == RM_CCA)
1296 { 1586 {
1297 PMEASURE_CCA_REPORT pReport = (PMEASURE_CCA_REPORT)pReportBuf; 1587 PMEASURE_CCA_REPORT pReport = (PMEASURE_CCA_REPORT)pReportBuf;
1298 ptr = eid_ptr->Octet + 3; 1588 ptr = (PUCHAR)(eid_ptr->Octet + 3);
1299 NdisMoveMemory(&pReport->ChNum, ptr, 1); 1589 NdisMoveMemory(&pReport->ChNum, ptr, 1);
1300 NdisMoveMemory(&pReport->MeasureStartTime, ptr + 1, 8); 1590 NdisMoveMemory(&pReport->MeasureStartTime, ptr + 1, 8);
1301 NdisMoveMemory(&pReport->MeasureDuration, ptr + 9, 2); 1591 NdisMoveMemory(&pReport->MeasureDuration, ptr + 9, 2);
@@ -1305,7 +1595,7 @@ static BOOLEAN PeerMeasureReportSanity(
1305 else if (pMeasureReportInfo->ReportType == RM_RPI_HISTOGRAM) 1595 else if (pMeasureReportInfo->ReportType == RM_RPI_HISTOGRAM)
1306 { 1596 {
1307 PMEASURE_RPI_REPORT pReport = (PMEASURE_RPI_REPORT)pReportBuf; 1597 PMEASURE_RPI_REPORT pReport = (PMEASURE_RPI_REPORT)pReportBuf;
1308 ptr = eid_ptr->Octet + 3; 1598 ptr = (PUCHAR)(eid_ptr->Octet + 3);
1309 NdisMoveMemory(&pReport->ChNum, ptr, 1); 1599 NdisMoveMemory(&pReport->ChNum, ptr, 1);
1310 NdisMoveMemory(&pReport->MeasureStartTime, ptr + 1, 8); 1600 NdisMoveMemory(&pReport->MeasureStartTime, ptr + 1, 8);
1311 NdisMoveMemory(&pReport->MeasureDuration, ptr + 9, 2); 1601 NdisMoveMemory(&pReport->MeasureDuration, ptr + 9, 2);
@@ -1533,9 +1823,10 @@ static VOID PeerMeasureReqAction(
1533 PFRAME_802_11 pFr = (PFRAME_802_11)Elem->Msg; 1823 PFRAME_802_11 pFr = (PFRAME_802_11)Elem->Msg;
1534 UINT8 DialogToken; 1824 UINT8 DialogToken;
1535 MEASURE_REQ_INFO MeasureReqInfo; 1825 MEASURE_REQ_INFO MeasureReqInfo;
1826 MEASURE_REQ MeasureReq;
1536 MEASURE_REPORT_MODE ReportMode; 1827 MEASURE_REPORT_MODE ReportMode;
1537 1828
1538 if(PeerMeasureReqSanity(pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &MeasureReqInfo)) 1829 if(PeerMeasureReqSanity(pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &MeasureReqInfo, &MeasureReq))
1539 { 1830 {
1540 ReportMode.word = 0; 1831 ReportMode.word = 0;
1541 ReportMode.field.Incapable = 1; 1832 ReportMode.field.Incapable = 1;
@@ -1729,8 +2020,8 @@ VOID PeerSpectrumAction(
1729 break; 2020 break;
1730 2021
1731 case SPEC_CHANNEL_SWITCH: 2022 case SPEC_CHANNEL_SWITCH:
1732{ 2023
1733} 2024
1734 PeerChSwAnnAction(pAd, Elem); 2025 PeerChSwAnnAction(pAd, Elem);
1735 break; 2026 break;
1736 } 2027 }
@@ -1749,16 +2040,31 @@ VOID PeerSpectrumAction(
1749 */ 2040 */
1750INT Set_MeasureReq_Proc( 2041INT Set_MeasureReq_Proc(
1751 IN PRTMP_ADAPTER pAd, 2042 IN PRTMP_ADAPTER pAd,
1752 IN PUCHAR arg) 2043 IN PSTRING arg)
1753{ 2044{
1754 UINT Aid = 1; 2045 UINT Aid = 1;
1755 UINT ArgIdx; 2046 UINT ArgIdx;
1756 PUCHAR thisChar; 2047 PSTRING thisChar;
1757 2048
1758 MEASURE_REQ_MODE MeasureReqMode; 2049 MEASURE_REQ_MODE MeasureReqMode;
1759 UINT8 MeasureReqToken = RandomByte(pAd); 2050 UINT8 MeasureReqToken = RandomByte(pAd);
1760 UINT8 MeasureReqType = RM_BASIC; 2051 UINT8 MeasureReqType = RM_BASIC;
1761 UINT8 MeasureCh = 1; 2052 UINT8 MeasureCh = 1;
2053 UINT64 MeasureStartTime = GetCurrentTimeStamp(pAd);
2054 MEASURE_REQ MeasureReq;
2055 UINT8 TotalLen;
2056
2057 HEADER_802_11 ActHdr;
2058 PUCHAR pOutBuffer = NULL;
2059 NDIS_STATUS NStatus;
2060 ULONG FrameLen;
2061
2062 NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); //Get an unused nonpaged memory
2063 if(NStatus != NDIS_STATUS_SUCCESS)
2064 {
2065 DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __func__));
2066 goto END_OF_MEASURE_REQ;
2067 }
1762 2068
1763 ArgIdx = 1; 2069 ArgIdx = 1;
1764 while ((thisChar = strsep((char **)&arg, "-")) != NULL) 2070 while ((thisChar = strsep((char **)&arg, "-")) != NULL)
@@ -1766,7 +2072,7 @@ INT Set_MeasureReq_Proc(
1766 switch(ArgIdx) 2072 switch(ArgIdx)
1767 { 2073 {
1768 case 1: // Aid. 2074 case 1: // Aid.
1769 Aid = simple_strtol(thisChar, 0, 16); 2075 Aid = (UINT8) simple_strtol(thisChar, 0, 16);
1770 break; 2076 break;
1771 2077
1772 case 2: // Measurement Request Type. 2078 case 2: // Measurement Request Type.
@@ -1774,12 +2080,12 @@ INT Set_MeasureReq_Proc(
1774 if (MeasureReqType > 3) 2080 if (MeasureReqType > 3)
1775 { 2081 {
1776 DBGPRINT(RT_DEBUG_ERROR, ("%s: unknow MeasureReqType(%d)\n", __func__, MeasureReqType)); 2082 DBGPRINT(RT_DEBUG_ERROR, ("%s: unknow MeasureReqType(%d)\n", __func__, MeasureReqType));
1777 return TRUE; 2083 goto END_OF_MEASURE_REQ;
1778 } 2084 }
1779 break; 2085 break;
1780 2086
1781 case 3: // Measurement channel. 2087 case 3: // Measurement channel.
1782 MeasureCh = simple_strtol(thisChar, 0, 16); 2088 MeasureCh = (UINT8) simple_strtol(thisChar, 0, 16);
1783 break; 2089 break;
1784 } 2090 }
1785 ArgIdx++; 2091 ArgIdx++;
@@ -1789,7 +2095,7 @@ INT Set_MeasureReq_Proc(
1789 if (!VALID_WCID(Aid)) 2095 if (!VALID_WCID(Aid))
1790 { 2096 {
1791 DBGPRINT(RT_DEBUG_ERROR, ("%s: unknow sta of Aid(%d)\n", __func__, Aid)); 2097 DBGPRINT(RT_DEBUG_ERROR, ("%s: unknow sta of Aid(%d)\n", __func__, Aid));
1792 return TRUE; 2098 goto END_OF_MEASURE_REQ;
1793 } 2099 }
1794 2100
1795 MeasureReqMode.word = 0; 2101 MeasureReqMode.word = 0;
@@ -1797,21 +2103,49 @@ INT Set_MeasureReq_Proc(
1797 2103
1798 MeasureReqInsert(pAd, MeasureReqToken); 2104 MeasureReqInsert(pAd, MeasureReqToken);
1799 2105
1800 EnqueueMeasurementReq(pAd, pAd->MacTab.Content[Aid].Addr, 2106 // build action frame header.
1801 MeasureReqToken, MeasureReqMode.word, MeasureReqType, MeasureCh, 2000); 2107 MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pAd->MacTab.Content[Aid].Addr,
2108 pAd->CurrentAddress);
2109
2110 NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11));
2111 FrameLen = sizeof(HEADER_802_11);
2112
2113 TotalLen = sizeof(MEASURE_REQ_INFO) + sizeof(MEASURE_REQ);
2114
2115 MakeMeasurementReqFrame(pAd, pOutBuffer, &FrameLen,
2116 sizeof(MEASURE_REQ_INFO), CATEGORY_RM, RM_BASIC,
2117 MeasureReqToken, MeasureReqMode.word,
2118 MeasureReqType, 0);
2119
2120 MeasureReq.ChNum = MeasureCh;
2121 MeasureReq.MeasureStartTime = cpu2le64(MeasureStartTime);
2122 MeasureReq.MeasureDuration = cpu2le16(2000);
2123
2124 {
2125 ULONG TempLen;
2126 MakeOutgoingFrame( pOutBuffer+FrameLen, &TempLen,
2127 sizeof(MEASURE_REQ), &MeasureReq,
2128 END_OF_ARGS);
2129 FrameLen += TempLen;
2130 }
2131
2132 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, (UINT)FrameLen);
2133
2134END_OF_MEASURE_REQ:
2135 MlmeFreeMemory(pAd, pOutBuffer);
1802 2136
1803 return TRUE; 2137 return TRUE;
1804} 2138}
1805 2139
1806INT Set_TpcReq_Proc( 2140INT Set_TpcReq_Proc(
1807 IN PRTMP_ADAPTER pAd, 2141 IN PRTMP_ADAPTER pAd,
1808 IN PUCHAR arg) 2142 IN PSTRING arg)
1809{ 2143{
1810 UINT Aid; 2144 UINT Aid;
1811 2145
1812 UINT8 TpcReqToken = RandomByte(pAd); 2146 UINT8 TpcReqToken = RandomByte(pAd);
1813 2147
1814 Aid = simple_strtol(arg, 0, 16); 2148 Aid = (UINT) simple_strtol(arg, 0, 16);
1815 2149
1816 DBGPRINT(RT_DEBUG_TRACE, ("%s::Aid = %d\n", __func__, Aid)); 2150 DBGPRINT(RT_DEBUG_TRACE, ("%s::Aid = %d\n", __func__, Aid));
1817 if (!VALID_WCID(Aid)) 2151 if (!VALID_WCID(Aid))