1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
6 * Purpose: Provide functions to setup NIC operation mode
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
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().
34 /*--------------------- Static Definitions -------------------------*/
36 #define C_SIFS_A 16 /* micro sec. */
39 #define C_EIFS 80 /* micro sec. */
41 #define C_SLOT_SHORT 9 /* micro sec. */
42 #define C_SLOT_LONG 20
44 #define C_CWMIN_A 15 /* slot time */
47 #define C_CWMAX 1023 /* slot time */
49 #define WAIT_BEACON_TX_DOWN_TMO 3 /* Times */
51 /*--------------------- Static Variables --------------------------*/
53 static const unsigned short cwRXBCNTSFOff[MAX_RATE] = {
54 17, 17, 17, 17, 34, 23, 17, 11, 8, 5, 4, 3};
56 /*--------------------- Static Functions --------------------------*/
58 static void s_vCalculateOFDMRParameter(unsigned char rate, u8 bb_type,
59 unsigned char *pbyTxRate,
60 unsigned char *pbyRsvTime);
62 /*--------------------- Export Functions --------------------------*/
65 * Description: Calculate TxRate and RsvTime fields for RSPINF in OFDM mode.
70 * byPktType - Tx Packet type
72 * pbyTxRate - pointer to RSPINF TxRate field
73 * pbyRsvTime - pointer to RSPINF RsvTime field
77 static void s_vCalculateOFDMRParameter(unsigned char rate,
79 unsigned char *pbyTxRate,
80 unsigned char *pbyRsvTime)
84 if (bb_type == BB_TYPE_11A) { /* 5GHZ */
94 if (bb_type == BB_TYPE_11A) { /* 5GHZ */
104 if (bb_type == BB_TYPE_11A) { /* 5GHZ */
114 if (bb_type == BB_TYPE_11A) { /* 5GHZ */
124 if (bb_type == BB_TYPE_11A) { /* 5GHZ */
134 if (bb_type == BB_TYPE_11A) { /* 5GHZ */
144 if (bb_type == BB_TYPE_11A) { /* 5GHZ */
155 if (bb_type == BB_TYPE_11A) { /* 5GHZ */
166 /*--------------------- Export Functions --------------------------*/
169 * Description: Update IFS
173 * priv - The adapter to be set
177 * Return Value: None.
179 bool CARDbSetPhyParameter(struct vnt_private *priv, u8 bb_type)
181 unsigned char byCWMaxMin = 0;
182 unsigned char bySlot = 0;
183 unsigned char bySIFS = 0;
184 unsigned char byDIFS = 0;
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;
193 byDIFS = C_SIFS_A + 2 * C_SLOT_SHORT;
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;
200 byDIFS = C_SIFS_BG + 2 * C_SLOT_LONG;
202 } else { /* PK_TYPE_11GA & PK_TYPE_11GB */
203 MACvSetBBType(priv->port_offset, BB_TYPE_11G);
204 bb_write_embedded(priv, 0x88, 0x08);
207 if (priv->short_slot_time) {
208 bySlot = C_SLOT_SHORT;
209 byDIFS = C_SIFS_BG + 2 * C_SLOT_SHORT;
211 bySlot = C_SLOT_LONG;
212 byDIFS = C_SIFS_BG + 2 * C_SLOT_LONG;
217 for (i = RATE_54M; i >= RATE_6M; i--) {
218 if (priv->basic_rates & ((u32)(0x1 << i))) {
225 if (priv->byRFType == RF_RFMD2959) {
227 * bcs TX_PE will reserve 3 us hardware's processing
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.
239 if (priv->bySIFS != bySIFS) {
240 priv->bySIFS = bySIFS;
241 iowrite8(priv->bySIFS, priv->port_offset + MAC_REG_SIFS);
243 if (priv->byDIFS != byDIFS) {
244 priv->byDIFS = byDIFS;
245 iowrite8(priv->byDIFS, priv->port_offset + MAC_REG_DIFS);
247 if (priv->byEIFS != C_EIFS) {
248 priv->byEIFS = C_EIFS;
249 iowrite8(priv->byEIFS, priv->port_offset + MAC_REG_EIFS);
251 if (priv->bySlot != bySlot) {
252 priv->bySlot = bySlot;
253 iowrite8(priv->bySlot, priv->port_offset + MAC_REG_SLOT);
255 bb_set_short_slot_time(priv);
257 if (priv->byCWMaxMin != byCWMaxMin) {
258 priv->byCWMaxMin = byCWMaxMin;
259 iowrite8(priv->byCWMaxMin, priv->port_offset + MAC_REG_CWMAXMIN0);
262 priv->byPacketType = CARDbyGetPktType(priv);
264 CARDvSetRSPINF(priv, bb_type);
270 * Description: Sync. TSF counter to BSS
271 * Get TSF offset and write to HW
275 * priv - The adapter to be sync.
276 * byRxRate - data rate of receive beacon
277 * qwBSSTimestamp - Rx BCN's TSF
278 * qwLocalTSF - Local TSF
284 bool CARDbUpdateTSF(struct vnt_private *priv, unsigned char byRxRate,
290 local_tsf = vt6655_get_current_tsf(priv);
292 if (qwBSSTimestamp != local_tsf) {
293 qwTSFOffset = CARDqGetTSFOffset(byRxRate, qwBSSTimestamp,
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);
305 * Description: Set NIC TSF counter for first Beacon time
306 * Get NEXTTBTT from adjusted TSF and Beacon Interval
310 * priv - The adapter to be set.
311 * wBeaconInterval - Beacon Interval
315 * Return Value: true if succeed; otherwise false
317 bool CARDbSetBeaconPeriod(struct vnt_private *priv,
318 unsigned short wBeaconInterval)
322 qwNextTBTT = vt6655_get_current_tsf(priv); /* Get Local TSF counter */
324 qwNextTBTT = CARDqGetNextTBTT(qwNextTBTT, wBeaconInterval);
326 /* set HW beacon interval */
327 iowrite16(wBeaconInterval, priv->port_offset + MAC_REG_BI);
328 priv->wBeaconInterval = wBeaconInterval;
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);
339 * Description: Turn off Radio power
343 * priv - The adapter to be turned off
348 void CARDbRadioPowerOff(struct vnt_private *priv)
353 switch (priv->byRFType) {
355 vt6655_mac_word_reg_bits_off(priv->port_offset, MAC_REG_SOFTPWRCTL,
357 vt6655_mac_word_reg_bits_on(priv->port_offset, MAC_REG_SOFTPWRCTL,
363 vt6655_mac_word_reg_bits_off(priv->port_offset, MAC_REG_SOFTPWRCTL,
365 vt6655_mac_word_reg_bits_off(priv->port_offset, MAC_REG_SOFTPWRCTL,
370 vt6655_mac_reg_bits_off(priv->port_offset, MAC_REG_HOSTCR, HOSTCR_RXON);
372 bb_set_deep_sleep(priv, priv->local_id);
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 */
379 void CARDvSafeResetTx(struct vnt_private *priv)
382 struct vnt_tx_desc *pCurrTD;
384 /* initialize TD index */
385 priv->apTailTD[0] = &priv->apTD0Rings[0];
386 priv->apCurrTD[0] = &priv->apTD0Rings[0];
388 priv->apTailTD[1] = &priv->apTD1Rings[0];
389 priv->apCurrTD[1] = &priv->apTD1Rings[0];
391 for (uu = 0; uu < TYPE_MAXTD; uu++)
392 priv->iTDUsed[uu] = 0;
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 */
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 */
405 /* set MAC TD pointer */
406 MACvSetCurrTXDescAddr(TYPE_TXDMA0, priv, priv->td0_pool_dma);
408 MACvSetCurrTXDescAddr(TYPE_AC0DMA, priv, priv->td1_pool_dma);
410 /* set MAC Beacon TX pointer */
411 iowrite32((u32)priv->tx_beacon_dma, priv->port_offset + MAC_REG_BCNDMAPTR);
420 * priv - Pointer to the adapter
426 void CARDvSafeResetRx(struct vnt_private *priv)
429 struct vnt_rx_desc *pDesc;
431 /* initialize RD index */
432 priv->pCurrRD[0] = &priv->aRD0Ring[0];
433 priv->pCurrRD[1] = &priv->aRD1Ring[0];
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);
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);
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);
457 MACvSetCurrRx1DescAddr(priv, priv->rd1_pool_dma);
461 * Description: Get response Control frame rate in CCK mode
465 * priv - The adapter to be set
466 * wRateIdx - Receiving data rate
470 * Return Value: response Control frame rate
472 static unsigned short CARDwGetCCKControlRate(struct vnt_private *priv,
473 unsigned short wRateIdx)
475 unsigned int ui = (unsigned int)wRateIdx;
477 while (ui > RATE_1M) {
478 if (priv->basic_rates & ((u32)0x1 << ui))
479 return (unsigned short)ui;
483 return (unsigned short)RATE_1M;
487 * Description: Get response Control frame rate in OFDM mode
491 * priv - The adapter to be set
492 * wRateIdx - Receiving data rate
496 * Return Value: response Control frame rate
498 static unsigned short CARDwGetOFDMControlRate(struct vnt_private *priv,
499 unsigned short wRateIdx)
501 unsigned int ui = (unsigned int)wRateIdx;
503 pr_debug("BASIC RATE: %X\n", priv->basic_rates);
505 if (!CARDbIsOFDMinBasicRate((void *)priv)) {
506 pr_debug("%s:(NO OFDM) %d\n", __func__, wRateIdx);
507 if (wRateIdx > RATE_24M)
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;
518 pr_debug("%s: 6M\n", __func__);
519 return (unsigned short)RATE_24M;
523 * Description: Set RSPINF
527 * priv - The adapter to be set
531 * Return Value: None.
533 void CARDvSetRSPINF(struct vnt_private *priv, u8 bb_type)
535 union vnt_phy_field_swap phy;
536 unsigned char byTxRate, byRsvTime; /* For OFDM */
539 spin_lock_irqsave(&priv->lock, flags);
542 MACvSelectPage1(priv->port_offset);
545 vnt_get_phy_field(priv, 14,
546 CARDwGetCCKControlRate(priv, RATE_1M),
547 PK_TYPE_11B, &phy.field_read);
549 /* swap over to get correct write order */
550 swap(phy.swap[0], phy.swap[1]);
552 iowrite32(phy.field_write, priv->port_offset + MAC_REG_RSPINF_B_1);
555 vnt_get_phy_field(priv, 14,
556 CARDwGetCCKControlRate(priv, RATE_2M),
557 PK_TYPE_11B, &phy.field_read);
559 swap(phy.swap[0], phy.swap[1]);
561 iowrite32(phy.field_write, priv->port_offset + MAC_REG_RSPINF_B_2);
564 vnt_get_phy_field(priv, 14,
565 CARDwGetCCKControlRate(priv, RATE_5M),
566 PK_TYPE_11B, &phy.field_read);
568 swap(phy.swap[0], phy.swap[1]);
570 iowrite32(phy.field_write, priv->port_offset + MAC_REG_RSPINF_B_5);
573 vnt_get_phy_field(priv, 14,
574 CARDwGetCCKControlRate(priv, RATE_11M),
575 PK_TYPE_11B, &phy.field_read);
577 swap(phy.swap[0], phy.swap[1]);
579 iowrite32(phy.field_write, priv->port_offset + MAC_REG_RSPINF_B_11);
582 s_vCalculateOFDMRParameter(RATE_6M,
586 iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_6);
588 s_vCalculateOFDMRParameter(RATE_9M,
592 iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_9);
594 s_vCalculateOFDMRParameter(RATE_12M,
598 iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_12);
600 s_vCalculateOFDMRParameter(RATE_18M,
604 iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_18);
606 s_vCalculateOFDMRParameter(RATE_24M,
610 iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_24);
612 s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)priv,
617 iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_36);
619 s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)priv,
624 iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_48);
626 s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)priv,
631 iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_54);
633 s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)priv,
638 iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_72);
640 MACvSelectPage0(priv->port_offset);
642 spin_unlock_irqrestore(&priv->lock, flags);
645 void CARDvUpdateBasicTopRate(struct vnt_private *priv)
647 unsigned char byTopOFDM = RATE_24M, byTopCCK = RATE_1M;
650 /* Determines the highest basic rate. */
651 for (ii = RATE_54M; ii >= RATE_6M; ii--) {
652 if ((priv->basic_rates) & ((u32)(1 << ii))) {
657 priv->byTopOFDMBasicRate = byTopOFDM;
659 for (ii = RATE_11M;; ii--) {
660 if ((priv->basic_rates) & ((u32)(1 << ii))) {
667 priv->byTopCCKBasicRate = byTopCCK;
670 bool CARDbIsOFDMinBasicRate(struct vnt_private *priv)
674 for (ii = RATE_54M; ii >= RATE_6M; ii--) {
675 if ((priv->basic_rates) & ((u32)BIT(ii)))
681 unsigned char CARDbyGetPktType(struct vnt_private *priv)
683 if (priv->byBBType == BB_TYPE_11A || priv->byBBType == BB_TYPE_11B)
684 return (unsigned char)priv->byBBType;
685 else if (CARDbIsOFDMinBasicRate((void *)priv))
692 * Description: Calculate TSF offset of two TSF input
693 * Get TSF Offset from RxBCN's TSF and local TSF
697 * priv - The adapter to be sync.
698 * qwTSF1 - Rx BCN's TSF
703 * Return Value: TSF Offset value
705 u64 CARDqGetTSFOffset(unsigned char byRxRate, u64 qwTSF1, u64 qwTSF2)
707 unsigned short wRxBcnTSFOffst;
709 wRxBcnTSFOffst = cwRXBCNTSFOff[byRxRate % MAX_RATE];
711 qwTSF2 += (u64)wRxBcnTSFOffst;
713 return qwTSF1 - qwTSF2;
717 * Description: Read NIC TSF counter
718 * Get local TSF counter
722 * priv - The adapter to be read
726 * Return Value: Current TSF counter
728 u64 vt6655_get_current_tsf(struct vnt_private *priv)
730 void __iomem *iobase = priv->port_offset;
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))
741 if (ww == W_MAX_TIMEOUT)
743 low = ioread32(iobase + MAC_REG_TSFCNTR);
744 high = ioread32(iobase + MAC_REG_TSFCNTR + 4);
745 return le64_to_cpu(low + ((u64)high << 32));
749 * Description: Read NIC TSF counter
750 * Get NEXTTBTT from adjusted TSF and Beacon Interval
754 * qwTSF - Current TSF counter
755 * wbeaconInterval - Beacon Interval
757 * qwCurrTSF - Current TSF counter
759 * Return Value: TSF value of next Beacon
761 u64 CARDqGetNextTBTT(u64 qwTSF, unsigned short wBeaconInterval)
765 beacon_int = wBeaconInterval * 1024;
767 do_div(qwTSF, beacon_int);
776 * Description: Set NIC TSF counter for first Beacon time
777 * Get NEXTTBTT from adjusted TSF and Beacon Interval
782 * wBeaconInterval - Beacon Interval
788 void CARDvSetFirstNextTBTT(struct vnt_private *priv,
789 unsigned short wBeaconInterval)
791 void __iomem *iobase = priv->port_offset;
794 qwNextTBTT = vt6655_get_current_tsf(priv); /* Get Local TSF counter */
796 qwNextTBTT = CARDqGetNextTBTT(qwNextTBTT, wBeaconInterval);
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);
805 * Description: Sync NIC TSF counter for Beacon time
806 * Get NEXTTBTT and write to HW
810 * priv - The adapter to be set
811 * qwTSF - Current TSF counter
812 * wBeaconInterval - Beacon Interval
818 void CARDvUpdateNextTBTT(struct vnt_private *priv, u64 qwTSF,
819 unsigned short wBeaconInterval)
821 void __iomem *iobase = priv->port_offset;
823 qwTSF = CARDqGetNextTBTT(qwTSF, wBeaconInterval);
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);