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 53 static const unsigned short cwRXBCNTSFOff[MAX_RATE] = { 54 17, 17, 17, 17, 34, 23, 17, 11, 8, 5, 4, 3}; 55 56 /*--------------------- Static Functions --------------------------*/ 57 58 static 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 */ 77 static 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 */ 179 bool 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 */ 284 bool 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 qwTSFOffset = le64_to_cpu(qwTSFOffset); 297 iowrite32((u32)qwTSFOffset, priv->port_offset + MAC_REG_TSFOFST); 298 iowrite32((u32)(qwTSFOffset >> 32), priv->port_offset + MAC_REG_TSFOFST + 4); 299 vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_TFTCTL, TFTCTL_TSFSYNCEN); 300 } 301 return true; 302 } 303 304 /* 305 * Description: Set NIC TSF counter for first Beacon time 306 * Get NEXTTBTT from adjusted TSF and Beacon Interval 307 * 308 * Parameters: 309 * In: 310 * priv - The adapter to be set. 311 * wBeaconInterval - Beacon Interval 312 * Out: 313 * none 314 * 315 * Return Value: true if succeed; otherwise false 316 */ 317 bool CARDbSetBeaconPeriod(struct vnt_private *priv, 318 unsigned short wBeaconInterval) 319 { 320 u64 qwNextTBTT; 321 322 qwNextTBTT = vt6655_get_current_tsf(priv); /* Get Local TSF counter */ 323 324 qwNextTBTT = CARDqGetNextTBTT(qwNextTBTT, wBeaconInterval); 325 326 /* set HW beacon interval */ 327 iowrite16(wBeaconInterval, priv->port_offset + MAC_REG_BI); 328 priv->wBeaconInterval = wBeaconInterval; 329 /* Set NextTBTT */ 330 qwNextTBTT = le64_to_cpu(qwNextTBTT); 331 iowrite32((u32)qwNextTBTT, priv->port_offset + MAC_REG_NEXTTBTT); 332 iowrite32((u32)(qwNextTBTT >> 32), priv->port_offset + MAC_REG_NEXTTBTT + 4); 333 vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN); 334 335 return true; 336 } 337 338 /* 339 * Description: Turn off Radio power 340 * 341 * Parameters: 342 * In: 343 * priv - The adapter to be turned off 344 * Out: 345 * none 346 * 347 */ 348 void CARDbRadioPowerOff(struct vnt_private *priv) 349 { 350 if (priv->radio_off) 351 return; 352 353 switch (priv->byRFType) { 354 case RF_RFMD2959: 355 vt6655_mac_word_reg_bits_off(priv->port_offset, MAC_REG_SOFTPWRCTL, 356 SOFTPWRCTL_TXPEINV); 357 vt6655_mac_word_reg_bits_on(priv->port_offset, MAC_REG_SOFTPWRCTL, 358 SOFTPWRCTL_SWPE1); 359 break; 360 361 case RF_AIROHA: 362 case RF_AL2230S: 363 vt6655_mac_word_reg_bits_off(priv->port_offset, MAC_REG_SOFTPWRCTL, 364 SOFTPWRCTL_SWPE2); 365 vt6655_mac_word_reg_bits_off(priv->port_offset, MAC_REG_SOFTPWRCTL, 366 SOFTPWRCTL_SWPE3); 367 break; 368 } 369 370 vt6655_mac_reg_bits_off(priv->port_offset, MAC_REG_HOSTCR, HOSTCR_RXON); 371 372 bb_set_deep_sleep(priv, priv->local_id); 373 374 priv->radio_off = true; 375 pr_debug("chester power off\n"); 376 vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_GPIOCTL0, LED_ACTSET); /* LED issue */ 377 } 378 379 void CARDvSafeResetTx(struct vnt_private *priv) 380 { 381 unsigned int uu; 382 struct vnt_tx_desc *pCurrTD; 383 384 /* initialize TD index */ 385 priv->apTailTD[0] = &priv->apTD0Rings[0]; 386 priv->apCurrTD[0] = &priv->apTD0Rings[0]; 387 388 priv->apTailTD[1] = &priv->apTD1Rings[0]; 389 priv->apCurrTD[1] = &priv->apTD1Rings[0]; 390 391 for (uu = 0; uu < TYPE_MAXTD; uu++) 392 priv->iTDUsed[uu] = 0; 393 394 for (uu = 0; uu < priv->opts.tx_descs[0]; uu++) { 395 pCurrTD = &priv->apTD0Rings[uu]; 396 pCurrTD->td0.owner = OWNED_BY_HOST; 397 /* init all Tx Packet pointer to NULL */ 398 } 399 for (uu = 0; uu < priv->opts.tx_descs[1]; uu++) { 400 pCurrTD = &priv->apTD1Rings[uu]; 401 pCurrTD->td0.owner = OWNED_BY_HOST; 402 /* init all Tx Packet pointer to NULL */ 403 } 404 405 /* set MAC TD pointer */ 406 MACvSetCurrTXDescAddr(TYPE_TXDMA0, priv, priv->td0_pool_dma); 407 408 MACvSetCurrTXDescAddr(TYPE_AC0DMA, priv, priv->td1_pool_dma); 409 410 /* set MAC Beacon TX pointer */ 411 iowrite32((u32)priv->tx_beacon_dma, priv->port_offset + MAC_REG_BCNDMAPTR); 412 } 413 414 /* 415 * Description: 416 * Reset Rx 417 * 418 * Parameters: 419 * In: 420 * priv - Pointer to the adapter 421 * Out: 422 * none 423 * 424 * Return Value: none 425 */ 426 void CARDvSafeResetRx(struct vnt_private *priv) 427 { 428 unsigned int uu; 429 struct vnt_rx_desc *pDesc; 430 431 /* initialize RD index */ 432 priv->pCurrRD[0] = &priv->aRD0Ring[0]; 433 priv->pCurrRD[1] = &priv->aRD1Ring[0]; 434 435 /* init state, all RD is chip's */ 436 for (uu = 0; uu < priv->opts.rx_descs0; uu++) { 437 pDesc = &priv->aRD0Ring[uu]; 438 pDesc->rd0.res_count = cpu_to_le16(priv->rx_buf_sz); 439 pDesc->rd0.owner = OWNED_BY_NIC; 440 pDesc->rd1.req_count = cpu_to_le16(priv->rx_buf_sz); 441 } 442 443 /* init state, all RD is chip's */ 444 for (uu = 0; uu < priv->opts.rx_descs1; uu++) { 445 pDesc = &priv->aRD1Ring[uu]; 446 pDesc->rd0.res_count = cpu_to_le16(priv->rx_buf_sz); 447 pDesc->rd0.owner = OWNED_BY_NIC; 448 pDesc->rd1.req_count = cpu_to_le16(priv->rx_buf_sz); 449 } 450 451 /* set perPkt mode */ 452 iowrite32(RX_PERPKT, priv->port_offset + MAC_REG_RXDMACTL0); 453 iowrite32(RX_PERPKT, priv->port_offset + MAC_REG_RXDMACTL1); 454 /* set MAC RD pointer */ 455 MACvSetCurrRx0DescAddr(priv, priv->rd0_pool_dma); 456 457 MACvSetCurrRx1DescAddr(priv, priv->rd1_pool_dma); 458 } 459 460 /* 461 * Description: Get response Control frame rate in CCK mode 462 * 463 * Parameters: 464 * In: 465 * priv - The adapter to be set 466 * wRateIdx - Receiving data rate 467 * Out: 468 * none 469 * 470 * Return Value: response Control frame rate 471 */ 472 static unsigned short CARDwGetCCKControlRate(struct vnt_private *priv, 473 unsigned short wRateIdx) 474 { 475 unsigned int ui = (unsigned int)wRateIdx; 476 477 while (ui > RATE_1M) { 478 if (priv->basic_rates & ((u32)0x1 << ui)) 479 return (unsigned short)ui; 480 481 ui--; 482 } 483 return (unsigned short)RATE_1M; 484 } 485 486 /* 487 * Description: Get response Control frame rate in OFDM mode 488 * 489 * Parameters: 490 * In: 491 * priv - The adapter to be set 492 * wRateIdx - Receiving data rate 493 * Out: 494 * none 495 * 496 * Return Value: response Control frame rate 497 */ 498 static unsigned short CARDwGetOFDMControlRate(struct vnt_private *priv, 499 unsigned short wRateIdx) 500 { 501 unsigned int ui = (unsigned int)wRateIdx; 502 503 pr_debug("BASIC RATE: %X\n", priv->basic_rates); 504 505 if (!CARDbIsOFDMinBasicRate((void *)priv)) { 506 pr_debug("%s:(NO OFDM) %d\n", __func__, wRateIdx); 507 if (wRateIdx > RATE_24M) 508 wRateIdx = RATE_24M; 509 return wRateIdx; 510 } 511 while (ui > RATE_11M) { 512 if (priv->basic_rates & ((u32)0x1 << ui)) { 513 pr_debug("%s : %d\n", __func__, ui); 514 return (unsigned short)ui; 515 } 516 ui--; 517 } 518 pr_debug("%s: 6M\n", __func__); 519 return (unsigned short)RATE_24M; 520 } 521 522 /* 523 * Description: Set RSPINF 524 * 525 * Parameters: 526 * In: 527 * priv - The adapter to be set 528 * Out: 529 * none 530 * 531 * Return Value: None. 532 */ 533 void CARDvSetRSPINF(struct vnt_private *priv, u8 bb_type) 534 { 535 union vnt_phy_field_swap phy; 536 unsigned char byTxRate, byRsvTime; /* For OFDM */ 537 unsigned long flags; 538 539 spin_lock_irqsave(&priv->lock, flags); 540 541 /* Set to Page1 */ 542 MACvSelectPage1(priv->port_offset); 543 544 /* RSPINF_b_1 */ 545 vnt_get_phy_field(priv, 14, 546 CARDwGetCCKControlRate(priv, RATE_1M), 547 PK_TYPE_11B, &phy.field_read); 548 549 /* swap over to get correct write order */ 550 swap(phy.swap[0], phy.swap[1]); 551 552 iowrite32(phy.field_write, priv->port_offset + MAC_REG_RSPINF_B_1); 553 554 /* RSPINF_b_2 */ 555 vnt_get_phy_field(priv, 14, 556 CARDwGetCCKControlRate(priv, RATE_2M), 557 PK_TYPE_11B, &phy.field_read); 558 559 swap(phy.swap[0], phy.swap[1]); 560 561 iowrite32(phy.field_write, priv->port_offset + MAC_REG_RSPINF_B_2); 562 563 /* RSPINF_b_5 */ 564 vnt_get_phy_field(priv, 14, 565 CARDwGetCCKControlRate(priv, RATE_5M), 566 PK_TYPE_11B, &phy.field_read); 567 568 swap(phy.swap[0], phy.swap[1]); 569 570 iowrite32(phy.field_write, priv->port_offset + MAC_REG_RSPINF_B_5); 571 572 /* RSPINF_b_11 */ 573 vnt_get_phy_field(priv, 14, 574 CARDwGetCCKControlRate(priv, RATE_11M), 575 PK_TYPE_11B, &phy.field_read); 576 577 swap(phy.swap[0], phy.swap[1]); 578 579 iowrite32(phy.field_write, priv->port_offset + MAC_REG_RSPINF_B_11); 580 581 /* RSPINF_a_6 */ 582 s_vCalculateOFDMRParameter(RATE_6M, 583 bb_type, 584 &byTxRate, 585 &byRsvTime); 586 iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_6); 587 /* RSPINF_a_9 */ 588 s_vCalculateOFDMRParameter(RATE_9M, 589 bb_type, 590 &byTxRate, 591 &byRsvTime); 592 iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_9); 593 /* RSPINF_a_12 */ 594 s_vCalculateOFDMRParameter(RATE_12M, 595 bb_type, 596 &byTxRate, 597 &byRsvTime); 598 iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_12); 599 /* RSPINF_a_18 */ 600 s_vCalculateOFDMRParameter(RATE_18M, 601 bb_type, 602 &byTxRate, 603 &byRsvTime); 604 iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_18); 605 /* RSPINF_a_24 */ 606 s_vCalculateOFDMRParameter(RATE_24M, 607 bb_type, 608 &byTxRate, 609 &byRsvTime); 610 iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_24); 611 /* RSPINF_a_36 */ 612 s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)priv, 613 RATE_36M), 614 bb_type, 615 &byTxRate, 616 &byRsvTime); 617 iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_36); 618 /* RSPINF_a_48 */ 619 s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)priv, 620 RATE_48M), 621 bb_type, 622 &byTxRate, 623 &byRsvTime); 624 iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_48); 625 /* RSPINF_a_54 */ 626 s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)priv, 627 RATE_54M), 628 bb_type, 629 &byTxRate, 630 &byRsvTime); 631 iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_54); 632 /* RSPINF_a_72 */ 633 s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)priv, 634 RATE_54M), 635 bb_type, 636 &byTxRate, 637 &byRsvTime); 638 iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_72); 639 /* Set to Page0 */ 640 MACvSelectPage0(priv->port_offset); 641 642 spin_unlock_irqrestore(&priv->lock, flags); 643 } 644 645 void CARDvUpdateBasicTopRate(struct vnt_private *priv) 646 { 647 unsigned char byTopOFDM = RATE_24M, byTopCCK = RATE_1M; 648 unsigned char ii; 649 650 /* Determines the highest basic rate. */ 651 for (ii = RATE_54M; ii >= RATE_6M; ii--) { 652 if ((priv->basic_rates) & ((u32)(1 << ii))) { 653 byTopOFDM = ii; 654 break; 655 } 656 } 657 priv->byTopOFDMBasicRate = byTopOFDM; 658 659 for (ii = RATE_11M;; ii--) { 660 if ((priv->basic_rates) & ((u32)(1 << ii))) { 661 byTopCCK = ii; 662 break; 663 } 664 if (ii == RATE_1M) 665 break; 666 } 667 priv->byTopCCKBasicRate = byTopCCK; 668 } 669 670 bool CARDbIsOFDMinBasicRate(struct vnt_private *priv) 671 { 672 int ii; 673 674 for (ii = RATE_54M; ii >= RATE_6M; ii--) { 675 if ((priv->basic_rates) & ((u32)BIT(ii))) 676 return true; 677 } 678 return false; 679 } 680 681 unsigned char CARDbyGetPktType(struct vnt_private *priv) 682 { 683 if (priv->byBBType == BB_TYPE_11A || priv->byBBType == BB_TYPE_11B) 684 return (unsigned char)priv->byBBType; 685 else if (CARDbIsOFDMinBasicRate((void *)priv)) 686 return PK_TYPE_11GA; 687 else 688 return PK_TYPE_11GB; 689 } 690 691 /* 692 * Description: Calculate TSF offset of two TSF input 693 * Get TSF Offset from RxBCN's TSF and local TSF 694 * 695 * Parameters: 696 * In: 697 * priv - The adapter to be sync. 698 * qwTSF1 - Rx BCN's TSF 699 * qwTSF2 - Local TSF 700 * Out: 701 * none 702 * 703 * Return Value: TSF Offset value 704 */ 705 u64 CARDqGetTSFOffset(unsigned char byRxRate, u64 qwTSF1, u64 qwTSF2) 706 { 707 unsigned short wRxBcnTSFOffst; 708 709 wRxBcnTSFOffst = cwRXBCNTSFOff[byRxRate % MAX_RATE]; 710 711 qwTSF2 += (u64)wRxBcnTSFOffst; 712 713 return qwTSF1 - qwTSF2; 714 } 715 716 /* 717 * Description: Read NIC TSF counter 718 * Get local TSF counter 719 * 720 * Parameters: 721 * In: 722 * priv - The adapter to be read 723 * Out: 724 * none 725 * 726 * Return Value: Current TSF counter 727 */ 728 u64 vt6655_get_current_tsf(struct vnt_private *priv) 729 { 730 void __iomem *iobase = priv->port_offset; 731 unsigned short ww; 732 unsigned char data; 733 u32 low, high; 734 735 vt6655_mac_reg_bits_on(iobase, MAC_REG_TFTCTL, TFTCTL_TSFCNTRRD); 736 for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { 737 data = ioread8(iobase + MAC_REG_TFTCTL); 738 if (!(data & TFTCTL_TSFCNTRRD)) 739 break; 740 } 741 if (ww == W_MAX_TIMEOUT) 742 return 0; 743 low = ioread32(iobase + MAC_REG_TSFCNTR); 744 high = ioread32(iobase + MAC_REG_TSFCNTR + 4); 745 return le64_to_cpu(low + ((u64)high << 32)); 746 } 747 748 /* 749 * Description: Read NIC TSF counter 750 * Get NEXTTBTT from adjusted TSF and Beacon Interval 751 * 752 * Parameters: 753 * In: 754 * qwTSF - Current TSF counter 755 * wbeaconInterval - Beacon Interval 756 * Out: 757 * qwCurrTSF - Current TSF counter 758 * 759 * Return Value: TSF value of next Beacon 760 */ 761 u64 CARDqGetNextTBTT(u64 qwTSF, unsigned short wBeaconInterval) 762 { 763 u32 beacon_int; 764 765 beacon_int = wBeaconInterval * 1024; 766 if (beacon_int) { 767 do_div(qwTSF, beacon_int); 768 qwTSF += 1; 769 qwTSF *= beacon_int; 770 } 771 772 return qwTSF; 773 } 774 775 /* 776 * Description: Set NIC TSF counter for first Beacon time 777 * Get NEXTTBTT from adjusted TSF and Beacon Interval 778 * 779 * Parameters: 780 * In: 781 * iobase - IO Base 782 * wBeaconInterval - Beacon Interval 783 * Out: 784 * none 785 * 786 * Return Value: none 787 */ 788 void CARDvSetFirstNextTBTT(struct vnt_private *priv, 789 unsigned short wBeaconInterval) 790 { 791 void __iomem *iobase = priv->port_offset; 792 u64 qwNextTBTT; 793 794 qwNextTBTT = vt6655_get_current_tsf(priv); /* Get Local TSF counter */ 795 796 qwNextTBTT = CARDqGetNextTBTT(qwNextTBTT, wBeaconInterval); 797 /* Set NextTBTT */ 798 qwNextTBTT = le64_to_cpu(qwNextTBTT); 799 iowrite32((u32)qwNextTBTT, iobase + MAC_REG_NEXTTBTT); 800 iowrite32((u32)(qwNextTBTT >> 32), iobase + MAC_REG_NEXTTBTT + 4); 801 vt6655_mac_reg_bits_on(iobase, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN); 802 } 803 804 /* 805 * Description: Sync NIC TSF counter for Beacon time 806 * Get NEXTTBTT and write to HW 807 * 808 * Parameters: 809 * In: 810 * priv - The adapter to be set 811 * qwTSF - Current TSF counter 812 * wBeaconInterval - Beacon Interval 813 * Out: 814 * none 815 * 816 * Return Value: none 817 */ 818 void CARDvUpdateNextTBTT(struct vnt_private *priv, u64 qwTSF, 819 unsigned short wBeaconInterval) 820 { 821 void __iomem *iobase = priv->port_offset; 822 823 qwTSF = CARDqGetNextTBTT(qwTSF, wBeaconInterval); 824 /* Set NextTBTT */ 825 qwTSF = le64_to_cpu(qwTSF); 826 iowrite32((u32)qwTSF, iobase + MAC_REG_NEXTTBTT); 827 iowrite32((u32)(qwTSF >> 32), iobase + MAC_REG_NEXTTBTT + 4); 828 vt6655_mac_reg_bits_on(iobase, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN); 829 pr_debug("Card:Update Next TBTT[%8llx]\n", qwTSF); 830 } 831