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 * File: card.c 20 * Purpose: Provide functions to setup NIC operation mode 21 * Functions: 22 * s_vSafeResetTx - Rest Tx 23 * CARDvSetRSPINF - Set RSPINF 24 * CARDvUpdateBasicTopRate - Update BasicTopRate 25 * CARDbAddBasicRate - Add to BasicRateSet 26 * CARDbIsOFDMinBasicRate - Check if any OFDM rate is in BasicRateSet 27 * CARDvSetLoopbackMode - Set Loopback mode 28 * CARDbSoftwareReset - Sortware reset NIC 29 * CARDqGetTSFOffset - Calculate TSFOffset 30 * CARDbGetCurrentTSF - Read Current NIC TSF counter 31 * CARDqGetNextTBTT - Calculate Next Beacon TSF counter 32 * CARDvSetFirstNextTBTT - Set NIC Beacon time 33 * CARDvUpdateNextTBTT - Sync. NIC Beacon time 34 * CARDbRadioPowerOff - Turn Off NIC Radio Power 35 * CARDbRadioPowerOn - Turn On NIC Radio Power 36 * 37 * Revision History: 38 * 06-10-2003 Bryan YC Fan: Re-write codes to support VT3253 spec. 39 * 08-26-2003 Kyle Hsu: Modify the defination type of dwIoBase. 40 * 09-01-2003 Bryan YC Fan: Add vUpdateIFS(). 41 * 42 */ 43 44 #include "tmacro.h" 45 #include "card.h" 46 #include "baseband.h" 47 #include "mac.h" 48 #include "desc.h" 49 #include "rf.h" 50 #include "power.h" 51 52 /*--------------------- Static Definitions -------------------------*/ 53 54 #define C_SIFS_A 16 /* micro sec. */ 55 #define C_SIFS_BG 10 56 57 #define C_EIFS 80 /* micro sec. */ 58 59 #define C_SLOT_SHORT 9 /* micro sec. */ 60 #define C_SLOT_LONG 20 61 62 #define C_CWMIN_A 15 /* slot time */ 63 #define C_CWMIN_B 31 64 65 #define C_CWMAX 1023 /* slot time */ 66 67 #define WAIT_BEACON_TX_DOWN_TMO 3 /* Times */ 68 69 /*--------------------- Static Variables --------------------------*/ 70 71 static const unsigned short cwRXBCNTSFOff[MAX_RATE] = { 72 17, 17, 17, 17, 34, 23, 17, 11, 8, 5, 4, 3}; 73 74 /*--------------------- Static Functions --------------------------*/ 75 76 static 77 void 78 s_vCalculateOFDMRParameter( 79 unsigned char byRate, 80 u8 bb_type, 81 unsigned char *pbyTxRate, 82 unsigned char *pbyRsvTime 83 ); 84 85 /*--------------------- Export Functions --------------------------*/ 86 87 /* 88 * Description: Calculate TxRate and RsvTime fields for RSPINF in OFDM mode. 89 * 90 * Parameters: 91 * In: 92 * wRate - Tx Rate 93 * byPktType - Tx Packet type 94 * Out: 95 * pbyTxRate - pointer to RSPINF TxRate field 96 * pbyRsvTime - pointer to RSPINF RsvTime field 97 * 98 * Return Value: none 99 */ 100 static 101 void 102 s_vCalculateOFDMRParameter( 103 unsigned char byRate, 104 u8 bb_type, 105 unsigned char *pbyTxRate, 106 unsigned char *pbyRsvTime 107 ) 108 { 109 switch (byRate) { 110 case RATE_6M: 111 if (bb_type == BB_TYPE_11A) { /* 5GHZ */ 112 *pbyTxRate = 0x9B; 113 *pbyRsvTime = 44; 114 } else { 115 *pbyTxRate = 0x8B; 116 *pbyRsvTime = 50; 117 } 118 break; 119 120 case RATE_9M: 121 if (bb_type == BB_TYPE_11A) { /* 5GHZ */ 122 *pbyTxRate = 0x9F; 123 *pbyRsvTime = 36; 124 } else { 125 *pbyTxRate = 0x8F; 126 *pbyRsvTime = 42; 127 } 128 break; 129 130 case RATE_12M: 131 if (bb_type == BB_TYPE_11A) { /* 5GHZ */ 132 *pbyTxRate = 0x9A; 133 *pbyRsvTime = 32; 134 } else { 135 *pbyTxRate = 0x8A; 136 *pbyRsvTime = 38; 137 } 138 break; 139 140 case RATE_18M: 141 if (bb_type == BB_TYPE_11A) { /* 5GHZ */ 142 *pbyTxRate = 0x9E; 143 *pbyRsvTime = 28; 144 } else { 145 *pbyTxRate = 0x8E; 146 *pbyRsvTime = 34; 147 } 148 break; 149 150 case RATE_36M: 151 if (bb_type == BB_TYPE_11A) { /* 5GHZ */ 152 *pbyTxRate = 0x9D; 153 *pbyRsvTime = 24; 154 } else { 155 *pbyTxRate = 0x8D; 156 *pbyRsvTime = 30; 157 } 158 break; 159 160 case RATE_48M: 161 if (bb_type == BB_TYPE_11A) { /* 5GHZ */ 162 *pbyTxRate = 0x98; 163 *pbyRsvTime = 24; 164 } else { 165 *pbyTxRate = 0x88; 166 *pbyRsvTime = 30; 167 } 168 break; 169 170 case RATE_54M: 171 if (bb_type == BB_TYPE_11A) { /* 5GHZ */ 172 *pbyTxRate = 0x9C; 173 *pbyRsvTime = 24; 174 } else { 175 *pbyTxRate = 0x8C; 176 *pbyRsvTime = 30; 177 } 178 break; 179 180 case RATE_24M: 181 default: 182 if (bb_type == BB_TYPE_11A) { /* 5GHZ */ 183 *pbyTxRate = 0x99; 184 *pbyRsvTime = 28; 185 } else { 186 *pbyTxRate = 0x89; 187 *pbyRsvTime = 34; 188 } 189 break; 190 } 191 } 192 193 /*--------------------- Export Functions --------------------------*/ 194 195 /* 196 * Description: Update IFS 197 * 198 * Parameters: 199 * In: 200 * priv - The adapter to be set 201 * Out: 202 * none 203 * 204 * Return Value: None. 205 */ 206 bool CARDbSetPhyParameter(struct vnt_private *priv, u8 bb_type) 207 { 208 unsigned char byCWMaxMin = 0; 209 unsigned char bySlot = 0; 210 unsigned char bySIFS = 0; 211 unsigned char byDIFS = 0; 212 unsigned char byData; 213 int i; 214 215 /* Set SIFS, DIFS, EIFS, SlotTime, CwMin */ 216 if (bb_type == BB_TYPE_11A) { 217 if (priv->byRFType == RF_AIROHA7230) { 218 /* AL7230 use single PAPE and connect to PAPE_2.4G */ 219 MACvSetBBType(priv->PortOffset, BB_TYPE_11G); 220 priv->abyBBVGA[0] = 0x20; 221 priv->abyBBVGA[2] = 0x10; 222 priv->abyBBVGA[3] = 0x10; 223 BBbReadEmbedded(priv, 0xE7, &byData); 224 if (byData == 0x1C) 225 BBbWriteEmbedded(priv, 0xE7, priv->abyBBVGA[0]); 226 227 } else if (priv->byRFType == RF_UW2452) { 228 MACvSetBBType(priv->PortOffset, BB_TYPE_11A); 229 priv->abyBBVGA[0] = 0x18; 230 BBbReadEmbedded(priv, 0xE7, &byData); 231 if (byData == 0x14) { 232 BBbWriteEmbedded(priv, 0xE7, priv->abyBBVGA[0]); 233 BBbWriteEmbedded(priv, 0xE1, 0x57); 234 } 235 } else { 236 MACvSetBBType(priv->PortOffset, BB_TYPE_11A); 237 } 238 BBbWriteEmbedded(priv, 0x88, 0x03); 239 bySlot = C_SLOT_SHORT; 240 bySIFS = C_SIFS_A; 241 byDIFS = C_SIFS_A + 2 * C_SLOT_SHORT; 242 byCWMaxMin = 0xA4; 243 } else if (bb_type == BB_TYPE_11B) { 244 MACvSetBBType(priv->PortOffset, BB_TYPE_11B); 245 if (priv->byRFType == RF_AIROHA7230) { 246 priv->abyBBVGA[0] = 0x1C; 247 priv->abyBBVGA[2] = 0x00; 248 priv->abyBBVGA[3] = 0x00; 249 BBbReadEmbedded(priv, 0xE7, &byData); 250 if (byData == 0x20) 251 BBbWriteEmbedded(priv, 0xE7, priv->abyBBVGA[0]); 252 253 } else if (priv->byRFType == RF_UW2452) { 254 priv->abyBBVGA[0] = 0x14; 255 BBbReadEmbedded(priv, 0xE7, &byData); 256 if (byData == 0x18) { 257 BBbWriteEmbedded(priv, 0xE7, priv->abyBBVGA[0]); 258 BBbWriteEmbedded(priv, 0xE1, 0xD3); 259 } 260 } 261 BBbWriteEmbedded(priv, 0x88, 0x02); 262 bySlot = C_SLOT_LONG; 263 bySIFS = C_SIFS_BG; 264 byDIFS = C_SIFS_BG + 2*C_SLOT_LONG; 265 byCWMaxMin = 0xA5; 266 } else { /* PK_TYPE_11GA & PK_TYPE_11GB */ 267 MACvSetBBType(priv->PortOffset, BB_TYPE_11G); 268 if (priv->byRFType == RF_AIROHA7230) { 269 priv->abyBBVGA[0] = 0x1C; 270 priv->abyBBVGA[2] = 0x00; 271 priv->abyBBVGA[3] = 0x00; 272 BBbReadEmbedded(priv, 0xE7, &byData); 273 if (byData == 0x20) 274 BBbWriteEmbedded(priv, 0xE7, priv->abyBBVGA[0]); 275 276 } else if (priv->byRFType == RF_UW2452) { 277 priv->abyBBVGA[0] = 0x14; 278 BBbReadEmbedded(priv, 0xE7, &byData); 279 if (byData == 0x18) { 280 BBbWriteEmbedded(priv, 0xE7, priv->abyBBVGA[0]); 281 BBbWriteEmbedded(priv, 0xE1, 0xD3); 282 } 283 } 284 BBbWriteEmbedded(priv, 0x88, 0x08); 285 bySIFS = C_SIFS_BG; 286 287 if (priv->bShortSlotTime) { 288 bySlot = C_SLOT_SHORT; 289 byDIFS = C_SIFS_BG + 2 * C_SLOT_SHORT; 290 } else { 291 bySlot = C_SLOT_LONG; 292 byDIFS = C_SIFS_BG + 2*C_SLOT_LONG; 293 } 294 295 byCWMaxMin = 0xa4; 296 297 for (i = RATE_54M; i >= RATE_6M; i--) { 298 if (priv->basic_rates & ((u32)(0x1 << i))) { 299 byCWMaxMin |= 0x1; 300 break; 301 } 302 } 303 } 304 305 if (priv->byRFType == RF_RFMD2959) { 306 /* 307 * bcs TX_PE will reserve 3 us hardware's processing 308 * time here is 2 us. 309 */ 310 bySIFS -= 3; 311 byDIFS -= 3; 312 /* 313 * TX_PE will reserve 3 us for MAX2829 A mode only, it is for 314 * better TX throughput; MAC will need 2 us to process, so the 315 * SIFS, DIFS can be shorter by 2 us. 316 */ 317 } 318 319 if (priv->bySIFS != bySIFS) { 320 priv->bySIFS = bySIFS; 321 VNSvOutPortB(priv->PortOffset + MAC_REG_SIFS, priv->bySIFS); 322 } 323 if (priv->byDIFS != byDIFS) { 324 priv->byDIFS = byDIFS; 325 VNSvOutPortB(priv->PortOffset + MAC_REG_DIFS, priv->byDIFS); 326 } 327 if (priv->byEIFS != C_EIFS) { 328 priv->byEIFS = C_EIFS; 329 VNSvOutPortB(priv->PortOffset + MAC_REG_EIFS, priv->byEIFS); 330 } 331 if (priv->bySlot != bySlot) { 332 priv->bySlot = bySlot; 333 VNSvOutPortB(priv->PortOffset + MAC_REG_SLOT, priv->bySlot); 334 335 BBvSetShortSlotTime(priv); 336 } 337 if (priv->byCWMaxMin != byCWMaxMin) { 338 priv->byCWMaxMin = byCWMaxMin; 339 VNSvOutPortB(priv->PortOffset + MAC_REG_CWMAXMIN0, 340 priv->byCWMaxMin); 341 } 342 343 priv->byPacketType = CARDbyGetPktType(priv); 344 345 CARDvSetRSPINF(priv, bb_type); 346 347 return true; 348 } 349 350 /* 351 * Description: Sync. TSF counter to BSS 352 * Get TSF offset and write to HW 353 * 354 * Parameters: 355 * In: 356 * priv - The adapter to be sync. 357 * byRxRate - data rate of receive beacon 358 * qwBSSTimestamp - Rx BCN's TSF 359 * qwLocalTSF - Local TSF 360 * Out: 361 * none 362 * 363 * Return Value: none 364 */ 365 bool CARDbUpdateTSF(struct vnt_private *priv, unsigned char byRxRate, 366 u64 qwBSSTimestamp) 367 { 368 u64 local_tsf; 369 u64 qwTSFOffset = 0; 370 371 CARDbGetCurrentTSF(priv, &local_tsf); 372 373 if (qwBSSTimestamp != local_tsf) { 374 qwTSFOffset = CARDqGetTSFOffset(byRxRate, qwBSSTimestamp, 375 local_tsf); 376 /* adjust TSF, HW's TSF add TSF Offset reg */ 377 VNSvOutPortD(priv->PortOffset + MAC_REG_TSFOFST, 378 (u32)qwTSFOffset); 379 VNSvOutPortD(priv->PortOffset + MAC_REG_TSFOFST + 4, 380 (u32)(qwTSFOffset >> 32)); 381 MACvRegBitsOn(priv->PortOffset, MAC_REG_TFTCTL, 382 TFTCTL_TSFSYNCEN); 383 } 384 return true; 385 } 386 387 /* 388 * Description: Set NIC TSF counter for first Beacon time 389 * Get NEXTTBTT from adjusted TSF and Beacon Interval 390 * 391 * Parameters: 392 * In: 393 * priv - The adapter to be set. 394 * wBeaconInterval - Beacon Interval 395 * Out: 396 * none 397 * 398 * Return Value: true if succeed; otherwise false 399 */ 400 bool CARDbSetBeaconPeriod(struct vnt_private *priv, 401 unsigned short wBeaconInterval) 402 { 403 u64 qwNextTBTT = 0; 404 405 CARDbGetCurrentTSF(priv, &qwNextTBTT); /* Get Local TSF counter */ 406 407 qwNextTBTT = CARDqGetNextTBTT(qwNextTBTT, wBeaconInterval); 408 409 /* set HW beacon interval */ 410 VNSvOutPortW(priv->PortOffset + MAC_REG_BI, wBeaconInterval); 411 priv->wBeaconInterval = wBeaconInterval; 412 /* Set NextTBTT */ 413 VNSvOutPortD(priv->PortOffset + MAC_REG_NEXTTBTT, (u32)qwNextTBTT); 414 VNSvOutPortD(priv->PortOffset + MAC_REG_NEXTTBTT + 4, 415 (u32)(qwNextTBTT >> 32)); 416 MACvRegBitsOn(priv->PortOffset, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN); 417 418 return true; 419 } 420 421 /* 422 * Description: Turn off Radio power 423 * 424 * Parameters: 425 * In: 426 * priv - The adapter to be turned off 427 * Out: 428 * none 429 * 430 * Return Value: true if success; otherwise false 431 */ 432 bool CARDbRadioPowerOff(struct vnt_private *priv) 433 { 434 bool bResult = true; 435 436 if (priv->bRadioOff) 437 return true; 438 439 switch (priv->byRFType) { 440 case RF_RFMD2959: 441 MACvWordRegBitsOff(priv->PortOffset, MAC_REG_SOFTPWRCTL, 442 SOFTPWRCTL_TXPEINV); 443 MACvWordRegBitsOn(priv->PortOffset, MAC_REG_SOFTPWRCTL, 444 SOFTPWRCTL_SWPE1); 445 break; 446 447 case RF_AIROHA: 448 case RF_AL2230S: 449 case RF_AIROHA7230: 450 MACvWordRegBitsOff(priv->PortOffset, MAC_REG_SOFTPWRCTL, 451 SOFTPWRCTL_SWPE2); 452 MACvWordRegBitsOff(priv->PortOffset, MAC_REG_SOFTPWRCTL, 453 SOFTPWRCTL_SWPE3); 454 break; 455 } 456 457 MACvRegBitsOff(priv->PortOffset, MAC_REG_HOSTCR, HOSTCR_RXON); 458 459 BBvSetDeepSleep(priv, priv->byLocalID); 460 461 priv->bRadioOff = true; 462 pr_debug("chester power off\n"); 463 MACvRegBitsOn(priv->PortOffset, MAC_REG_GPIOCTL0, 464 LED_ACTSET); /* LED issue */ 465 return bResult; 466 } 467 468 /* 469 * Description: Turn on Radio power 470 * 471 * Parameters: 472 * In: 473 * priv - The adapter to be turned on 474 * Out: 475 * none 476 * 477 * Return Value: true if success; otherwise false 478 */ 479 bool CARDbRadioPowerOn(struct vnt_private *priv) 480 { 481 bool bResult = true; 482 483 pr_debug("chester power on\n"); 484 if (priv->bRadioControlOff) { 485 if (priv->bHWRadioOff) 486 pr_debug("chester bHWRadioOff\n"); 487 if (priv->bRadioControlOff) 488 pr_debug("chester bRadioControlOff\n"); 489 return false; } 490 491 if (!priv->bRadioOff) { 492 pr_debug("chester pbRadioOff\n"); 493 return true; } 494 495 BBvExitDeepSleep(priv, priv->byLocalID); 496 497 MACvRegBitsOn(priv->PortOffset, MAC_REG_HOSTCR, HOSTCR_RXON); 498 499 switch (priv->byRFType) { 500 case RF_RFMD2959: 501 MACvWordRegBitsOn(priv->PortOffset, MAC_REG_SOFTPWRCTL, 502 SOFTPWRCTL_TXPEINV); 503 MACvWordRegBitsOff(priv->PortOffset, MAC_REG_SOFTPWRCTL, 504 SOFTPWRCTL_SWPE1); 505 break; 506 507 case RF_AIROHA: 508 case RF_AL2230S: 509 case RF_AIROHA7230: 510 MACvWordRegBitsOn(priv->PortOffset, MAC_REG_SOFTPWRCTL, 511 (SOFTPWRCTL_SWPE2 | SOFTPWRCTL_SWPE3)); 512 break; 513 } 514 515 priv->bRadioOff = false; 516 pr_debug("chester power on\n"); 517 MACvRegBitsOff(priv->PortOffset, MAC_REG_GPIOCTL0, 518 LED_ACTSET); /* LED issue */ 519 return bResult; 520 } 521 522 void 523 CARDvSafeResetTx( 524 struct vnt_private *priv 525 ) 526 { 527 unsigned int uu; 528 struct vnt_tx_desc *pCurrTD; 529 530 /* initialize TD index */ 531 priv->apTailTD[0] = priv->apCurrTD[0] = &(priv->apTD0Rings[0]); 532 priv->apTailTD[1] = priv->apCurrTD[1] = &(priv->apTD1Rings[0]); 533 534 for (uu = 0; uu < TYPE_MAXTD; uu++) 535 priv->iTDUsed[uu] = 0; 536 537 for (uu = 0; uu < priv->opts.tx_descs[0]; uu++) { 538 pCurrTD = &(priv->apTD0Rings[uu]); 539 pCurrTD->td0.owner = OWNED_BY_HOST; 540 /* init all Tx Packet pointer to NULL */ 541 } 542 for (uu = 0; uu < priv->opts.tx_descs[1]; uu++) { 543 pCurrTD = &(priv->apTD1Rings[uu]); 544 pCurrTD->td0.owner = OWNED_BY_HOST; 545 /* init all Tx Packet pointer to NULL */ 546 } 547 548 /* set MAC TD pointer */ 549 MACvSetCurrTXDescAddr(TYPE_TXDMA0, priv, priv->td0_pool_dma); 550 551 MACvSetCurrTXDescAddr(TYPE_AC0DMA, priv, priv->td1_pool_dma); 552 553 /* set MAC Beacon TX pointer */ 554 MACvSetCurrBCNTxDescAddr(priv->PortOffset, 555 (priv->tx_beacon_dma)); 556 } 557 558 /* 559 * Description: 560 * Reset Rx 561 * 562 * Parameters: 563 * In: 564 * priv - Pointer to the adapter 565 * Out: 566 * none 567 * 568 * Return Value: none 569 */ 570 void 571 CARDvSafeResetRx( 572 struct vnt_private *priv 573 ) 574 { 575 unsigned int uu; 576 struct vnt_rx_desc *pDesc; 577 578 /* initialize RD index */ 579 priv->pCurrRD[0] = &(priv->aRD0Ring[0]); 580 priv->pCurrRD[1] = &(priv->aRD1Ring[0]); 581 582 /* init state, all RD is chip's */ 583 for (uu = 0; uu < priv->opts.rx_descs0; uu++) { 584 pDesc = &(priv->aRD0Ring[uu]); 585 pDesc->rd0.res_count = cpu_to_le16(priv->rx_buf_sz); 586 pDesc->rd0.owner = OWNED_BY_NIC; 587 pDesc->rd1.req_count = cpu_to_le16(priv->rx_buf_sz); 588 } 589 590 /* init state, all RD is chip's */ 591 for (uu = 0; uu < priv->opts.rx_descs1; uu++) { 592 pDesc = &(priv->aRD1Ring[uu]); 593 pDesc->rd0.res_count = cpu_to_le16(priv->rx_buf_sz); 594 pDesc->rd0.owner = OWNED_BY_NIC; 595 pDesc->rd1.req_count = cpu_to_le16(priv->rx_buf_sz); 596 } 597 598 /* set perPkt mode */ 599 MACvRx0PerPktMode(priv->PortOffset); 600 MACvRx1PerPktMode(priv->PortOffset); 601 /* set MAC RD pointer */ 602 MACvSetCurrRx0DescAddr(priv, priv->rd0_pool_dma); 603 604 MACvSetCurrRx1DescAddr(priv, priv->rd1_pool_dma); 605 } 606 607 /* 608 * Description: Get response Control frame rate in CCK mode 609 * 610 * Parameters: 611 * In: 612 * priv - The adapter to be set 613 * wRateIdx - Receiving data rate 614 * Out: 615 * none 616 * 617 * Return Value: response Control frame rate 618 */ 619 static unsigned short CARDwGetCCKControlRate(struct vnt_private *priv, 620 unsigned short wRateIdx) 621 { 622 unsigned int ui = (unsigned int) wRateIdx; 623 624 while (ui > RATE_1M) { 625 if (priv->basic_rates & ((u32)0x1 << ui)) 626 return (unsigned short)ui; 627 628 ui--; 629 } 630 return (unsigned short)RATE_1M; 631 } 632 633 /* 634 * Description: Get response Control frame rate in OFDM mode 635 * 636 * Parameters: 637 * In: 638 * priv - The adapter to be set 639 * wRateIdx - Receiving data rate 640 * Out: 641 * none 642 * 643 * Return Value: response Control frame rate 644 */ 645 static unsigned short CARDwGetOFDMControlRate(struct vnt_private *priv, 646 unsigned short wRateIdx) 647 { 648 unsigned int ui = (unsigned int) wRateIdx; 649 650 pr_debug("BASIC RATE: %X\n", priv->basic_rates); 651 652 if (!CARDbIsOFDMinBasicRate((void *)priv)) { 653 pr_debug("CARDwGetOFDMControlRate:(NO OFDM) %d\n", wRateIdx); 654 if (wRateIdx > RATE_24M) 655 wRateIdx = RATE_24M; 656 return wRateIdx; 657 } 658 while (ui > RATE_11M) { 659 if (priv->basic_rates & ((u32)0x1 << ui)) { 660 pr_debug("CARDwGetOFDMControlRate : %d\n", ui); 661 return (unsigned short)ui; 662 } 663 ui--; 664 } 665 pr_debug("CARDwGetOFDMControlRate: 6M\n"); 666 return (unsigned short)RATE_24M; 667 } 668 669 /* 670 * Description: Set RSPINF 671 * 672 * Parameters: 673 * In: 674 * priv - The adapter to be set 675 * Out: 676 * none 677 * 678 * Return Value: None. 679 */ 680 void CARDvSetRSPINF(struct vnt_private *priv, u8 bb_type) 681 { 682 union vnt_phy_field_swap phy; 683 unsigned char byTxRate, byRsvTime; /* For OFDM */ 684 unsigned long flags; 685 686 spin_lock_irqsave(&priv->lock, flags); 687 688 /* Set to Page1 */ 689 MACvSelectPage1(priv->PortOffset); 690 691 /* RSPINF_b_1 */ 692 vnt_get_phy_field(priv, 14, 693 CARDwGetCCKControlRate(priv, RATE_1M), 694 PK_TYPE_11B, &phy.field_read); 695 696 /* swap over to get correct write order */ 697 swap(phy.swap[0], phy.swap[1]); 698 699 VNSvOutPortD(priv->PortOffset + MAC_REG_RSPINF_B_1, phy.field_write); 700 701 /* RSPINF_b_2 */ 702 vnt_get_phy_field(priv, 14, 703 CARDwGetCCKControlRate(priv, RATE_2M), 704 PK_TYPE_11B, &phy.field_read); 705 706 swap(phy.swap[0], phy.swap[1]); 707 708 VNSvOutPortD(priv->PortOffset + MAC_REG_RSPINF_B_2, phy.field_write); 709 710 /* RSPINF_b_5 */ 711 vnt_get_phy_field(priv, 14, 712 CARDwGetCCKControlRate(priv, RATE_5M), 713 PK_TYPE_11B, &phy.field_read); 714 715 swap(phy.swap[0], phy.swap[1]); 716 717 VNSvOutPortD(priv->PortOffset + MAC_REG_RSPINF_B_5, phy.field_write); 718 719 /* RSPINF_b_11 */ 720 vnt_get_phy_field(priv, 14, 721 CARDwGetCCKControlRate(priv, RATE_11M), 722 PK_TYPE_11B, &phy.field_read); 723 724 swap(phy.swap[0], phy.swap[1]); 725 726 VNSvOutPortD(priv->PortOffset + MAC_REG_RSPINF_B_11, phy.field_write); 727 728 /* RSPINF_a_6 */ 729 s_vCalculateOFDMRParameter(RATE_6M, 730 bb_type, 731 &byTxRate, 732 &byRsvTime); 733 VNSvOutPortW(priv->PortOffset + MAC_REG_RSPINF_A_6, 734 MAKEWORD(byTxRate, byRsvTime)); 735 /* RSPINF_a_9 */ 736 s_vCalculateOFDMRParameter(RATE_9M, 737 bb_type, 738 &byTxRate, 739 &byRsvTime); 740 VNSvOutPortW(priv->PortOffset + MAC_REG_RSPINF_A_9, 741 MAKEWORD(byTxRate, byRsvTime)); 742 /* RSPINF_a_12 */ 743 s_vCalculateOFDMRParameter(RATE_12M, 744 bb_type, 745 &byTxRate, 746 &byRsvTime); 747 VNSvOutPortW(priv->PortOffset + MAC_REG_RSPINF_A_12, 748 MAKEWORD(byTxRate, byRsvTime)); 749 /* RSPINF_a_18 */ 750 s_vCalculateOFDMRParameter(RATE_18M, 751 bb_type, 752 &byTxRate, 753 &byRsvTime); 754 VNSvOutPortW(priv->PortOffset + MAC_REG_RSPINF_A_18, 755 MAKEWORD(byTxRate, byRsvTime)); 756 /* RSPINF_a_24 */ 757 s_vCalculateOFDMRParameter(RATE_24M, 758 bb_type, 759 &byTxRate, 760 &byRsvTime); 761 VNSvOutPortW(priv->PortOffset + MAC_REG_RSPINF_A_24, 762 MAKEWORD(byTxRate, byRsvTime)); 763 /* RSPINF_a_36 */ 764 s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate( 765 (void *)priv, 766 RATE_36M), 767 bb_type, 768 &byTxRate, 769 &byRsvTime); 770 VNSvOutPortW(priv->PortOffset + MAC_REG_RSPINF_A_36, 771 MAKEWORD(byTxRate, byRsvTime)); 772 /* RSPINF_a_48 */ 773 s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate( 774 (void *)priv, 775 RATE_48M), 776 bb_type, 777 &byTxRate, 778 &byRsvTime); 779 VNSvOutPortW(priv->PortOffset + MAC_REG_RSPINF_A_48, 780 MAKEWORD(byTxRate, byRsvTime)); 781 /* RSPINF_a_54 */ 782 s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate( 783 (void *)priv, 784 RATE_54M), 785 bb_type, 786 &byTxRate, 787 &byRsvTime); 788 VNSvOutPortW(priv->PortOffset + MAC_REG_RSPINF_A_54, 789 MAKEWORD(byTxRate, byRsvTime)); 790 /* RSPINF_a_72 */ 791 s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate( 792 (void *)priv, 793 RATE_54M), 794 bb_type, 795 &byTxRate, 796 &byRsvTime); 797 VNSvOutPortW(priv->PortOffset + MAC_REG_RSPINF_A_72, 798 MAKEWORD(byTxRate, byRsvTime)); 799 /* Set to Page0 */ 800 MACvSelectPage0(priv->PortOffset); 801 802 spin_unlock_irqrestore(&priv->lock, flags); 803 } 804 805 void CARDvUpdateBasicTopRate(struct vnt_private *priv) 806 { 807 unsigned char byTopOFDM = RATE_24M, byTopCCK = RATE_1M; 808 unsigned char ii; 809 810 /* Determines the highest basic rate. */ 811 for (ii = RATE_54M; ii >= RATE_6M; ii--) { 812 if ((priv->basic_rates) & ((u32)(1 << ii))) { 813 byTopOFDM = ii; 814 break; 815 } 816 } 817 priv->byTopOFDMBasicRate = byTopOFDM; 818 819 for (ii = RATE_11M;; ii--) { 820 if ((priv->basic_rates) & ((u32)(1 << ii))) { 821 byTopCCK = ii; 822 break; 823 } 824 if (ii == RATE_1M) 825 break; 826 } 827 priv->byTopCCKBasicRate = byTopCCK; 828 } 829 830 bool CARDbIsOFDMinBasicRate(struct vnt_private *priv) 831 { 832 int ii; 833 834 for (ii = RATE_54M; ii >= RATE_6M; ii--) { 835 if ((priv->basic_rates) & ((u32)BIT(ii))) 836 return true; 837 } 838 return false; 839 } 840 841 unsigned char CARDbyGetPktType(struct vnt_private *priv) 842 { 843 if (priv->byBBType == BB_TYPE_11A || priv->byBBType == BB_TYPE_11B) 844 return (unsigned char)priv->byBBType; 845 else if (CARDbIsOFDMinBasicRate((void *)priv)) 846 return PK_TYPE_11GA; 847 else 848 return PK_TYPE_11GB; 849 } 850 851 /* 852 * Description: Set NIC Loopback mode 853 * 854 * Parameters: 855 * In: 856 * priv - The adapter to be set 857 * wLoopbackMode - Loopback mode to be set 858 * Out: 859 * none 860 * 861 * Return Value: none 862 */ 863 void CARDvSetLoopbackMode(struct vnt_private *priv, 864 unsigned short wLoopbackMode) 865 { 866 switch (wLoopbackMode) { 867 case CARD_LB_NONE: 868 case CARD_LB_MAC: 869 case CARD_LB_PHY: 870 break; 871 default: 872 break; 873 } 874 /* set MAC loopback */ 875 MACvSetLoopbackMode(priv, LOBYTE(wLoopbackMode)); 876 /* set Baseband loopback */ 877 } 878 879 /* 880 * Description: Software Reset NIC 881 * 882 * Parameters: 883 * In: 884 * priv - The adapter to be reset 885 * Out: 886 * none 887 * 888 * Return Value: none 889 */ 890 bool CARDbSoftwareReset(struct vnt_private *priv) 891 { 892 /* reset MAC */ 893 if (!MACbSafeSoftwareReset(priv)) 894 return false; 895 896 return true; 897 } 898 899 /* 900 * Description: Calculate TSF offset of two TSF input 901 * Get TSF Offset from RxBCN's TSF and local TSF 902 * 903 * Parameters: 904 * In: 905 * priv - The adapter to be sync. 906 * qwTSF1 - Rx BCN's TSF 907 * qwTSF2 - Local TSF 908 * Out: 909 * none 910 * 911 * Return Value: TSF Offset value 912 */ 913 u64 CARDqGetTSFOffset(unsigned char byRxRate, u64 qwTSF1, u64 qwTSF2) 914 { 915 u64 qwTSFOffset = 0; 916 unsigned short wRxBcnTSFOffst; 917 918 wRxBcnTSFOffst = cwRXBCNTSFOff[byRxRate%MAX_RATE]; 919 920 qwTSF2 += (u64)wRxBcnTSFOffst; 921 922 qwTSFOffset = qwTSF1 - qwTSF2; 923 924 return qwTSFOffset; 925 } 926 927 /* 928 * Description: Read NIC TSF counter 929 * Get local TSF counter 930 * 931 * Parameters: 932 * In: 933 * priv - The adapter to be read 934 * Out: 935 * qwCurrTSF - Current TSF counter 936 * 937 * Return Value: true if success; otherwise false 938 */ 939 bool CARDbGetCurrentTSF(struct vnt_private *priv, u64 *pqwCurrTSF) 940 { 941 void __iomem *dwIoBase = priv->PortOffset; 942 unsigned short ww; 943 unsigned char byData; 944 945 MACvRegBitsOn(dwIoBase, MAC_REG_TFTCTL, TFTCTL_TSFCNTRRD); 946 for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { 947 VNSvInPortB(dwIoBase + MAC_REG_TFTCTL, &byData); 948 if (!(byData & TFTCTL_TSFCNTRRD)) 949 break; 950 } 951 if (ww == W_MAX_TIMEOUT) 952 return false; 953 VNSvInPortD(dwIoBase + MAC_REG_TSFCNTR, (u32 *)pqwCurrTSF); 954 VNSvInPortD(dwIoBase + MAC_REG_TSFCNTR + 4, (u32 *)pqwCurrTSF + 1); 955 956 return true; 957 } 958 959 /* 960 * Description: Read NIC TSF counter 961 * Get NEXTTBTT from adjusted TSF and Beacon Interval 962 * 963 * Parameters: 964 * In: 965 * qwTSF - Current TSF counter 966 * wbeaconInterval - Beacon Interval 967 * Out: 968 * qwCurrTSF - Current TSF counter 969 * 970 * Return Value: TSF value of next Beacon 971 */ 972 u64 CARDqGetNextTBTT(u64 qwTSF, unsigned short wBeaconInterval) 973 { 974 u32 beacon_int; 975 976 beacon_int = wBeaconInterval * 1024; 977 if (beacon_int) { 978 do_div(qwTSF, beacon_int); 979 qwTSF += 1; 980 qwTSF *= beacon_int; 981 } 982 983 return qwTSF; 984 } 985 986 /* 987 * Description: Set NIC TSF counter for first Beacon time 988 * Get NEXTTBTT from adjusted TSF and Beacon Interval 989 * 990 * Parameters: 991 * In: 992 * dwIoBase - IO Base 993 * wBeaconInterval - Beacon Interval 994 * Out: 995 * none 996 * 997 * Return Value: none 998 */ 999 void CARDvSetFirstNextTBTT(struct vnt_private *priv, 1000 unsigned short wBeaconInterval) 1001 { 1002 void __iomem *dwIoBase = priv->PortOffset; 1003 u64 qwNextTBTT = 0; 1004 1005 CARDbGetCurrentTSF(priv, &qwNextTBTT); /* Get Local TSF counter */ 1006 1007 qwNextTBTT = CARDqGetNextTBTT(qwNextTBTT, wBeaconInterval); 1008 /* Set NextTBTT */ 1009 VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT, (u32)qwNextTBTT); 1010 VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT + 4, (u32)(qwNextTBTT >> 32)); 1011 MACvRegBitsOn(dwIoBase, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN); 1012 } 1013 1014 /* 1015 * Description: Sync NIC TSF counter for Beacon time 1016 * Get NEXTTBTT and write to HW 1017 * 1018 * Parameters: 1019 * In: 1020 * priv - The adapter to be set 1021 * qwTSF - Current TSF counter 1022 * wBeaconInterval - Beacon Interval 1023 * Out: 1024 * none 1025 * 1026 * Return Value: none 1027 */ 1028 void CARDvUpdateNextTBTT(struct vnt_private *priv, u64 qwTSF, 1029 unsigned short wBeaconInterval) 1030 { 1031 void __iomem *dwIoBase = priv->PortOffset; 1032 1033 qwTSF = CARDqGetNextTBTT(qwTSF, wBeaconInterval); 1034 /* Set NextTBTT */ 1035 VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT, (u32)qwTSF); 1036 VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT + 4, (u32)(qwTSF >> 32)); 1037 MACvRegBitsOn(dwIoBase, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN); 1038 pr_debug("Card:Update Next TBTT[%8llx]\n", qwTSF); 1039 } 1040