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