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