]>
Commit | Line | Data |
---|---|---|
c55519ff GKH |
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 | rtusb_io.c | |
29 | ||
30 | Abstract: | |
31 | ||
32 | Revision History: | |
33 | Who When What | |
34 | -------- ---------- ---------------------------------------------- | |
35 | Name Date Modification logs | |
36 | Paul Lin 06-25-2004 created | |
37 | */ | |
38 | ||
ca97b838 BZ |
39 | #ifdef RTMP_MAC_USB |
40 | ||
41 | ||
c55519ff GKH |
42 | #include "../rt_config.h" |
43 | ||
44 | ||
45 | /* | |
46 | ======================================================================== | |
47 | ||
48 | Routine Description: NIC initialization complete | |
49 | ||
50 | Arguments: | |
51 | ||
52 | Return Value: | |
53 | ||
54 | IRQL = | |
55 | ||
56 | Note: | |
57 | ||
58 | ======================================================================== | |
59 | */ | |
60 | ||
ca97b838 | 61 | static NTSTATUS RTUSBFirmwareRun( |
c55519ff GKH |
62 | IN PRTMP_ADAPTER pAd) |
63 | { | |
64 | NTSTATUS Status; | |
65 | ||
66 | Status = RTUSB_VendorRequest( | |
67 | pAd, | |
68 | USBD_TRANSFER_DIRECTION_OUT, | |
69 | DEVICE_VENDOR_REQUEST_OUT, | |
70 | 0x01, | |
71 | 0x8, | |
72 | 0, | |
73 | NULL, | |
74 | 0); | |
75 | ||
76 | return Status; | |
77 | } | |
78 | ||
79 | ||
80 | ||
81 | /* | |
82 | ======================================================================== | |
83 | ||
84 | Routine Description: Write Firmware to NIC. | |
85 | ||
86 | Arguments: | |
87 | ||
88 | Return Value: | |
89 | ||
90 | IRQL = | |
91 | ||
92 | Note: | |
93 | ||
94 | ======================================================================== | |
95 | */ | |
96 | NTSTATUS RTUSBFirmwareWrite( | |
97 | IN PRTMP_ADAPTER pAd, | |
98 | IN PUCHAR pFwImage, | |
99 | IN ULONG FwLen) | |
100 | { | |
101 | UINT32 MacReg; | |
102 | NTSTATUS Status; | |
103 | // ULONG i; | |
104 | USHORT writeLen; | |
105 | ||
106 | Status = RTUSBReadMACRegister(pAd, MAC_CSR0, &MacReg); | |
107 | ||
108 | ||
109 | writeLen = FwLen; | |
110 | RTUSBMultiWrite(pAd, FIRMWARE_IMAGE_BASE, pFwImage, writeLen); | |
111 | ||
112 | Status = RTUSBWriteMACRegister(pAd, 0x7014, 0xffffffff); | |
113 | Status = RTUSBWriteMACRegister(pAd, 0x701c, 0xffffffff); | |
114 | Status = RTUSBFirmwareRun(pAd); | |
115 | ||
ca97b838 | 116 | //2008/11/28:KH add to fix the dead rf frequency offset bug<-- |
ffbc7b85 BZ |
117 | RTMPusecDelay(10000); |
118 | RTUSBWriteMACRegister(pAd,H2M_MAILBOX_CSR,0); | |
ca97b838 BZ |
119 | AsicSendCommandToMcu(pAd, 0x72, 0x00, 0x00, 0x00); //reset rf by MCU supported by new firmware |
120 | //2008/11/28:KH add to fix the dead rf frequency offset bug--> | |
ffbc7b85 | 121 | |
c55519ff GKH |
122 | return Status; |
123 | } | |
124 | ||
125 | ||
c55519ff GKH |
126 | NTSTATUS RTUSBVenderReset( |
127 | IN PRTMP_ADAPTER pAd) | |
128 | { | |
129 | NTSTATUS Status; | |
130 | DBGPRINT_RAW(RT_DEBUG_ERROR, ("-->RTUSBVenderReset\n")); | |
131 | Status = RTUSB_VendorRequest( | |
132 | pAd, | |
133 | USBD_TRANSFER_DIRECTION_OUT, | |
134 | DEVICE_VENDOR_REQUEST_OUT, | |
135 | 0x01, | |
136 | 0x1, | |
137 | 0, | |
138 | NULL, | |
139 | 0); | |
140 | ||
141 | DBGPRINT_RAW(RT_DEBUG_ERROR, ("<--RTUSBVenderReset\n")); | |
142 | return Status; | |
143 | } | |
144 | /* | |
145 | ======================================================================== | |
146 | ||
147 | Routine Description: Read various length data from RT2573 | |
148 | ||
149 | Arguments: | |
150 | ||
151 | Return Value: | |
152 | ||
153 | IRQL = | |
154 | ||
155 | Note: | |
156 | ||
157 | ======================================================================== | |
158 | */ | |
159 | NTSTATUS RTUSBMultiRead( | |
160 | IN PRTMP_ADAPTER pAd, | |
161 | IN USHORT Offset, | |
162 | OUT PUCHAR pData, | |
163 | IN USHORT length) | |
164 | { | |
165 | NTSTATUS Status; | |
166 | ||
167 | Status = RTUSB_VendorRequest( | |
168 | pAd, | |
169 | (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK), | |
170 | DEVICE_VENDOR_REQUEST_IN, | |
171 | 0x7, | |
172 | 0, | |
173 | Offset, | |
174 | pData, | |
175 | length); | |
176 | ||
177 | return Status; | |
178 | } | |
179 | ||
180 | /* | |
181 | ======================================================================== | |
182 | ||
183 | Routine Description: Write various length data to RT2573 | |
184 | ||
185 | Arguments: | |
186 | ||
187 | Return Value: | |
188 | ||
189 | IRQL = | |
190 | ||
191 | Note: | |
192 | ||
193 | ======================================================================== | |
194 | */ | |
195 | NTSTATUS RTUSBMultiWrite_OneByte( | |
196 | IN PRTMP_ADAPTER pAd, | |
197 | IN USHORT Offset, | |
198 | IN PUCHAR pData) | |
199 | { | |
200 | NTSTATUS Status; | |
201 | ||
202 | // TODO: In 2870, use this funciton carefully cause it's not stable. | |
203 | Status = RTUSB_VendorRequest( | |
204 | pAd, | |
205 | USBD_TRANSFER_DIRECTION_OUT, | |
206 | DEVICE_VENDOR_REQUEST_OUT, | |
207 | 0x6, | |
208 | 0, | |
209 | Offset, | |
210 | pData, | |
211 | 1); | |
212 | ||
213 | return Status; | |
214 | } | |
215 | ||
216 | NTSTATUS RTUSBMultiWrite( | |
217 | IN PRTMP_ADAPTER pAd, | |
218 | IN USHORT Offset, | |
219 | IN PUCHAR pData, | |
220 | IN USHORT length) | |
221 | { | |
222 | NTSTATUS Status; | |
223 | ||
224 | ||
225 | USHORT index = 0,Value; | |
226 | PUCHAR pSrc = pData; | |
227 | USHORT resude = 0; | |
228 | ||
229 | resude = length % 2; | |
230 | length += resude; | |
231 | do | |
232 | { | |
233 | Value =(USHORT)( *pSrc | (*(pSrc + 1) << 8)); | |
234 | Status = RTUSBSingleWrite(pAd,Offset + index,Value); | |
235 | index +=2; | |
236 | length -= 2; | |
237 | pSrc = pSrc + 2; | |
238 | }while(length > 0); | |
239 | ||
240 | return Status; | |
241 | } | |
242 | ||
243 | ||
244 | NTSTATUS RTUSBSingleWrite( | |
245 | IN RTMP_ADAPTER *pAd, | |
246 | IN USHORT Offset, | |
247 | IN USHORT Value) | |
248 | { | |
249 | NTSTATUS Status; | |
250 | ||
251 | Status = RTUSB_VendorRequest( | |
252 | pAd, | |
253 | USBD_TRANSFER_DIRECTION_OUT, | |
254 | DEVICE_VENDOR_REQUEST_OUT, | |
255 | 0x2, | |
256 | Value, | |
257 | Offset, | |
258 | NULL, | |
259 | 0); | |
260 | ||
261 | return Status; | |
262 | ||
263 | } | |
264 | ||
265 | ||
266 | /* | |
267 | ======================================================================== | |
268 | ||
269 | Routine Description: Read 32-bit MAC register | |
270 | ||
271 | Arguments: | |
272 | ||
273 | Return Value: | |
274 | ||
275 | IRQL = | |
276 | ||
277 | Note: | |
278 | ||
279 | ======================================================================== | |
280 | */ | |
281 | NTSTATUS RTUSBReadMACRegister( | |
282 | IN PRTMP_ADAPTER pAd, | |
283 | IN USHORT Offset, | |
284 | OUT PUINT32 pValue) | |
285 | { | |
ca97b838 | 286 | NTSTATUS Status = 0; |
c55519ff GKH |
287 | UINT32 localVal; |
288 | ||
289 | Status = RTUSB_VendorRequest( | |
290 | pAd, | |
291 | (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK), | |
292 | DEVICE_VENDOR_REQUEST_IN, | |
293 | 0x7, | |
294 | 0, | |
295 | Offset, | |
296 | &localVal, | |
297 | 4); | |
298 | ||
299 | *pValue = le2cpu32(localVal); | |
300 | ||
301 | ||
302 | if (Status < 0) | |
303 | *pValue = 0xffffffff; | |
304 | ||
305 | return Status; | |
306 | } | |
307 | ||
308 | ||
309 | /* | |
310 | ======================================================================== | |
311 | ||
312 | Routine Description: Write 32-bit MAC register | |
313 | ||
314 | Arguments: | |
315 | ||
316 | Return Value: | |
317 | ||
318 | IRQL = | |
319 | ||
320 | Note: | |
321 | ||
322 | ======================================================================== | |
323 | */ | |
324 | NTSTATUS RTUSBWriteMACRegister( | |
325 | IN PRTMP_ADAPTER pAd, | |
326 | IN USHORT Offset, | |
327 | IN UINT32 Value) | |
328 | { | |
329 | NTSTATUS Status; | |
330 | UINT32 localVal; | |
331 | ||
332 | localVal = Value; | |
333 | ||
334 | Status = RTUSBSingleWrite(pAd, Offset, (USHORT)(localVal & 0xffff)); | |
335 | Status = RTUSBSingleWrite(pAd, Offset + 2, (USHORT)((localVal & 0xffff0000) >> 16)); | |
336 | ||
337 | return Status; | |
338 | } | |
339 | ||
340 | ||
341 | ||
c55519ff GKH |
342 | /* |
343 | ======================================================================== | |
344 | ||
345 | Routine Description: Read 8-bit BBP register | |
346 | ||
347 | Arguments: | |
348 | ||
349 | Return Value: | |
350 | ||
351 | IRQL = | |
352 | ||
353 | Note: | |
354 | ||
355 | ======================================================================== | |
356 | */ | |
357 | NTSTATUS RTUSBReadBBPRegister( | |
358 | IN PRTMP_ADAPTER pAd, | |
359 | IN UCHAR Id, | |
360 | IN PUCHAR pValue) | |
361 | { | |
362 | BBP_CSR_CFG_STRUC BbpCsr; | |
363 | UINT i = 0; | |
364 | NTSTATUS status; | |
365 | ||
366 | // Verify the busy condition | |
367 | do | |
368 | { | |
369 | status = RTUSBReadMACRegister(pAd, BBP_CSR_CFG, &BbpCsr.word); | |
370 | if(status >= 0) | |
371 | { | |
372 | if (!(BbpCsr.field.Busy == BUSY)) | |
373 | break; | |
374 | } | |
ca97b838 | 375 | DBGPRINT(RT_DEBUG_TRACE, ("RTUSBReadBBPRegister(BBP_CSR_CFG_1):retry count=%d!\n", i)); |
c55519ff | 376 | i++; |
ca97b838 | 377 | }while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))); |
c55519ff GKH |
378 | |
379 | if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) | |
380 | { | |
381 | // | |
382 | // Read failed then Return Default value. | |
383 | // | |
384 | *pValue = pAd->BbpWriteLatch[Id]; | |
385 | ||
386 | DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n")); | |
387 | return STATUS_UNSUCCESSFUL; | |
388 | } | |
389 | ||
390 | // Prepare for write material | |
391 | BbpCsr.word = 0; | |
392 | BbpCsr.field.fRead = 1; | |
393 | BbpCsr.field.Busy = 1; | |
394 | BbpCsr.field.RegNum = Id; | |
395 | RTUSBWriteMACRegister(pAd, BBP_CSR_CFG, BbpCsr.word); | |
396 | ||
397 | i = 0; | |
398 | // Verify the busy condition | |
399 | do | |
400 | { | |
401 | status = RTUSBReadMACRegister(pAd, BBP_CSR_CFG, &BbpCsr.word); | |
402 | if (status >= 0) | |
403 | { | |
404 | if (!(BbpCsr.field.Busy == BUSY)) | |
405 | { | |
406 | *pValue = (UCHAR)BbpCsr.field.Value; | |
407 | break; | |
408 | } | |
409 | } | |
ca97b838 | 410 | DBGPRINT(RT_DEBUG_TRACE, ("RTUSBReadBBPRegister(BBP_CSR_CFG_2):retry count=%d!\n", i)); |
c55519ff | 411 | i++; |
ca97b838 | 412 | }while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))); |
c55519ff GKH |
413 | |
414 | if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) | |
415 | { | |
416 | // | |
417 | // Read failed then Return Default value. | |
418 | // | |
419 | *pValue = pAd->BbpWriteLatch[Id]; | |
420 | ||
421 | DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n")); | |
422 | return STATUS_UNSUCCESSFUL; | |
423 | } | |
424 | ||
425 | return STATUS_SUCCESS; | |
426 | } | |
c55519ff | 427 | |
c55519ff | 428 | |
c55519ff GKH |
429 | /* |
430 | ======================================================================== | |
431 | ||
432 | Routine Description: Write 8-bit BBP register | |
433 | ||
434 | Arguments: | |
435 | ||
436 | Return Value: | |
437 | ||
438 | IRQL = | |
439 | ||
440 | Note: | |
441 | ||
442 | ======================================================================== | |
443 | */ | |
444 | NTSTATUS RTUSBWriteBBPRegister( | |
445 | IN PRTMP_ADAPTER pAd, | |
446 | IN UCHAR Id, | |
447 | IN UCHAR Value) | |
448 | { | |
449 | BBP_CSR_CFG_STRUC BbpCsr; | |
450 | UINT i = 0; | |
451 | NTSTATUS status; | |
452 | // Verify the busy condition | |
453 | do | |
454 | { | |
455 | status = RTUSBReadMACRegister(pAd, BBP_CSR_CFG, &BbpCsr.word); | |
456 | if (status >= 0) | |
457 | { | |
458 | if (!(BbpCsr.field.Busy == BUSY)) | |
459 | break; | |
460 | } | |
ca97b838 | 461 | DBGPRINT(RT_DEBUG_TRACE, ("RTUSBWriteBBPRegister(BBP_CSR_CFG):retry count=%d!\n", i)); |
c55519ff GKH |
462 | i++; |
463 | } | |
464 | while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))); | |
465 | ||
466 | if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) | |
467 | { | |
468 | DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n")); | |
469 | return STATUS_UNSUCCESSFUL; | |
470 | } | |
471 | ||
472 | // Prepare for write material | |
473 | BbpCsr.word = 0; | |
474 | BbpCsr.field.fRead = 0; | |
475 | BbpCsr.field.Value = Value; | |
476 | BbpCsr.field.Busy = 1; | |
477 | BbpCsr.field.RegNum = Id; | |
478 | RTUSBWriteMACRegister(pAd, BBP_CSR_CFG, BbpCsr.word); | |
479 | ||
480 | pAd->BbpWriteLatch[Id] = Value; | |
481 | ||
482 | return STATUS_SUCCESS; | |
483 | } | |
c55519ff GKH |
484 | /* |
485 | ======================================================================== | |
486 | ||
487 | Routine Description: Write RF register through MAC | |
488 | ||
489 | Arguments: | |
490 | ||
491 | Return Value: | |
492 | ||
493 | IRQL = | |
494 | ||
495 | Note: | |
496 | ||
497 | ======================================================================== | |
498 | */ | |
499 | NTSTATUS RTUSBWriteRFRegister( | |
500 | IN PRTMP_ADAPTER pAd, | |
501 | IN UINT32 Value) | |
502 | { | |
503 | PHY_CSR4_STRUC PhyCsr4; | |
504 | UINT i = 0; | |
505 | NTSTATUS status; | |
506 | ||
507 | NdisZeroMemory(&PhyCsr4, sizeof(PHY_CSR4_STRUC)); | |
508 | do | |
509 | { | |
510 | status = RTUSBReadMACRegister(pAd, RF_CSR_CFG0, &PhyCsr4.word); | |
511 | if (status >= 0) | |
512 | { | |
513 | if (!(PhyCsr4.field.Busy)) | |
514 | break; | |
515 | } | |
ca97b838 | 516 | DBGPRINT(RT_DEBUG_TRACE, ("RTUSBWriteRFRegister(RF_CSR_CFG0):retry count=%d!\n", i)); |
c55519ff GKH |
517 | i++; |
518 | } | |
519 | while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))); | |
520 | ||
521 | if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) | |
522 | { | |
523 | DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n")); | |
524 | return STATUS_UNSUCCESSFUL; | |
525 | } | |
526 | ||
527 | RTUSBWriteMACRegister(pAd, RF_CSR_CFG0, Value); | |
528 | ||
529 | return STATUS_SUCCESS; | |
530 | } | |
531 | ||
c55519ff GKH |
532 | |
533 | /* | |
534 | ======================================================================== | |
535 | ||
536 | Routine Description: | |
537 | ||
538 | Arguments: | |
539 | ||
540 | Return Value: | |
541 | ||
542 | IRQL = | |
543 | ||
544 | Note: | |
545 | ||
546 | ======================================================================== | |
547 | */ | |
548 | NTSTATUS RTUSBReadEEPROM( | |
549 | IN PRTMP_ADAPTER pAd, | |
550 | IN USHORT Offset, | |
551 | OUT PUCHAR pData, | |
552 | IN USHORT length) | |
553 | { | |
554 | NTSTATUS Status = STATUS_SUCCESS; | |
555 | ||
556 | Status = RTUSB_VendorRequest( | |
557 | pAd, | |
558 | (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK), | |
559 | DEVICE_VENDOR_REQUEST_IN, | |
560 | 0x9, | |
561 | 0, | |
562 | Offset, | |
563 | pData, | |
564 | length); | |
565 | ||
566 | return Status; | |
567 | } | |
568 | ||
569 | /* | |
570 | ======================================================================== | |
571 | ||
572 | Routine Description: | |
573 | ||
574 | Arguments: | |
575 | ||
576 | Return Value: | |
577 | ||
578 | IRQL = | |
579 | ||
580 | Note: | |
581 | ||
582 | ======================================================================== | |
583 | */ | |
584 | NTSTATUS RTUSBWriteEEPROM( | |
585 | IN PRTMP_ADAPTER pAd, | |
586 | IN USHORT Offset, | |
587 | IN PUCHAR pData, | |
588 | IN USHORT length) | |
589 | { | |
590 | NTSTATUS Status = STATUS_SUCCESS; | |
591 | ||
592 | Status = RTUSB_VendorRequest( | |
593 | pAd, | |
594 | USBD_TRANSFER_DIRECTION_OUT, | |
595 | DEVICE_VENDOR_REQUEST_OUT, | |
596 | 0x8, | |
597 | 0, | |
598 | Offset, | |
599 | pData, | |
600 | length); | |
601 | ||
602 | return Status; | |
603 | } | |
604 | ||
ca97b838 BZ |
605 | |
606 | NTSTATUS RTUSBReadEEPROM16( | |
607 | IN PRTMP_ADAPTER pAd, | |
608 | IN USHORT offset, | |
609 | OUT PUSHORT pData) | |
610 | { | |
611 | NTSTATUS status; | |
612 | USHORT localData; | |
613 | ||
614 | status = RTUSBReadEEPROM(pAd, offset, (PUCHAR)(&localData), 2); | |
615 | if (status == STATUS_SUCCESS) | |
616 | *pData = le2cpu16(localData); | |
617 | ||
618 | return status; | |
619 | ||
620 | } | |
621 | ||
c55519ff GKH |
622 | /* |
623 | ======================================================================== | |
624 | ||
625 | Routine Description: | |
626 | ||
627 | Arguments: | |
628 | ||
629 | Return Value: | |
630 | ||
631 | IRQL = | |
632 | ||
633 | Note: | |
634 | ||
635 | ======================================================================== | |
636 | */ | |
637 | VOID RTUSBPutToSleep( | |
638 | IN PRTMP_ADAPTER pAd) | |
639 | { | |
640 | UINT32 value; | |
641 | ||
642 | // Timeout 0x40 x 50us | |
643 | value = (SLEEPCID<<16)+(OWNERMCU<<24)+ (0x40<<8)+1; | |
644 | RTUSBWriteMACRegister(pAd, 0x7010, value); | |
645 | RTUSBWriteMACRegister(pAd, 0x404, 0x30); | |
646 | //RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); | |
647 | DBGPRINT_RAW(RT_DEBUG_ERROR, ("Sleep Mailbox testvalue %x\n", value)); | |
648 | ||
649 | } | |
650 | ||
651 | /* | |
652 | ======================================================================== | |
653 | ||
654 | Routine Description: | |
655 | ||
656 | Arguments: | |
657 | ||
658 | Return Value: | |
659 | ||
660 | IRQL = | |
661 | ||
662 | Note: | |
663 | ||
664 | ======================================================================== | |
665 | */ | |
666 | NTSTATUS RTUSBWakeUp( | |
667 | IN PRTMP_ADAPTER pAd) | |
668 | { | |
669 | NTSTATUS Status; | |
670 | ||
671 | Status = RTUSB_VendorRequest( | |
672 | pAd, | |
673 | USBD_TRANSFER_DIRECTION_OUT, | |
674 | DEVICE_VENDOR_REQUEST_OUT, | |
675 | 0x01, | |
676 | 0x09, | |
677 | 0, | |
678 | NULL, | |
679 | 0); | |
680 | ||
681 | return Status; | |
682 | } | |
683 | ||
684 | /* | |
685 | ======================================================================== | |
686 | ||
687 | Routine Description: | |
688 | ||
689 | Arguments: | |
690 | ||
691 | Return Value: | |
692 | ||
693 | IRQL = | |
694 | ||
695 | Note: | |
696 | ||
697 | ======================================================================== | |
698 | */ | |
699 | VOID RTUSBInitializeCmdQ( | |
700 | IN PCmdQ cmdq) | |
701 | { | |
702 | cmdq->head = NULL; | |
703 | cmdq->tail = NULL; | |
704 | cmdq->size = 0; | |
ca97b838 | 705 | cmdq->CmdQState = RTMP_TASK_STAT_INITED; |
c55519ff GKH |
706 | } |
707 | ||
708 | /* | |
709 | ======================================================================== | |
710 | ||
711 | Routine Description: | |
712 | ||
713 | Arguments: | |
714 | ||
715 | Return Value: | |
716 | ||
717 | IRQL = | |
718 | ||
719 | Note: | |
720 | ||
721 | ======================================================================== | |
722 | */ | |
723 | NDIS_STATUS RTUSBEnqueueCmdFromNdis( | |
724 | IN PRTMP_ADAPTER pAd, | |
725 | IN NDIS_OID Oid, | |
726 | IN BOOLEAN SetInformation, | |
727 | IN PVOID pInformationBuffer, | |
728 | IN UINT32 InformationBufferLength) | |
729 | { | |
730 | NDIS_STATUS status; | |
731 | PCmdQElmt cmdqelmt = NULL; | |
ca97b838 | 732 | RTMP_OS_TASK *pTask = &pAd->cmdQTask; |
c55519ff | 733 | |
ca97b838 BZ |
734 | #ifdef KTHREAD_SUPPORT |
735 | if (pTask->kthread_task == NULL) | |
736 | #else | |
737 | CHECK_PID_LEGALITY(pTask->taskPID) | |
738 | { | |
739 | } | |
740 | else | |
741 | #endif | |
c55519ff GKH |
742 | return (NDIS_STATUS_RESOURCES); |
743 | ||
ca97b838 | 744 | status = os_alloc_mem(pAd, (PUCHAR *)(&cmdqelmt), sizeof(CmdQElmt)); |
c55519ff GKH |
745 | if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt == NULL)) |
746 | return (NDIS_STATUS_RESOURCES); | |
747 | ||
748 | cmdqelmt->buffer = NULL; | |
749 | if (pInformationBuffer != NULL) | |
750 | { | |
ca97b838 | 751 | status = os_alloc_mem(pAd, (PUCHAR *)&cmdqelmt->buffer, InformationBufferLength); |
c55519ff GKH |
752 | if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt->buffer == NULL)) |
753 | { | |
754 | kfree(cmdqelmt); | |
755 | return (NDIS_STATUS_RESOURCES); | |
756 | } | |
757 | else | |
758 | { | |
759 | NdisMoveMemory(cmdqelmt->buffer, pInformationBuffer, InformationBufferLength); | |
760 | cmdqelmt->bufferlength = InformationBufferLength; | |
761 | } | |
762 | } | |
763 | else | |
764 | cmdqelmt->bufferlength = 0; | |
765 | ||
766 | cmdqelmt->command = Oid; | |
767 | cmdqelmt->CmdFromNdis = TRUE; | |
768 | if (SetInformation == TRUE) | |
769 | cmdqelmt->SetOperation = TRUE; | |
770 | else | |
771 | cmdqelmt->SetOperation = FALSE; | |
772 | ||
773 | NdisAcquireSpinLock(&pAd->CmdQLock); | |
ca97b838 | 774 | if (pAd->CmdQ.CmdQState & RTMP_TASK_CAN_DO_INSERT) |
c55519ff GKH |
775 | { |
776 | EnqueueCmd((&pAd->CmdQ), cmdqelmt); | |
777 | status = NDIS_STATUS_SUCCESS; | |
778 | } | |
779 | else | |
780 | { | |
781 | status = NDIS_STATUS_FAILURE; | |
782 | } | |
783 | NdisReleaseSpinLock(&pAd->CmdQLock); | |
784 | ||
785 | if (status == NDIS_STATUS_FAILURE) | |
786 | { | |
787 | if (cmdqelmt->buffer) | |
ca97b838 BZ |
788 | os_free_mem(pAd, cmdqelmt->buffer); |
789 | os_free_mem(pAd, cmdqelmt); | |
c55519ff GKH |
790 | } |
791 | else | |
792 | RTUSBCMDUp(pAd); | |
793 | ||
794 | ||
795 | return(NDIS_STATUS_SUCCESS); | |
796 | } | |
797 | ||
798 | /* | |
799 | ======================================================================== | |
800 | ||
801 | Routine Description: | |
802 | ||
803 | Arguments: | |
804 | ||
805 | Return Value: | |
806 | ||
807 | IRQL = | |
808 | ||
809 | Note: | |
810 | ||
811 | ======================================================================== | |
812 | */ | |
813 | NDIS_STATUS RTUSBEnqueueInternalCmd( | |
814 | IN PRTMP_ADAPTER pAd, | |
815 | IN NDIS_OID Oid, | |
816 | IN PVOID pInformationBuffer, | |
817 | IN UINT32 InformationBufferLength) | |
818 | { | |
819 | NDIS_STATUS status; | |
820 | PCmdQElmt cmdqelmt = NULL; | |
821 | ||
822 | ||
ca97b838 | 823 | status = os_alloc_mem(pAd, (PUCHAR *)&cmdqelmt, sizeof(CmdQElmt)); |
c55519ff GKH |
824 | if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt == NULL)) |
825 | return (NDIS_STATUS_RESOURCES); | |
826 | NdisZeroMemory(cmdqelmt, sizeof(CmdQElmt)); | |
827 | ||
828 | if(InformationBufferLength > 0) | |
829 | { | |
ca97b838 | 830 | status = os_alloc_mem(pAd, (PUCHAR *)&cmdqelmt->buffer, InformationBufferLength); |
c55519ff GKH |
831 | if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt->buffer == NULL)) |
832 | { | |
ca97b838 | 833 | os_free_mem(pAd, cmdqelmt); |
c55519ff GKH |
834 | return (NDIS_STATUS_RESOURCES); |
835 | } | |
836 | else | |
837 | { | |
838 | NdisMoveMemory(cmdqelmt->buffer, pInformationBuffer, InformationBufferLength); | |
839 | cmdqelmt->bufferlength = InformationBufferLength; | |
840 | } | |
841 | } | |
842 | else | |
843 | { | |
844 | cmdqelmt->buffer = NULL; | |
845 | cmdqelmt->bufferlength = 0; | |
846 | } | |
847 | ||
848 | cmdqelmt->command = Oid; | |
849 | cmdqelmt->CmdFromNdis = FALSE; | |
850 | ||
851 | if (cmdqelmt != NULL) | |
852 | { | |
853 | NdisAcquireSpinLock(&pAd->CmdQLock); | |
ca97b838 | 854 | if (pAd->CmdQ.CmdQState & RTMP_TASK_CAN_DO_INSERT) |
c55519ff GKH |
855 | { |
856 | EnqueueCmd((&pAd->CmdQ), cmdqelmt); | |
857 | status = NDIS_STATUS_SUCCESS; | |
858 | } | |
859 | else | |
860 | { | |
861 | status = NDIS_STATUS_FAILURE; | |
862 | } | |
863 | NdisReleaseSpinLock(&pAd->CmdQLock); | |
864 | ||
865 | if (status == NDIS_STATUS_FAILURE) | |
866 | { | |
867 | if (cmdqelmt->buffer) | |
ca97b838 BZ |
868 | os_free_mem(pAd, cmdqelmt->buffer); |
869 | os_free_mem(pAd, cmdqelmt); | |
c55519ff GKH |
870 | } |
871 | else | |
872 | RTUSBCMDUp(pAd); | |
873 | } | |
874 | return(NDIS_STATUS_SUCCESS); | |
875 | } | |
876 | ||
877 | /* | |
878 | ======================================================================== | |
879 | ||
880 | Routine Description: | |
881 | ||
882 | Arguments: | |
883 | ||
884 | Return Value: | |
885 | ||
886 | IRQL = | |
887 | ||
888 | Note: | |
889 | ||
890 | ======================================================================== | |
891 | */ | |
892 | VOID RTUSBDequeueCmd( | |
893 | IN PCmdQ cmdq, | |
894 | OUT PCmdQElmt *pcmdqelmt) | |
895 | { | |
896 | *pcmdqelmt = cmdq->head; | |
897 | ||
898 | if (*pcmdqelmt != NULL) | |
899 | { | |
900 | cmdq->head = cmdq->head->next; | |
901 | cmdq->size--; | |
902 | if (cmdq->size == 0) | |
903 | cmdq->tail = NULL; | |
904 | } | |
905 | } | |
906 | ||
907 | /* | |
908 | ======================================================================== | |
909 | usb_control_msg - Builds a control urb, sends it off and waits for completion | |
910 | @dev: pointer to the usb device to send the message to | |
911 | @pipe: endpoint "pipe" to send the message to | |
912 | @request: USB message request value | |
913 | @requesttype: USB message request type value | |
914 | @value: USB message value | |
915 | @index: USB message index value | |
916 | @data: pointer to the data to send | |
917 | @size: length in bytes of the data to send | |
918 | @timeout: time in jiffies to wait for the message to complete before | |
919 | timing out (if 0 the wait is forever) | |
920 | Context: !in_interrupt () | |
921 | ||
922 | This function sends a simple control message to a specified endpoint | |
923 | and waits for the message to complete, or timeout. | |
924 | If successful, it returns the number of bytes transferred, otherwise a negative error number. | |
925 | ||
926 | Don't use this function from within an interrupt context, like a | |
927 | bottom half handler. If you need an asynchronous message, or need to send | |
928 | a message from within interrupt context, use usb_submit_urb() | |
929 | If a thread in your driver uses this call, make sure your disconnect() | |
930 | method can wait for it to complete. Since you don't have a handle on | |
931 | the URB used, you can't cancel the request. | |
932 | ||
933 | ||
934 | Routine Description: | |
935 | ||
936 | Arguments: | |
937 | ||
938 | Return Value: | |
939 | ||
940 | Note: | |
941 | ||
942 | ======================================================================== | |
943 | */ | |
944 | NTSTATUS RTUSB_VendorRequest( | |
945 | IN PRTMP_ADAPTER pAd, | |
946 | IN UINT32 TransferFlags, | |
947 | IN UCHAR RequestType, | |
948 | IN UCHAR Request, | |
949 | IN USHORT Value, | |
950 | IN USHORT Index, | |
951 | IN PVOID TransferBuffer, | |
952 | IN UINT32 TransferBufferLength) | |
953 | { | |
ca97b838 | 954 | int ret = 0; |
c55519ff GKH |
955 | POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; |
956 | ||
957 | if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) | |
958 | { | |
959 | DBGPRINT(RT_DEBUG_ERROR, ("device disconnected\n")); | |
960 | return -1; | |
961 | } | |
962 | else if (in_interrupt()) | |
963 | { | |
964 | DBGPRINT(RT_DEBUG_ERROR, ("in_interrupt, RTUSB_VendorRequest Request%02x Value%04x Offset%04x\n",Request,Value,Index)); | |
965 | ||
966 | return -1; | |
967 | } | |
968 | else | |
969 | { | |
970 | #define MAX_RETRY_COUNT 10 | |
971 | ||
972 | int retryCount = 0; | |
973 | void *tmpBuf = TransferBuffer; | |
974 | ||
ca97b838 BZ |
975 | ret = down_interruptible(&(pAd->UsbVendorReq_semaphore)); |
976 | if (pAd->UsbVendorReqBuf) | |
977 | { | |
978 | ASSERT(TransferBufferLength <MAX_PARAM_BUFFER_SIZE); | |
979 | ||
980 | tmpBuf = (void *)pAd->UsbVendorReqBuf; | |
981 | NdisZeroMemory(pAd->UsbVendorReqBuf, TransferBufferLength); | |
982 | ||
983 | if (RequestType == DEVICE_VENDOR_REQUEST_OUT) | |
984 | NdisMoveMemory(tmpBuf, TransferBuffer, TransferBufferLength); | |
985 | } | |
986 | ||
c55519ff GKH |
987 | do { |
988 | if( RequestType == DEVICE_VENDOR_REQUEST_OUT) | |
989 | ret=usb_control_msg(pObj->pUsb_Dev, usb_sndctrlpipe( pObj->pUsb_Dev, 0 ), Request, RequestType, Value,Index, tmpBuf, TransferBufferLength, CONTROL_TIMEOUT_JIFFIES); | |
990 | else if(RequestType == DEVICE_VENDOR_REQUEST_IN) | |
991 | ret=usb_control_msg(pObj->pUsb_Dev, usb_rcvctrlpipe( pObj->pUsb_Dev, 0 ), Request, RequestType, Value,Index, tmpBuf, TransferBufferLength, CONTROL_TIMEOUT_JIFFIES); | |
992 | else | |
993 | { | |
994 | DBGPRINT(RT_DEBUG_ERROR, ("vendor request direction is failed\n")); | |
995 | ret = -1; | |
996 | } | |
997 | ||
998 | retryCount++; | |
999 | if (ret < 0) { | |
ca97b838 | 1000 | DBGPRINT(RT_DEBUG_OFF, ("#\n")); |
c55519ff GKH |
1001 | RTMPusecDelay(5000); |
1002 | } | |
1003 | } while((ret < 0) && (retryCount < MAX_RETRY_COUNT)); | |
1004 | ||
ca97b838 BZ |
1005 | if ((pAd->UsbVendorReqBuf) && (RequestType == DEVICE_VENDOR_REQUEST_IN)) |
1006 | NdisMoveMemory(TransferBuffer, tmpBuf, TransferBufferLength); | |
1007 | up(&(pAd->UsbVendorReq_semaphore)); | |
1008 | ||
c55519ff | 1009 | if (ret < 0) { |
c55519ff GKH |
1010 | DBGPRINT(RT_DEBUG_ERROR, ("RTUSB_VendorRequest failed(%d),TxFlags=0x%x, ReqType=%s, Req=0x%x, Index=0x%x\n", |
1011 | ret, TransferFlags, (RequestType == DEVICE_VENDOR_REQUEST_OUT ? "OUT" : "IN"), Request, Index)); | |
1012 | if (Request == 0x2) | |
1013 | DBGPRINT(RT_DEBUG_ERROR, ("\tRequest Value=0x%04x!\n", Value)); | |
1014 | ||
1015 | if ((TransferBuffer!= NULL) && (TransferBufferLength > 0)) | |
1016 | hex_dump("Failed TransferBuffer value", TransferBuffer, TransferBufferLength); | |
1017 | } | |
ca97b838 BZ |
1018 | |
1019 | ||
c55519ff | 1020 | } |
ca97b838 BZ |
1021 | |
1022 | if (ret != -1) | |
1023 | return STATUS_SUCCESS; | |
1024 | else | |
1025 | return STATUS_UNSUCCESSFUL; | |
c55519ff GKH |
1026 | } |
1027 | ||
1028 | /* | |
1029 | ======================================================================== | |
1030 | ||
1031 | Routine Description: | |
1032 | Creates an IRP to submite an IOCTL_INTERNAL_USB_RESET_PORT | |
1033 | synchronously. Callers of this function must be running at | |
1034 | PASSIVE LEVEL. | |
1035 | ||
1036 | Arguments: | |
1037 | ||
1038 | Return Value: | |
1039 | ||
1040 | Note: | |
1041 | ||
1042 | ======================================================================== | |
1043 | */ | |
1044 | NTSTATUS RTUSB_ResetDevice( | |
1045 | IN PRTMP_ADAPTER pAd) | |
1046 | { | |
1047 | NTSTATUS Status = TRUE; | |
1048 | ||
1049 | DBGPRINT_RAW(RT_DEBUG_TRACE, ("--->USB_ResetDevice\n")); | |
1050 | //RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS); | |
1051 | return Status; | |
1052 | } | |
1053 | ||
1054 | VOID CMDHandler( | |
1055 | IN PRTMP_ADAPTER pAd) | |
1056 | { | |
1057 | PCmdQElmt cmdqelmt; | |
1058 | PUCHAR pData; | |
1059 | NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS; | |
1060 | // ULONG Now = 0; | |
1061 | NTSTATUS ntStatus; | |
1062 | // unsigned long IrqFlags; | |
1063 | ||
ca97b838 | 1064 | while (pAd && pAd->CmdQ.size > 0) |
c55519ff GKH |
1065 | { |
1066 | NdisStatus = NDIS_STATUS_SUCCESS; | |
1067 | ||
1068 | NdisAcquireSpinLock(&pAd->CmdQLock); | |
1069 | RTUSBDequeueCmd(&pAd->CmdQ, &cmdqelmt); | |
1070 | NdisReleaseSpinLock(&pAd->CmdQLock); | |
1071 | ||
1072 | if (cmdqelmt == NULL) | |
1073 | break; | |
1074 | ||
1075 | pData = cmdqelmt->buffer; | |
1076 | ||
1077 | if(!(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))) | |
1078 | { | |
1079 | switch (cmdqelmt->command) | |
1080 | { | |
1081 | case CMDTHREAD_CHECK_GPIO: | |
1082 | { | |
c55519ff | 1083 | UINT32 data; |
c55519ff | 1084 | |
c55519ff GKH |
1085 | { |
1086 | // Read GPIO pin2 as Hardware controlled radio state | |
1087 | ||
1088 | RTUSBReadMACRegister( pAd, GPIO_CTRL_CFG, &data); | |
1089 | ||
1090 | if (data & 0x04) | |
1091 | { | |
1092 | pAd->StaCfg.bHwRadio = TRUE; | |
1093 | } | |
1094 | else | |
1095 | { | |
1096 | pAd->StaCfg.bHwRadio = FALSE; | |
1097 | } | |
1098 | ||
1099 | if(pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio)) | |
1100 | { | |
1101 | pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio); | |
1102 | if(pAd->StaCfg.bRadio == TRUE) | |
1103 | { | |
1104 | DBGPRINT_RAW(RT_DEBUG_ERROR, ("!!! Radio On !!!\n")); | |
1105 | ||
1106 | MlmeRadioOn(pAd); | |
1107 | // Update extra information | |
1108 | pAd->ExtraInfo = EXTRA_INFO_CLEAR; | |
1109 | } | |
1110 | else | |
1111 | { | |
1112 | DBGPRINT_RAW(RT_DEBUG_ERROR, ("!!! Radio Off !!!\n")); | |
1113 | ||
1114 | MlmeRadioOff(pAd); | |
1115 | // Update extra information | |
1116 | pAd->ExtraInfo = HW_RADIO_OFF; | |
1117 | } | |
1118 | } | |
1119 | } | |
c55519ff GKH |
1120 | } |
1121 | break; | |
1122 | ||
c55519ff GKH |
1123 | case CMDTHREAD_QKERIODIC_EXECUT: |
1124 | { | |
1125 | StaQuickResponeForRateUpExec(NULL, pAd, NULL, NULL); | |
1126 | } | |
1127 | break; | |
c55519ff GKH |
1128 | |
1129 | case CMDTHREAD_RESET_BULK_OUT: | |
1130 | { | |
1131 | UINT32 MACValue; | |
1132 | UCHAR Index; | |
1133 | int ret=0; | |
1134 | PHT_TX_CONTEXT pHTTXContext; | |
1135 | // RTMP_TX_RING *pTxRing; | |
1136 | unsigned long IrqFlags; | |
ae2d5411 | 1137 | |
c55519ff GKH |
1138 | DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_OUT(ResetPipeid=0x%0x)===>\n", pAd->bulkResetPipeid)); |
1139 | // All transfers must be aborted or cancelled before attempting to reset the pipe. | |
1140 | //RTUSBCancelPendingBulkOutIRP(pAd); | |
1141 | // Wait 10ms to let previous packet that are already in HW FIFO to clear. by MAXLEE 12-25-2007 | |
1142 | Index = 0; | |
1143 | do | |
1144 | { | |
1145 | RTUSBReadMACRegister(pAd, TXRXQ_PCNT, &MACValue); | |
1146 | if ((MACValue & 0xf00000/*0x800000*/) == 0) | |
1147 | break; | |
1148 | Index++; | |
1149 | RTMPusecDelay(10000); | |
1150 | }while(Index < 100); | |
1151 | MACValue = 0; | |
1152 | RTUSBReadMACRegister(pAd, USB_DMA_CFG, &MACValue); | |
1153 | // To prevent Read Register error, we 2nd check the validity. | |
1154 | if ((MACValue & 0xc00000) == 0) | |
1155 | RTUSBReadMACRegister(pAd, USB_DMA_CFG, &MACValue); | |
1156 | // To prevent Read Register error, we 3rd check the validity. | |
1157 | if ((MACValue & 0xc00000) == 0) | |
1158 | RTUSBReadMACRegister(pAd, USB_DMA_CFG, &MACValue); | |
1159 | MACValue |= 0x80000; | |
1160 | RTUSBWriteMACRegister(pAd, USB_DMA_CFG, MACValue); | |
1161 | ||
1162 | // Wait 1ms to prevent next URB to bulkout before HW reset. by MAXLEE 12-25-2007 | |
1163 | RTMPusecDelay(1000); | |
1164 | ||
1165 | MACValue &= (~0x80000); | |
1166 | RTUSBWriteMACRegister(pAd, USB_DMA_CFG, MACValue); | |
1167 | DBGPRINT_RAW(RT_DEBUG_TRACE, ("\tSet 0x2a0 bit19. Clear USB DMA TX path\n")); | |
1168 | ||
1169 | // Wait 5ms to prevent next URB to bulkout before HW reset. by MAXLEE 12-25-2007 | |
1170 | //RTMPusecDelay(5000); | |
1171 | ||
1172 | if ((pAd->bulkResetPipeid & BULKOUT_MGMT_RESET_FLAG) == BULKOUT_MGMT_RESET_FLAG) | |
1173 | { | |
1174 | RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET); | |
1175 | if (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE /* pMLMEContext->bWaitingBulkOut == TRUE */) | |
1176 | { | |
1177 | RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME); | |
1178 | } | |
1179 | RTUSBKickBulkOut(pAd); | |
1180 | ||
1181 | DBGPRINT_RAW(RT_DEBUG_TRACE, ("\tTX MGMT RECOVER Done!\n")); | |
1182 | } | |
1183 | else | |
1184 | { | |
1185 | pHTTXContext = &(pAd->TxContext[pAd->bulkResetPipeid]); | |
1186 | //NdisAcquireSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]); | |
1187 | RTMP_INT_LOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags); | |
1188 | if ( pAd->BulkOutPending[pAd->bulkResetPipeid] == FALSE) | |
1189 | { | |
1190 | pAd->BulkOutPending[pAd->bulkResetPipeid] = TRUE; | |
1191 | pHTTXContext->IRPPending = TRUE; | |
1192 | pAd->watchDogTxPendingCnt[pAd->bulkResetPipeid] = 1; | |
1193 | ||
1194 | // no matter what, clean the flag | |
1195 | RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET); | |
1196 | ||
1197 | //NdisReleaseSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]); | |
1198 | RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags); | |
c55519ff GKH |
1199 | { |
1200 | RTUSBInitHTTxDesc(pAd, pHTTXContext, pAd->bulkResetPipeid, pHTTXContext->BulkOutSize, (usb_complete_t)RTUSBBulkOutDataPacketComplete); | |
1201 | ||
1202 | if((ret = RTUSB_SUBMIT_URB(pHTTXContext->pUrb))!=0) | |
1203 | { | |
1204 | RTMP_INT_LOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags); | |
1205 | pAd->BulkOutPending[pAd->bulkResetPipeid] = FALSE; | |
1206 | pHTTXContext->IRPPending = FALSE; | |
1207 | pAd->watchDogTxPendingCnt[pAd->bulkResetPipeid] = 0; | |
1208 | RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags); | |
1209 | ||
1210 | DBGPRINT(RT_DEBUG_ERROR, ("CmdThread : CMDTHREAD_RESET_BULK_OUT: Submit Tx URB failed %d\n", ret)); | |
1211 | } | |
1212 | else | |
1213 | { | |
1214 | RTMP_IRQ_LOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags); | |
1215 | DBGPRINT_RAW(RT_DEBUG_TRACE,("\tCMDTHREAD_RESET_BULK_OUT: TxContext[%d]:CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d, pending=%d!\n", | |
1216 | pAd->bulkResetPipeid, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, | |
1217 | pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad, pAd->BulkOutPending[pAd->bulkResetPipeid])); | |
1218 | DBGPRINT_RAW(RT_DEBUG_TRACE,("\t\tBulkOut Req=0x%lx, Complete=0x%lx, Other=0x%lx\n", | |
1219 | pAd->BulkOutReq, pAd->BulkOutComplete, pAd->BulkOutCompleteOther)); | |
1220 | RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags); | |
1221 | DBGPRINT_RAW(RT_DEBUG_TRACE, ("\tCMDTHREAD_RESET_BULK_OUT: Submit Tx DATA URB for failed BulkReq(0x%lx) Done, status=%d!\n", pAd->bulkResetReq[pAd->bulkResetPipeid], pHTTXContext->pUrb->status)); | |
1222 | ||
1223 | } | |
1224 | } | |
1225 | } | |
1226 | else | |
1227 | { | |
1228 | //NdisReleaseSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]); | |
1229 | //RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags); | |
1230 | ||
1231 | DBGPRINT_RAW(RT_DEBUG_ERROR, ("CmdThread : TX DATA RECOVER FAIL for BulkReq(0x%lx) because BulkOutPending[%d] is TRUE!\n", pAd->bulkResetReq[pAd->bulkResetPipeid], pAd->bulkResetPipeid)); | |
1232 | if (pAd->bulkResetPipeid == 0) | |
1233 | { | |
1234 | UCHAR pendingContext = 0; | |
1235 | PHT_TX_CONTEXT pHTTXContext = (PHT_TX_CONTEXT)(&pAd->TxContext[pAd->bulkResetPipeid ]); | |
1236 | PTX_CONTEXT pMLMEContext = (PTX_CONTEXT)(pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa); | |
1237 | PTX_CONTEXT pNULLContext = (PTX_CONTEXT)(&pAd->PsPollContext); | |
1238 | PTX_CONTEXT pPsPollContext = (PTX_CONTEXT)(&pAd->NullContext); | |
1239 | ||
1240 | if (pHTTXContext->IRPPending) | |
1241 | pendingContext |= 1; | |
1242 | else if (pMLMEContext->IRPPending) | |
1243 | pendingContext |= 2; | |
1244 | else if (pNULLContext->IRPPending) | |
1245 | pendingContext |= 4; | |
1246 | else if (pPsPollContext->IRPPending) | |
1247 | pendingContext |= 8; | |
1248 | else | |
1249 | pendingContext = 0; | |
1250 | ||
1251 | DBGPRINT_RAW(RT_DEBUG_ERROR, ("\tTX Occupied by %d!\n", pendingContext)); | |
1252 | } | |
1253 | ||
1254 | // no matter what, clean the flag | |
1255 | RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET); | |
1256 | ||
1257 | RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags); | |
1258 | ||
1259 | RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << pAd->bulkResetPipeid)); | |
1260 | } | |
1261 | ||
1262 | RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS); | |
1263 | //RTUSBKickBulkOut(pAd); | |
1264 | } | |
1265 | ||
1266 | } | |
1267 | /* | |
1268 | // Don't cancel BULKIN. | |
1269 | while ((atomic_read(&pAd->PendingRx) > 0) && | |
1270 | (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) | |
1271 | { | |
1272 | if (atomic_read(&pAd->PendingRx) > 0) | |
1273 | { | |
1274 | DBGPRINT_RAW(RT_DEBUG_ERROR, ("BulkIn IRP Pending!!cancel it!\n")); | |
1275 | RTUSBCancelPendingBulkInIRP(pAd); | |
1276 | } | |
1277 | RTMPusecDelay(100000); | |
1278 | } | |
1279 | ||
1280 | if ((atomic_read(&pAd->PendingRx) == 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))) | |
1281 | { | |
1282 | UCHAR i; | |
1283 | RTUSBRxPacket(pAd); | |
1284 | pAd->NextRxBulkInReadIndex = 0; // Next Rx Read index | |
1285 | pAd->NextRxBulkInIndex = 0; // Rx Bulk pointer | |
1286 | for (i = 0; i < (RX_RING_SIZE); i++) | |
1287 | { | |
1288 | PRX_CONTEXT pRxContext = &(pAd->RxContext[i]); | |
1289 | ||
1290 | pRxContext->pAd = pAd; | |
1291 | pRxContext->InUse = FALSE; | |
1292 | pRxContext->IRPPending = FALSE; | |
1293 | pRxContext->Readable = FALSE; | |
1294 | pRxContext->ReorderInUse = FALSE; | |
1295 | ||
1296 | } | |
1297 | RTUSBBulkReceive(pAd); | |
1298 | DBGPRINT_RAW(RT_DEBUG_ERROR, ("RTUSBBulkReceive\n")); | |
1299 | }*/ | |
1300 | DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_OUT<===\n")); | |
1301 | break; | |
1302 | ||
1303 | case CMDTHREAD_RESET_BULK_IN: | |
1304 | DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_IN === >\n")); | |
1305 | ||
1306 | // All transfers must be aborted or cancelled before attempting to reset the pipe. | |
1307 | { | |
1308 | UINT32 MACValue; | |
ca97b838 | 1309 | |
c55519ff GKH |
1310 | { |
1311 | //while ((atomic_read(&pAd->PendingRx) > 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) | |
1312 | if((pAd->PendingRx > 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) | |
1313 | { | |
1314 | DBGPRINT_RAW(RT_DEBUG_ERROR, ("BulkIn IRP Pending!!!\n")); | |
1315 | RTUSBCancelPendingBulkInIRP(pAd); | |
1316 | RTMPusecDelay(100000); | |
1317 | pAd->PendingRx = 0; | |
1318 | } | |
1319 | } | |
1320 | ||
1321 | // Wait 10ms before reading register. | |
1322 | RTMPusecDelay(10000); | |
1323 | ntStatus = RTUSBReadMACRegister(pAd, MAC_CSR0, &MACValue); | |
1324 | ||
1325 | if ((NT_SUCCESS(ntStatus) == TRUE) && | |
1326 | (!(RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_RADIO_OFF | | |
1327 | fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))))) | |
1328 | { | |
1329 | UCHAR i; | |
1330 | ||
1331 | if (RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_RADIO_OFF | | |
1332 | fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))) | |
1333 | break; | |
1334 | pAd->NextRxBulkInPosition = pAd->RxContext[pAd->NextRxBulkInIndex].BulkInOffset; | |
1335 | DBGPRINT(RT_DEBUG_TRACE, ("BULK_IN_RESET: NBIIdx=0x%x,NBIRIdx=0x%x, BIRPos=0x%lx. BIReq=x%lx, BIComplete=0x%lx, BICFail0x%lx\n", | |
1336 | pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex, pAd->NextRxBulkInPosition, pAd->BulkInReq, pAd->BulkInComplete, pAd->BulkInCompleteFail)); | |
1337 | for (i = 0; i < RX_RING_SIZE; i++) | |
1338 | { | |
1339 | DBGPRINT(RT_DEBUG_TRACE, ("\tRxContext[%d]: IRPPending=%d, InUse=%d, Readable=%d!\n" | |
1340 | , i, pAd->RxContext[i].IRPPending, pAd->RxContext[i].InUse, pAd->RxContext[i].Readable)); | |
1341 | } | |
1342 | /* | |
1343 | ||
1344 | DBGPRINT_RAW(RT_DEBUG_ERROR, ("==========================================\n")); | |
1345 | ||
1346 | pAd->NextRxBulkInReadIndex = 0; // Next Rx Read index | |
1347 | pAd->NextRxBulkInIndex = 0; // Rx Bulk pointer | |
1348 | for (i = 0; i < (RX_RING_SIZE); i++) | |
1349 | { | |
1350 | PRX_CONTEXT pRxContext = &(pAd->RxContext[i]); | |
1351 | ||
1352 | pRxContext->pAd = pAd; | |
1353 | pRxContext->InUse = FALSE; | |
1354 | pRxContext->IRPPending = FALSE; | |
1355 | pRxContext->Readable = FALSE; | |
1356 | pRxContext->ReorderInUse = FALSE; | |
1357 | ||
1358 | }*/ | |
1359 | RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET); | |
1360 | for (i = 0; i < pAd->CommonCfg.NumOfBulkInIRP; i++) | |
1361 | { | |
1362 | //RTUSBBulkReceive(pAd); | |
1363 | PRX_CONTEXT pRxContext; | |
1364 | PURB pUrb; | |
1365 | int ret = 0; | |
1366 | unsigned long IrqFlags; | |
1367 | ||
1368 | ||
1369 | RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags); | |
1370 | pRxContext = &(pAd->RxContext[pAd->NextRxBulkInIndex]); | |
1371 | if ((pAd->PendingRx > 0) || (pRxContext->Readable == TRUE) || (pRxContext->InUse == TRUE)) | |
1372 | { | |
1373 | RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags); | |
1374 | break; | |
1375 | } | |
1376 | pRxContext->InUse = TRUE; | |
1377 | pRxContext->IRPPending = TRUE; | |
1378 | pAd->PendingRx++; | |
1379 | pAd->BulkInReq++; | |
1380 | RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags); | |
1381 | ||
1382 | // Init Rx context descriptor | |
1383 | RTUSBInitRxDesc(pAd, pRxContext); | |
1384 | pUrb = pRxContext->pUrb; | |
1385 | if ((ret = RTUSB_SUBMIT_URB(pUrb))!=0) | |
1386 | { // fail | |
1387 | ||
1388 | RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags); | |
1389 | pRxContext->InUse = FALSE; | |
1390 | pRxContext->IRPPending = FALSE; | |
1391 | pAd->PendingRx--; | |
1392 | pAd->BulkInReq--; | |
1393 | RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags); | |
1394 | DBGPRINT(RT_DEBUG_ERROR, ("CMDTHREAD_RESET_BULK_IN: Submit Rx URB failed(%d), status=%d\n", ret, pUrb->status)); | |
1395 | } | |
1396 | else | |
1397 | { // success | |
ca97b838 BZ |
1398 | //DBGPRINT(RT_DEBUG_TRACE, ("BIDone, Pend=%d,BIIdx=%d,BIRIdx=%d!\n", |
1399 | // pAd->PendingRx, pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex)); | |
c55519ff GKH |
1400 | DBGPRINT_RAW(RT_DEBUG_TRACE, ("CMDTHREAD_RESET_BULK_IN: Submit Rx URB Done, status=%d!\n", pUrb->status)); |
1401 | ASSERT((pRxContext->InUse == pRxContext->IRPPending)); | |
1402 | } | |
1403 | } | |
1404 | ||
1405 | } | |
1406 | else | |
1407 | { | |
1408 | // Card must be removed | |
1409 | if (NT_SUCCESS(ntStatus) != TRUE) | |
1410 | { | |
1411 | RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST); | |
1412 | DBGPRINT_RAW(RT_DEBUG_ERROR, ("CMDTHREAD_RESET_BULK_IN: Read Register Failed!Card must be removed!!\n\n")); | |
1413 | } | |
1414 | else | |
1415 | { | |
1416 | DBGPRINT_RAW(RT_DEBUG_ERROR, ("CMDTHREAD_RESET_BULK_IN: Cannot do bulk in because flags(0x%lx) on !\n", pAd->Flags)); | |
1417 | } | |
1418 | } | |
1419 | } | |
1420 | DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_IN <===\n")); | |
1421 | break; | |
1422 | ||
1423 | case CMDTHREAD_SET_ASIC_WCID: | |
1424 | { | |
1425 | RT_SET_ASIC_WCID SetAsicWcid; | |
1426 | USHORT offset; | |
1427 | UINT32 MACValue, MACRValue = 0; | |
1428 | SetAsicWcid = *((PRT_SET_ASIC_WCID)(pData)); | |
1429 | ||
1430 | if (SetAsicWcid.WCID >= MAX_LEN_OF_MAC_TABLE) | |
1431 | return; | |
1432 | ||
1433 | offset = MAC_WCID_BASE + ((UCHAR)SetAsicWcid.WCID)*HW_WCID_ENTRY_SIZE; | |
1434 | ||
1435 | DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_SET_ASIC_WCID : WCID = %ld, SetTid = %lx, DeleteTid = %lx.\n", SetAsicWcid.WCID, SetAsicWcid.SetTid, SetAsicWcid.DeleteTid)); | |
1436 | MACValue = (pAd->MacTab.Content[SetAsicWcid.WCID].Addr[3]<<24)+(pAd->MacTab.Content[SetAsicWcid.WCID].Addr[2]<<16)+(pAd->MacTab.Content[SetAsicWcid.WCID].Addr[1]<<8)+(pAd->MacTab.Content[SetAsicWcid.WCID].Addr[0]); | |
1437 | DBGPRINT_RAW(RT_DEBUG_TRACE, ("1-MACValue= %x,\n", MACValue)); | |
1438 | RTUSBWriteMACRegister(pAd, offset, MACValue); | |
1439 | // Read bitmask | |
1440 | RTUSBReadMACRegister(pAd, offset+4, &MACRValue); | |
1441 | if ( SetAsicWcid.DeleteTid != 0xffffffff) | |
1442 | MACRValue &= (~SetAsicWcid.DeleteTid); | |
1443 | if (SetAsicWcid.SetTid != 0xffffffff) | |
1444 | MACRValue |= (SetAsicWcid.SetTid); | |
1445 | MACRValue &= 0xffff0000; | |
1446 | ||
1447 | MACValue = (pAd->MacTab.Content[SetAsicWcid.WCID].Addr[5]<<8)+pAd->MacTab.Content[SetAsicWcid.WCID].Addr[4]; | |
1448 | MACValue |= MACRValue; | |
1449 | RTUSBWriteMACRegister(pAd, offset+4, MACValue); | |
1450 | ||
1451 | DBGPRINT_RAW(RT_DEBUG_TRACE, ("2-MACValue= %x,\n", MACValue)); | |
1452 | } | |
1453 | break; | |
1454 | ||
1455 | case CMDTHREAD_SET_ASIC_WCID_CIPHER: | |
1456 | { | |
c55519ff GKH |
1457 | RT_SET_ASIC_WCID_ATTRI SetAsicWcidAttri; |
1458 | USHORT offset; | |
1459 | UINT32 MACRValue = 0; | |
1460 | SHAREDKEY_MODE_STRUC csr1; | |
1461 | SetAsicWcidAttri = *((PRT_SET_ASIC_WCID_ATTRI)(pData)); | |
1462 | ||
1463 | if (SetAsicWcidAttri.WCID >= MAX_LEN_OF_MAC_TABLE) | |
1464 | return; | |
1465 | ||
1466 | offset = MAC_WCID_ATTRIBUTE_BASE + ((UCHAR)SetAsicWcidAttri.WCID)*HW_WCID_ATTRI_SIZE; | |
1467 | ||
1468 | DBGPRINT_RAW(RT_DEBUG_TRACE, ("Cmd : CMDTHREAD_SET_ASIC_WCID_CIPHER : WCID = %ld, Cipher = %lx.\n", SetAsicWcidAttri.WCID, SetAsicWcidAttri.Cipher)); | |
1469 | // Read bitmask | |
1470 | RTUSBReadMACRegister(pAd, offset, &MACRValue); | |
1471 | MACRValue = 0; | |
1472 | MACRValue |= (((UCHAR)SetAsicWcidAttri.Cipher) << 1); | |
1473 | ||
1474 | RTUSBWriteMACRegister(pAd, offset, MACRValue); | |
1475 | DBGPRINT_RAW(RT_DEBUG_TRACE, ("2-offset = %x , MACValue= %x,\n", offset, MACRValue)); | |
1476 | ||
1477 | offset = PAIRWISE_IVEIV_TABLE_BASE + ((UCHAR)SetAsicWcidAttri.WCID)*HW_IVEIV_ENTRY_SIZE; | |
1478 | MACRValue = 0; | |
1479 | if ( (SetAsicWcidAttri.Cipher <= CIPHER_WEP128)) | |
1480 | MACRValue |= ( pAd->StaCfg.DefaultKeyId << 30); | |
1481 | else | |
1482 | MACRValue |= (0x20000000); | |
1483 | RTUSBWriteMACRegister(pAd, offset, MACRValue); | |
1484 | DBGPRINT_RAW(RT_DEBUG_TRACE, ("2-offset = %x , MACValue= %x,\n", offset, MACRValue)); | |
1485 | ||
1486 | // | |
1487 | // Update cipher algorithm. WSTA always use BSS0 | |
1488 | // | |
1489 | // for adhoc mode only ,because wep status slow than add key, when use zero config | |
1490 | if (pAd->StaCfg.BssType == BSS_ADHOC ) | |
1491 | { | |
1492 | offset = MAC_WCID_ATTRIBUTE_BASE; | |
1493 | ||
1494 | RTUSBReadMACRegister(pAd, offset, &MACRValue); | |
1495 | MACRValue &= (~0xe); | |
1496 | MACRValue |= (((UCHAR)SetAsicWcidAttri.Cipher) << 1); | |
1497 | ||
1498 | RTUSBWriteMACRegister(pAd, offset, MACRValue); | |
1499 | ||
1500 | //Update group key cipher,,because wep status slow than add key, when use zero config | |
1501 | RTUSBReadMACRegister(pAd, SHARED_KEY_MODE_BASE+4*(0/2), &csr1.word); | |
1502 | ||
1503 | csr1.field.Bss0Key0CipherAlg = SetAsicWcidAttri.Cipher; | |
1504 | csr1.field.Bss0Key1CipherAlg = SetAsicWcidAttri.Cipher; | |
1505 | ||
1506 | RTUSBWriteMACRegister(pAd, SHARED_KEY_MODE_BASE+4*(0/2), csr1.word); | |
1507 | } | |
c55519ff GKH |
1508 | } |
1509 | break; | |
ca97b838 BZ |
1510 | |
1511 | //Benson modified for USB interface, avoid in interrupt when write key, 20080724 --> | |
1512 | case RT_CMD_SET_KEY_TABLE: //General call for AsicAddPairwiseKeyEntry() | |
1513 | { | |
1514 | RT_ADD_PAIRWISE_KEY_ENTRY KeyInfo; | |
1515 | KeyInfo = *((PRT_ADD_PAIRWISE_KEY_ENTRY)(pData)); | |
1516 | AsicAddPairwiseKeyEntry(pAd, | |
1517 | KeyInfo.MacAddr, | |
1518 | (UCHAR)KeyInfo.MacTabMatchWCID, | |
1519 | &KeyInfo.CipherKey); | |
1520 | } | |
1521 | break; | |
1522 | ||
1523 | case RT_CMD_SET_RX_WCID_TABLE: //General call for RTMPAddWcidAttributeEntry() | |
1524 | { | |
1525 | PMAC_TABLE_ENTRY pEntry ; | |
1526 | UCHAR KeyIdx = 0; | |
1527 | UCHAR CipherAlg = CIPHER_NONE; | |
1528 | UCHAR ApIdx = BSS0; | |
1529 | ||
1530 | pEntry = (PMAC_TABLE_ENTRY)(pData); | |
1531 | ||
1532 | ||
1533 | ||
1534 | RTMPAddWcidAttributeEntry( | |
1535 | pAd, | |
1536 | ApIdx, | |
1537 | KeyIdx, | |
1538 | CipherAlg, | |
1539 | pEntry); | |
1540 | } | |
1541 | break; | |
1542 | //Benson modified for USB interface, avoid in interrupt when write key, 20080724 <-- | |
1543 | ||
c55519ff GKH |
1544 | case CMDTHREAD_SET_CLIENT_MAC_ENTRY: |
1545 | { | |
1546 | MAC_TABLE_ENTRY *pEntry; | |
1547 | pEntry = (MAC_TABLE_ENTRY *)pData; | |
1548 | ||
c55519ff GKH |
1549 | { |
1550 | AsicRemovePairwiseKeyEntry(pAd, pEntry->apidx, (UCHAR)pEntry->Aid); | |
1551 | if ((pEntry->AuthMode <= Ndis802_11AuthModeAutoSwitch) && (pEntry->WepStatus == Ndis802_11Encryption1Enabled)) | |
1552 | { | |
ca97b838 | 1553 | UINT32 uIV = 1; |
c55519ff GKH |
1554 | PUCHAR ptr; |
1555 | ||
1556 | ptr = (PUCHAR) &uIV; | |
1557 | *(ptr + 3) = (pAd->StaCfg.DefaultKeyId << 6); | |
1558 | AsicUpdateWCIDIVEIV(pAd, pEntry->Aid, uIV, 0); | |
1559 | AsicUpdateWCIDAttribute(pAd, pEntry->Aid, BSS0, pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg, FALSE); | |
1560 | } | |
1561 | else if (pEntry->AuthMode == Ndis802_11AuthModeWPANone) | |
1562 | { | |
ca97b838 | 1563 | UINT32 uIV = 1; |
c55519ff GKH |
1564 | PUCHAR ptr; |
1565 | ||
1566 | ptr = (PUCHAR) &uIV; | |
1567 | *(ptr + 3) = (pAd->StaCfg.DefaultKeyId << 6); | |
1568 | AsicUpdateWCIDIVEIV(pAd, pEntry->Aid, uIV, 0); | |
1569 | AsicUpdateWCIDAttribute(pAd, pEntry->Aid, BSS0, pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg, FALSE); | |
1570 | } | |
1571 | else | |
1572 | { | |
1573 | // | |
1574 | // Other case, disable engine. | |
1575 | // Don't worry WPA key, we will add WPA Key after 4-Way handshaking. | |
1576 | // | |
1577 | USHORT offset; | |
1578 | offset = MAC_WCID_ATTRIBUTE_BASE + (pEntry->Aid * HW_WCID_ATTRI_SIZE); | |
1579 | // RX_PKEY_MODE:0 for no security; RX_KEY_TAB:0 for shared key table; BSS_IDX:0 | |
1580 | RTUSBWriteMACRegister(pAd, offset, 0); | |
1581 | } | |
1582 | } | |
c55519ff GKH |
1583 | |
1584 | AsicUpdateRxWCIDTable(pAd, pEntry->Aid, pEntry->Addr); | |
ca97b838 BZ |
1585 | DBGPRINT(RT_DEBUG_TRACE, ("UpdateRxWCIDTable(): Aid=%d, Addr=%02x:%02x:%02x:%02x:%02x:%02x!\n", pEntry->Aid, |
1586 | pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2], pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5])); | |
c55519ff GKH |
1587 | } |
1588 | break; | |
ca97b838 BZ |
1589 | |
1590 | // add by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet | |
ffbc7b85 BZ |
1591 | case CMDTHREAD_UPDATE_PROTECT: |
1592 | { | |
1593 | AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT), TRUE, 0); | |
1594 | } | |
1595 | break; | |
ca97b838 BZ |
1596 | // end johnli |
1597 | ||
c55519ff GKH |
1598 | case OID_802_11_ADD_WEP: |
1599 | { | |
c55519ff GKH |
1600 | UINT i; |
1601 | UINT32 KeyIdx; | |
1602 | PNDIS_802_11_WEP pWepKey; | |
1603 | ||
1604 | DBGPRINT(RT_DEBUG_TRACE, ("CmdThread::OID_802_11_ADD_WEP \n")); | |
1605 | ||
1606 | pWepKey = (PNDIS_802_11_WEP)pData; | |
1607 | KeyIdx = pWepKey->KeyIndex & 0x0fffffff; | |
1608 | ||
1609 | // it is a shared key | |
1610 | if ((KeyIdx >= 4) || ((pWepKey->KeyLength != 5) && (pWepKey->KeyLength != 13))) | |
1611 | { | |
1612 | NdisStatus = NDIS_STATUS_INVALID_DATA; | |
1613 | DBGPRINT(RT_DEBUG_ERROR, ("CmdThread::OID_802_11_ADD_WEP, INVALID_DATA!!\n")); | |
1614 | } | |
1615 | else | |
1616 | { | |
1617 | UCHAR CipherAlg; | |
1618 | pAd->SharedKey[BSS0][KeyIdx].KeyLen = (UCHAR) pWepKey->KeyLength; | |
1619 | NdisMoveMemory(pAd->SharedKey[BSS0][KeyIdx].Key, &pWepKey->KeyMaterial, pWepKey->KeyLength); | |
1620 | CipherAlg = (pAd->SharedKey[BSS0][KeyIdx].KeyLen == 5)? CIPHER_WEP64 : CIPHER_WEP128; | |
1621 | ||
1622 | // | |
1623 | // Change the WEP cipher to CKIP cipher if CKIP KP on. | |
1624 | // Funk UI or Meetinghouse UI will add ckip key from this path. | |
1625 | // | |
1626 | ||
1627 | if (pAd->OpMode == OPMODE_STA) | |
1628 | { | |
1629 | pAd->MacTab.Content[BSSID_WCID].PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][KeyIdx].CipherAlg; | |
1630 | pAd->MacTab.Content[BSSID_WCID].PairwiseKey.KeyLen = pAd->SharedKey[BSS0][KeyIdx].KeyLen; | |
1631 | } | |
1632 | pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CipherAlg; | |
1633 | if (pWepKey->KeyIndex & 0x80000000) | |
1634 | { | |
1635 | // Default key for tx (shared key) | |
1636 | UCHAR IVEIV[8]; | |
1637 | UINT32 WCIDAttri, Value; | |
1638 | USHORT offset, offset2; | |
1639 | NdisZeroMemory(IVEIV, 8); | |
1640 | pAd->StaCfg.DefaultKeyId = (UCHAR) KeyIdx; | |
1641 | // Add BSSID to WCTable. because this is Tx wep key. | |
1642 | // WCID Attribute UDF:3, BSSIdx:3, Alg:3, Keytable:1=PAIRWISE KEY, BSSIdx is 0 | |
1643 | WCIDAttri = (CipherAlg<<1)|SHAREDKEYTABLE; | |
1644 | ||
1645 | offset = MAC_WCID_ATTRIBUTE_BASE + (BSSID_WCID* HW_WCID_ATTRI_SIZE); | |
1646 | RTUSBWriteMACRegister(pAd, offset, WCIDAttri); | |
1647 | // 1. IV/EIV | |
1648 | // Specify key index to find shared key. | |
1649 | IVEIV[3] = (UCHAR)(KeyIdx<< 6); //WEP Eiv bit off. groupkey index is not 0 | |
1650 | offset = PAIRWISE_IVEIV_TABLE_BASE + (BSS0Mcast_WCID * HW_IVEIV_ENTRY_SIZE); | |
1651 | offset2 = PAIRWISE_IVEIV_TABLE_BASE + (BSSID_WCID* HW_IVEIV_ENTRY_SIZE); | |
1652 | for (i=0; i<8;) | |
1653 | { | |
1654 | Value = IVEIV[i]; | |
1655 | Value += (IVEIV[i+1]<<8); | |
1656 | Value += (IVEIV[i+2]<<16); | |
1657 | Value += (IVEIV[i+3]<<24); | |
1658 | RTUSBWriteMACRegister(pAd, offset+i, Value); | |
1659 | RTUSBWriteMACRegister(pAd, offset2+i, Value); | |
1660 | i+=4; | |
1661 | } | |
1662 | ||
1663 | // 2. WCID Attribute UDF:3, BSSIdx:3, Alg:3, Keytable:use share key, BSSIdx is 0 | |
1664 | WCIDAttri = (pAd->SharedKey[BSS0][KeyIdx].CipherAlg<<1)|SHAREDKEYTABLE; | |
1665 | offset = MAC_WCID_ATTRIBUTE_BASE + (BSS0Mcast_WCID* HW_WCID_ATTRI_SIZE); | |
1666 | DBGPRINT(RT_DEBUG_TRACE, ("BSS0Mcast_WCID : offset = %x, WCIDAttri = %x\n", offset, WCIDAttri)); | |
1667 | RTUSBWriteMACRegister(pAd, offset, WCIDAttri); | |
1668 | ||
1669 | } | |
1670 | AsicAddSharedKeyEntry(pAd, BSS0, (UCHAR)KeyIdx, CipherAlg, pWepKey->KeyMaterial, NULL, NULL); | |
1671 | DBGPRINT(RT_DEBUG_TRACE, ("CmdThread::OID_802_11_ADD_WEP (KeyIdx=%d, Len=%d-byte)\n", KeyIdx, pWepKey->KeyLength)); | |
1672 | } | |
c55519ff GKH |
1673 | } |
1674 | break; | |
1675 | ||
1676 | case CMDTHREAD_802_11_COUNTER_MEASURE: | |
1677 | break; | |
ca97b838 BZ |
1678 | |
1679 | case CMDTHREAD_SET_GROUP_KEY: | |
1680 | WpaStaGroupKeySetting(pAd); | |
1681 | break; | |
1682 | ||
1683 | case CMDTHREAD_SET_PAIRWISE_KEY: | |
1684 | WpaStaPairwiseKeySetting(pAd); | |
1685 | break; | |
1686 | ||
1687 | case CMDTHREAD_SET_PSM_BIT: | |
1688 | { | |
1689 | USHORT *pPsm = (USHORT *)pData; | |
1690 | MlmeSetPsmBit(pAd, *pPsm); | |
1691 | } | |
1692 | break; | |
1693 | case CMDTHREAD_FORCE_WAKE_UP: | |
1694 | AsicForceWakeup(pAd, TRUE); | |
1695 | break; | |
1696 | ||
c55519ff GKH |
1697 | default: |
1698 | DBGPRINT(RT_DEBUG_ERROR, ("--> Control Thread !! ERROR !! Unknown(cmdqelmt->command=0x%x) !! \n", cmdqelmt->command)); | |
1699 | break; | |
1700 | } | |
1701 | } | |
1702 | ||
1703 | if (cmdqelmt->CmdFromNdis == TRUE) | |
1704 | { | |
1705 | if (cmdqelmt->buffer != NULL) | |
ca97b838 BZ |
1706 | os_free_mem(pAd, cmdqelmt->buffer); |
1707 | os_free_mem(pAd, cmdqelmt); | |
c55519ff GKH |
1708 | } |
1709 | else | |
1710 | { | |
1711 | if ((cmdqelmt->buffer != NULL) && (cmdqelmt->bufferlength != 0)) | |
ca97b838 BZ |
1712 | os_free_mem(pAd, cmdqelmt->buffer); |
1713 | os_free_mem(pAd, cmdqelmt); | |
c55519ff GKH |
1714 | } |
1715 | } /* end of while */ | |
1716 | } | |
1717 | ||
ca97b838 | 1718 | #endif // RTMP_MAC_USB // |