1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
4  * All rights reserved.
5  *
6  * Purpose:  MAC routines
7  *
8  * Author: Tevin Chen
9  *
10  * Date: May 21, 1996
11  *
12  * Functions:
13  *      MACbIsRegBitsOff - Test if All test Bits Off
14  *      MACbIsIntDisable - Test if MAC interrupt disable
15  *      MACvSetShortRetryLimit - Set 802.11 Short Retry limit
16  *      MACvSetLongRetryLimit - Set 802.11 Long Retry limit
17  *      MACvSetLoopbackMode - Set MAC Loopback Mode
18  *      MACvSaveContext - Save Context of MAC Registers
19  *      MACvRestoreContext - Restore Context of MAC Registers
20  *      MACbSoftwareReset - Software Reset MAC
21  *      MACbSafeRxOff - Turn Off MAC Rx
22  *      MACbSafeTxOff - Turn Off MAC Tx
23  *      MACbSafeStop - Stop MAC function
24  *      MACbShutdown - Shut down MAC
25  *      MACvInitialize - Initialize MAC
26  *      MACvSetCurrRxDescAddr - Set Rx Descriptors Address
27  *      MACvSetCurrTx0DescAddr - Set Tx0 Descriptors Address
28  *      MACvSetCurrTx1DescAddr - Set Tx1 Descriptors Address
29  *      MACvTimer0MicroSDelay - Micro Second Delay Loop by MAC
30  *
31  * Revision History:
32  *      08-22-2003 Kyle Hsu     :  Porting MAC functions from sim53
33  *      09-03-2003 Bryan YC Fan :  Add MACvClearBusSusInd()&
34  *				   MACvEnableBusSusEn()
35  *      09-18-2003 Jerry Chen   :  Add MACvSetKeyEntry & MACvDisableKeyEntry
36  *
37  */
38 
39 #include "mac.h"
40 
41 /*
42  * Description:
43  *      Test if all test bits off
44  *
45  * Parameters:
46  *  In:
47  *      io_base    - Base Address for MAC
48  *      byRegOfs    - Offset of MAC Register
49  *      byTestBits  - Test bits
50  *  Out:
51  *      none
52  *
53  * Return Value: true if all test bits Off; otherwise false
54  *
55  */
MACbIsRegBitsOff(struct vnt_private * priv,unsigned char byRegOfs,unsigned char byTestBits)56 bool MACbIsRegBitsOff(struct vnt_private *priv, unsigned char byRegOfs,
57 		      unsigned char byTestBits)
58 {
59 	void __iomem *io_base = priv->port_offset;
60 
61 	return !(ioread8(io_base + byRegOfs) & byTestBits);
62 }
63 
64 /*
65  * Description:
66  *      Test if MAC interrupt disable
67  *
68  * Parameters:
69  *  In:
70  *      io_base    - Base Address for MAC
71  *  Out:
72  *      none
73  *
74  * Return Value: true if interrupt is disable; otherwise false
75  *
76  */
MACbIsIntDisable(struct vnt_private * priv)77 bool MACbIsIntDisable(struct vnt_private *priv)
78 {
79 	void __iomem *io_base = priv->port_offset;
80 
81 	if (ioread32(io_base + MAC_REG_IMR))
82 		return false;
83 
84 	return true;
85 }
86 
87 /*
88  * Description:
89  *      Set 802.11 Short Retry Limit
90  *
91  * Parameters:
92  *  In:
93  *      io_base    - Base Address for MAC
94  *      byRetryLimit- Retry Limit
95  *  Out:
96  *      none
97  *
98  * Return Value: none
99  *
100  */
MACvSetShortRetryLimit(struct vnt_private * priv,unsigned char byRetryLimit)101 void MACvSetShortRetryLimit(struct vnt_private *priv,
102 			    unsigned char byRetryLimit)
103 {
104 	void __iomem *io_base = priv->port_offset;
105 	/* set SRT */
106 	iowrite8(byRetryLimit, io_base + MAC_REG_SRT);
107 }
108 
109 /*
110  * Description:
111  *      Set 802.11 Long Retry Limit
112  *
113  * Parameters:
114  *  In:
115  *      io_base    - Base Address for MAC
116  *      byRetryLimit- Retry Limit
117  *  Out:
118  *      none
119  *
120  * Return Value: none
121  *
122  */
MACvSetLongRetryLimit(struct vnt_private * priv,unsigned char byRetryLimit)123 void MACvSetLongRetryLimit(struct vnt_private *priv,
124 			   unsigned char byRetryLimit)
125 {
126 	void __iomem *io_base = priv->port_offset;
127 	/* set LRT */
128 	iowrite8(byRetryLimit, io_base + MAC_REG_LRT);
129 }
130 
131 /*
132  * Description:
133  *      Set MAC Loopback mode
134  *
135  * Parameters:
136  *  In:
137  *      io_base        - Base Address for MAC
138  *      byLoopbackMode  - Loopback Mode
139  *  Out:
140  *      none
141  *
142  * Return Value: none
143  *
144  */
MACvSetLoopbackMode(struct vnt_private * priv,unsigned char byLoopbackMode)145 void MACvSetLoopbackMode(struct vnt_private *priv, unsigned char byLoopbackMode)
146 {
147 	void __iomem *io_base = priv->port_offset;
148 
149 	byLoopbackMode <<= 6;
150 	/* set TCR */
151 	iowrite8((ioread8(io_base + MAC_REG_TEST) & 0x3f) | byLoopbackMode,
152 		 io_base + MAC_REG_TEST);
153 }
154 
155 /*
156  * Description:
157  *      Save MAC registers to context buffer
158  *
159  * Parameters:
160  *  In:
161  *      io_base    - Base Address for MAC
162  *  Out:
163  *      cxt_buf   - Context buffer
164  *
165  * Return Value: none
166  *
167  */
MACvSaveContext(struct vnt_private * priv,unsigned char * cxt_buf)168 void MACvSaveContext(struct vnt_private *priv, unsigned char *cxt_buf)
169 {
170 	void __iomem *io_base = priv->port_offset;
171 
172 	/* read page0 register */
173 	memcpy_fromio(cxt_buf, io_base, MAC_MAX_CONTEXT_SIZE_PAGE0);
174 
175 	MACvSelectPage1(io_base);
176 
177 	/* read page1 register */
178 	memcpy_fromio(cxt_buf + MAC_MAX_CONTEXT_SIZE_PAGE0, io_base,
179 		      MAC_MAX_CONTEXT_SIZE_PAGE1);
180 
181 	MACvSelectPage0(io_base);
182 }
183 
184 /*
185  * Description:
186  *      Restore MAC registers from context buffer
187  *
188  * Parameters:
189  *  In:
190  *      io_base    - Base Address for MAC
191  *      cxt_buf   - Context buffer
192  *  Out:
193  *      none
194  *
195  * Return Value: none
196  *
197  */
MACvRestoreContext(struct vnt_private * priv,unsigned char * cxt_buf)198 void MACvRestoreContext(struct vnt_private *priv, unsigned char *cxt_buf)
199 {
200 	void __iomem *io_base = priv->port_offset;
201 
202 	MACvSelectPage1(io_base);
203 	/* restore page1 */
204 	memcpy_toio(io_base, cxt_buf + MAC_MAX_CONTEXT_SIZE_PAGE0,
205 		    MAC_MAX_CONTEXT_SIZE_PAGE1);
206 
207 	MACvSelectPage0(io_base);
208 
209 	/* restore RCR,TCR,IMR... */
210 	memcpy_toio(io_base + MAC_REG_RCR, cxt_buf + MAC_REG_RCR,
211 		    MAC_REG_ISR - MAC_REG_RCR);
212 
213 	/* restore MAC Config. */
214 	memcpy_toio(io_base + MAC_REG_LRT, cxt_buf + MAC_REG_LRT,
215 		    MAC_REG_PAGE1SEL - MAC_REG_LRT);
216 
217 	iowrite8(*(cxt_buf + MAC_REG_CFG), io_base + MAC_REG_CFG);
218 
219 	/* restore PS Config. */
220 	memcpy_toio(io_base + MAC_REG_PSCFG, cxt_buf + MAC_REG_PSCFG,
221 		    MAC_REG_BBREGCTL - MAC_REG_PSCFG);
222 
223 	/* restore CURR_RX_DESC_ADDR, CURR_TX_DESC_ADDR */
224 	iowrite32(*(u32 *)(cxt_buf + MAC_REG_TXDMAPTR0),
225 		  io_base + MAC_REG_TXDMAPTR0);
226 	iowrite32(*(u32 *)(cxt_buf + MAC_REG_AC0DMAPTR),
227 		  io_base + MAC_REG_AC0DMAPTR);
228 	iowrite32(*(u32 *)(cxt_buf + MAC_REG_BCNDMAPTR),
229 		  io_base + MAC_REG_BCNDMAPTR);
230 	iowrite32(*(u32 *)(cxt_buf + MAC_REG_RXDMAPTR0),
231 		  io_base + MAC_REG_RXDMAPTR0);
232 	iowrite32(*(u32 *)(cxt_buf + MAC_REG_RXDMAPTR1),
233 		  io_base + MAC_REG_RXDMAPTR1);
234 }
235 
236 /*
237  * Description:
238  *      Software Reset MAC
239  *
240  * Parameters:
241  *  In:
242  *      io_base    - Base Address for MAC
243  *  Out:
244  *      none
245  *
246  * Return Value: true if Reset Success; otherwise false
247  *
248  */
MACbSoftwareReset(struct vnt_private * priv)249 bool MACbSoftwareReset(struct vnt_private *priv)
250 {
251 	void __iomem *io_base = priv->port_offset;
252 	unsigned short ww;
253 
254 	/* turn on HOSTCR_SOFTRST, just write 0x01 to reset */
255 	iowrite8(0x01, io_base + MAC_REG_HOSTCR);
256 
257 	for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
258 		if (!(ioread8(io_base + MAC_REG_HOSTCR) & HOSTCR_SOFTRST))
259 			break;
260 	}
261 	if (ww == W_MAX_TIMEOUT)
262 		return false;
263 	return true;
264 }
265 
266 /*
267  * Description:
268  *      save some important register's value, then do reset, then restore
269  *	register's value
270  *
271  * Parameters:
272  *  In:
273  *      io_base    - Base Address for MAC
274  *  Out:
275  *      none
276  *
277  * Return Value: true if success; otherwise false
278  *
279  */
MACbSafeSoftwareReset(struct vnt_private * priv)280 bool MACbSafeSoftwareReset(struct vnt_private *priv)
281 {
282 	unsigned char abyTmpRegData[MAC_MAX_CONTEXT_SIZE_PAGE0 + MAC_MAX_CONTEXT_SIZE_PAGE1];
283 	bool bRetVal;
284 
285 	/* PATCH....
286 	 * save some important register's value, then do
287 	 * reset, then restore register's value
288 	 */
289 	/* save MAC context */
290 	MACvSaveContext(priv, abyTmpRegData);
291 	/* do reset */
292 	bRetVal = MACbSoftwareReset(priv);
293 	/* restore MAC context, except CR0 */
294 	MACvRestoreContext(priv, abyTmpRegData);
295 
296 	return bRetVal;
297 }
298 
299 /*
300  * Description:
301  *      Turn Off MAC Rx
302  *
303  * Parameters:
304  *  In:
305  *      io_base    - Base Address for MAC
306  *  Out:
307  *      none
308  *
309  * Return Value: true if success; otherwise false
310  *
311  */
MACbSafeRxOff(struct vnt_private * priv)312 bool MACbSafeRxOff(struct vnt_private *priv)
313 {
314 	void __iomem *io_base = priv->port_offset;
315 	unsigned short ww;
316 
317 	/* turn off wow temp for turn off Rx safely */
318 
319 	/* Clear RX DMA0,1 */
320 	iowrite32(DMACTL_CLRRUN, io_base + MAC_REG_RXDMACTL0);
321 	iowrite32(DMACTL_CLRRUN, io_base + MAC_REG_RXDMACTL1);
322 	for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
323 		if (!(ioread32(io_base + MAC_REG_RXDMACTL0) & DMACTL_RUN))
324 			break;
325 	}
326 	if (ww == W_MAX_TIMEOUT) {
327 		pr_debug(" DBG_PORT80(0x10)\n");
328 		return false;
329 	}
330 	for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
331 		if (!(ioread32(io_base + MAC_REG_RXDMACTL1) & DMACTL_RUN))
332 			break;
333 	}
334 	if (ww == W_MAX_TIMEOUT) {
335 		pr_debug(" DBG_PORT80(0x11)\n");
336 		return false;
337 	}
338 
339 	/* try to safe shutdown RX */
340 	MACvRegBitsOff(io_base, MAC_REG_HOSTCR, HOSTCR_RXON);
341 	/* W_MAX_TIMEOUT is the timeout period */
342 	for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
343 		if (!(ioread8(io_base + MAC_REG_HOSTCR) & HOSTCR_RXONST))
344 			break;
345 	}
346 	if (ww == W_MAX_TIMEOUT) {
347 		pr_debug(" DBG_PORT80(0x12)\n");
348 		return false;
349 	}
350 	return true;
351 }
352 
353 /*
354  * Description:
355  *      Turn Off MAC Tx
356  *
357  * Parameters:
358  *  In:
359  *      io_base    - Base Address for MAC
360  *  Out:
361  *      none
362  *
363  * Return Value: true if success; otherwise false
364  *
365  */
MACbSafeTxOff(struct vnt_private * priv)366 bool MACbSafeTxOff(struct vnt_private *priv)
367 {
368 	void __iomem *io_base = priv->port_offset;
369 	unsigned short ww;
370 
371 	/* Clear TX DMA */
372 	/* Tx0 */
373 	iowrite32(DMACTL_CLRRUN, io_base + MAC_REG_TXDMACTL0);
374 	/* AC0 */
375 	iowrite32(DMACTL_CLRRUN, io_base + MAC_REG_AC0DMACTL);
376 
377 	for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
378 		if (!(ioread32(io_base + MAC_REG_TXDMACTL0) & DMACTL_RUN))
379 			break;
380 	}
381 	if (ww == W_MAX_TIMEOUT) {
382 		pr_debug(" DBG_PORT80(0x20)\n");
383 		return false;
384 	}
385 	for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
386 		if (!(ioread32(io_base + MAC_REG_AC0DMACTL) & DMACTL_RUN))
387 			break;
388 	}
389 	if (ww == W_MAX_TIMEOUT) {
390 		pr_debug(" DBG_PORT80(0x21)\n");
391 		return false;
392 	}
393 
394 	/* try to safe shutdown TX */
395 	MACvRegBitsOff(io_base, MAC_REG_HOSTCR, HOSTCR_TXON);
396 
397 	/* W_MAX_TIMEOUT is the timeout period */
398 	for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
399 		if (!(ioread8(io_base + MAC_REG_HOSTCR) & HOSTCR_TXONST))
400 			break;
401 	}
402 	if (ww == W_MAX_TIMEOUT) {
403 		pr_debug(" DBG_PORT80(0x24)\n");
404 		return false;
405 	}
406 	return true;
407 }
408 
409 /*
410  * Description:
411  *      Stop MAC function
412  *
413  * Parameters:
414  *  In:
415  *      io_base    - Base Address for MAC
416  *  Out:
417  *      none
418  *
419  * Return Value: true if success; otherwise false
420  *
421  */
MACbSafeStop(struct vnt_private * priv)422 bool MACbSafeStop(struct vnt_private *priv)
423 {
424 	void __iomem *io_base = priv->port_offset;
425 
426 	MACvRegBitsOff(io_base, MAC_REG_TCR, TCR_AUTOBCNTX);
427 
428 	if (!MACbSafeRxOff(priv)) {
429 		pr_debug(" MACbSafeRxOff == false)\n");
430 		MACbSafeSoftwareReset(priv);
431 		return false;
432 	}
433 	if (!MACbSafeTxOff(priv)) {
434 		pr_debug(" MACbSafeTxOff == false)\n");
435 		MACbSafeSoftwareReset(priv);
436 		return false;
437 	}
438 
439 	MACvRegBitsOff(io_base, MAC_REG_HOSTCR, HOSTCR_MACEN);
440 
441 	return true;
442 }
443 
444 /*
445  * Description:
446  *      Shut Down MAC
447  *
448  * Parameters:
449  *  In:
450  *      io_base    - Base Address for MAC
451  *  Out:
452  *      none
453  *
454  * Return Value: true if success; otherwise false
455  *
456  */
MACbShutdown(struct vnt_private * priv)457 bool MACbShutdown(struct vnt_private *priv)
458 {
459 	void __iomem *io_base = priv->port_offset;
460 	/* disable MAC IMR */
461 	MACvIntDisable(io_base);
462 	MACvSetLoopbackMode(priv, MAC_LB_INTERNAL);
463 	/* stop the adapter */
464 	if (!MACbSafeStop(priv)) {
465 		MACvSetLoopbackMode(priv, MAC_LB_NONE);
466 		return false;
467 	}
468 	MACvSetLoopbackMode(priv, MAC_LB_NONE);
469 	return true;
470 }
471 
472 /*
473  * Description:
474  *      Initialize MAC
475  *
476  * Parameters:
477  *  In:
478  *      io_base    - Base Address for MAC
479  *  Out:
480  *      none
481  *
482  * Return Value: none
483  *
484  */
MACvInitialize(struct vnt_private * priv)485 void MACvInitialize(struct vnt_private *priv)
486 {
487 	void __iomem *io_base = priv->port_offset;
488 	/* clear sticky bits */
489 	MACvClearStckDS(io_base);
490 	/* disable force PME-enable */
491 	iowrite8(PME_OVR, io_base + MAC_REG_PMC1);
492 	/* only 3253 A */
493 
494 	/* do reset */
495 	MACbSoftwareReset(priv);
496 
497 	/* reset TSF counter */
498 	iowrite8(TFTCTL_TSFCNTRST, io_base + MAC_REG_TFTCTL);
499 	/* enable TSF counter */
500 	iowrite8(TFTCTL_TSFCNTREN, io_base + MAC_REG_TFTCTL);
501 }
502 
503 /*
504  * Description:
505  *      Set the chip with current rx descriptor address
506  *
507  * Parameters:
508  *  In:
509  *      io_base        - Base Address for MAC
510  *      curr_desc_addr  - Descriptor Address
511  *  Out:
512  *      none
513  *
514  * Return Value: none
515  *
516  */
MACvSetCurrRx0DescAddr(struct vnt_private * priv,u32 curr_desc_addr)517 void MACvSetCurrRx0DescAddr(struct vnt_private *priv, u32 curr_desc_addr)
518 {
519 	void __iomem *io_base = priv->port_offset;
520 	unsigned short ww;
521 	unsigned char org_dma_ctl;
522 
523 	org_dma_ctl = ioread8(io_base + MAC_REG_RXDMACTL0);
524 	if (org_dma_ctl & DMACTL_RUN)
525 		iowrite8(DMACTL_RUN, io_base + MAC_REG_RXDMACTL0 + 2);
526 
527 	for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
528 		if (!(ioread8(io_base + MAC_REG_RXDMACTL0) & DMACTL_RUN))
529 			break;
530 	}
531 
532 	iowrite32(curr_desc_addr, io_base + MAC_REG_RXDMAPTR0);
533 	if (org_dma_ctl & DMACTL_RUN)
534 		iowrite8(DMACTL_RUN, io_base + MAC_REG_RXDMACTL0);
535 }
536 
537 /*
538  * Description:
539  *      Set the chip with current rx descriptor address
540  *
541  * Parameters:
542  *  In:
543  *      io_base        - Base Address for MAC
544  *      curr_desc_addr  - Descriptor Address
545  *  Out:
546  *      none
547  *
548  * Return Value: none
549  *
550  */
MACvSetCurrRx1DescAddr(struct vnt_private * priv,u32 curr_desc_addr)551 void MACvSetCurrRx1DescAddr(struct vnt_private *priv, u32 curr_desc_addr)
552 {
553 	void __iomem *io_base = priv->port_offset;
554 	unsigned short ww;
555 	unsigned char org_dma_ctl;
556 
557 	org_dma_ctl = ioread8(io_base + MAC_REG_RXDMACTL1);
558 	if (org_dma_ctl & DMACTL_RUN)
559 		iowrite8(DMACTL_RUN, io_base + MAC_REG_RXDMACTL1 + 2);
560 
561 	for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
562 		if (!(ioread8(io_base + MAC_REG_RXDMACTL1) & DMACTL_RUN))
563 			break;
564 	}
565 
566 	iowrite32(curr_desc_addr, io_base + MAC_REG_RXDMAPTR1);
567 	if (org_dma_ctl & DMACTL_RUN)
568 		iowrite8(DMACTL_RUN, io_base + MAC_REG_RXDMACTL1);
569 }
570 
571 /*
572  * Description:
573  *      Set the chip with current tx0 descriptor address
574  *
575  * Parameters:
576  *  In:
577  *      io_base        - Base Address for MAC
578  *      curr_desc_addr  - Descriptor Address
579  *  Out:
580  *      none
581  *
582  * Return Value: none
583  *
584  */
MACvSetCurrTx0DescAddrEx(struct vnt_private * priv,u32 curr_desc_addr)585 void MACvSetCurrTx0DescAddrEx(struct vnt_private *priv,
586 			      u32 curr_desc_addr)
587 {
588 	void __iomem *io_base = priv->port_offset;
589 	unsigned short ww;
590 	unsigned char org_dma_ctl;
591 
592 	org_dma_ctl = ioread8(io_base + MAC_REG_TXDMACTL0);
593 	if (org_dma_ctl & DMACTL_RUN)
594 		iowrite8(DMACTL_RUN, io_base + MAC_REG_TXDMACTL0 + 2);
595 
596 	for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
597 		if (!(ioread8(io_base + MAC_REG_TXDMACTL0) & DMACTL_RUN))
598 			break;
599 	}
600 
601 	iowrite32(curr_desc_addr, io_base + MAC_REG_TXDMAPTR0);
602 	if (org_dma_ctl & DMACTL_RUN)
603 		iowrite8(DMACTL_RUN, io_base + MAC_REG_TXDMACTL0);
604 }
605 
606 /*
607  * Description:
608  *      Set the chip with current AC0 descriptor address
609  *
610  * Parameters:
611  *  In:
612  *      io_base        - Base Address for MAC
613  *      curr_desc_addr  - Descriptor Address
614  *  Out:
615  *      none
616  *
617  * Return Value: none
618  *
619  */
620 /* TxDMA1 = AC0DMA */
MACvSetCurrAC0DescAddrEx(struct vnt_private * priv,u32 curr_desc_addr)621 void MACvSetCurrAC0DescAddrEx(struct vnt_private *priv,
622 			      u32 curr_desc_addr)
623 {
624 	void __iomem *io_base = priv->port_offset;
625 	unsigned short ww;
626 	unsigned char org_dma_ctl;
627 
628 	org_dma_ctl = ioread8(io_base + MAC_REG_AC0DMACTL);
629 	if (org_dma_ctl & DMACTL_RUN)
630 		iowrite8(DMACTL_RUN, io_base + MAC_REG_AC0DMACTL + 2);
631 
632 	for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
633 		if (!(ioread8(io_base + MAC_REG_AC0DMACTL) & DMACTL_RUN))
634 			break;
635 	}
636 	if (ww == W_MAX_TIMEOUT)
637 		pr_debug(" DBG_PORT80(0x26)\n");
638 	iowrite32(curr_desc_addr, io_base + MAC_REG_AC0DMAPTR);
639 	if (org_dma_ctl & DMACTL_RUN)
640 		iowrite8(DMACTL_RUN, io_base + MAC_REG_AC0DMACTL);
641 }
642 
MACvSetCurrTXDescAddr(int iTxType,struct vnt_private * priv,u32 curr_desc_addr)643 void MACvSetCurrTXDescAddr(int iTxType, struct vnt_private *priv,
644 			   u32 curr_desc_addr)
645 {
646 	if (iTxType == TYPE_AC0DMA)
647 		MACvSetCurrAC0DescAddrEx(priv, curr_desc_addr);
648 	else if (iTxType == TYPE_TXDMA0)
649 		MACvSetCurrTx0DescAddrEx(priv, curr_desc_addr);
650 }
651 
652 /*
653  * Description:
654  *      Micro Second Delay via MAC
655  *
656  * Parameters:
657  *  In:
658  *      io_base    - Base Address for MAC
659  *      uDelay      - Delay time (timer resolution is 4 us)
660  *  Out:
661  *      none
662  *
663  * Return Value: none
664  *
665  */
MACvTimer0MicroSDelay(struct vnt_private * priv,unsigned int uDelay)666 void MACvTimer0MicroSDelay(struct vnt_private *priv, unsigned int uDelay)
667 {
668 	void __iomem *io_base = priv->port_offset;
669 	unsigned char byValue;
670 	unsigned int uu, ii;
671 
672 	iowrite8(0, io_base + MAC_REG_TMCTL0);
673 	iowrite32(uDelay, io_base + MAC_REG_TMDATA0);
674 	iowrite8((TMCTL_TMD | TMCTL_TE), io_base + MAC_REG_TMCTL0);
675 	for (ii = 0; ii < 66; ii++) {  /* assume max PCI clock is 66Mhz */
676 		for (uu = 0; uu < uDelay; uu++) {
677 			byValue = ioread8(io_base + MAC_REG_TMCTL0);
678 			if ((byValue == 0) ||
679 			    (byValue & TMCTL_TSUSP)) {
680 				iowrite8(0, io_base + MAC_REG_TMCTL0);
681 				return;
682 			}
683 		}
684 	}
685 	iowrite8(0, io_base + MAC_REG_TMCTL0);
686 }
687 
688 /*
689  * Description:
690  *      Micro Second One shot timer via MAC
691  *
692  * Parameters:
693  *  In:
694  *      io_base    - Base Address for MAC
695  *      uDelay      - Delay time
696  *  Out:
697  *      none
698  *
699  * Return Value: none
700  *
701  */
MACvOneShotTimer1MicroSec(struct vnt_private * priv,unsigned int uDelayTime)702 void MACvOneShotTimer1MicroSec(struct vnt_private *priv,
703 			       unsigned int uDelayTime)
704 {
705 	void __iomem *io_base = priv->port_offset;
706 
707 	iowrite8(0, io_base + MAC_REG_TMCTL1);
708 	iowrite32(uDelayTime, io_base + MAC_REG_TMDATA1);
709 	iowrite8((TMCTL_TMD | TMCTL_TE), io_base + MAC_REG_TMCTL1);
710 }
711 
MACvSetMISCFifo(struct vnt_private * priv,unsigned short offset,u32 data)712 void MACvSetMISCFifo(struct vnt_private *priv, unsigned short offset,
713 		     u32 data)
714 {
715 	void __iomem *io_base = priv->port_offset;
716 
717 	if (offset > 273)
718 		return;
719 	iowrite16(offset, io_base + MAC_REG_MISCFFNDEX);
720 	iowrite32(data, io_base + MAC_REG_MISCFFDATA);
721 	iowrite16(MISCFFCTL_WRITE, io_base + MAC_REG_MISCFFCTL);
722 }
723 
MACbPSWakeup(struct vnt_private * priv)724 bool MACbPSWakeup(struct vnt_private *priv)
725 {
726 	void __iomem *io_base = priv->port_offset;
727 	unsigned int ww;
728 	/* Read PSCTL */
729 	if (MACbIsRegBitsOff(priv, MAC_REG_PSCTL, PSCTL_PS))
730 		return true;
731 
732 	/* Disable PS */
733 	MACvRegBitsOff(io_base, MAC_REG_PSCTL, PSCTL_PSEN);
734 
735 	/* Check if SyncFlushOK */
736 	for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
737 		if (ioread8(io_base + MAC_REG_PSCTL) & PSCTL_WAKEDONE)
738 			break;
739 	}
740 	if (ww == W_MAX_TIMEOUT) {
741 		pr_debug(" DBG_PORT80(0x33)\n");
742 		return false;
743 	}
744 	return true;
745 }
746 
747 /*
748  * Description:
749  *      Set the Key by MISCFIFO
750  *
751  * Parameters:
752  *  In:
753  *      io_base        - Base Address for MAC
754  *
755  *  Out:
756  *      none
757  *
758  * Return Value: none
759  *
760  */
761 
MACvSetKeyEntry(struct vnt_private * priv,unsigned short wKeyCtl,unsigned int uEntryIdx,unsigned int uKeyIdx,unsigned char * pbyAddr,u32 * pdwKey,unsigned char local_id)762 void MACvSetKeyEntry(struct vnt_private *priv, unsigned short wKeyCtl,
763 		     unsigned int uEntryIdx, unsigned int uKeyIdx,
764 		     unsigned char *pbyAddr, u32 *pdwKey,
765 		     unsigned char local_id)
766 {
767 	void __iomem *io_base = priv->port_offset;
768 	unsigned short offset;
769 	u32 data;
770 	int     ii;
771 
772 	if (local_id <= 1)
773 		return;
774 
775 	offset = MISCFIFO_KEYETRY0;
776 	offset += (uEntryIdx * MISCFIFO_KEYENTRYSIZE);
777 
778 	data = 0;
779 	data |= wKeyCtl;
780 	data <<= 16;
781 	data |= MAKEWORD(*(pbyAddr + 4), *(pbyAddr + 5));
782 	pr_debug("1. offset: %d, Data: %X, KeyCtl:%X\n",
783 		 offset, data, wKeyCtl);
784 
785 	iowrite16(offset, io_base + MAC_REG_MISCFFNDEX);
786 	iowrite32(data, io_base + MAC_REG_MISCFFDATA);
787 	iowrite16(MISCFFCTL_WRITE, io_base + MAC_REG_MISCFFCTL);
788 	offset++;
789 
790 	data = 0;
791 	data |= *(pbyAddr + 3);
792 	data <<= 8;
793 	data |= *(pbyAddr + 2);
794 	data <<= 8;
795 	data |= *(pbyAddr + 1);
796 	data <<= 8;
797 	data |= *pbyAddr;
798 	pr_debug("2. offset: %d, Data: %X\n", offset, data);
799 
800 	iowrite16(offset, io_base + MAC_REG_MISCFFNDEX);
801 	iowrite32(data, io_base + MAC_REG_MISCFFDATA);
802 	iowrite16(MISCFFCTL_WRITE, io_base + MAC_REG_MISCFFCTL);
803 	offset++;
804 
805 	offset += (uKeyIdx * 4);
806 	for (ii = 0; ii < 4; ii++) {
807 		/* always push 128 bits */
808 		pr_debug("3.(%d) offset: %d, Data: %X\n",
809 			 ii, offset + ii, *pdwKey);
810 		iowrite16(offset + ii, io_base + MAC_REG_MISCFFNDEX);
811 		iowrite32(*pdwKey++, io_base + MAC_REG_MISCFFDATA);
812 		iowrite16(MISCFFCTL_WRITE, io_base + MAC_REG_MISCFFCTL);
813 	}
814 }
815 
816 /*
817  * Description:
818  *      Disable the Key Entry by MISCFIFO
819  *
820  * Parameters:
821  *  In:
822  *      io_base        - Base Address for MAC
823  *
824  *  Out:
825  *      none
826  *
827  * Return Value: none
828  *
829  */
MACvDisableKeyEntry(struct vnt_private * priv,unsigned int uEntryIdx)830 void MACvDisableKeyEntry(struct vnt_private *priv, unsigned int uEntryIdx)
831 {
832 	void __iomem *io_base = priv->port_offset;
833 	unsigned short offset;
834 
835 	offset = MISCFIFO_KEYETRY0;
836 	offset += (uEntryIdx * MISCFIFO_KEYENTRYSIZE);
837 
838 	iowrite16(offset, io_base + MAC_REG_MISCFFNDEX);
839 	iowrite32(0, io_base + MAC_REG_MISCFFDATA);
840 	iowrite16(MISCFFCTL_WRITE, io_base + MAC_REG_MISCFFCTL);
841 }
842