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