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