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 */
73bool 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 */
97bool 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 */
119bool 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 */
144void 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 */
165void 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 */
185void 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 */
210void 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 */
242void 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 */
296bool 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 */
327bool 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 */
359bool 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 */
417bool 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 */
477bool 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 */
510bool 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 */
537void 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 */
568void 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 */
603void 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 */
639void 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 */
676void 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
699void 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 */
722void 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 */
757void 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
764void 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
774bool 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
813void 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 */
881void 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