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, tmp_reg_data); 306 /* do reset */ 307 MACbSoftwareReset(priv); 308 /* restore MAC context, except CR0 */ 309 vt6655_mac_restore_context(priv, 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(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(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(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(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(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(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