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