xref: /openbmc/linux/drivers/staging/vt6655/mac.c (revision 9cfc5c90)
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 	byLoopbackMode <<= 6;
190 	/* set TCR */
191 	VNSvInPortB(dwIoBase + MAC_REG_TEST, &byOrgValue);
192 	byOrgValue = byOrgValue & 0x3F;
193 	byOrgValue = byOrgValue | byLoopbackMode;
194 	VNSvOutPortB(dwIoBase + MAC_REG_TEST, byOrgValue);
195 }
196 
197 /*
198  * Description:
199  *      Save MAC registers to context buffer
200  *
201  * Parameters:
202  *  In:
203  *      dwIoBase    - Base Address for MAC
204  *  Out:
205  *      pbyCxtBuf   - Context buffer
206  *
207  * Return Value: none
208  *
209  */
210 void MACvSaveContext(void __iomem *dwIoBase, unsigned char *pbyCxtBuf)
211 {
212 	int         ii;
213 
214 	/* read page0 register */
215 	for (ii = 0; ii < MAC_MAX_CONTEXT_SIZE_PAGE0; ii++)
216 		VNSvInPortB((dwIoBase + ii), (pbyCxtBuf + ii));
217 
218 	MACvSelectPage1(dwIoBase);
219 
220 	/* read page1 register */
221 	for (ii = 0; ii < MAC_MAX_CONTEXT_SIZE_PAGE1; ii++)
222 		VNSvInPortB((dwIoBase + ii),
223 			    (pbyCxtBuf + MAC_MAX_CONTEXT_SIZE_PAGE0 + ii));
224 
225 	MACvSelectPage0(dwIoBase);
226 }
227 
228 /*
229  * Description:
230  *      Restore MAC registers from context buffer
231  *
232  * Parameters:
233  *  In:
234  *      dwIoBase    - Base Address for MAC
235  *      pbyCxtBuf   - Context buffer
236  *  Out:
237  *      none
238  *
239  * Return Value: none
240  *
241  */
242 void MACvRestoreContext(void __iomem *dwIoBase, unsigned char *pbyCxtBuf)
243 {
244 	int         ii;
245 
246 	MACvSelectPage1(dwIoBase);
247 	/* restore page1 */
248 	for (ii = 0; ii < MAC_MAX_CONTEXT_SIZE_PAGE1; ii++)
249 		VNSvOutPortB((dwIoBase + ii),
250 			     *(pbyCxtBuf + MAC_MAX_CONTEXT_SIZE_PAGE0 + ii));
251 
252 	MACvSelectPage0(dwIoBase);
253 
254 	/* restore RCR,TCR,IMR... */
255 	for (ii = MAC_REG_RCR; ii < MAC_REG_ISR; ii++)
256 		VNSvOutPortB(dwIoBase + ii, *(pbyCxtBuf + ii));
257 
258 	/* restore MAC Config. */
259 	for (ii = MAC_REG_LRT; ii < MAC_REG_PAGE1SEL; ii++)
260 		VNSvOutPortB(dwIoBase + ii, *(pbyCxtBuf + ii));
261 
262 	VNSvOutPortB(dwIoBase + MAC_REG_CFG, *(pbyCxtBuf + MAC_REG_CFG));
263 
264 	/* restore PS Config. */
265 	for (ii = MAC_REG_PSCFG; ii < MAC_REG_BBREGCTL; ii++)
266 		VNSvOutPortB(dwIoBase + ii, *(pbyCxtBuf + ii));
267 
268 	/* restore CURR_RX_DESC_ADDR, CURR_TX_DESC_ADDR */
269 	VNSvOutPortD(dwIoBase + MAC_REG_TXDMAPTR0,
270 		     *(unsigned long *)(pbyCxtBuf + MAC_REG_TXDMAPTR0));
271 	VNSvOutPortD(dwIoBase + MAC_REG_AC0DMAPTR,
272 		     *(unsigned long *)(pbyCxtBuf + MAC_REG_AC0DMAPTR));
273 	VNSvOutPortD(dwIoBase + MAC_REG_BCNDMAPTR,
274 		     *(unsigned long *)(pbyCxtBuf + MAC_REG_BCNDMAPTR));
275 
276 	VNSvOutPortD(dwIoBase + MAC_REG_RXDMAPTR0,
277 		     *(unsigned long *)(pbyCxtBuf + MAC_REG_RXDMAPTR0));
278 
279 	VNSvOutPortD(dwIoBase + MAC_REG_RXDMAPTR1,
280 		     *(unsigned long *)(pbyCxtBuf + MAC_REG_RXDMAPTR1));
281 }
282 
283 /*
284  * Description:
285  *      Software Reset MAC
286  *
287  * Parameters:
288  *  In:
289  *      dwIoBase    - Base Address for MAC
290  *  Out:
291  *      none
292  *
293  * Return Value: true if Reset Success; otherwise false
294  *
295  */
296 bool MACbSoftwareReset(void __iomem *dwIoBase)
297 {
298 	unsigned char byData;
299 	unsigned short ww;
300 
301 	/* turn on HOSTCR_SOFTRST, just write 0x01 to reset */
302 	VNSvOutPortB(dwIoBase + MAC_REG_HOSTCR, 0x01);
303 
304 	for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
305 		VNSvInPortB(dwIoBase + MAC_REG_HOSTCR, &byData);
306 		if (!(byData & HOSTCR_SOFTRST))
307 			break;
308 	}
309 	if (ww == W_MAX_TIMEOUT)
310 		return false;
311 	return true;
312 }
313 
314 /*
315  * Description:
316  *      save some important register's value, then do reset, then restore register's value
317  *
318  * Parameters:
319  *  In:
320  *      dwIoBase    - Base Address for MAC
321  *  Out:
322  *      none
323  *
324  * Return Value: true if success; otherwise false
325  *
326  */
327 bool MACbSafeSoftwareReset(void __iomem *dwIoBase)
328 {
329 	unsigned char abyTmpRegData[MAC_MAX_CONTEXT_SIZE_PAGE0+MAC_MAX_CONTEXT_SIZE_PAGE1];
330 	bool bRetVal;
331 
332 	/* PATCH....
333 	 * save some important register's value, then do
334 	 * reset, then restore register's value
335 	 */
336 	/* save MAC context */
337 	MACvSaveContext(dwIoBase, abyTmpRegData);
338 	/* do reset */
339 	bRetVal = MACbSoftwareReset(dwIoBase);
340 	/* restore MAC context, except CR0 */
341 	MACvRestoreContext(dwIoBase, abyTmpRegData);
342 
343 	return bRetVal;
344 }
345 
346 /*
347  * Description:
348  *      Turn Off MAC Rx
349  *
350  * Parameters:
351  *  In:
352  *      dwIoBase    - Base Address for MAC
353  *  Out:
354  *      none
355  *
356  * Return Value: true if success; otherwise false
357  *
358  */
359 bool MACbSafeRxOff(void __iomem *dwIoBase)
360 {
361 	unsigned short ww;
362 	unsigned long dwData;
363 	unsigned char byData;
364 
365 	/* turn off wow temp for turn off Rx safely */
366 
367 	/* Clear RX DMA0,1 */
368 	VNSvOutPortD(dwIoBase + MAC_REG_RXDMACTL0, DMACTL_CLRRUN);
369 	VNSvOutPortD(dwIoBase + MAC_REG_RXDMACTL1, DMACTL_CLRRUN);
370 	for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
371 		VNSvInPortD(dwIoBase + MAC_REG_RXDMACTL0, &dwData);
372 		if (!(dwData & DMACTL_RUN))
373 			break;
374 	}
375 	if (ww == W_MAX_TIMEOUT) {
376 		pr_debug(" DBG_PORT80(0x10)\n");
377 		return false;
378 	}
379 	for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
380 		VNSvInPortD(dwIoBase + MAC_REG_RXDMACTL1, &dwData);
381 		if (!(dwData & DMACTL_RUN))
382 			break;
383 	}
384 	if (ww == W_MAX_TIMEOUT) {
385 		pr_debug(" DBG_PORT80(0x11)\n");
386 		return false;
387 	}
388 
389 	/* try to safe shutdown RX */
390 	MACvRegBitsOff(dwIoBase, MAC_REG_HOSTCR, HOSTCR_RXON);
391 	/* W_MAX_TIMEOUT is the timeout period */
392 	for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
393 		VNSvInPortB(dwIoBase + MAC_REG_HOSTCR, &byData);
394 		if (!(byData & HOSTCR_RXONST))
395 			break;
396 	}
397 	if (ww == W_MAX_TIMEOUT) {
398 		pr_debug(" DBG_PORT80(0x12)\n");
399 		return false;
400 	}
401 	return true;
402 }
403 
404 /*
405  * Description:
406  *      Turn Off MAC Tx
407  *
408  * Parameters:
409  *  In:
410  *      dwIoBase    - Base Address for MAC
411  *  Out:
412  *      none
413  *
414  * Return Value: true if success; otherwise false
415  *
416  */
417 bool MACbSafeTxOff(void __iomem *dwIoBase)
418 {
419 	unsigned short ww;
420 	unsigned long dwData;
421 	unsigned char byData;
422 
423 	/* Clear TX DMA */
424 	/* Tx0 */
425 	VNSvOutPortD(dwIoBase + MAC_REG_TXDMACTL0, DMACTL_CLRRUN);
426 	/* AC0 */
427 	VNSvOutPortD(dwIoBase + MAC_REG_AC0DMACTL, DMACTL_CLRRUN);
428 
429 	for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
430 		VNSvInPortD(dwIoBase + MAC_REG_TXDMACTL0, &dwData);
431 		if (!(dwData & DMACTL_RUN))
432 			break;
433 	}
434 	if (ww == W_MAX_TIMEOUT) {
435 		pr_debug(" DBG_PORT80(0x20)\n");
436 		return false;
437 	}
438 	for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
439 		VNSvInPortD(dwIoBase + MAC_REG_AC0DMACTL, &dwData);
440 		if (!(dwData & DMACTL_RUN))
441 			break;
442 	}
443 	if (ww == W_MAX_TIMEOUT) {
444 		pr_debug(" DBG_PORT80(0x21)\n");
445 		return false;
446 	}
447 
448 	/* try to safe shutdown TX */
449 	MACvRegBitsOff(dwIoBase, MAC_REG_HOSTCR, HOSTCR_TXON);
450 
451 	/* W_MAX_TIMEOUT is the timeout period */
452 	for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
453 		VNSvInPortB(dwIoBase + MAC_REG_HOSTCR, &byData);
454 		if (!(byData & HOSTCR_TXONST))
455 			break;
456 	}
457 	if (ww == W_MAX_TIMEOUT) {
458 		pr_debug(" DBG_PORT80(0x24)\n");
459 		return false;
460 	}
461 	return true;
462 }
463 
464 /*
465  * Description:
466  *      Stop MAC function
467  *
468  * Parameters:
469  *  In:
470  *      dwIoBase    - Base Address for MAC
471  *  Out:
472  *      none
473  *
474  * Return Value: true if success; otherwise false
475  *
476  */
477 bool MACbSafeStop(void __iomem *dwIoBase)
478 {
479 	MACvRegBitsOff(dwIoBase, MAC_REG_TCR, TCR_AUTOBCNTX);
480 
481 	if (!MACbSafeRxOff(dwIoBase)) {
482 		pr_debug(" MACbSafeRxOff == false)\n");
483 		MACbSafeSoftwareReset(dwIoBase);
484 		return false;
485 	}
486 	if (!MACbSafeTxOff(dwIoBase)) {
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 	VNSvOutPortD(dwIoBase + MAC_REG_RXDMAPTR0, dwCurrDescAddr);
585 	if (byOrgDMACtl & DMACTL_RUN)
586 		VNSvOutPortB(dwIoBase + MAC_REG_RXDMACTL0, DMACTL_RUN);
587 }
588 
589 /*
590  * Description:
591  *      Set the chip with current rx descriptor address
592  *
593  * Parameters:
594  *  In:
595  *      dwIoBase        - Base Address for MAC
596  *      dwCurrDescAddr  - Descriptor Address
597  *  Out:
598  *      none
599  *
600  * Return Value: none
601  *
602  */
603 void MACvSetCurrRx1DescAddr(void __iomem *dwIoBase, unsigned long dwCurrDescAddr)
604 {
605 	unsigned short ww;
606 	unsigned char byData;
607 	unsigned char byOrgDMACtl;
608 
609 	VNSvInPortB(dwIoBase + MAC_REG_RXDMACTL1, &byOrgDMACtl);
610 	if (byOrgDMACtl & DMACTL_RUN)
611 		VNSvOutPortB(dwIoBase + MAC_REG_RXDMACTL1+2, DMACTL_RUN);
612 
613 	for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
614 		VNSvInPortB(dwIoBase + MAC_REG_RXDMACTL1, &byData);
615 		if (!(byData & DMACTL_RUN))
616 			break;
617 	}
618 
619 	VNSvOutPortD(dwIoBase + MAC_REG_RXDMAPTR1, dwCurrDescAddr);
620 	if (byOrgDMACtl & DMACTL_RUN)
621 		VNSvOutPortB(dwIoBase + MAC_REG_RXDMACTL1, DMACTL_RUN);
622 
623 }
624 
625 /*
626  * Description:
627  *      Set the chip with current tx0 descriptor address
628  *
629  * Parameters:
630  *  In:
631  *      dwIoBase        - Base Address for MAC
632  *      dwCurrDescAddr  - Descriptor Address
633  *  Out:
634  *      none
635  *
636  * Return Value: none
637  *
638  */
639 void MACvSetCurrTx0DescAddrEx(void __iomem *dwIoBase,
640 			      unsigned long dwCurrDescAddr)
641 {
642 	unsigned short ww;
643 	unsigned char byData;
644 	unsigned char byOrgDMACtl;
645 
646 	VNSvInPortB(dwIoBase + MAC_REG_TXDMACTL0, &byOrgDMACtl);
647 	if (byOrgDMACtl & DMACTL_RUN)
648 		VNSvOutPortB(dwIoBase + MAC_REG_TXDMACTL0+2, DMACTL_RUN);
649 
650 	for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
651 		VNSvInPortB(dwIoBase + MAC_REG_TXDMACTL0, &byData);
652 		if (!(byData & DMACTL_RUN))
653 			break;
654 	}
655 
656 	VNSvOutPortD(dwIoBase + MAC_REG_TXDMAPTR0, dwCurrDescAddr);
657 	if (byOrgDMACtl & DMACTL_RUN)
658 		VNSvOutPortB(dwIoBase + MAC_REG_TXDMACTL0, DMACTL_RUN);
659 }
660 
661 /*
662  * Description:
663  *      Set the chip with current AC0 descriptor address
664  *
665  * Parameters:
666  *  In:
667  *      dwIoBase        - Base Address for MAC
668  *      dwCurrDescAddr  - Descriptor Address
669  *  Out:
670  *      none
671  *
672  * Return Value: none
673  *
674  */
675 /* TxDMA1 = AC0DMA */
676 void MACvSetCurrAC0DescAddrEx(void __iomem *dwIoBase,
677 			      unsigned long dwCurrDescAddr)
678 {
679 	unsigned short ww;
680 	unsigned char byData;
681 	unsigned char byOrgDMACtl;
682 
683 	VNSvInPortB(dwIoBase + MAC_REG_AC0DMACTL, &byOrgDMACtl);
684 	if (byOrgDMACtl & DMACTL_RUN)
685 		VNSvOutPortB(dwIoBase + MAC_REG_AC0DMACTL+2, DMACTL_RUN);
686 
687 	for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
688 		VNSvInPortB(dwIoBase + MAC_REG_AC0DMACTL, &byData);
689 		if (!(byData & DMACTL_RUN))
690 			break;
691 	}
692 	if (ww == W_MAX_TIMEOUT)
693 		pr_debug(" DBG_PORT80(0x26)\n");
694 	VNSvOutPortD(dwIoBase + MAC_REG_AC0DMAPTR, dwCurrDescAddr);
695 	if (byOrgDMACtl & DMACTL_RUN)
696 		VNSvOutPortB(dwIoBase + MAC_REG_AC0DMACTL, DMACTL_RUN);
697 }
698 
699 void MACvSetCurrTXDescAddr(int iTxType, void __iomem *dwIoBase,
700 			   unsigned long dwCurrDescAddr)
701 {
702 	if (iTxType == TYPE_AC0DMA)
703 		MACvSetCurrAC0DescAddrEx(dwIoBase, dwCurrDescAddr);
704 	else if (iTxType == TYPE_TXDMA0)
705 		MACvSetCurrTx0DescAddrEx(dwIoBase, dwCurrDescAddr);
706 }
707 
708 /*
709  * Description:
710  *      Micro Second Delay via MAC
711  *
712  * Parameters:
713  *  In:
714  *      dwIoBase    - Base Address for MAC
715  *      uDelay      - Delay time (timer resolution is 4 us)
716  *  Out:
717  *      none
718  *
719  * Return Value: none
720  *
721  */
722 void MACvTimer0MicroSDelay(void __iomem *dwIoBase, unsigned int uDelay)
723 {
724 	unsigned char byValue;
725 	unsigned int uu, ii;
726 
727 	VNSvOutPortB(dwIoBase + MAC_REG_TMCTL0, 0);
728 	VNSvOutPortD(dwIoBase + MAC_REG_TMDATA0, uDelay);
729 	VNSvOutPortB(dwIoBase + MAC_REG_TMCTL0, (TMCTL_TMD | TMCTL_TE));
730 	for (ii = 0; ii < 66; ii++) {  /* assume max PCI clock is 66Mhz */
731 		for (uu = 0; uu < uDelay; uu++) {
732 			VNSvInPortB(dwIoBase + MAC_REG_TMCTL0, &byValue);
733 			if ((byValue == 0) ||
734 			    (byValue & TMCTL_TSUSP)) {
735 				VNSvOutPortB(dwIoBase + MAC_REG_TMCTL0, 0);
736 				return;
737 			}
738 		}
739 	}
740 	VNSvOutPortB(dwIoBase + MAC_REG_TMCTL0, 0);
741 }
742 
743 /*
744  * Description:
745  *      Micro Second One shot timer via MAC
746  *
747  * Parameters:
748  *  In:
749  *      dwIoBase    - Base Address for MAC
750  *      uDelay      - Delay time
751  *  Out:
752  *      none
753  *
754  * Return Value: none
755  *
756  */
757 void MACvOneShotTimer1MicroSec(void __iomem *dwIoBase, unsigned int uDelayTime)
758 {
759 	VNSvOutPortB(dwIoBase + MAC_REG_TMCTL1, 0);
760 	VNSvOutPortD(dwIoBase + MAC_REG_TMDATA1, uDelayTime);
761 	VNSvOutPortB(dwIoBase + MAC_REG_TMCTL1, (TMCTL_TMD | TMCTL_TE));
762 }
763 
764 void MACvSetMISCFifo(void __iomem *dwIoBase, unsigned short wOffset,
765 		     unsigned long dwData)
766 {
767 	if (wOffset > 273)
768 		return;
769 	VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset);
770 	VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData);
771 	VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
772 }
773 
774 bool MACbPSWakeup(void __iomem *dwIoBase)
775 {
776 	unsigned char byOrgValue;
777 	unsigned int ww;
778 	/* Read PSCTL */
779 	if (MACbIsRegBitsOff(dwIoBase, MAC_REG_PSCTL, PSCTL_PS))
780 		return true;
781 
782 	/* Disable PS */
783 	MACvRegBitsOff(dwIoBase, MAC_REG_PSCTL, PSCTL_PSEN);
784 
785 	/* Check if SyncFlushOK */
786 	for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
787 		VNSvInPortB(dwIoBase + MAC_REG_PSCTL, &byOrgValue);
788 		if (byOrgValue & PSCTL_WAKEDONE)
789 			break;
790 	}
791 	if (ww == W_MAX_TIMEOUT) {
792 		pr_debug(" DBG_PORT80(0x33)\n");
793 		return false;
794 	}
795 	return true;
796 }
797 
798 /*
799  * Description:
800  *      Set the Key by MISCFIFO
801  *
802  * Parameters:
803  *  In:
804  *      dwIoBase        - Base Address for MAC
805  *
806  *  Out:
807  *      none
808  *
809  * Return Value: none
810  *
811  */
812 
813 void MACvSetKeyEntry(void __iomem *dwIoBase, unsigned short wKeyCtl,
814 		     unsigned int uEntryIdx, unsigned int uKeyIdx,
815 		     unsigned char *pbyAddr, u32 *pdwKey,
816 		     unsigned char byLocalID)
817 {
818 	unsigned short wOffset;
819 	u32 dwData;
820 	int     ii;
821 
822 	if (byLocalID <= 1)
823 		return;
824 
825 	pr_debug("MACvSetKeyEntry\n");
826 	wOffset = MISCFIFO_KEYETRY0;
827 	wOffset += (uEntryIdx * MISCFIFO_KEYENTRYSIZE);
828 
829 	dwData = 0;
830 	dwData |= wKeyCtl;
831 	dwData <<= 16;
832 	dwData |= MAKEWORD(*(pbyAddr+4), *(pbyAddr+5));
833 	pr_debug("1. wOffset: %d, Data: %X, KeyCtl:%X\n",
834 		 wOffset, dwData, wKeyCtl);
835 
836 	VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset);
837 	VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData);
838 	VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
839 	wOffset++;
840 
841 	dwData = 0;
842 	dwData |= *(pbyAddr+3);
843 	dwData <<= 8;
844 	dwData |= *(pbyAddr+2);
845 	dwData <<= 8;
846 	dwData |= *(pbyAddr+1);
847 	dwData <<= 8;
848 	dwData |= *(pbyAddr+0);
849 	pr_debug("2. wOffset: %d, Data: %X\n", wOffset, dwData);
850 
851 	VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset);
852 	VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData);
853 	VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
854 	wOffset++;
855 
856 	wOffset += (uKeyIdx * 4);
857 	for (ii = 0; ii < 4; ii++) {
858 		/* always push 128 bits */
859 		pr_debug("3.(%d) wOffset: %d, Data: %X\n",
860 			 ii, wOffset+ii, *pdwKey);
861 		VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset+ii);
862 		VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, *pdwKey++);
863 		VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
864 	}
865 }
866 
867 /*
868  * Description:
869  *      Disable the Key Entry by MISCFIFO
870  *
871  * Parameters:
872  *  In:
873  *      dwIoBase        - Base Address for MAC
874  *
875  *  Out:
876  *      none
877  *
878  * Return Value: none
879  *
880  */
881 void MACvDisableKeyEntry(void __iomem *dwIoBase, unsigned int uEntryIdx)
882 {
883 	unsigned short wOffset;
884 
885 	wOffset = MISCFIFO_KEYETRY0;
886 	wOffset += (uEntryIdx * MISCFIFO_KEYENTRYSIZE);
887 
888 	VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset);
889 	VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, 0);
890 	VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
891 }
892