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