cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

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}