]> Pileus Git - ~andy/linux/blob - drivers/staging/vt6655/mac.c
Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab...
[~andy/linux] / drivers / staging / vt6655 / mac.c
1 /*
2  * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
3  * All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  *
20  * File: mac.c
21  *
22  * Purpose:  MAC routines
23  *
24  * Author: Tevin Chen
25  *
26  * Date: May 21, 1996
27  *
28  * Functions:
29  *      MACvReadAllRegs - Read All MAC Registers to buffer
30  *      MACbIsRegBitsOn - Test if All test Bits On
31  *      MACbIsRegBitsOff - Test if All test Bits Off
32  *      MACbIsIntDisable - Test if MAC interrupt disable
33  *      MACbyReadMultiAddr - Read Multicast Address Mask Pattern
34  *      MACvWriteMultiAddr - Write Multicast Address Mask Pattern
35  *      MACvSetMultiAddrByHash - Set Multicast Address Mask by Hash value
36  *      MACvResetMultiAddrByHash - Clear Multicast Address Mask by Hash value
37  *      MACvSetRxThreshold - Set Rx Threshold value
38  *      MACvGetRxThreshold - Get Rx Threshold value
39  *      MACvSetTxThreshold - Set Tx Threshold value
40  *      MACvGetTxThreshold - Get Tx Threshold value
41  *      MACvSetDmaLength - Set Dma Length value
42  *      MACvGetDmaLength - Get Dma Length value
43  *      MACvSetShortRetryLimit - Set 802.11 Short Retry limit
44  *      MACvGetShortRetryLimit - Get 802.11 Short Retry limit
45  *      MACvSetLongRetryLimit - Set 802.11 Long Retry limit
46  *      MACvGetLongRetryLimit - Get 802.11 Long Retry limit
47  *      MACvSetLoopbackMode - Set MAC Loopback Mode
48  *      MACbIsInLoopbackMode - Test if MAC in Loopback mode
49  *      MACvSetPacketFilter - Set MAC Address Filter
50  *      MACvSaveContext - Save Context of MAC Registers
51  *      MACvRestoreContext - Restore Context of MAC Registers
52  *      MACbCompareContext - Compare if values of MAC Registers same as Context
53  *      MACbSoftwareReset - Software Reset MAC
54  *      MACbSafeRxOff - Turn Off MAC Rx
55  *      MACbSafeTxOff - Turn Off MAC Tx
56  *      MACbSafeStop - Stop MAC function
57  *      MACbShutdown - Shut down MAC
58  *      MACvInitialize - Initialize MAC
59  *      MACvSetCurrRxDescAddr - Set Rx Descriptors Address
60  *      MACvSetCurrTx0DescAddr - Set Tx0 Descriptors Address
61  *      MACvSetCurrTx1DescAddr - Set Tx1 Descriptors Address
62  *      MACvTimer0MicroSDelay - Micro Second Delay Loop by MAC
63  *
64  * Revision History:
65  *      08-22-2003 Kyle Hsu     :  Porting MAC functions from sim53
66  *      09-03-2003 Bryan YC Fan :  Add MACvClearBusSusInd()& MACvEnableBusSusEn()
67  *      09-18-2003 Jerry Chen   :  Add MACvSetKeyEntry & MACvDisableKeyEntry
68  *
69  */
70
71 #include "tmacro.h"
72 #include "tether.h"
73 #include "mac.h"
74
75 unsigned short TxRate_iwconfig;//2008-5-8 <add> by chester
76 /*---------------------  Static Definitions -------------------------*/
77 //static int          msglevel                =MSG_LEVEL_DEBUG;
78 static int msglevel = MSG_LEVEL_INFO;
79 /*---------------------  Static Classes  ----------------------------*/
80
81 /*---------------------  Static Variables  --------------------------*/
82
83 /*---------------------  Static Functions  --------------------------*/
84
85 /*---------------------  Export Variables  --------------------------*/
86
87 /*---------------------  Export Functions  --------------------------*/
88
89 /*
90  * Description:
91  *      Read All MAC Registers to buffer
92  *
93  * Parameters:
94  *  In:
95  *      dwIoBase    - Base Address for MAC
96  *  Out:
97  *      pbyMacRegs  - buffer to read
98  *
99  * Return Value: none
100  *
101  */
102 void MACvReadAllRegs(unsigned long dwIoBase, unsigned char *pbyMacRegs)
103 {
104         int ii;
105
106         // read page0 register
107         for (ii = 0; ii < MAC_MAX_CONTEXT_SIZE_PAGE0; ii++) {
108                 VNSvInPortB(dwIoBase + ii, pbyMacRegs);
109                 pbyMacRegs++;
110         }
111
112         MACvSelectPage1(dwIoBase);
113
114         // read page1 register
115         for (ii = 0; ii < MAC_MAX_CONTEXT_SIZE_PAGE1; ii++) {
116                 VNSvInPortB(dwIoBase + ii, pbyMacRegs);
117                 pbyMacRegs++;
118         }
119
120         MACvSelectPage0(dwIoBase);
121 }
122
123 /*
124  * Description:
125  *      Test if all test bits on
126  *
127  * Parameters:
128  *  In:
129  *      dwIoBase    - Base Address for MAC
130  *      byRegOfs    - Offset of MAC Register
131  *      byTestBits  - Test bits
132  *  Out:
133  *      none
134  *
135  * Return Value: true if all test bits On; otherwise false
136  *
137  */
138 bool MACbIsRegBitsOn(unsigned long dwIoBase, unsigned char byRegOfs, unsigned char byTestBits)
139 {
140         unsigned char byData;
141
142         VNSvInPortB(dwIoBase + byRegOfs, &byData);
143         return (byData & byTestBits) == byTestBits;
144 }
145
146 /*
147  * Description:
148  *      Test if all test bits off
149  *
150  * Parameters:
151  *  In:
152  *      dwIoBase    - Base Address for MAC
153  *      byRegOfs    - Offset of MAC Register
154  *      byTestBits  - Test bits
155  *  Out:
156  *      none
157  *
158  * Return Value: true if all test bits Off; otherwise false
159  *
160  */
161 bool MACbIsRegBitsOff(unsigned long dwIoBase, unsigned char byRegOfs, unsigned char byTestBits)
162 {
163         unsigned char byData;
164
165         VNSvInPortB(dwIoBase + byRegOfs, &byData);
166         return !(byData & byTestBits);
167 }
168
169 /*
170  * Description:
171  *      Test if MAC interrupt disable
172  *
173  * Parameters:
174  *  In:
175  *      dwIoBase    - Base Address for MAC
176  *  Out:
177  *      none
178  *
179  * Return Value: true if interrupt is disable; otherwise false
180  *
181  */
182 bool MACbIsIntDisable(unsigned long dwIoBase)
183 {
184         unsigned long dwData;
185
186         VNSvInPortD(dwIoBase + MAC_REG_IMR, &dwData);
187         if (dwData != 0)
188                 return false;
189
190         return true;
191 }
192
193 /*
194  * Description:
195  *      Read MAC Multicast Address Mask
196  *
197  * Parameters:
198  *  In:
199  *      dwIoBase    - Base Address for MAC
200  *      uByteidx    - Index of Mask
201  *  Out:
202  *      none
203  *
204  * Return Value: Mask Value read
205  *
206  */
207 unsigned char MACbyReadMultiAddr(unsigned long dwIoBase, unsigned int uByteIdx)
208 {
209         unsigned char byData;
210
211         MACvSelectPage1(dwIoBase);
212         VNSvInPortB(dwIoBase + MAC_REG_MAR0 + uByteIdx, &byData);
213         MACvSelectPage0(dwIoBase);
214         return byData;
215 }
216
217 /*
218  * Description:
219  *      Write MAC Multicast Address Mask
220  *
221  * Parameters:
222  *  In:
223  *      dwIoBase    - Base Address for MAC
224  *      uByteidx    - Index of Mask
225  *      byData      - Mask Value to write
226  *  Out:
227  *      none
228  *
229  * Return Value: none
230  *
231  */
232 void MACvWriteMultiAddr(unsigned long dwIoBase, unsigned int uByteIdx, unsigned char byData)
233 {
234         MACvSelectPage1(dwIoBase);
235         VNSvOutPortB(dwIoBase + MAC_REG_MAR0 + uByteIdx, byData);
236         MACvSelectPage0(dwIoBase);
237 }
238
239 /*
240  * Description:
241  *      Set this hash index into multicast address register bit
242  *
243  * Parameters:
244  *  In:
245  *      dwIoBase    - Base Address for MAC
246  *      byHashIdx   - Hash index to set
247  *  Out:
248  *      none
249  *
250  * Return Value: none
251  *
252  */
253 void MACvSetMultiAddrByHash(unsigned long dwIoBase, unsigned char byHashIdx)
254 {
255         unsigned int uByteIdx;
256         unsigned char byBitMask;
257         unsigned char byOrgValue;
258
259         // calculate byte position
260         uByteIdx = byHashIdx / 8;
261         ASSERT(uByteIdx < 8);
262         // calculate bit position
263         byBitMask = 1;
264         byBitMask <<= (byHashIdx % 8);
265         // turn on the bit
266         byOrgValue = MACbyReadMultiAddr(dwIoBase, uByteIdx);
267         MACvWriteMultiAddr(dwIoBase, uByteIdx, (unsigned char)(byOrgValue | byBitMask));
268 }
269
270 /*
271  * Description:
272  *      Reset this hash index into multicast address register bit
273  *
274  * Parameters:
275  *  In:
276  *      dwIoBase    - Base Address for MAC
277  *      byHashIdx   - Hash index to clear
278  *  Out:
279  *      none
280  *
281  * Return Value: none
282  *
283  */
284 void MACvResetMultiAddrByHash(unsigned long dwIoBase, unsigned char byHashIdx)
285 {
286         unsigned int uByteIdx;
287         unsigned char byBitMask;
288         unsigned char byOrgValue;
289
290         // calculate byte position
291         uByteIdx = byHashIdx / 8;
292         ASSERT(uByteIdx < 8);
293         // calculate bit position
294         byBitMask = 1;
295         byBitMask <<= (byHashIdx % 8);
296         // turn off the bit
297         byOrgValue = MACbyReadMultiAddr(dwIoBase, uByteIdx);
298         MACvWriteMultiAddr(dwIoBase, uByteIdx, (unsigned char)(byOrgValue & (~byBitMask)));
299 }
300
301 /*
302  * Description:
303  *      Set Rx Threshold
304  *
305  * Parameters:
306  *  In:
307  *      dwIoBase    - Base Address for MAC
308  *      byThreshold - Threshold Value
309  *  Out:
310  *      none
311  *
312  * Return Value: none
313  *
314  */
315 void MACvSetRxThreshold(unsigned long dwIoBase, unsigned char byThreshold)
316 {
317         unsigned char byOrgValue;
318
319         ASSERT(byThreshold < 4);
320
321         // set FCR0
322         VNSvInPortB(dwIoBase + MAC_REG_FCR0, &byOrgValue);
323         byOrgValue = (byOrgValue & 0xCF) | (byThreshold << 4);
324         VNSvOutPortB(dwIoBase + MAC_REG_FCR0, byOrgValue);
325 }
326
327 /*
328  * Description:
329  *      Get Rx Threshold
330  *
331  * Parameters:
332  *  In:
333  *      dwIoBase    - Base Address for MAC
334  *  Out:
335  *      pbyThreshold- Threshold Value Get
336  *
337  * Return Value: none
338  *
339  */
340 void MACvGetRxThreshold(unsigned long dwIoBase, unsigned char *pbyThreshold)
341 {
342         // get FCR0
343         VNSvInPortB(dwIoBase + MAC_REG_FCR0, pbyThreshold);
344         *pbyThreshold = (*pbyThreshold >> 4) & 0x03;
345 }
346
347 /*
348  * Description:
349  *      Set Tx Threshold
350  *
351  * Parameters:
352  *  In:
353  *      dwIoBase    - Base Address for MAC
354  *      byThreshold - Threshold Value
355  *  Out:
356  *      none
357  *
358  * Return Value: none
359  *
360  */
361 void MACvSetTxThreshold(unsigned long dwIoBase, unsigned char byThreshold)
362 {
363         unsigned char byOrgValue;
364
365         ASSERT(byThreshold < 4);
366
367         // set FCR0
368         VNSvInPortB(dwIoBase + MAC_REG_FCR0, &byOrgValue);
369         byOrgValue = (byOrgValue & 0xF3) | (byThreshold << 2);
370         VNSvOutPortB(dwIoBase + MAC_REG_FCR0, byOrgValue);
371 }
372
373 /*
374  * Description:
375  *      Get Tx Threshold
376  *
377  * Parameters:
378  *  In:
379  *      dwIoBase    - Base Address for MAC
380  *  Out:
381  *      pbyThreshold- Threshold Value Get
382  *
383  * Return Value: none
384  *
385  */
386 void MACvGetTxThreshold(unsigned long dwIoBase, unsigned char *pbyThreshold)
387 {
388         // get FCR0
389         VNSvInPortB(dwIoBase + MAC_REG_FCR0, pbyThreshold);
390         *pbyThreshold = (*pbyThreshold >> 2) & 0x03;
391 }
392
393 /*
394  * Description:
395  *      Set Dma Length
396  *
397  * Parameters:
398  *  In:
399  *      dwIoBase    - Base Address for MAC
400  *      byDmaLength - Dma Length Value
401  *  Out:
402  *      none
403  *
404  * Return Value: none
405  *
406  */
407 void MACvSetDmaLength(unsigned long dwIoBase, unsigned char byDmaLength)
408 {
409         unsigned char byOrgValue;
410
411         ASSERT(byDmaLength < 4);
412
413         // set FCR0
414         VNSvInPortB(dwIoBase + MAC_REG_FCR0, &byOrgValue);
415         byOrgValue = (byOrgValue & 0xFC) | byDmaLength;
416         VNSvOutPortB(dwIoBase + MAC_REG_FCR0, byOrgValue);
417 }
418
419 /*
420  * Description:
421  *      Get Dma Length
422  *
423  * Parameters:
424  *  In:
425  *      dwIoBase    - Base Address for MAC
426  *  Out:
427  *      pbyDmaLength- Dma Length Value Get
428  *
429  * Return Value: none
430  *
431  */
432 void MACvGetDmaLength(unsigned long dwIoBase, unsigned char *pbyDmaLength)
433 {
434         // get FCR0
435         VNSvInPortB(dwIoBase + MAC_REG_FCR0, pbyDmaLength);
436         *pbyDmaLength &= 0x03;
437 }
438
439 /*
440  * Description:
441  *      Set 802.11 Short Retry Limit
442  *
443  * Parameters:
444  *  In:
445  *      dwIoBase    - Base Address for MAC
446  *      byRetryLimit- Retry Limit
447  *  Out:
448  *      none
449  *
450  * Return Value: none
451  *
452  */
453 void MACvSetShortRetryLimit(unsigned long dwIoBase, unsigned char byRetryLimit)
454 {
455         // set SRT
456         VNSvOutPortB(dwIoBase + MAC_REG_SRT, byRetryLimit);
457 }
458
459 /*
460  * Description:
461  *      Get 802.11 Short Retry Limit
462  *
463  * Parameters:
464  *  In:
465  *      dwIoBase        - Base Address for MAC
466  *  Out:
467  *      pbyRetryLimit   - Retry Limit Get
468  *
469  * Return Value: none
470  *
471  */
472 void MACvGetShortRetryLimit(unsigned long dwIoBase, unsigned char *pbyRetryLimit)
473 {
474         // get SRT
475         VNSvInPortB(dwIoBase + MAC_REG_SRT, pbyRetryLimit);
476 }
477
478 /*
479  * Description:
480  *      Set 802.11 Long Retry Limit
481  *
482  * Parameters:
483  *  In:
484  *      dwIoBase    - Base Address for MAC
485  *      byRetryLimit- Retry Limit
486  *  Out:
487  *      none
488  *
489  * Return Value: none
490  *
491  */
492 void MACvSetLongRetryLimit(unsigned long dwIoBase, unsigned char byRetryLimit)
493 {
494         // set LRT
495         VNSvOutPortB(dwIoBase + MAC_REG_LRT, byRetryLimit);
496 }
497
498 /*
499  * Description:
500  *      Get 802.11 Long Retry Limit
501  *
502  * Parameters:
503  *  In:
504  *      dwIoBase        - Base Address for MAC
505  *  Out:
506  *      pbyRetryLimit   - Retry Limit Get
507  *
508  * Return Value: none
509  *
510  */
511 void MACvGetLongRetryLimit(unsigned long dwIoBase, unsigned char *pbyRetryLimit)
512 {
513         // get LRT
514         VNSvInPortB(dwIoBase + MAC_REG_LRT, pbyRetryLimit);
515 }
516
517 /*
518  * Description:
519  *      Set MAC Loopback mode
520  *
521  * Parameters:
522  *  In:
523  *      dwIoBase        - Base Address for MAC
524  *      byLoopbackMode  - Loopback Mode
525  *  Out:
526  *      none
527  *
528  * Return Value: none
529  *
530  */
531 void MACvSetLoopbackMode(unsigned long dwIoBase, unsigned char byLoopbackMode)
532 {
533         unsigned char byOrgValue;
534
535         ASSERT(byLoopbackMode < 3);
536         byLoopbackMode <<= 6;
537         // set TCR
538         VNSvInPortB(dwIoBase + MAC_REG_TEST, &byOrgValue);
539         byOrgValue = byOrgValue & 0x3F;
540         byOrgValue = byOrgValue | byLoopbackMode;
541         VNSvOutPortB(dwIoBase + MAC_REG_TEST, byOrgValue);
542 }
543
544 /*
545  * Description:
546  *      Test if MAC in Loopback mode
547  *
548  * Parameters:
549  *  In:
550  *      dwIoBase        - Base Address for MAC
551  *  Out:
552  *      none
553  *
554  * Return Value: true if in Loopback mode; otherwise false
555  *
556  */
557 bool MACbIsInLoopbackMode(unsigned long dwIoBase)
558 {
559         unsigned char byOrgValue;
560
561         VNSvInPortB(dwIoBase + MAC_REG_TEST, &byOrgValue);
562         if (byOrgValue & (TEST_LBINT | TEST_LBEXT))
563                 return true;
564         return false;
565 }
566
567 /*
568  * Description:
569  *      Set MAC Address filter
570  *
571  * Parameters:
572  *  In:
573  *      dwIoBase        - Base Address for MAC
574  *      wFilterType     - Filter Type
575  *  Out:
576  *      none
577  *
578  * Return Value: none
579  *
580  */
581 void MACvSetPacketFilter(unsigned long dwIoBase, unsigned short wFilterType)
582 {
583         unsigned char byOldRCR;
584         unsigned char byNewRCR = 0;
585
586         // if only in DIRECTED mode, multicast-address will set to zero,
587         // but if other mode exist (e.g. PROMISCUOUS), multicast-address
588         // will be open
589         if (wFilterType & PKT_TYPE_DIRECTED) {
590                 // set multicast address to accept none
591                 MACvSelectPage1(dwIoBase);
592                 VNSvOutPortD(dwIoBase + MAC_REG_MAR0, 0L);
593                 VNSvOutPortD(dwIoBase + MAC_REG_MAR0 + sizeof(unsigned long), 0L);
594                 MACvSelectPage0(dwIoBase);
595         }
596
597         if (wFilterType & (PKT_TYPE_PROMISCUOUS | PKT_TYPE_ALL_MULTICAST)) {
598                 // set multicast address to accept all
599                 MACvSelectPage1(dwIoBase);
600                 VNSvOutPortD(dwIoBase + MAC_REG_MAR0, 0xFFFFFFFFL);
601                 VNSvOutPortD(dwIoBase + MAC_REG_MAR0 + sizeof(unsigned long), 0xFFFFFFFFL);
602                 MACvSelectPage0(dwIoBase);
603         }
604
605         if (wFilterType & PKT_TYPE_PROMISCUOUS) {
606                 byNewRCR |= (RCR_RXALLTYPE | RCR_UNICAST | RCR_MULTICAST | RCR_BROADCAST);
607
608                 byNewRCR &= ~RCR_BSSID;
609         }
610
611         if (wFilterType & (PKT_TYPE_ALL_MULTICAST | PKT_TYPE_MULTICAST))
612                 byNewRCR |= RCR_MULTICAST;
613
614         if (wFilterType & PKT_TYPE_BROADCAST)
615                 byNewRCR |= RCR_BROADCAST;
616
617         if (wFilterType & PKT_TYPE_ERROR_CRC)
618                 byNewRCR |= RCR_ERRCRC;
619
620         VNSvInPortB(dwIoBase + MAC_REG_RCR,  &byOldRCR);
621         if (byNewRCR != byOldRCR) {
622                 // Modify the Receive Command Register
623                 VNSvOutPortB(dwIoBase + MAC_REG_RCR, byNewRCR);
624         }
625 }
626
627 /*
628  * Description:
629  *      Save MAC registers to context buffer
630  *
631  * Parameters:
632  *  In:
633  *      dwIoBase    - Base Address for MAC
634  *  Out:
635  *      pbyCxtBuf   - Context buffer
636  *
637  * Return Value: none
638  *
639  */
640 void MACvSaveContext(unsigned long dwIoBase, unsigned char *pbyCxtBuf)
641 {
642         int         ii;
643
644         // read page0 register
645         for (ii = 0; ii < MAC_MAX_CONTEXT_SIZE_PAGE0; ii++) {
646                 VNSvInPortB((dwIoBase + ii), (pbyCxtBuf + ii));
647         }
648
649         MACvSelectPage1(dwIoBase);
650
651         // read page1 register
652         for (ii = 0; ii < MAC_MAX_CONTEXT_SIZE_PAGE1; ii++) {
653                 VNSvInPortB((dwIoBase + ii), (pbyCxtBuf + MAC_MAX_CONTEXT_SIZE_PAGE0 + ii));
654         }
655
656         MACvSelectPage0(dwIoBase);
657 }
658
659 /*
660  * Description:
661  *      Restore MAC registers from context buffer
662  *
663  * Parameters:
664  *  In:
665  *      dwIoBase    - Base Address for MAC
666  *      pbyCxtBuf   - Context buffer
667  *  Out:
668  *      none
669  *
670  * Return Value: none
671  *
672  */
673 void MACvRestoreContext(unsigned long dwIoBase, unsigned char *pbyCxtBuf)
674 {
675         int         ii;
676
677         MACvSelectPage1(dwIoBase);
678         // restore page1
679         for (ii = 0; ii < MAC_MAX_CONTEXT_SIZE_PAGE1; ii++) {
680                 VNSvOutPortB((dwIoBase + ii), *(pbyCxtBuf + MAC_MAX_CONTEXT_SIZE_PAGE0 + ii));
681         }
682         MACvSelectPage0(dwIoBase);
683
684         // restore RCR,TCR,IMR...
685         for (ii = MAC_REG_RCR; ii < MAC_REG_ISR; ii++) {
686                 VNSvOutPortB(dwIoBase + ii, *(pbyCxtBuf + ii));
687         }
688         // restore MAC Config.
689         for (ii = MAC_REG_LRT; ii < MAC_REG_PAGE1SEL; ii++) {
690                 VNSvOutPortB(dwIoBase + ii, *(pbyCxtBuf + ii));
691         }
692         VNSvOutPortB(dwIoBase + MAC_REG_CFG, *(pbyCxtBuf + MAC_REG_CFG));
693
694         // restore PS Config.
695         for (ii = MAC_REG_PSCFG; ii < MAC_REG_BBREGCTL; ii++) {
696                 VNSvOutPortB(dwIoBase + ii, *(pbyCxtBuf + ii));
697         }
698
699         // restore CURR_RX_DESC_ADDR, CURR_TX_DESC_ADDR
700         VNSvOutPortD(dwIoBase + MAC_REG_TXDMAPTR0, *(unsigned long *)(pbyCxtBuf + MAC_REG_TXDMAPTR0));
701         VNSvOutPortD(dwIoBase + MAC_REG_AC0DMAPTR, *(unsigned long *)(pbyCxtBuf + MAC_REG_AC0DMAPTR));
702         VNSvOutPortD(dwIoBase + MAC_REG_BCNDMAPTR, *(unsigned long *)(pbyCxtBuf + MAC_REG_BCNDMAPTR));
703
704         VNSvOutPortD(dwIoBase + MAC_REG_RXDMAPTR0, *(unsigned long *)(pbyCxtBuf + MAC_REG_RXDMAPTR0));
705
706         VNSvOutPortD(dwIoBase + MAC_REG_RXDMAPTR1, *(unsigned long *)(pbyCxtBuf + MAC_REG_RXDMAPTR1));
707 }
708
709 /*
710  * Description:
711  *      Compare if MAC registers same as context buffer
712  *
713  * Parameters:
714  *  In:
715  *      dwIoBase    - Base Address for MAC
716  *      pbyCxtBuf   - Context buffer
717  *  Out:
718  *      none
719  *
720  * Return Value: true if all values are the same; otherwise false
721  *
722  */
723 bool MACbCompareContext(unsigned long dwIoBase, unsigned char *pbyCxtBuf)
724 {
725         unsigned long dwData;
726
727         // compare MAC context to determine if this is a power lost init,
728         // return true for power remaining init, return false for power lost init
729
730         // compare CURR_RX_DESC_ADDR, CURR_TX_DESC_ADDR
731         VNSvInPortD(dwIoBase + MAC_REG_TXDMAPTR0, &dwData);
732         if (dwData != *(unsigned long *)(pbyCxtBuf + MAC_REG_TXDMAPTR0)) {
733                 return false;
734         }
735
736         VNSvInPortD(dwIoBase + MAC_REG_AC0DMAPTR, &dwData);
737         if (dwData != *(unsigned long *)(pbyCxtBuf + MAC_REG_AC0DMAPTR)) {
738                 return false;
739         }
740
741         VNSvInPortD(dwIoBase + MAC_REG_RXDMAPTR0, &dwData);
742         if (dwData != *(unsigned long *)(pbyCxtBuf + MAC_REG_RXDMAPTR0)) {
743                 return false;
744         }
745
746         VNSvInPortD(dwIoBase + MAC_REG_RXDMAPTR1, &dwData);
747         if (dwData != *(unsigned long *)(pbyCxtBuf + MAC_REG_RXDMAPTR1)) {
748                 return false;
749         }
750
751         return true;
752 }
753
754 /*
755  * Description:
756  *      Software Reset MAC
757  *
758  * Parameters:
759  *  In:
760  *      dwIoBase    - Base Address for MAC
761  *  Out:
762  *      none
763  *
764  * Return Value: true if Reset Success; otherwise false
765  *
766  */
767 bool MACbSoftwareReset(unsigned long dwIoBase)
768 {
769         unsigned char byData;
770         unsigned short ww;
771
772         // turn on HOSTCR_SOFTRST, just write 0x01 to reset
773         //MACvRegBitsOn(dwIoBase, MAC_REG_HOSTCR, HOSTCR_SOFTRST);
774         VNSvOutPortB(dwIoBase + MAC_REG_HOSTCR, 0x01);
775
776         for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
777                 VNSvInPortB(dwIoBase + MAC_REG_HOSTCR, &byData);
778                 if (!(byData & HOSTCR_SOFTRST))
779                         break;
780         }
781         if (ww == W_MAX_TIMEOUT)
782                 return false;
783         return true;
784 }
785
786 /*
787  * Description:
788  *      save some important register's value, then do reset, then restore register's value
789  *
790  * Parameters:
791  *  In:
792  *      dwIoBase    - Base Address for MAC
793  *  Out:
794  *      none
795  *
796  * Return Value: true if success; otherwise false
797  *
798  */
799 bool MACbSafeSoftwareReset(unsigned long dwIoBase)
800 {
801         unsigned char abyTmpRegData[MAC_MAX_CONTEXT_SIZE_PAGE0+MAC_MAX_CONTEXT_SIZE_PAGE1];
802         bool bRetVal;
803
804         // PATCH....
805         // save some important register's value, then do
806         // reset, then restore register's value
807
808         // save MAC context
809         MACvSaveContext(dwIoBase, abyTmpRegData);
810         // do reset
811         bRetVal = MACbSoftwareReset(dwIoBase);
812         //BBvSoftwareReset(pDevice->PortOffset);
813         // restore MAC context, except CR0
814         MACvRestoreContext(dwIoBase, abyTmpRegData);
815
816         return bRetVal;
817 }
818
819 /*
820  * Description:
821  *      Trun Off MAC Rx
822  *
823  * Parameters:
824  *  In:
825  *      dwIoBase    - Base Address for MAC
826  *  Out:
827  *      none
828  *
829  * Return Value: true if success; otherwise false
830  *
831  */
832 bool MACbSafeRxOff(unsigned long dwIoBase)
833 {
834         unsigned short ww;
835         unsigned long dwData;
836         unsigned char byData;
837
838         // turn off wow temp for turn off Rx safely
839
840         // Clear RX DMA0,1
841         VNSvOutPortD(dwIoBase + MAC_REG_RXDMACTL0, DMACTL_CLRRUN);
842         VNSvOutPortD(dwIoBase + MAC_REG_RXDMACTL1, DMACTL_CLRRUN);
843         for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
844                 VNSvInPortD(dwIoBase + MAC_REG_RXDMACTL0, &dwData);
845                 if (!(dwData & DMACTL_RUN))
846                         break;
847         }
848         if (ww == W_MAX_TIMEOUT) {
849                 DBG_PORT80(0x10);
850                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x10)\n");
851                 return false;
852         }
853         for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
854                 VNSvInPortD(dwIoBase + MAC_REG_RXDMACTL1, &dwData);
855                 if (!(dwData & DMACTL_RUN))
856                         break;
857         }
858         if (ww == W_MAX_TIMEOUT) {
859                 DBG_PORT80(0x11);
860                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x11)\n");
861                 return false;
862         }
863
864         // try to safe shutdown RX
865         MACvRegBitsOff(dwIoBase, MAC_REG_HOSTCR, HOSTCR_RXON);
866         // W_MAX_TIMEOUT is the timeout period
867         for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
868                 VNSvInPortB(dwIoBase + MAC_REG_HOSTCR, &byData);
869                 if (!(byData & HOSTCR_RXONST))
870                         break;
871         }
872         if (ww == W_MAX_TIMEOUT) {
873                 DBG_PORT80(0x12);
874                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x12)\n");
875                 return false;
876         }
877         return true;
878 }
879
880 /*
881  * Description:
882  *      Trun Off MAC Tx
883  *
884  * Parameters:
885  *  In:
886  *      dwIoBase    - Base Address for MAC
887  *  Out:
888  *      none
889  *
890  * Return Value: true if success; otherwise false
891  *
892  */
893 bool MACbSafeTxOff(unsigned long dwIoBase)
894 {
895         unsigned short ww;
896         unsigned long dwData;
897         unsigned char byData;
898
899         // Clear TX DMA
900         //Tx0
901         VNSvOutPortD(dwIoBase + MAC_REG_TXDMACTL0, DMACTL_CLRRUN);
902         //AC0
903         VNSvOutPortD(dwIoBase + MAC_REG_AC0DMACTL, DMACTL_CLRRUN);
904
905         for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
906                 VNSvInPortD(dwIoBase + MAC_REG_TXDMACTL0, &dwData);
907                 if (!(dwData & DMACTL_RUN))
908                         break;
909         }
910         if (ww == W_MAX_TIMEOUT) {
911                 DBG_PORT80(0x20);
912                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x20)\n");
913                 return false;
914         }
915         for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
916                 VNSvInPortD(dwIoBase + MAC_REG_AC0DMACTL, &dwData);
917                 if (!(dwData & DMACTL_RUN))
918                         break;
919         }
920         if (ww == W_MAX_TIMEOUT) {
921                 DBG_PORT80(0x21);
922                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x21)\n");
923                 return false;
924         }
925
926         // try to safe shutdown TX
927         MACvRegBitsOff(dwIoBase, MAC_REG_HOSTCR, HOSTCR_TXON);
928
929         // W_MAX_TIMEOUT is the timeout period
930         for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
931                 VNSvInPortB(dwIoBase + MAC_REG_HOSTCR, &byData);
932                 if (!(byData & HOSTCR_TXONST))
933                         break;
934         }
935         if (ww == W_MAX_TIMEOUT) {
936                 DBG_PORT80(0x24);
937                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x24)\n");
938                 return false;
939         }
940         return true;
941 }
942
943 /*
944  * Description:
945  *      Stop MAC function
946  *
947  * Parameters:
948  *  In:
949  *      dwIoBase    - Base Address for MAC
950  *  Out:
951  *      none
952  *
953  * Return Value: true if success; otherwise false
954  *
955  */
956 bool MACbSafeStop(unsigned long dwIoBase)
957 {
958         MACvRegBitsOff(dwIoBase, MAC_REG_TCR, TCR_AUTOBCNTX);
959
960         if (MACbSafeRxOff(dwIoBase) == false) {
961                 DBG_PORT80(0xA1);
962                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " MACbSafeRxOff == false)\n");
963                 MACbSafeSoftwareReset(dwIoBase);
964                 return false;
965         }
966         if (MACbSafeTxOff(dwIoBase) == false) {
967                 DBG_PORT80(0xA2);
968                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " MACbSafeTxOff == false)\n");
969                 MACbSafeSoftwareReset(dwIoBase);
970                 return false;
971         }
972
973         MACvRegBitsOff(dwIoBase, MAC_REG_HOSTCR, HOSTCR_MACEN);
974
975         return true;
976 }
977
978 /*
979  * Description:
980  *      Shut Down MAC
981  *
982  * Parameters:
983  *  In:
984  *      dwIoBase    - Base Address for MAC
985  *  Out:
986  *      none
987  *
988  * Return Value: true if success; otherwise false
989  *
990  */
991 bool MACbShutdown(unsigned long dwIoBase)
992 {
993         // disable MAC IMR
994         MACvIntDisable(dwIoBase);
995         MACvSetLoopbackMode(dwIoBase, MAC_LB_INTERNAL);
996         // stop the adapter
997         if (!MACbSafeStop(dwIoBase)) {
998                 MACvSetLoopbackMode(dwIoBase, MAC_LB_NONE);
999                 return false;
1000         }
1001         MACvSetLoopbackMode(dwIoBase, MAC_LB_NONE);
1002         return true;
1003 }
1004
1005 /*
1006  * Description:
1007  *      Initialize MAC
1008  *
1009  * Parameters:
1010  *  In:
1011  *      dwIoBase    - Base Address for MAC
1012  *  Out:
1013  *      none
1014  *
1015  * Return Value: none
1016  *
1017  */
1018 void MACvInitialize(unsigned long dwIoBase)
1019 {
1020         // clear sticky bits
1021         MACvClearStckDS(dwIoBase);
1022         // disable force PME-enable
1023         VNSvOutPortB(dwIoBase + MAC_REG_PMC1, PME_OVR);
1024         // only 3253 A
1025         /*
1026           MACvPwrEvntDisable(dwIoBase);
1027           // clear power status
1028           VNSvOutPortW(dwIoBase + MAC_REG_WAKEUPSR0, 0x0F0F);
1029         */
1030
1031         // do reset
1032         MACbSoftwareReset(dwIoBase);
1033
1034         // reset TSF counter
1035         VNSvOutPortB(dwIoBase + MAC_REG_TFTCTL, TFTCTL_TSFCNTRST);
1036         // enable TSF counter
1037         VNSvOutPortB(dwIoBase + MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
1038
1039         // set packet filter
1040         // receive directed and broadcast address
1041
1042         MACvSetPacketFilter(dwIoBase, PKT_TYPE_DIRECTED | PKT_TYPE_BROADCAST);
1043 }
1044
1045 /*
1046  * Description:
1047  *      Set the chip with current rx descriptor address
1048  *
1049  * Parameters:
1050  *  In:
1051  *      dwIoBase        - Base Address for MAC
1052  *      dwCurrDescAddr  - Descriptor Address
1053  *  Out:
1054  *      none
1055  *
1056  * Return Value: none
1057  *
1058  */
1059 void MACvSetCurrRx0DescAddr(unsigned long dwIoBase, unsigned long dwCurrDescAddr)
1060 {
1061         unsigned short ww;
1062         unsigned char byData;
1063         unsigned char byOrgDMACtl;
1064
1065         VNSvInPortB(dwIoBase + MAC_REG_RXDMACTL0, &byOrgDMACtl);
1066         if (byOrgDMACtl & DMACTL_RUN) {
1067                 VNSvOutPortB(dwIoBase + MAC_REG_RXDMACTL0+2, DMACTL_RUN);
1068         }
1069         for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
1070                 VNSvInPortB(dwIoBase + MAC_REG_RXDMACTL0, &byData);
1071                 if (!(byData & DMACTL_RUN))
1072                         break;
1073         }
1074         if (ww == W_MAX_TIMEOUT) {
1075                 DBG_PORT80(0x13);
1076         }
1077         VNSvOutPortD(dwIoBase + MAC_REG_RXDMAPTR0, dwCurrDescAddr);
1078         if (byOrgDMACtl & DMACTL_RUN) {
1079                 VNSvOutPortB(dwIoBase + MAC_REG_RXDMACTL0, DMACTL_RUN);
1080         }
1081 }
1082
1083 /*
1084  * Description:
1085  *      Set the chip with current rx descriptor address
1086  *
1087  * Parameters:
1088  *  In:
1089  *      dwIoBase        - Base Address for MAC
1090  *      dwCurrDescAddr  - Descriptor Address
1091  *  Out:
1092  *      none
1093  *
1094  * Return Value: none
1095  *
1096  */
1097 void MACvSetCurrRx1DescAddr(unsigned long dwIoBase, unsigned long dwCurrDescAddr)
1098 {
1099         unsigned short ww;
1100         unsigned char byData;
1101         unsigned char byOrgDMACtl;
1102
1103         VNSvInPortB(dwIoBase + MAC_REG_RXDMACTL1, &byOrgDMACtl);
1104         if (byOrgDMACtl & DMACTL_RUN) {
1105                 VNSvOutPortB(dwIoBase + MAC_REG_RXDMACTL1+2, DMACTL_RUN);
1106         }
1107         for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
1108                 VNSvInPortB(dwIoBase + MAC_REG_RXDMACTL1, &byData);
1109                 if (!(byData & DMACTL_RUN))
1110                         break;
1111         }
1112         if (ww == W_MAX_TIMEOUT) {
1113                 DBG_PORT80(0x14);
1114         }
1115         VNSvOutPortD(dwIoBase + MAC_REG_RXDMAPTR1, dwCurrDescAddr);
1116         if (byOrgDMACtl & DMACTL_RUN) {
1117                 VNSvOutPortB(dwIoBase + MAC_REG_RXDMACTL1, DMACTL_RUN);
1118         }
1119 }
1120
1121 /*
1122  * Description:
1123  *      Set the chip with current tx0 descriptor address
1124  *
1125  * Parameters:
1126  *  In:
1127  *      dwIoBase        - Base Address for MAC
1128  *      dwCurrDescAddr  - Descriptor Address
1129  *  Out:
1130  *      none
1131  *
1132  * Return Value: none
1133  *
1134  */
1135 void MACvSetCurrTx0DescAddrEx(unsigned long dwIoBase, unsigned long dwCurrDescAddr)
1136 {
1137         unsigned short ww;
1138         unsigned char byData;
1139         unsigned char byOrgDMACtl;
1140
1141         VNSvInPortB(dwIoBase + MAC_REG_TXDMACTL0, &byOrgDMACtl);
1142         if (byOrgDMACtl & DMACTL_RUN) {
1143                 VNSvOutPortB(dwIoBase + MAC_REG_TXDMACTL0+2, DMACTL_RUN);
1144         }
1145         for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
1146                 VNSvInPortB(dwIoBase + MAC_REG_TXDMACTL0, &byData);
1147                 if (!(byData & DMACTL_RUN))
1148                         break;
1149         }
1150         if (ww == W_MAX_TIMEOUT) {
1151                 DBG_PORT80(0x25);
1152         }
1153         VNSvOutPortD(dwIoBase + MAC_REG_TXDMAPTR0, dwCurrDescAddr);
1154         if (byOrgDMACtl & DMACTL_RUN) {
1155                 VNSvOutPortB(dwIoBase + MAC_REG_TXDMACTL0, DMACTL_RUN);
1156         }
1157 }
1158
1159 /*
1160  * Description:
1161  *      Set the chip with current AC0 descriptor address
1162  *
1163  * Parameters:
1164  *  In:
1165  *      dwIoBase        - Base Address for MAC
1166  *      dwCurrDescAddr  - Descriptor Address
1167  *  Out:
1168  *      none
1169  *
1170  * Return Value: none
1171  *
1172  */
1173 //TxDMA1 = AC0DMA
1174 void MACvSetCurrAC0DescAddrEx(unsigned long dwIoBase, unsigned long dwCurrDescAddr)
1175 {
1176         unsigned short ww;
1177         unsigned char byData;
1178         unsigned char byOrgDMACtl;
1179
1180         VNSvInPortB(dwIoBase + MAC_REG_AC0DMACTL, &byOrgDMACtl);
1181         if (byOrgDMACtl & DMACTL_RUN) {
1182                 VNSvOutPortB(dwIoBase + MAC_REG_AC0DMACTL+2, DMACTL_RUN);
1183         }
1184         for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
1185                 VNSvInPortB(dwIoBase + MAC_REG_AC0DMACTL, &byData);
1186                 if (!(byData & DMACTL_RUN))
1187                         break;
1188         }
1189         if (ww == W_MAX_TIMEOUT) {
1190                 DBG_PORT80(0x26);
1191                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x26)\n");
1192         }
1193         VNSvOutPortD(dwIoBase + MAC_REG_AC0DMAPTR, dwCurrDescAddr);
1194         if (byOrgDMACtl & DMACTL_RUN) {
1195                 VNSvOutPortB(dwIoBase + MAC_REG_AC0DMACTL, DMACTL_RUN);
1196         }
1197 }
1198
1199 void MACvSetCurrTXDescAddr(int iTxType, unsigned long dwIoBase, unsigned long dwCurrDescAddr)
1200 {
1201         if (iTxType == TYPE_AC0DMA) {
1202                 MACvSetCurrAC0DescAddrEx(dwIoBase, dwCurrDescAddr);
1203         } else if (iTxType == TYPE_TXDMA0) {
1204                 MACvSetCurrTx0DescAddrEx(dwIoBase, dwCurrDescAddr);
1205         }
1206 }
1207
1208 /*
1209  * Description:
1210  *      Micro Second Delay via MAC
1211  *
1212  * Parameters:
1213  *  In:
1214  *      dwIoBase    - Base Address for MAC
1215  *      uDelay      - Delay time (timer resolution is 4 us)
1216  *  Out:
1217  *      none
1218  *
1219  * Return Value: none
1220  *
1221  */
1222 void MACvTimer0MicroSDelay(unsigned long dwIoBase, unsigned int uDelay)
1223 {
1224         unsigned char byValue;
1225         unsigned int uu, ii;
1226
1227         VNSvOutPortB(dwIoBase + MAC_REG_TMCTL0, 0);
1228         VNSvOutPortD(dwIoBase + MAC_REG_TMDATA0, uDelay);
1229         VNSvOutPortB(dwIoBase + MAC_REG_TMCTL0, (TMCTL_TMD | TMCTL_TE));
1230         for (ii = 0; ii < 66; ii++) {  // assume max PCI clock is 66Mhz
1231                 for (uu = 0; uu < uDelay; uu++) {
1232                         VNSvInPortB(dwIoBase + MAC_REG_TMCTL0, &byValue);
1233                         if ((byValue == 0) ||
1234                             (byValue & TMCTL_TSUSP)) {
1235                                 VNSvOutPortB(dwIoBase + MAC_REG_TMCTL0, 0);
1236                                 return;
1237                         }
1238                 }
1239         }
1240         VNSvOutPortB(dwIoBase + MAC_REG_TMCTL0, 0);
1241 }
1242
1243 /*
1244  * Description:
1245  *      Micro Second One shot timer via MAC
1246  *
1247  * Parameters:
1248  *  In:
1249  *      dwIoBase    - Base Address for MAC
1250  *      uDelay      - Delay time
1251  *  Out:
1252  *      none
1253  *
1254  * Return Value: none
1255  *
1256  */
1257 void MACvOneShotTimer0MicroSec(unsigned long dwIoBase, unsigned int uDelayTime)
1258 {
1259         VNSvOutPortB(dwIoBase + MAC_REG_TMCTL0, 0);
1260         VNSvOutPortD(dwIoBase + MAC_REG_TMDATA0, uDelayTime);
1261         VNSvOutPortB(dwIoBase + MAC_REG_TMCTL0, (TMCTL_TMD | TMCTL_TE));
1262 }
1263
1264 /*
1265  * Description:
1266  *      Micro Second One shot timer via MAC
1267  *
1268  * Parameters:
1269  *  In:
1270  *      dwIoBase    - Base Address for MAC
1271  *      uDelay      - Delay time
1272  *  Out:
1273  *      none
1274  *
1275  * Return Value: none
1276  *
1277  */
1278 void MACvOneShotTimer1MicroSec(unsigned long dwIoBase, unsigned int uDelayTime)
1279 {
1280         VNSvOutPortB(dwIoBase + MAC_REG_TMCTL1, 0);
1281         VNSvOutPortD(dwIoBase + MAC_REG_TMDATA1, uDelayTime);
1282         VNSvOutPortB(dwIoBase + MAC_REG_TMCTL1, (TMCTL_TMD | TMCTL_TE));
1283 }
1284
1285 void MACvSetMISCFifo(unsigned long dwIoBase, unsigned short wOffset, unsigned long dwData)
1286 {
1287         if (wOffset > 273)
1288                 return;
1289         VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset);
1290         VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData);
1291         VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
1292 }
1293
1294 bool MACbTxDMAOff(unsigned long dwIoBase, unsigned int idx)
1295 {
1296         unsigned char byData;
1297         unsigned int ww = 0;
1298
1299         if (idx == TYPE_TXDMA0) {
1300                 VNSvOutPortB(dwIoBase + MAC_REG_TXDMACTL0+2, DMACTL_RUN);
1301                 for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
1302                         VNSvInPortB(dwIoBase + MAC_REG_TXDMACTL0, &byData);
1303                         if (!(byData & DMACTL_RUN))
1304                                 break;
1305                 }
1306         } else if (idx == TYPE_AC0DMA) {
1307                 VNSvOutPortB(dwIoBase + MAC_REG_AC0DMACTL+2, DMACTL_RUN);
1308                 for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
1309                         VNSvInPortB(dwIoBase + MAC_REG_AC0DMACTL, &byData);
1310                         if (!(byData & DMACTL_RUN))
1311                                 break;
1312                 }
1313         }
1314         if (ww == W_MAX_TIMEOUT) {
1315                 DBG_PORT80(0x29);
1316                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x29)\n");
1317                 return false;
1318         }
1319         return true;
1320 }
1321
1322 void MACvClearBusSusInd(unsigned long dwIoBase)
1323 {
1324         unsigned long dwOrgValue;
1325         unsigned int ww;
1326         // check if BcnSusInd enabled
1327         VNSvInPortD(dwIoBase + MAC_REG_ENCFG , &dwOrgValue);
1328         if (!(dwOrgValue & EnCFG_BcnSusInd))
1329                 return;
1330         //Set BcnSusClr
1331         dwOrgValue = dwOrgValue | EnCFG_BcnSusClr;
1332         VNSvOutPortD(dwIoBase + MAC_REG_ENCFG, dwOrgValue);
1333         for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
1334                 VNSvInPortD(dwIoBase + MAC_REG_ENCFG , &dwOrgValue);
1335                 if (!(dwOrgValue & EnCFG_BcnSusInd))
1336                         break;
1337         }
1338         if (ww == W_MAX_TIMEOUT) {
1339                 DBG_PORT80(0x33);
1340                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x33)\n");
1341         }
1342 }
1343
1344 void MACvEnableBusSusEn(unsigned long dwIoBase)
1345 {
1346         unsigned char byOrgValue;
1347         unsigned long dwOrgValue;
1348         unsigned int ww;
1349         // check if BcnSusInd enabled
1350         VNSvInPortB(dwIoBase + MAC_REG_CFG , &byOrgValue);
1351
1352         //Set BcnSusEn
1353         byOrgValue = byOrgValue | CFG_BCNSUSEN;
1354         VNSvOutPortB(dwIoBase + MAC_REG_ENCFG, byOrgValue);
1355         for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
1356                 VNSvInPortD(dwIoBase + MAC_REG_ENCFG , &dwOrgValue);
1357                 if (dwOrgValue & EnCFG_BcnSusInd)
1358                         break;
1359         }
1360         if (ww == W_MAX_TIMEOUT) {
1361                 DBG_PORT80(0x34);
1362                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x34)\n");
1363         }
1364 }
1365
1366 bool MACbFlushSYNCFifo(unsigned long dwIoBase)
1367 {
1368         unsigned char byOrgValue;
1369         unsigned int ww;
1370         // Read MACCR
1371         VNSvInPortB(dwIoBase + MAC_REG_MACCR , &byOrgValue);
1372
1373         // Set SYNCFLUSH
1374         byOrgValue = byOrgValue | MACCR_SYNCFLUSH;
1375         VNSvOutPortB(dwIoBase + MAC_REG_MACCR, byOrgValue);
1376
1377         // Check if SyncFlushOK
1378         for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
1379                 VNSvInPortB(dwIoBase + MAC_REG_MACCR , &byOrgValue);
1380                 if (byOrgValue & MACCR_SYNCFLUSHOK)
1381                         break;
1382         }
1383         if (ww == W_MAX_TIMEOUT) {
1384                 DBG_PORT80(0x35);
1385                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x33)\n");
1386         }
1387         return true;
1388 }
1389
1390 bool MACbPSWakeup(unsigned long dwIoBase)
1391 {
1392         unsigned char byOrgValue;
1393         unsigned int ww;
1394         // Read PSCTL
1395         if (MACbIsRegBitsOff(dwIoBase, MAC_REG_PSCTL, PSCTL_PS)) {
1396                 return true;
1397         }
1398         // Disable PS
1399         MACvRegBitsOff(dwIoBase, MAC_REG_PSCTL, PSCTL_PSEN);
1400
1401         // Check if SyncFlushOK
1402         for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
1403                 VNSvInPortB(dwIoBase + MAC_REG_PSCTL , &byOrgValue);
1404                 if (byOrgValue & PSCTL_WAKEDONE)
1405                         break;
1406         }
1407         if (ww == W_MAX_TIMEOUT) {
1408                 DBG_PORT80(0x36);
1409                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x33)\n");
1410                 return false;
1411         }
1412         return true;
1413 }
1414
1415 /*
1416  * Description:
1417  *      Set the Key by MISCFIFO
1418  *
1419  * Parameters:
1420  *  In:
1421  *      dwIoBase        - Base Address for MAC
1422  *
1423  *  Out:
1424  *      none
1425  *
1426  * Return Value: none
1427  *
1428  */
1429
1430 void MACvSetKeyEntry(unsigned long dwIoBase, unsigned short wKeyCtl, unsigned int uEntryIdx,
1431                      unsigned int uKeyIdx, unsigned char *pbyAddr, unsigned long *pdwKey, unsigned char byLocalID)
1432 {
1433         unsigned short wOffset;
1434         unsigned long dwData;
1435         int     ii;
1436
1437         if (byLocalID <= 1)
1438                 return;
1439
1440         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MACvSetKeyEntry\n");
1441         wOffset = MISCFIFO_KEYETRY0;
1442         wOffset += (uEntryIdx * MISCFIFO_KEYENTRYSIZE);
1443
1444         dwData = 0;
1445         dwData |= wKeyCtl;
1446         dwData <<= 16;
1447         dwData |= MAKEWORD(*(pbyAddr+4), *(pbyAddr+5));
1448         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "1. wOffset: %d, Data: %lX, KeyCtl:%X\n", wOffset, dwData, wKeyCtl);
1449
1450         VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset);
1451         VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData);
1452         VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
1453         wOffset++;
1454
1455         dwData = 0;
1456         dwData |= *(pbyAddr+3);
1457         dwData <<= 8;
1458         dwData |= *(pbyAddr+2);
1459         dwData <<= 8;
1460         dwData |= *(pbyAddr+1);
1461         dwData <<= 8;
1462         dwData |= *(pbyAddr+0);
1463         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "2. wOffset: %d, Data: %lX\n", wOffset, dwData);
1464
1465         VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset);
1466         VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData);
1467         VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
1468         wOffset++;
1469
1470         wOffset += (uKeyIdx * 4);
1471         for (ii = 0; ii < 4; ii++) {
1472                 // always push 128 bits
1473                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "3.(%d) wOffset: %d, Data: %lX\n", ii, wOffset+ii, *pdwKey);
1474                 VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset+ii);
1475                 VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, *pdwKey++);
1476                 VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
1477         }
1478 }
1479
1480 /*
1481  * Description:
1482  *      Disable the Key Entry by MISCFIFO
1483  *
1484  * Parameters:
1485  *  In:
1486  *      dwIoBase        - Base Address for MAC
1487  *
1488  *  Out:
1489  *      none
1490  *
1491  * Return Value: none
1492  *
1493  */
1494 void MACvDisableKeyEntry(unsigned long dwIoBase, unsigned int uEntryIdx)
1495 {
1496         unsigned short wOffset;
1497
1498         wOffset = MISCFIFO_KEYETRY0;
1499         wOffset += (uEntryIdx * MISCFIFO_KEYENTRYSIZE);
1500
1501         VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset);
1502         VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, 0);
1503         VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
1504 }
1505
1506 /*
1507  * Description:
1508  *      Set the default Key (KeyEntry[10]) by MISCFIFO
1509  *
1510  * Parameters:
1511  *  In:
1512  *      dwIoBase        - Base Address for MAC
1513  *
1514  *  Out:
1515  *      none
1516  *
1517  * Return Value: none
1518  *
1519  */
1520
1521 void MACvSetDefaultKeyEntry(unsigned long dwIoBase, unsigned int uKeyLen,
1522                             unsigned int uKeyIdx, unsigned long *pdwKey, unsigned char byLocalID)
1523 {
1524         unsigned short wOffset;
1525         unsigned long dwData;
1526         int     ii;
1527
1528         if (byLocalID <= 1)
1529                 return;
1530
1531         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MACvSetDefaultKeyEntry\n");
1532         wOffset = MISCFIFO_KEYETRY0;
1533         wOffset += (10 * MISCFIFO_KEYENTRYSIZE);
1534
1535         wOffset++;
1536         wOffset++;
1537         wOffset += (uKeyIdx * 4);
1538         // always push 128 bits
1539         for (ii = 0; ii < 3; ii++) {
1540                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "(%d) wOffset: %d, Data: %lX\n", ii, wOffset+ii, *pdwKey);
1541                 VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset+ii);
1542                 VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, *pdwKey++);
1543                 VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
1544         }
1545         dwData = *pdwKey;
1546         if (uKeyLen == WLAN_WEP104_KEYLEN) {
1547                 dwData |= 0x80000000;
1548         }
1549         VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset+3);
1550         VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData);
1551         VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
1552         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "End. wOffset: %d, Data: %lX\n", wOffset+3, dwData);
1553 }
1554
1555 /*
1556  * Description:
1557  *      Enable default Key (KeyEntry[10]) by MISCFIFO
1558  *
1559  * Parameters:
1560  *  In:
1561  *      dwIoBase        - Base Address for MAC
1562  *
1563  *  Out:
1564  *      none
1565  *
1566  * Return Value: none
1567  *
1568  */
1569 /*
1570   void MACvEnableDefaultKey(unsigned long dwIoBase, unsigned char byLocalID)
1571   {
1572   unsigned short wOffset;
1573   unsigned long dwData;
1574
1575   if (byLocalID <= 1)
1576   return;
1577
1578   wOffset = MISCFIFO_KEYETRY0;
1579   wOffset += (10 * MISCFIFO_KEYENTRYSIZE);
1580
1581   dwData = 0xC0440000;
1582   VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset);
1583   VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData);
1584   VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
1585   DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MACvEnableDefaultKey: wOffset: %d, Data: %lX\n", wOffset, dwData);
1586
1587   }
1588 */
1589
1590 /*
1591  * Description:
1592  *      Disable default Key (KeyEntry[10]) by MISCFIFO
1593  *
1594  * Parameters:
1595  *  In:
1596  *      dwIoBase        - Base Address for MAC
1597  *
1598  *  Out:
1599  *      none
1600  *
1601  * Return Value: none
1602  *
1603  */
1604 void MACvDisableDefaultKey(unsigned long dwIoBase)
1605 {
1606         unsigned short wOffset;
1607         unsigned long dwData;
1608
1609         wOffset = MISCFIFO_KEYETRY0;
1610         wOffset += (10 * MISCFIFO_KEYENTRYSIZE);
1611
1612         dwData = 0x0;
1613         VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset);
1614         VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData);
1615         VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
1616         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MACvDisableDefaultKey: wOffset: %d, Data: %lX\n", wOffset, dwData);
1617 }
1618
1619 /*
1620  * Description:
1621  *      Set the default TKIP Group Key (KeyEntry[10]) by MISCFIFO
1622  *
1623  * Parameters:
1624  *  In:
1625  *      dwIoBase        - Base Address for MAC
1626  *
1627  *  Out:
1628  *      none
1629  *
1630  * Return Value: none
1631  *
1632  */
1633 void MACvSetDefaultTKIPKeyEntry(unsigned long dwIoBase, unsigned int uKeyLen,
1634                                 unsigned int uKeyIdx, unsigned long *pdwKey, unsigned char byLocalID)
1635 {
1636         unsigned short wOffset;
1637         unsigned long dwData;
1638         int     ii;
1639
1640         if (byLocalID <= 1)
1641                 return;
1642
1643         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MACvSetDefaultTKIPKeyEntry\n");
1644         wOffset = MISCFIFO_KEYETRY0;
1645         // Kyle test : change offset from 10 -> 0
1646         wOffset += (10 * MISCFIFO_KEYENTRYSIZE);
1647
1648         dwData = 0xC0660000;
1649         VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset);
1650         VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData);
1651         VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
1652         wOffset++;
1653
1654         dwData = 0;
1655         VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset);
1656         VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData);
1657         VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
1658         wOffset++;
1659
1660         wOffset += (uKeyIdx * 4);
1661         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "1. wOffset: %d, Data: %lX, idx:%d\n", wOffset, *pdwKey, uKeyIdx);
1662         // always push 128 bits
1663         for (ii = 0; ii < 4; ii++) {
1664                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "2.(%d) wOffset: %d, Data: %lX\n", ii, wOffset+ii, *pdwKey);
1665                 VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset+ii);
1666                 VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, *pdwKey++);
1667                 VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
1668         }
1669 }
1670
1671 /*
1672  * Description:
1673  *      Set the Key Control by MISCFIFO
1674  *
1675  * Parameters:
1676  *  In:
1677  *      dwIoBase        - Base Address for MAC
1678  *
1679  *  Out:
1680  *      none
1681  *
1682  * Return Value: none
1683  *
1684  */
1685
1686 void MACvSetDefaultKeyCtl(unsigned long dwIoBase, unsigned short wKeyCtl, unsigned int uEntryIdx, unsigned char byLocalID)
1687 {
1688         unsigned short wOffset;
1689         unsigned long dwData;
1690
1691         if (byLocalID <= 1)
1692                 return;
1693
1694         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MACvSetKeyEntry\n");
1695         wOffset = MISCFIFO_KEYETRY0;
1696         wOffset += (uEntryIdx * MISCFIFO_KEYENTRYSIZE);
1697
1698         dwData = 0;
1699         dwData |= wKeyCtl;
1700         dwData <<= 16;
1701         dwData |= 0xffff;
1702         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "1. wOffset: %d, Data: %lX, KeyCtl:%X\n", wOffset, dwData, wKeyCtl);
1703
1704         VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset);
1705         VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData);
1706         VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
1707 }