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

source code of linux/drivers/staging/vt6655/mac.c