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  */
MACbIsRegBitsOn(void __iomem * dwIoBase,unsigned char byRegOfs,unsigned char byTestBits)73 bool 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  */
MACbIsRegBitsOff(void __iomem * dwIoBase,unsigned char byRegOfs,unsigned char byTestBits)96 bool 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  */
MACbIsIntDisable(void __iomem * dwIoBase)117 bool 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  */
MACvSetShortRetryLimit(void __iomem * dwIoBase,unsigned char byRetryLimit)142 void 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  */
MACvSetLongRetryLimit(void __iomem * dwIoBase,unsigned char byRetryLimit)163 void 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  */
MACvSetLoopbackMode(void __iomem * dwIoBase,unsigned char byLoopbackMode)183 void 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  */
MACvSaveContext(void __iomem * dwIoBase,unsigned char * pbyCxtBuf)209 void 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  */
MACvRestoreContext(void __iomem * dwIoBase,unsigned char * pbyCxtBuf)240 void 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  */
MACbSoftwareReset(void __iomem * dwIoBase)288 bool 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  */
MACbSafeSoftwareReset(void __iomem * dwIoBase)319 bool 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  */
MACbSafeRxOff(void __iomem * dwIoBase)351 bool 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  */
MACbSafeTxOff(void __iomem * dwIoBase)412 bool 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  */
MACbSafeStop(void __iomem * dwIoBase)475 bool 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  */
MACbShutdown(void __iomem * dwIoBase)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  */
MACvInitialize(void __iomem * dwIoBase)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  */
MACvSetCurrRx0DescAddr(void __iomem * dwIoBase,unsigned long dwCurrDescAddr)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 	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  */
MACvSetCurrRx1DescAddr(void __iomem * dwIoBase,unsigned long dwCurrDescAddr)606 void 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  */
MACvSetCurrTx0DescAddrEx(void __iomem * dwIoBase,unsigned long dwCurrDescAddr)644 void 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 */
MACvSetCurrAC0DescAddrEx(void __iomem * dwIoBase,unsigned long dwCurrDescAddr)682 void 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 
MACvSetCurrTXDescAddr(int iTxType,void __iomem * dwIoBase,unsigned long dwCurrDescAddr)706 void 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  */
MACvTimer0MicroSDelay(void __iomem * dwIoBase,unsigned int uDelay)728 void 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  */
MACvOneShotTimer1MicroSec(void __iomem * dwIoBase,unsigned int uDelayTime)763 void 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 
MACvSetMISCFifo(void __iomem * dwIoBase,unsigned short wOffset,unsigned long dwData)770 void 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 
MACbPSWakeup(void __iomem * dwIoBase)779 bool 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 
MACvSetKeyEntry(void __iomem * dwIoBase,unsigned short wKeyCtl,unsigned int uEntryIdx,unsigned int uKeyIdx,unsigned char * pbyAddr,u32 * pdwKey,unsigned char byLocalID)819 void 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  */
MACvDisableKeyEntry(void __iomem * dwIoBase,unsigned int uEntryIdx)885 void 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