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