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