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