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