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 | |
40 | void 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 | |
48 | void 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 | |
56 | void 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 | |
64 | void 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 | |
72 | static 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 | */ |
96 | static 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 | */ |
119 | void 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 | */ |
140 | void 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 | */ |
162 | static 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 | */ |
184 | static 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 | */ |
214 | static 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 | */ |
265 | bool 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 | */ |
296 | static 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 | */ |
325 | static 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 | */ |
379 | static 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 | */ |
435 | static 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 | */ |
470 | bool 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 | */ |
498 | void 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 | */ |
530 | void 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 | */ |
564 | void 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 | */ |
598 | static 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 */ |
633 | static 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 | |
654 | void 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 | */ |
676 | void 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 | */ |
712 | void 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 | |
722 | void 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 | |
734 | bool 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 | |
772 | void 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 | */ |
840 | void 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 | |