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