Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / 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  *      MACbIsRegBitsOn - Test if All test Bits On
30  *      MACbIsRegBitsOff - Test if All test Bits Off
31  *      MACbIsIntDisable - Test if MAC interrupt disable
32  *      MACvSetShortRetryLimit - Set 802.11 Short Retry limit
33  *      MACvSetLongRetryLimit - Set 802.11 Long Retry limit
34  *      MACvSetLoopbackMode - Set MAC Loopback Mode
35  *      MACvSaveContext - Save Context of MAC Registers
36  *      MACvRestoreContext - Restore Context of MAC Registers
37  *      MACbSoftwareReset - Software Reset MAC
38  *      MACbSafeRxOff - Turn Off MAC Rx
39  *      MACbSafeTxOff - Turn Off MAC Tx
40  *      MACbSafeStop - Stop MAC function
41  *      MACbShutdown - Shut down MAC
42  *      MACvInitialize - Initialize MAC
43  *      MACvSetCurrRxDescAddr - Set Rx Descriptors Address
44  *      MACvSetCurrTx0DescAddr - Set Tx0 Descriptors Address
45  *      MACvSetCurrTx1DescAddr - Set Tx1 Descriptors Address
46  *      MACvTimer0MicroSDelay - Micro Second Delay Loop by MAC
47  *
48  * Revision History:
49  *      08-22-2003 Kyle Hsu     :  Porting MAC functions from sim53
50  *      09-03-2003 Bryan YC Fan :  Add MACvClearBusSusInd()& MACvEnableBusSusEn()
51  *      09-18-2003 Jerry Chen   :  Add MACvSetKeyEntry & MACvDisableKeyEntry
52  *
53  */
54
55 #include "tmacro.h"
56 #include "mac.h"
57
58 /*
59  * Description:
60  *      Test if all test bits on
61  *
62  * Parameters:
63  *  In:
64  *      dwIoBase    - Base Address for MAC
65  *      byRegOfs    - Offset of MAC Register
66  *      byTestBits  - Test bits
67  *  Out:
68  *      none
69  *
70  * Return Value: true if all test bits On; otherwise false
71  *
72  */
73 bool MACbIsRegBitsOn(void __iomem *dwIoBase, unsigned char byRegOfs, unsigned char byTestBits)
74 {
75         unsigned char byData;
76
77         VNSvInPortB(dwIoBase + byRegOfs, &byData);
78         return (byData & byTestBits) == byTestBits;
79 }
80
81 /*
82  * Description:
83  *      Test if all test bits off
84  *
85  * Parameters:
86  *  In:
87  *      dwIoBase    - Base Address for MAC
88  *      byRegOfs    - Offset of MAC Register
89  *      byTestBits  - Test bits
90  *  Out:
91  *      none
92  *
93  * Return Value: true if all test bits Off; otherwise false
94  *
95  */
96 bool MACbIsRegBitsOff(void __iomem *dwIoBase, unsigned char byRegOfs, unsigned char byTestBits)
97 {
98         unsigned char byData;
99
100         VNSvInPortB(dwIoBase + byRegOfs, &byData);
101         return !(byData & byTestBits);
102 }
103
104 /*
105  * Description:
106  *      Test if MAC interrupt disable
107  *
108  * Parameters:
109  *  In:
110  *      dwIoBase    - Base Address for MAC
111  *  Out:
112  *      none
113  *
114  * Return Value: true if interrupt is disable; otherwise false
115  *
116  */
117 bool MACbIsIntDisable(void __iomem *dwIoBase)
118 {
119         unsigned long dwData;
120
121         VNSvInPortD(dwIoBase + MAC_REG_IMR, &dwData);
122         if (dwData != 0)
123                 return false;
124
125         return true;
126 }
127
128 /*
129  * Description:
130  *      Set 802.11 Short Retry Limit
131  *
132  * Parameters:
133  *  In:
134  *      dwIoBase    - Base Address for MAC
135  *      byRetryLimit- Retry Limit
136  *  Out:
137  *      none
138  *
139  * Return Value: none
140  *
141  */
142 void MACvSetShortRetryLimit(void __iomem *dwIoBase, unsigned char byRetryLimit)
143 {
144         /* set SRT */
145         VNSvOutPortB(dwIoBase + MAC_REG_SRT, byRetryLimit);
146 }
147
148
149 /*
150  * Description:
151  *      Set 802.11 Long Retry Limit
152  *
153  * Parameters:
154  *  In:
155  *      dwIoBase    - Base Address for MAC
156  *      byRetryLimit- Retry Limit
157  *  Out:
158  *      none
159  *
160  * Return Value: none
161  *
162  */
163 void MACvSetLongRetryLimit(void __iomem *dwIoBase, unsigned char byRetryLimit)
164 {
165         /* set LRT */
166         VNSvOutPortB(dwIoBase + MAC_REG_LRT, byRetryLimit);
167 }
168
169 /*
170  * Description:
171  *      Set MAC Loopback mode
172  *
173  * Parameters:
174  *  In:
175  *      dwIoBase        - Base Address for MAC
176  *      byLoopbackMode  - Loopback Mode
177  *  Out:
178  *      none
179  *
180  * Return Value: none
181  *
182  */
183 void MACvSetLoopbackMode(void __iomem *dwIoBase, unsigned char byLoopbackMode)
184 {
185         unsigned char byOrgValue;
186
187         ASSERT(byLoopbackMode < 3);
188         byLoopbackMode <<= 6;
189         /* set TCR */
190         VNSvInPortB(dwIoBase + MAC_REG_TEST, &byOrgValue);
191         byOrgValue = byOrgValue & 0x3F;
192         byOrgValue = byOrgValue | byLoopbackMode;
193         VNSvOutPortB(dwIoBase + MAC_REG_TEST, byOrgValue);
194 }
195
196 /*
197  * Description:
198  *      Save MAC registers to context buffer
199  *
200  * Parameters:
201  *  In:
202  *      dwIoBase    - Base Address for MAC
203  *  Out:
204  *      pbyCxtBuf   - Context buffer
205  *
206  * Return Value: none
207  *
208  */
209 void MACvSaveContext(void __iomem *dwIoBase, unsigned char *pbyCxtBuf)
210 {
211         int         ii;
212
213         /* read page0 register */
214         for (ii = 0; ii < MAC_MAX_CONTEXT_SIZE_PAGE0; ii++)
215                 VNSvInPortB((dwIoBase + ii), (pbyCxtBuf + ii));
216
217         MACvSelectPage1(dwIoBase);
218
219         /* read page1 register */
220         for (ii = 0; ii < MAC_MAX_CONTEXT_SIZE_PAGE1; ii++)
221                 VNSvInPortB((dwIoBase + ii), (pbyCxtBuf + MAC_MAX_CONTEXT_SIZE_PAGE0 + ii));
222
223         MACvSelectPage0(dwIoBase);
224 }
225
226 /*
227  * Description:
228  *      Restore MAC registers from context buffer
229  *
230  * Parameters:
231  *  In:
232  *      dwIoBase    - Base Address for MAC
233  *      pbyCxtBuf   - Context buffer
234  *  Out:
235  *      none
236  *
237  * Return Value: none
238  *
239  */
240 void MACvRestoreContext(void __iomem *dwIoBase, unsigned char *pbyCxtBuf)
241 {
242         int         ii;
243
244         MACvSelectPage1(dwIoBase);
245         /* restore page1 */
246         for (ii = 0; ii < MAC_MAX_CONTEXT_SIZE_PAGE1; ii++)
247                 VNSvOutPortB((dwIoBase + ii), *(pbyCxtBuf + MAC_MAX_CONTEXT_SIZE_PAGE0 + ii));
248
249         MACvSelectPage0(dwIoBase);
250
251         /* restore RCR,TCR,IMR... */
252         for (ii = MAC_REG_RCR; ii < MAC_REG_ISR; ii++)
253                 VNSvOutPortB(dwIoBase + ii, *(pbyCxtBuf + ii));
254
255         /* restore MAC Config. */
256         for (ii = MAC_REG_LRT; ii < MAC_REG_PAGE1SEL; ii++)
257                 VNSvOutPortB(dwIoBase + ii, *(pbyCxtBuf + ii));
258
259         VNSvOutPortB(dwIoBase + MAC_REG_CFG, *(pbyCxtBuf + MAC_REG_CFG));
260
261         /* restore PS Config. */
262         for (ii = MAC_REG_PSCFG; ii < MAC_REG_BBREGCTL; ii++)
263                 VNSvOutPortB(dwIoBase + ii, *(pbyCxtBuf + ii));
264
265         /* restore CURR_RX_DESC_ADDR, CURR_TX_DESC_ADDR */
266         VNSvOutPortD(dwIoBase + MAC_REG_TXDMAPTR0, *(unsigned long *)(pbyCxtBuf + MAC_REG_TXDMAPTR0));
267         VNSvOutPortD(dwIoBase + MAC_REG_AC0DMAPTR, *(unsigned long *)(pbyCxtBuf + MAC_REG_AC0DMAPTR));
268         VNSvOutPortD(dwIoBase + MAC_REG_BCNDMAPTR, *(unsigned long *)(pbyCxtBuf + MAC_REG_BCNDMAPTR));
269
270         VNSvOutPortD(dwIoBase + MAC_REG_RXDMAPTR0, *(unsigned long *)(pbyCxtBuf + MAC_REG_RXDMAPTR0));
271
272         VNSvOutPortD(dwIoBase + MAC_REG_RXDMAPTR1, *(unsigned long *)(pbyCxtBuf + MAC_REG_RXDMAPTR1));
273 }
274
275 /*
276  * Description:
277  *      Software Reset MAC
278  *
279  * Parameters:
280  *  In:
281  *      dwIoBase    - Base Address for MAC
282  *  Out:
283  *      none
284  *
285  * Return Value: true if Reset Success; otherwise false
286  *
287  */
288 bool MACbSoftwareReset(void __iomem *dwIoBase)
289 {
290         unsigned char byData;
291         unsigned short ww;
292
293         /* turn on HOSTCR_SOFTRST, just write 0x01 to reset */
294         VNSvOutPortB(dwIoBase + MAC_REG_HOSTCR, 0x01);
295
296         for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
297                 VNSvInPortB(dwIoBase + MAC_REG_HOSTCR, &byData);
298                 if (!(byData & HOSTCR_SOFTRST))
299                         break;
300         }
301         if (ww == W_MAX_TIMEOUT)
302                 return false;
303         return true;
304 }
305
306 /*
307  * Description:
308  *      save some important register's value, then do reset, then restore register's value
309  *
310  * Parameters:
311  *  In:
312  *      dwIoBase    - Base Address for MAC
313  *  Out:
314  *      none
315  *
316  * Return Value: true if success; otherwise false
317  *
318  */
319 bool MACbSafeSoftwareReset(void __iomem *dwIoBase)
320 {
321         unsigned char abyTmpRegData[MAC_MAX_CONTEXT_SIZE_PAGE0+MAC_MAX_CONTEXT_SIZE_PAGE1];
322         bool bRetVal;
323
324         /* PATCH....
325          * save some important register's value, then do
326          * reset, then restore register's value
327          */
328         /* save MAC context */
329         MACvSaveContext(dwIoBase, abyTmpRegData);
330         /* do reset */
331         bRetVal = MACbSoftwareReset(dwIoBase);
332         /* restore MAC context, except CR0 */
333         MACvRestoreContext(dwIoBase, abyTmpRegData);
334
335         return bRetVal;
336 }
337
338 /*
339  * Description:
340  *      Turn Off MAC Rx
341  *
342  * Parameters:
343  *  In:
344  *      dwIoBase    - Base Address for MAC
345  *  Out:
346  *      none
347  *
348  * Return Value: true if success; otherwise false
349  *
350  */
351 bool MACbSafeRxOff(void __iomem *dwIoBase)
352 {
353         unsigned short ww;
354         unsigned long dwData;
355         unsigned char byData;
356
357         /* turn off wow temp for turn off Rx safely */
358
359         /* Clear RX DMA0,1 */
360         VNSvOutPortD(dwIoBase + MAC_REG_RXDMACTL0, DMACTL_CLRRUN);
361         VNSvOutPortD(dwIoBase + MAC_REG_RXDMACTL1, DMACTL_CLRRUN);
362         for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
363                 VNSvInPortD(dwIoBase + MAC_REG_RXDMACTL0, &dwData);
364                 if (!(dwData & DMACTL_RUN))
365                         break;
366         }
367         if (ww == W_MAX_TIMEOUT) {
368                 DBG_PORT80(0x10);
369                 pr_debug(" DBG_PORT80(0x10)\n");
370                 return false;
371         }
372         for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
373                 VNSvInPortD(dwIoBase + MAC_REG_RXDMACTL1, &dwData);
374                 if (!(dwData & DMACTL_RUN))
375                         break;
376         }
377         if (ww == W_MAX_TIMEOUT) {
378                 DBG_PORT80(0x11);
379                 pr_debug(" DBG_PORT80(0x11)\n");
380                 return false;
381         }
382
383         /* try to safe shutdown RX */
384         MACvRegBitsOff(dwIoBase, MAC_REG_HOSTCR, HOSTCR_RXON);
385         /* W_MAX_TIMEOUT is the timeout period */
386         for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
387                 VNSvInPortB(dwIoBase + MAC_REG_HOSTCR, &byData);
388                 if (!(byData & HOSTCR_RXONST))
389                         break;
390         }
391         if (ww == W_MAX_TIMEOUT) {
392                 DBG_PORT80(0x12);
393                 pr_debug(" DBG_PORT80(0x12)\n");
394                 return false;
395         }
396         return true;
397 }
398
399 /*
400  * Description:
401  *      Turn Off MAC Tx
402  *
403  * Parameters:
404  *  In:
405  *      dwIoBase    - Base Address for MAC
406  *  Out:
407  *      none
408  *
409  * Return Value: true if success; otherwise false
410  *
411  */
412 bool MACbSafeTxOff(void __iomem *dwIoBase)
413 {
414         unsigned short ww;
415         unsigned long dwData;
416         unsigned char byData;
417
418         /* Clear TX DMA */
419         /* Tx0 */
420         VNSvOutPortD(dwIoBase + MAC_REG_TXDMACTL0, DMACTL_CLRRUN);
421         /* AC0 */
422         VNSvOutPortD(dwIoBase + MAC_REG_AC0DMACTL, DMACTL_CLRRUN);
423
424         for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
425                 VNSvInPortD(dwIoBase + MAC_REG_TXDMACTL0, &dwData);
426                 if (!(dwData & DMACTL_RUN))
427                         break;
428         }
429         if (ww == W_MAX_TIMEOUT) {
430                 DBG_PORT80(0x20);
431                 pr_debug(" DBG_PORT80(0x20)\n");
432                 return false;
433         }
434         for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
435                 VNSvInPortD(dwIoBase + MAC_REG_AC0DMACTL, &dwData);
436                 if (!(dwData & DMACTL_RUN))
437                         break;
438         }
439         if (ww == W_MAX_TIMEOUT) {
440                 DBG_PORT80(0x21);
441                 pr_debug(" DBG_PORT80(0x21)\n");
442                 return false;
443         }
444
445         /* try to safe shutdown TX */
446         MACvRegBitsOff(dwIoBase, MAC_REG_HOSTCR, HOSTCR_TXON);
447
448         /* W_MAX_TIMEOUT is the timeout period */
449         for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
450                 VNSvInPortB(dwIoBase + MAC_REG_HOSTCR, &byData);
451                 if (!(byData & HOSTCR_TXONST))
452                         break;
453         }
454         if (ww == W_MAX_TIMEOUT) {
455                 DBG_PORT80(0x24);
456                 pr_debug(" DBG_PORT80(0x24)\n");
457                 return false;
458         }
459         return true;
460 }
461
462 /*
463  * Description:
464  *      Stop MAC function
465  *
466  * Parameters:
467  *  In:
468  *      dwIoBase    - Base Address for MAC
469  *  Out:
470  *      none
471  *
472  * Return Value: true if success; otherwise false
473  *
474  */
475 bool MACbSafeStop(void __iomem *dwIoBase)
476 {
477         MACvRegBitsOff(dwIoBase, MAC_REG_TCR, TCR_AUTOBCNTX);
478
479         if (!MACbSafeRxOff(dwIoBase)) {
480                 DBG_PORT80(0xA1);
481                 pr_debug(" MACbSafeRxOff == false)\n");
482                 MACbSafeSoftwareReset(dwIoBase);
483                 return false;
484         }
485         if (!MACbSafeTxOff(dwIoBase)) {
486                 DBG_PORT80(0xA2);
487                 pr_debug(" MACbSafeTxOff == false)\n");
488                 MACbSafeSoftwareReset(dwIoBase);
489                 return false;
490         }
491
492         MACvRegBitsOff(dwIoBase, MAC_REG_HOSTCR, HOSTCR_MACEN);
493
494         return true;
495 }
496
497 /*
498  * Description:
499  *      Shut Down MAC
500  *
501  * Parameters:
502  *  In:
503  *      dwIoBase    - Base Address for MAC
504  *  Out:
505  *      none
506  *
507  * Return Value: true if success; otherwise false
508  *
509  */
510 bool MACbShutdown(void __iomem *dwIoBase)
511 {
512         /* disable MAC IMR */
513         MACvIntDisable(dwIoBase);
514         MACvSetLoopbackMode(dwIoBase, MAC_LB_INTERNAL);
515         /* stop the adapter */
516         if (!MACbSafeStop(dwIoBase)) {
517                 MACvSetLoopbackMode(dwIoBase, MAC_LB_NONE);
518                 return false;
519         }
520         MACvSetLoopbackMode(dwIoBase, MAC_LB_NONE);
521         return true;
522 }
523
524 /*
525  * Description:
526  *      Initialize MAC
527  *
528  * Parameters:
529  *  In:
530  *      dwIoBase    - Base Address for MAC
531  *  Out:
532  *      none
533  *
534  * Return Value: none
535  *
536  */
537 void MACvInitialize(void __iomem *dwIoBase)
538 {
539         /* clear sticky bits */
540         MACvClearStckDS(dwIoBase);
541         /* disable force PME-enable */
542         VNSvOutPortB(dwIoBase + MAC_REG_PMC1, PME_OVR);
543         /* only 3253 A */
544
545         /* do reset */
546         MACbSoftwareReset(dwIoBase);
547
548         /* reset TSF counter */
549         VNSvOutPortB(dwIoBase + MAC_REG_TFTCTL, TFTCTL_TSFCNTRST);
550         /* enable TSF counter */
551         VNSvOutPortB(dwIoBase + MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
552 }
553
554 /*
555  * Description:
556  *      Set the chip with current rx descriptor address
557  *
558  * Parameters:
559  *  In:
560  *      dwIoBase        - Base Address for MAC
561  *      dwCurrDescAddr  - Descriptor Address
562  *  Out:
563  *      none
564  *
565  * Return Value: none
566  *
567  */
568 void MACvSetCurrRx0DescAddr(void __iomem *dwIoBase, unsigned long dwCurrDescAddr)
569 {
570         unsigned short ww;
571         unsigned char byData;
572         unsigned char byOrgDMACtl;
573
574         VNSvInPortB(dwIoBase + MAC_REG_RXDMACTL0, &byOrgDMACtl);
575         if (byOrgDMACtl & DMACTL_RUN)
576                 VNSvOutPortB(dwIoBase + MAC_REG_RXDMACTL0+2, DMACTL_RUN);
577
578         for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
579                 VNSvInPortB(dwIoBase + MAC_REG_RXDMACTL0, &byData);
580                 if (!(byData & DMACTL_RUN))
581                         break;
582         }
583
584         if (ww == W_MAX_TIMEOUT)
585                 DBG_PORT80(0x13);
586
587         VNSvOutPortD(dwIoBase + MAC_REG_RXDMAPTR0, dwCurrDescAddr);
588         if (byOrgDMACtl & DMACTL_RUN)
589                 VNSvOutPortB(dwIoBase + MAC_REG_RXDMACTL0, DMACTL_RUN);
590 }
591
592 /*
593  * Description:
594  *      Set the chip with current rx descriptor address
595  *
596  * Parameters:
597  *  In:
598  *      dwIoBase        - Base Address for MAC
599  *      dwCurrDescAddr  - Descriptor Address
600  *  Out:
601  *      none
602  *
603  * Return Value: none
604  *
605  */
606 void MACvSetCurrRx1DescAddr(void __iomem *dwIoBase, unsigned long dwCurrDescAddr)
607 {
608         unsigned short ww;
609         unsigned char byData;
610         unsigned char byOrgDMACtl;
611
612         VNSvInPortB(dwIoBase + MAC_REG_RXDMACTL1, &byOrgDMACtl);
613         if (byOrgDMACtl & DMACTL_RUN)
614                 VNSvOutPortB(dwIoBase + MAC_REG_RXDMACTL1+2, DMACTL_RUN);
615
616         for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
617                 VNSvInPortB(dwIoBase + MAC_REG_RXDMACTL1, &byData);
618                 if (!(byData & DMACTL_RUN))
619                         break;
620         }
621         if (ww == W_MAX_TIMEOUT)
622                 DBG_PORT80(0x14);
623
624         VNSvOutPortD(dwIoBase + MAC_REG_RXDMAPTR1, dwCurrDescAddr);
625         if (byOrgDMACtl & DMACTL_RUN)
626                 VNSvOutPortB(dwIoBase + MAC_REG_RXDMACTL1, DMACTL_RUN);
627
628 }
629
630 /*
631  * Description:
632  *      Set the chip with current tx0 descriptor address
633  *
634  * Parameters:
635  *  In:
636  *      dwIoBase        - Base Address for MAC
637  *      dwCurrDescAddr  - Descriptor Address
638  *  Out:
639  *      none
640  *
641  * Return Value: none
642  *
643  */
644 void MACvSetCurrTx0DescAddrEx(void __iomem *dwIoBase, unsigned long dwCurrDescAddr)
645 {
646         unsigned short ww;
647         unsigned char byData;
648         unsigned char byOrgDMACtl;
649
650         VNSvInPortB(dwIoBase + MAC_REG_TXDMACTL0, &byOrgDMACtl);
651         if (byOrgDMACtl & DMACTL_RUN)
652                 VNSvOutPortB(dwIoBase + MAC_REG_TXDMACTL0+2, DMACTL_RUN);
653
654         for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
655                 VNSvInPortB(dwIoBase + MAC_REG_TXDMACTL0, &byData);
656                 if (!(byData & DMACTL_RUN))
657                         break;
658         }
659         if (ww == W_MAX_TIMEOUT)
660                 DBG_PORT80(0x25);
661
662         VNSvOutPortD(dwIoBase + MAC_REG_TXDMAPTR0, dwCurrDescAddr);
663         if (byOrgDMACtl & DMACTL_RUN)
664                 VNSvOutPortB(dwIoBase + MAC_REG_TXDMACTL0, DMACTL_RUN);
665 }
666
667 /*
668  * Description:
669  *      Set the chip with current AC0 descriptor address
670  *
671  * Parameters:
672  *  In:
673  *      dwIoBase        - Base Address for MAC
674  *      dwCurrDescAddr  - Descriptor Address
675  *  Out:
676  *      none
677  *
678  * Return Value: none
679  *
680  */
681 /* TxDMA1 = AC0DMA */
682 void MACvSetCurrAC0DescAddrEx(void __iomem *dwIoBase, unsigned long dwCurrDescAddr)
683 {
684         unsigned short ww;
685         unsigned char byData;
686         unsigned char byOrgDMACtl;
687
688         VNSvInPortB(dwIoBase + MAC_REG_AC0DMACTL, &byOrgDMACtl);
689         if (byOrgDMACtl & DMACTL_RUN)
690                 VNSvOutPortB(dwIoBase + MAC_REG_AC0DMACTL+2, DMACTL_RUN);
691
692         for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
693                 VNSvInPortB(dwIoBase + MAC_REG_AC0DMACTL, &byData);
694                 if (!(byData & DMACTL_RUN))
695                         break;
696         }
697         if (ww == W_MAX_TIMEOUT) {
698                 DBG_PORT80(0x26);
699                 pr_debug(" DBG_PORT80(0x26)\n");
700         }
701         VNSvOutPortD(dwIoBase + MAC_REG_AC0DMAPTR, dwCurrDescAddr);
702         if (byOrgDMACtl & DMACTL_RUN)
703                 VNSvOutPortB(dwIoBase + MAC_REG_AC0DMACTL, DMACTL_RUN);
704 }
705
706 void MACvSetCurrTXDescAddr(int iTxType, void __iomem *dwIoBase, unsigned long dwCurrDescAddr)
707 {
708         if (iTxType == TYPE_AC0DMA)
709                 MACvSetCurrAC0DescAddrEx(dwIoBase, dwCurrDescAddr);
710         else if (iTxType == TYPE_TXDMA0)
711                 MACvSetCurrTx0DescAddrEx(dwIoBase, dwCurrDescAddr);
712 }
713
714 /*
715  * Description:
716  *      Micro Second Delay via MAC
717  *
718  * Parameters:
719  *  In:
720  *      dwIoBase    - Base Address for MAC
721  *      uDelay      - Delay time (timer resolution is 4 us)
722  *  Out:
723  *      none
724  *
725  * Return Value: none
726  *
727  */
728 void MACvTimer0MicroSDelay(void __iomem *dwIoBase, unsigned int uDelay)
729 {
730         unsigned char byValue;
731         unsigned int uu, ii;
732
733         VNSvOutPortB(dwIoBase + MAC_REG_TMCTL0, 0);
734         VNSvOutPortD(dwIoBase + MAC_REG_TMDATA0, uDelay);
735         VNSvOutPortB(dwIoBase + MAC_REG_TMCTL0, (TMCTL_TMD | TMCTL_TE));
736         for (ii = 0; ii < 66; ii++) {  /* assume max PCI clock is 66Mhz */
737                 for (uu = 0; uu < uDelay; uu++) {
738                         VNSvInPortB(dwIoBase + MAC_REG_TMCTL0, &byValue);
739                         if ((byValue == 0) ||
740                             (byValue & TMCTL_TSUSP)) {
741                                 VNSvOutPortB(dwIoBase + MAC_REG_TMCTL0, 0);
742                                 return;
743                         }
744                 }
745         }
746         VNSvOutPortB(dwIoBase + MAC_REG_TMCTL0, 0);
747 }
748
749 /*
750  * Description:
751  *      Micro Second One shot timer via MAC
752  *
753  * Parameters:
754  *  In:
755  *      dwIoBase    - Base Address for MAC
756  *      uDelay      - Delay time
757  *  Out:
758  *      none
759  *
760  * Return Value: none
761  *
762  */
763 void MACvOneShotTimer1MicroSec(void __iomem *dwIoBase, unsigned int uDelayTime)
764 {
765         VNSvOutPortB(dwIoBase + MAC_REG_TMCTL1, 0);
766         VNSvOutPortD(dwIoBase + MAC_REG_TMDATA1, uDelayTime);
767         VNSvOutPortB(dwIoBase + MAC_REG_TMCTL1, (TMCTL_TMD | TMCTL_TE));
768 }
769
770 void MACvSetMISCFifo(void __iomem *dwIoBase, unsigned short wOffset, unsigned long dwData)
771 {
772         if (wOffset > 273)
773                 return;
774         VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset);
775         VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData);
776         VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
777 }
778
779 bool MACbPSWakeup(void __iomem *dwIoBase)
780 {
781         unsigned char byOrgValue;
782         unsigned int ww;
783         /* Read PSCTL */
784         if (MACbIsRegBitsOff(dwIoBase, MAC_REG_PSCTL, PSCTL_PS))
785                 return true;
786
787         /* Disable PS */
788         MACvRegBitsOff(dwIoBase, MAC_REG_PSCTL, PSCTL_PSEN);
789
790         /* Check if SyncFlushOK */
791         for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
792                 VNSvInPortB(dwIoBase + MAC_REG_PSCTL, &byOrgValue);
793                 if (byOrgValue & PSCTL_WAKEDONE)
794                         break;
795         }
796         if (ww == W_MAX_TIMEOUT) {
797                 DBG_PORT80(0x36);
798                 pr_debug(" DBG_PORT80(0x33)\n");
799                 return false;
800         }
801         return true;
802 }
803
804 /*
805  * Description:
806  *      Set the Key by MISCFIFO
807  *
808  * Parameters:
809  *  In:
810  *      dwIoBase        - Base Address for MAC
811  *
812  *  Out:
813  *      none
814  *
815  * Return Value: none
816  *
817  */
818
819 void MACvSetKeyEntry(void __iomem *dwIoBase, unsigned short wKeyCtl, unsigned int uEntryIdx,
820                      unsigned int uKeyIdx, unsigned char *pbyAddr, u32 *pdwKey, unsigned char byLocalID)
821 {
822         unsigned short wOffset;
823         u32 dwData;
824         int     ii;
825
826         if (byLocalID <= 1)
827                 return;
828
829         pr_debug("MACvSetKeyEntry\n");
830         wOffset = MISCFIFO_KEYETRY0;
831         wOffset += (uEntryIdx * MISCFIFO_KEYENTRYSIZE);
832
833         dwData = 0;
834         dwData |= wKeyCtl;
835         dwData <<= 16;
836         dwData |= MAKEWORD(*(pbyAddr+4), *(pbyAddr+5));
837         pr_debug("1. wOffset: %d, Data: %X, KeyCtl:%X\n",
838                  wOffset, dwData, wKeyCtl);
839
840         VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset);
841         VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData);
842         VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
843         wOffset++;
844
845         dwData = 0;
846         dwData |= *(pbyAddr+3);
847         dwData <<= 8;
848         dwData |= *(pbyAddr+2);
849         dwData <<= 8;
850         dwData |= *(pbyAddr+1);
851         dwData <<= 8;
852         dwData |= *(pbyAddr+0);
853         pr_debug("2. wOffset: %d, Data: %X\n", wOffset, dwData);
854
855         VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset);
856         VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData);
857         VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
858         wOffset++;
859
860         wOffset += (uKeyIdx * 4);
861         for (ii = 0; ii < 4; ii++) {
862                 /* always push 128 bits */
863                 pr_debug("3.(%d) wOffset: %d, Data: %X\n",
864                          ii, wOffset+ii, *pdwKey);
865                 VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset+ii);
866                 VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, *pdwKey++);
867                 VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
868         }
869 }
870
871 /*
872  * Description:
873  *      Disable the Key Entry by MISCFIFO
874  *
875  * Parameters:
876  *  In:
877  *      dwIoBase        - Base Address for MAC
878  *
879  *  Out:
880  *      none
881  *
882  * Return Value: none
883  *
884  */
885 void MACvDisableKeyEntry(void __iomem *dwIoBase, unsigned int uEntryIdx)
886 {
887         unsigned short wOffset;
888
889         wOffset = MISCFIFO_KEYETRY0;
890         wOffset += (uEntryIdx * MISCFIFO_KEYENTRYSIZE);
891
892         VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset);
893         VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, 0);
894         VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
895 }