Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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