837 lines · c
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 mode7 * Functions:8 * s_vSafeResetTx - Rest Tx9 * card_set_rspinf - Set RSPINF10 * CARDvUpdateBasicTopRate - Update BasicTopRate11 * CARDbAddBasicRate - Add to BasicRateSet12 * CARDbIsOFDMinBasicRate - Check if any OFDM rate is in BasicRateSet13 * card_get_tsf_offset - Calculate TSFOffset14 * vt6655_get_current_tsf - Read Current NIC TSF counter15 * card_get_next_tbtt - Calculate Next Beacon TSF counter16 * CARDvSetFirstNextTBTT - Set NIC Beacon time17 * CARDvUpdateNextTBTT - Sync. NIC Beacon time18 * card_radio_power_off - Turn Off NIC Radio Power19 *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 1038 39#define C_EIFS 80 /* micro sec. */40 41#define C_SLOT_SHORT 9 /* micro sec. */42#define C_SLOT_LONG 2043 44#define C_CWMIN_A 15 /* slot time */45#define C_CWMIN_B 3146 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 rx_bcn_tsf_off[MAX_RATE] = {54 17, 17, 17, 17, 34, 23, 17, 11, 8, 5, 4, 3};55 56/*--------------------- Static Functions --------------------------*/57 58static void vt6655_mac_set_bb_type(void __iomem *iobase, u32 mask)59{60 u32 reg_value;61 62 reg_value = ioread32(iobase + MAC_REG_ENCFG);63 reg_value = reg_value & ~ENCFG_BBTYPE_MASK;64 reg_value = reg_value | mask;65 iowrite32(reg_value, iobase + MAC_REG_ENCFG);66}67 68/*--------------------- Export Functions --------------------------*/69 70/*71 * Description: Calculate TxRate and RsvTime fields for RSPINF in OFDM mode.72 *73 * Parameters:74 * In:75 * wRate - Tx Rate76 * byPktType - Tx Packet type77 * Out:78 * tx_rate - pointer to RSPINF TxRate field79 * rsv_time - pointer to RSPINF RsvTime field80 *81 * Return Value: none82 */83static void calculate_ofdmr_parameter(unsigned char rate,84 u8 bb_type,85 unsigned char *tx_rate,86 unsigned char *rsv_time)87{88 switch (rate) {89 case RATE_6M:90 if (bb_type == BB_TYPE_11A) { /* 5GHZ */91 *tx_rate = 0x9B;92 *rsv_time = 44;93 } else {94 *tx_rate = 0x8B;95 *rsv_time = 50;96 }97 break;98 99 case RATE_9M:100 if (bb_type == BB_TYPE_11A) { /* 5GHZ */101 *tx_rate = 0x9F;102 *rsv_time = 36;103 } else {104 *tx_rate = 0x8F;105 *rsv_time = 42;106 }107 break;108 109 case RATE_12M:110 if (bb_type == BB_TYPE_11A) { /* 5GHZ */111 *tx_rate = 0x9A;112 *rsv_time = 32;113 } else {114 *tx_rate = 0x8A;115 *rsv_time = 38;116 }117 break;118 119 case RATE_18M:120 if (bb_type == BB_TYPE_11A) { /* 5GHZ */121 *tx_rate = 0x9E;122 *rsv_time = 28;123 } else {124 *tx_rate = 0x8E;125 *rsv_time = 34;126 }127 break;128 129 case RATE_36M:130 if (bb_type == BB_TYPE_11A) { /* 5GHZ */131 *tx_rate = 0x9D;132 *rsv_time = 24;133 } else {134 *tx_rate = 0x8D;135 *rsv_time = 30;136 }137 break;138 139 case RATE_48M:140 if (bb_type == BB_TYPE_11A) { /* 5GHZ */141 *tx_rate = 0x98;142 *rsv_time = 24;143 } else {144 *tx_rate = 0x88;145 *rsv_time = 30;146 }147 break;148 149 case RATE_54M:150 if (bb_type == BB_TYPE_11A) { /* 5GHZ */151 *tx_rate = 0x9C;152 *rsv_time = 24;153 } else {154 *tx_rate = 0x8C;155 *rsv_time = 30;156 }157 break;158 159 case RATE_24M:160 default:161 if (bb_type == BB_TYPE_11A) { /* 5GHZ */162 *tx_rate = 0x99;163 *rsv_time = 28;164 } else {165 *tx_rate = 0x89;166 *rsv_time = 34;167 }168 break;169 }170}171 172/*--------------------- Export Functions --------------------------*/173 174/*175 * Description: Update IFS176 *177 * Parameters:178 * In:179 * priv - The adapter to be set180 * Out:181 * none182 *183 * Return Value: None.184 */185bool card_set_phy_parameter(struct vnt_private *priv, u8 bb_type)186{187 unsigned char cw_max_min = 0;188 unsigned char slot = 0;189 unsigned char sifs = 0;190 unsigned char difs = 0;191 int i;192 193 /* Set SIFS, DIFS, EIFS, SlotTime, CwMin */194 if (bb_type == BB_TYPE_11A) {195 vt6655_mac_set_bb_type(priv->port_offset, BB_TYPE_11A);196 bb_write_embedded(priv, 0x88, 0x03);197 slot = C_SLOT_SHORT;198 sifs = C_SIFS_A;199 difs = C_SIFS_A + 2 * C_SLOT_SHORT;200 cw_max_min = 0xA4;201 } else if (bb_type == BB_TYPE_11B) {202 vt6655_mac_set_bb_type(priv->port_offset, BB_TYPE_11B);203 bb_write_embedded(priv, 0x88, 0x02);204 slot = C_SLOT_LONG;205 sifs = C_SIFS_BG;206 difs = C_SIFS_BG + 2 * C_SLOT_LONG;207 cw_max_min = 0xA5;208 } else { /* PK_TYPE_11GA & PK_TYPE_11GB */209 vt6655_mac_set_bb_type(priv->port_offset, BB_TYPE_11G);210 bb_write_embedded(priv, 0x88, 0x08);211 sifs = C_SIFS_BG;212 213 if (priv->short_slot_time) {214 slot = C_SLOT_SHORT;215 difs = C_SIFS_BG + 2 * C_SLOT_SHORT;216 } else {217 slot = C_SLOT_LONG;218 difs = C_SIFS_BG + 2 * C_SLOT_LONG;219 }220 221 cw_max_min = 0xa4;222 223 for (i = RATE_54M; i >= RATE_6M; i--) {224 if (priv->basic_rates & ((u32)(0x1 << i))) {225 cw_max_min |= 0x1;226 break;227 }228 }229 }230 231 if (priv->rf_type == RF_RFMD2959) {232 /*233 * bcs TX_PE will reserve 3 us hardware's processing234 * time here is 2 us.235 */236 sifs -= 3;237 difs -= 3;238 /*239 * TX_PE will reserve 3 us for MAX2829 A mode only, it is for240 * better TX throughput; MAC will need 2 us to process, so the241 * SIFS, DIFS can be shorter by 2 us.242 */243 }244 245 if (priv->sifs != sifs) {246 priv->sifs = sifs;247 iowrite8(priv->sifs, priv->port_offset + MAC_REG_SIFS);248 }249 if (priv->difs != difs) {250 priv->difs = difs;251 iowrite8(priv->difs, priv->port_offset + MAC_REG_DIFS);252 }253 if (priv->eifs != C_EIFS) {254 priv->eifs = C_EIFS;255 iowrite8(priv->eifs, priv->port_offset + MAC_REG_EIFS);256 }257 if (priv->slot != slot) {258 priv->slot = slot;259 iowrite8(priv->slot, priv->port_offset + MAC_REG_SLOT);260 261 bb_set_short_slot_time(priv);262 }263 if (priv->cw_max_min != cw_max_min) {264 priv->cw_max_min = cw_max_min;265 iowrite8(priv->cw_max_min, priv->port_offset + MAC_REG_CWMAXMIN0);266 }267 268 priv->packet_type = card_get_pkt_type(priv);269 270 card_set_rspinf(priv, bb_type);271 272 return true;273}274 275/*276 * Description: Sync. TSF counter to BSS277 * Get TSF offset and write to HW278 *279 * Parameters:280 * In:281 * priv - The adapter to be sync.282 * rx_rate - data rate of receive beacon283 * bss_timestamp - Rx BCN's TSF284 * qwLocalTSF - Local TSF285 * Out:286 * none287 *288 * Return Value: none289 */290bool card_update_tsf(struct vnt_private *priv, unsigned char rx_rate,291 u64 bss_timestamp)292{293 u64 local_tsf;294 u64 tsf_offset = 0;295 296 local_tsf = vt6655_get_current_tsf(priv);297 298 if (bss_timestamp != local_tsf) {299 tsf_offset = card_get_tsf_offset(rx_rate, bss_timestamp,300 local_tsf);301 /* adjust TSF, HW's TSF add TSF Offset reg */302 tsf_offset = le64_to_cpu(tsf_offset);303 iowrite32((u32)tsf_offset, priv->port_offset + MAC_REG_TSFOFST);304 iowrite32((u32)(tsf_offset >> 32), priv->port_offset + MAC_REG_TSFOFST + 4);305 vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_TFTCTL, TFTCTL_TSFSYNCEN);306 }307 return true;308}309 310/*311 * Description: Set NIC TSF counter for first Beacon time312 * Get NEXTTBTT from adjusted TSF and Beacon Interval313 *314 * Parameters:315 * In:316 * priv - The adapter to be set.317 * beacon_interval - Beacon Interval318 * Out:319 * none320 *321 * Return Value: true if succeed; otherwise false322 */323bool card_set_beacon_period(struct vnt_private *priv,324 unsigned short beacon_interval)325{326 u64 next_tbtt;327 328 next_tbtt = vt6655_get_current_tsf(priv); /* Get Local TSF counter */329 330 next_tbtt = card_get_next_tbtt(next_tbtt, beacon_interval);331 332 /* set HW beacon interval */333 iowrite16(beacon_interval, priv->port_offset + MAC_REG_BI);334 priv->beacon_interval = beacon_interval;335 /* Set NextTBTT */336 next_tbtt = le64_to_cpu(next_tbtt);337 iowrite32((u32)next_tbtt, priv->port_offset + MAC_REG_NEXTTBTT);338 iowrite32((u32)(next_tbtt >> 32), priv->port_offset + MAC_REG_NEXTTBTT + 4);339 vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN);340 341 return true;342}343 344/*345 * Description: Turn off Radio power346 *347 * Parameters:348 * In:349 * priv - The adapter to be turned off350 * Out:351 * none352 *353 */354void card_radio_power_off(struct vnt_private *priv)355{356 if (priv->radio_off)357 return;358 359 switch (priv->rf_type) {360 case RF_RFMD2959:361 vt6655_mac_word_reg_bits_off(priv->port_offset, MAC_REG_SOFTPWRCTL,362 SOFTPWRCTL_TXPEINV);363 vt6655_mac_word_reg_bits_on(priv->port_offset, MAC_REG_SOFTPWRCTL,364 SOFTPWRCTL_SWPE1);365 break;366 367 case RF_AIROHA:368 case RF_AL2230S:369 vt6655_mac_word_reg_bits_off(priv->port_offset, MAC_REG_SOFTPWRCTL,370 SOFTPWRCTL_SWPE2);371 vt6655_mac_word_reg_bits_off(priv->port_offset, MAC_REG_SOFTPWRCTL,372 SOFTPWRCTL_SWPE3);373 break;374 }375 376 vt6655_mac_reg_bits_off(priv->port_offset, MAC_REG_HOSTCR, HOSTCR_RXON);377 378 bb_set_deep_sleep(priv, priv->local_id);379 380 priv->radio_off = true;381 pr_debug("chester power off\n");382 vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_GPIOCTL0, LED_ACTSET); /* LED issue */383}384 385void card_safe_reset_tx(struct vnt_private *priv)386{387 unsigned int uu;388 struct vnt_tx_desc *curr_td;389 390 /* initialize TD index */391 priv->tail_td[0] = &priv->ap_td0_rings[0];392 priv->apCurrTD[0] = &priv->ap_td0_rings[0];393 394 priv->tail_td[1] = &priv->ap_td1_rings[0];395 priv->apCurrTD[1] = &priv->ap_td1_rings[0];396 397 for (uu = 0; uu < TYPE_MAXTD; uu++)398 priv->iTDUsed[uu] = 0;399 400 for (uu = 0; uu < priv->opts.tx_descs[0]; uu++) {401 curr_td = &priv->ap_td0_rings[uu];402 curr_td->td0.owner = OWNED_BY_HOST;403 /* init all Tx Packet pointer to NULL */404 }405 for (uu = 0; uu < priv->opts.tx_descs[1]; uu++) {406 curr_td = &priv->ap_td1_rings[uu];407 curr_td->td0.owner = OWNED_BY_HOST;408 /* init all Tx Packet pointer to NULL */409 }410 411 /* set MAC TD pointer */412 vt6655_mac_set_curr_tx_desc_addr(TYPE_TXDMA0, priv, priv->td0_pool_dma);413 414 vt6655_mac_set_curr_tx_desc_addr(TYPE_AC0DMA, priv, priv->td1_pool_dma);415 416 /* set MAC Beacon TX pointer */417 iowrite32((u32)priv->tx_beacon_dma, priv->port_offset + MAC_REG_BCNDMAPTR);418}419 420/*421 * Description:422 * Reset Rx423 *424 * Parameters:425 * In:426 * priv - Pointer to the adapter427 * Out:428 * none429 *430 * Return Value: none431 */432void CARDvSafeResetRx(struct vnt_private *priv)433{434 unsigned int uu;435 struct vnt_rx_desc *pDesc;436 437 /* initialize RD index */438 priv->pCurrRD[0] = &priv->aRD0Ring[0];439 priv->pCurrRD[1] = &priv->aRD1Ring[0];440 441 /* init state, all RD is chip's */442 for (uu = 0; uu < priv->opts.rx_descs0; uu++) {443 pDesc = &priv->aRD0Ring[uu];444 pDesc->rd0.res_count = cpu_to_le16(priv->rx_buf_sz);445 pDesc->rd0.owner = OWNED_BY_NIC;446 pDesc->rd1.req_count = cpu_to_le16(priv->rx_buf_sz);447 }448 449 /* init state, all RD is chip's */450 for (uu = 0; uu < priv->opts.rx_descs1; uu++) {451 pDesc = &priv->aRD1Ring[uu];452 pDesc->rd0.res_count = cpu_to_le16(priv->rx_buf_sz);453 pDesc->rd0.owner = OWNED_BY_NIC;454 pDesc->rd1.req_count = cpu_to_le16(priv->rx_buf_sz);455 }456 457 /* set perPkt mode */458 iowrite32(RX_PERPKT, priv->port_offset + MAC_REG_RXDMACTL0);459 iowrite32(RX_PERPKT, priv->port_offset + MAC_REG_RXDMACTL1);460 /* set MAC RD pointer */461 vt6655_mac_set_curr_rx_0_desc_addr(priv, priv->rd0_pool_dma);462 463 vt6655_mac_set_curr_rx_1_desc_addr(priv, priv->rd1_pool_dma);464}465 466/*467 * Description: Get response Control frame rate in CCK mode468 *469 * Parameters:470 * In:471 * priv - The adapter to be set472 * wRateIdx - Receiving data rate473 * Out:474 * none475 *476 * Return Value: response Control frame rate477 */478static unsigned short CARDwGetCCKControlRate(struct vnt_private *priv,479 unsigned short wRateIdx)480{481 unsigned int ui = (unsigned int)wRateIdx;482 483 while (ui > RATE_1M) {484 if (priv->basic_rates & ((u32)0x1 << ui))485 return (unsigned short)ui;486 487 ui--;488 }489 return (unsigned short)RATE_1M;490}491 492/*493 * Description: Get response Control frame rate in OFDM mode494 *495 * Parameters:496 * In:497 * priv - The adapter to be set498 * wRateIdx - Receiving data rate499 * Out:500 * none501 *502 * Return Value: response Control frame rate503 */504static unsigned short CARDwGetOFDMControlRate(struct vnt_private *priv,505 unsigned short wRateIdx)506{507 unsigned int ui = (unsigned int)wRateIdx;508 509 pr_debug("BASIC RATE: %X\n", priv->basic_rates);510 511 if (!CARDbIsOFDMinBasicRate((void *)priv)) {512 pr_debug("%s:(NO OFDM) %d\n", __func__, wRateIdx);513 if (wRateIdx > RATE_24M)514 wRateIdx = RATE_24M;515 return wRateIdx;516 }517 while (ui > RATE_11M) {518 if (priv->basic_rates & ((u32)0x1 << ui)) {519 pr_debug("%s : %d\n", __func__, ui);520 return (unsigned short)ui;521 }522 ui--;523 }524 pr_debug("%s: 6M\n", __func__);525 return (unsigned short)RATE_24M;526}527 528/*529 * Description: Set RSPINF530 *531 * Parameters:532 * In:533 * priv - The adapter to be set534 * Out:535 * none536 *537 * Return Value: None.538 */539void card_set_rspinf(struct vnt_private *priv, u8 bb_type)540{541 union vnt_phy_field_swap phy;542 unsigned char byTxRate, byRsvTime; /* For OFDM */543 unsigned long flags;544 545 spin_lock_irqsave(&priv->lock, flags);546 547 /* Set to Page1 */548 VT6655_MAC_SELECT_PAGE1(priv->port_offset);549 550 /* RSPINF_b_1 */551 vnt_get_phy_field(priv, 14,552 CARDwGetCCKControlRate(priv, RATE_1M),553 PK_TYPE_11B, &phy.field_read);554 555 /* swap over to get correct write order */556 swap(phy.swap[0], phy.swap[1]);557 558 iowrite32(phy.field_write, priv->port_offset + MAC_REG_RSPINF_B_1);559 560 /* RSPINF_b_2 */561 vnt_get_phy_field(priv, 14,562 CARDwGetCCKControlRate(priv, RATE_2M),563 PK_TYPE_11B, &phy.field_read);564 565 swap(phy.swap[0], phy.swap[1]);566 567 iowrite32(phy.field_write, priv->port_offset + MAC_REG_RSPINF_B_2);568 569 /* RSPINF_b_5 */570 vnt_get_phy_field(priv, 14,571 CARDwGetCCKControlRate(priv, RATE_5M),572 PK_TYPE_11B, &phy.field_read);573 574 swap(phy.swap[0], phy.swap[1]);575 576 iowrite32(phy.field_write, priv->port_offset + MAC_REG_RSPINF_B_5);577 578 /* RSPINF_b_11 */579 vnt_get_phy_field(priv, 14,580 CARDwGetCCKControlRate(priv, RATE_11M),581 PK_TYPE_11B, &phy.field_read);582 583 swap(phy.swap[0], phy.swap[1]);584 585 iowrite32(phy.field_write, priv->port_offset + MAC_REG_RSPINF_B_11);586 587 /* RSPINF_a_6 */588 calculate_ofdmr_parameter(RATE_6M,589 bb_type,590 &byTxRate,591 &byRsvTime);592 iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_6);593 /* RSPINF_a_9 */594 calculate_ofdmr_parameter(RATE_9M,595 bb_type,596 &byTxRate,597 &byRsvTime);598 iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_9);599 /* RSPINF_a_12 */600 calculate_ofdmr_parameter(RATE_12M,601 bb_type,602 &byTxRate,603 &byRsvTime);604 iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_12);605 /* RSPINF_a_18 */606 calculate_ofdmr_parameter(RATE_18M,607 bb_type,608 &byTxRate,609 &byRsvTime);610 iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_18);611 /* RSPINF_a_24 */612 calculate_ofdmr_parameter(RATE_24M,613 bb_type,614 &byTxRate,615 &byRsvTime);616 iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_24);617 /* RSPINF_a_36 */618 calculate_ofdmr_parameter(CARDwGetOFDMControlRate((void *)priv,619 RATE_36M),620 bb_type,621 &byTxRate,622 &byRsvTime);623 iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_36);624 /* RSPINF_a_48 */625 calculate_ofdmr_parameter(CARDwGetOFDMControlRate((void *)priv,626 RATE_48M),627 bb_type,628 &byTxRate,629 &byRsvTime);630 iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_48);631 /* RSPINF_a_54 */632 calculate_ofdmr_parameter(CARDwGetOFDMControlRate((void *)priv,633 RATE_54M),634 bb_type,635 &byTxRate,636 &byRsvTime);637 iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_54);638 /* RSPINF_a_72 */639 calculate_ofdmr_parameter(CARDwGetOFDMControlRate((void *)priv,640 RATE_54M),641 bb_type,642 &byTxRate,643 &byRsvTime);644 iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_72);645 /* Set to Page0 */646 VT6655_MAC_SELECT_PAGE0(priv->port_offset);647 648 spin_unlock_irqrestore(&priv->lock, flags);649}650 651void CARDvUpdateBasicTopRate(struct vnt_private *priv)652{653 unsigned char byTopOFDM = RATE_24M, byTopCCK = RATE_1M;654 unsigned char ii;655 656 /* Determines the highest basic rate. */657 for (ii = RATE_54M; ii >= RATE_6M; ii--) {658 if ((priv->basic_rates) & ((u32)(1 << ii))) {659 byTopOFDM = ii;660 break;661 }662 }663 priv->byTopOFDMBasicRate = byTopOFDM;664 665 for (ii = RATE_11M;; ii--) {666 if ((priv->basic_rates) & ((u32)(1 << ii))) {667 byTopCCK = ii;668 break;669 }670 if (ii == RATE_1M)671 break;672 }673 priv->byTopCCKBasicRate = byTopCCK;674}675 676bool CARDbIsOFDMinBasicRate(struct vnt_private *priv)677{678 int ii;679 680 for (ii = RATE_54M; ii >= RATE_6M; ii--) {681 if ((priv->basic_rates) & ((u32)BIT(ii)))682 return true;683 }684 return false;685}686 687unsigned char card_get_pkt_type(struct vnt_private *priv)688{689 if (priv->byBBType == BB_TYPE_11A || priv->byBBType == BB_TYPE_11B)690 return (unsigned char)priv->byBBType;691 else if (CARDbIsOFDMinBasicRate((void *)priv))692 return PK_TYPE_11GA;693 else694 return PK_TYPE_11GB;695}696 697/*698 * Description: Calculate TSF offset of two TSF input699 * Get TSF Offset from RxBCN's TSF and local TSF700 *701 * Parameters:702 * In:703 * priv - The adapter to be sync.704 * qwTSF1 - Rx BCN's TSF705 * qwTSF2 - Local TSF706 * Out:707 * none708 *709 * Return Value: TSF Offset value710 */711u64 card_get_tsf_offset(unsigned char rx_rate, u64 qwTSF1, u64 qwTSF2)712{713 unsigned short wRxBcnTSFOffst;714 715 wRxBcnTSFOffst = rx_bcn_tsf_off[rx_rate % MAX_RATE];716 717 qwTSF2 += (u64)wRxBcnTSFOffst;718 719 return qwTSF1 - qwTSF2;720}721 722/*723 * Description: Read NIC TSF counter724 * Get local TSF counter725 *726 * Parameters:727 * In:728 * priv - The adapter to be read729 * Out:730 * none731 *732 * Return Value: Current TSF counter733 */734u64 vt6655_get_current_tsf(struct vnt_private *priv)735{736 void __iomem *iobase = priv->port_offset;737 unsigned short ww;738 unsigned char data;739 u32 low, high;740 741 vt6655_mac_reg_bits_on(iobase, MAC_REG_TFTCTL, TFTCTL_TSFCNTRRD);742 for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {743 data = ioread8(iobase + MAC_REG_TFTCTL);744 if (!(data & TFTCTL_TSFCNTRRD))745 break;746 }747 if (ww == W_MAX_TIMEOUT)748 return 0;749 low = ioread32(iobase + MAC_REG_TSFCNTR);750 high = ioread32(iobase + MAC_REG_TSFCNTR + 4);751 return le64_to_cpu(low + ((u64)high << 32));752}753 754/*755 * Description: Read NIC TSF counter756 * Get NEXTTBTT from adjusted TSF and Beacon Interval757 *758 * Parameters:759 * In:760 * qwTSF - Current TSF counter761 * wbeaconInterval - Beacon Interval762 * Out:763 * qwCurrTSF - Current TSF counter764 *765 * Return Value: TSF value of next Beacon766 */767u64 card_get_next_tbtt(u64 qwTSF, unsigned short beacon_interval)768{769 u32 beacon_int;770 771 beacon_int = beacon_interval * 1024;772 if (beacon_int) {773 do_div(qwTSF, beacon_int);774 qwTSF += 1;775 qwTSF *= beacon_int;776 }777 778 return qwTSF;779}780 781/*782 * Description: Set NIC TSF counter for first Beacon time783 * Get NEXTTBTT from adjusted TSF and Beacon Interval784 *785 * Parameters:786 * In:787 * iobase - IO Base788 * beacon_interval - Beacon Interval789 * Out:790 * none791 *792 * Return Value: none793 */794void CARDvSetFirstNextTBTT(struct vnt_private *priv,795 unsigned short beacon_interval)796{797 void __iomem *iobase = priv->port_offset;798 u64 next_tbtt;799 800 next_tbtt = vt6655_get_current_tsf(priv); /* Get Local TSF counter */801 802 next_tbtt = card_get_next_tbtt(next_tbtt, beacon_interval);803 /* Set NextTBTT */804 next_tbtt = le64_to_cpu(next_tbtt);805 iowrite32((u32)next_tbtt, iobase + MAC_REG_NEXTTBTT);806 iowrite32((u32)(next_tbtt >> 32), iobase + MAC_REG_NEXTTBTT + 4);807 vt6655_mac_reg_bits_on(iobase, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN);808}809 810/*811 * Description: Sync NIC TSF counter for Beacon time812 * Get NEXTTBTT and write to HW813 *814 * Parameters:815 * In:816 * priv - The adapter to be set817 * qwTSF - Current TSF counter818 * beacon_interval - Beacon Interval819 * Out:820 * none821 *822 * Return Value: none823 */824void CARDvUpdateNextTBTT(struct vnt_private *priv, u64 qwTSF,825 unsigned short beacon_interval)826{827 void __iomem *iobase = priv->port_offset;828 829 qwTSF = card_get_next_tbtt(qwTSF, beacon_interval);830 /* Set NextTBTT */831 qwTSF = le64_to_cpu(qwTSF);832 iowrite32((u32)qwTSF, iobase + MAC_REG_NEXTTBTT);833 iowrite32((u32)(qwTSF >> 32), iobase + MAC_REG_NEXTTBTT + 4);834 vt6655_mac_reg_bits_on(iobase, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN);835 pr_debug("Card:Update Next TBTT[%8llx]\n", qwTSF);836}837