2 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 * Purpose: Provide functions to setup NIC operation mode
22 * s_vSafeResetTx - Rest Tx
23 * CARDvSetRSPINF - Set RSPINF
24 * CARDvUpdateBasicTopRate - Update BasicTopRate
25 * CARDbAddBasicRate - Add to BasicRateSet
26 * CARDbIsOFDMinBasicRate - Check if any OFDM rate is in BasicRateSet
27 * CARDvSetLoopbackMode - Set Loopback mode
28 * CARDbSoftwareReset - Sortware reset NIC
29 * CARDqGetTSFOffset - Calculate TSFOffset
30 * CARDbGetCurrentTSF - Read Current NIC TSF counter
31 * CARDqGetNextTBTT - Calculate Next Beacon TSF counter
32 * CARDvSetFirstNextTBTT - Set NIC Beacon time
33 * CARDvUpdateNextTBTT - Sync. NIC Beacon time
34 * CARDbRadioPowerOff - Turn Off NIC Radio Power
35 * CARDbRadioPowerOn - Turn On NIC Radio Power
38 * 06-10-2003 Bryan YC Fan: Re-write codes to support VT3253 spec.
39 * 08-26-2003 Kyle Hsu: Modify the defination type of dwIoBase.
40 * 09-01-2003 Bryan YC Fan: Add vUpdateIFS().
52 /*--------------------- Static Definitions -------------------------*/
54 #define C_SIFS_A 16 /* micro sec. */
57 #define C_EIFS 80 /* micro sec. */
59 #define C_SLOT_SHORT 9 /* micro sec. */
60 #define C_SLOT_LONG 20
62 #define C_CWMIN_A 15 /* slot time */
65 #define C_CWMAX 1023 /* slot time */
67 #define WAIT_BEACON_TX_DOWN_TMO 3 /* Times */
69 /*--------------------- Static Variables --------------------------*/
71 static const unsigned short cwRXBCNTSFOff[MAX_RATE] = {
72 17, 17, 17, 17, 34, 23, 17, 11, 8, 5, 4, 3};
74 /*--------------------- Static Functions --------------------------*/
78 s_vCalculateOFDMRParameter(
81 unsigned char *pbyTxRate,
82 unsigned char *pbyRsvTime
85 /*--------------------- Export Functions --------------------------*/
88 * Description: Calculate TxRate and RsvTime fields for RSPINF in OFDM mode.
93 * byPktType - Tx Packet type
95 * pbyTxRate - pointer to RSPINF TxRate field
96 * pbyRsvTime - pointer to RSPINF RsvTime field
102 s_vCalculateOFDMRParameter(
103 unsigned char byRate,
105 unsigned char *pbyTxRate,
106 unsigned char *pbyRsvTime
111 if (bb_type == BB_TYPE_11A) { /* 5GHZ */
121 if (bb_type == BB_TYPE_11A) { /* 5GHZ */
131 if (bb_type == BB_TYPE_11A) { /* 5GHZ */
141 if (bb_type == BB_TYPE_11A) { /* 5GHZ */
151 if (bb_type == BB_TYPE_11A) { /* 5GHZ */
161 if (bb_type == BB_TYPE_11A) { /* 5GHZ */
171 if (bb_type == BB_TYPE_11A) { /* 5GHZ */
182 if (bb_type == BB_TYPE_11A) { /* 5GHZ */
193 /*--------------------- Export Functions --------------------------*/
196 * Description: Update IFS
200 * priv - The adapter to be set
204 * Return Value: None.
206 bool CARDbSetPhyParameter(struct vnt_private *priv, u8 bb_type)
208 unsigned char byCWMaxMin = 0;
209 unsigned char bySlot = 0;
210 unsigned char bySIFS = 0;
211 unsigned char byDIFS = 0;
212 unsigned char byData;
215 /* Set SIFS, DIFS, EIFS, SlotTime, CwMin */
216 if (bb_type == BB_TYPE_11A) {
217 if (priv->byRFType == RF_AIROHA7230) {
218 /* AL7230 use single PAPE and connect to PAPE_2.4G */
219 MACvSetBBType(priv->PortOffset, BB_TYPE_11G);
220 priv->abyBBVGA[0] = 0x20;
221 priv->abyBBVGA[2] = 0x10;
222 priv->abyBBVGA[3] = 0x10;
223 BBbReadEmbedded(priv, 0xE7, &byData);
225 BBbWriteEmbedded(priv, 0xE7, priv->abyBBVGA[0]);
227 } else if (priv->byRFType == RF_UW2452) {
228 MACvSetBBType(priv->PortOffset, BB_TYPE_11A);
229 priv->abyBBVGA[0] = 0x18;
230 BBbReadEmbedded(priv, 0xE7, &byData);
231 if (byData == 0x14) {
232 BBbWriteEmbedded(priv, 0xE7, priv->abyBBVGA[0]);
233 BBbWriteEmbedded(priv, 0xE1, 0x57);
236 MACvSetBBType(priv->PortOffset, BB_TYPE_11A);
238 BBbWriteEmbedded(priv, 0x88, 0x03);
239 bySlot = C_SLOT_SHORT;
241 byDIFS = C_SIFS_A + 2 * C_SLOT_SHORT;
243 } else if (bb_type == BB_TYPE_11B) {
244 MACvSetBBType(priv->PortOffset, BB_TYPE_11B);
245 if (priv->byRFType == RF_AIROHA7230) {
246 priv->abyBBVGA[0] = 0x1C;
247 priv->abyBBVGA[2] = 0x00;
248 priv->abyBBVGA[3] = 0x00;
249 BBbReadEmbedded(priv, 0xE7, &byData);
251 BBbWriteEmbedded(priv, 0xE7, priv->abyBBVGA[0]);
253 } else if (priv->byRFType == RF_UW2452) {
254 priv->abyBBVGA[0] = 0x14;
255 BBbReadEmbedded(priv, 0xE7, &byData);
256 if (byData == 0x18) {
257 BBbWriteEmbedded(priv, 0xE7, priv->abyBBVGA[0]);
258 BBbWriteEmbedded(priv, 0xE1, 0xD3);
261 BBbWriteEmbedded(priv, 0x88, 0x02);
262 bySlot = C_SLOT_LONG;
264 byDIFS = C_SIFS_BG + 2*C_SLOT_LONG;
266 } else { /* PK_TYPE_11GA & PK_TYPE_11GB */
267 MACvSetBBType(priv->PortOffset, BB_TYPE_11G);
268 if (priv->byRFType == RF_AIROHA7230) {
269 priv->abyBBVGA[0] = 0x1C;
270 priv->abyBBVGA[2] = 0x00;
271 priv->abyBBVGA[3] = 0x00;
272 BBbReadEmbedded(priv, 0xE7, &byData);
274 BBbWriteEmbedded(priv, 0xE7, priv->abyBBVGA[0]);
276 } else if (priv->byRFType == RF_UW2452) {
277 priv->abyBBVGA[0] = 0x14;
278 BBbReadEmbedded(priv, 0xE7, &byData);
279 if (byData == 0x18) {
280 BBbWriteEmbedded(priv, 0xE7, priv->abyBBVGA[0]);
281 BBbWriteEmbedded(priv, 0xE1, 0xD3);
284 BBbWriteEmbedded(priv, 0x88, 0x08);
287 if (priv->bShortSlotTime) {
288 bySlot = C_SLOT_SHORT;
289 byDIFS = C_SIFS_BG + 2 * C_SLOT_SHORT;
291 bySlot = C_SLOT_LONG;
292 byDIFS = C_SIFS_BG + 2*C_SLOT_LONG;
297 for (i = RATE_54M; i >= RATE_6M; i--) {
298 if (priv->basic_rates & ((u32)(0x1 << i))) {
305 if (priv->byRFType == RF_RFMD2959) {
307 * bcs TX_PE will reserve 3 us hardware's processing
313 * TX_PE will reserve 3 us for MAX2829 A mode only, it is for
314 * better TX throughput; MAC will need 2 us to process, so the
315 * SIFS, DIFS can be shorter by 2 us.
319 if (priv->bySIFS != bySIFS) {
320 priv->bySIFS = bySIFS;
321 VNSvOutPortB(priv->PortOffset + MAC_REG_SIFS, priv->bySIFS);
323 if (priv->byDIFS != byDIFS) {
324 priv->byDIFS = byDIFS;
325 VNSvOutPortB(priv->PortOffset + MAC_REG_DIFS, priv->byDIFS);
327 if (priv->byEIFS != C_EIFS) {
328 priv->byEIFS = C_EIFS;
329 VNSvOutPortB(priv->PortOffset + MAC_REG_EIFS, priv->byEIFS);
331 if (priv->bySlot != bySlot) {
332 priv->bySlot = bySlot;
333 VNSvOutPortB(priv->PortOffset + MAC_REG_SLOT, priv->bySlot);
335 BBvSetShortSlotTime(priv);
337 if (priv->byCWMaxMin != byCWMaxMin) {
338 priv->byCWMaxMin = byCWMaxMin;
339 VNSvOutPortB(priv->PortOffset + MAC_REG_CWMAXMIN0, priv->byCWMaxMin);
342 priv->byPacketType = CARDbyGetPktType(priv);
344 CARDvSetRSPINF(priv, bb_type);
350 * Description: Sync. TSF counter to BSS
351 * Get TSF offset and write to HW
355 * priv - The adapter to be sync.
356 * byRxRate - data rate of receive beacon
357 * qwBSSTimestamp - Rx BCN's TSF
358 * qwLocalTSF - Local TSF
364 bool CARDbUpdateTSF(struct vnt_private *priv, unsigned char byRxRate,
370 CARDbGetCurrentTSF(priv, &local_tsf);
372 if (qwBSSTimestamp != local_tsf) {
373 qwTSFOffset = CARDqGetTSFOffset(byRxRate, qwBSSTimestamp,
375 /* adjust TSF, HW's TSF add TSF Offset reg */
376 VNSvOutPortD(priv->PortOffset + MAC_REG_TSFOFST, (u32)qwTSFOffset);
377 VNSvOutPortD(priv->PortOffset + MAC_REG_TSFOFST + 4, (u32)(qwTSFOffset >> 32));
378 MACvRegBitsOn(priv->PortOffset, MAC_REG_TFTCTL, TFTCTL_TSFSYNCEN);
384 * Description: Set NIC TSF counter for first Beacon time
385 * Get NEXTTBTT from adjusted TSF and Beacon Interval
389 * priv - The adapter to be set.
390 * wBeaconInterval - Beacon Interval
394 * Return Value: true if succeed; otherwise false
396 bool CARDbSetBeaconPeriod(struct vnt_private *priv,
397 unsigned short wBeaconInterval)
401 CARDbGetCurrentTSF(priv, &qwNextTBTT); /* Get Local TSF counter */
403 qwNextTBTT = CARDqGetNextTBTT(qwNextTBTT, wBeaconInterval);
405 /* set HW beacon interval */
406 VNSvOutPortW(priv->PortOffset + MAC_REG_BI, wBeaconInterval);
407 priv->wBeaconInterval = wBeaconInterval;
409 VNSvOutPortD(priv->PortOffset + MAC_REG_NEXTTBTT, (u32)qwNextTBTT);
410 VNSvOutPortD(priv->PortOffset + MAC_REG_NEXTTBTT + 4, (u32)(qwNextTBTT >> 32));
411 MACvRegBitsOn(priv->PortOffset, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN);
417 * Description: Turn off Radio power
421 * priv - The adapter to be turned off
425 * Return Value: true if success; otherwise false
427 bool CARDbRadioPowerOff(struct vnt_private *priv)
434 switch (priv->byRFType) {
436 MACvWordRegBitsOff(priv->PortOffset, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_TXPEINV);
437 MACvWordRegBitsOn(priv->PortOffset, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE1);
443 MACvWordRegBitsOff(priv->PortOffset, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE2);
444 MACvWordRegBitsOff(priv->PortOffset, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE3);
448 MACvRegBitsOff(priv->PortOffset, MAC_REG_HOSTCR, HOSTCR_RXON);
450 BBvSetDeepSleep(priv, priv->byLocalID);
452 priv->bRadioOff = true;
453 pr_debug("chester power off\n");
454 MACvRegBitsOn(priv->PortOffset, MAC_REG_GPIOCTL0, LED_ACTSET); /* LED issue */
459 * Description: Turn on Radio power
463 * priv - The adapter to be turned on
467 * Return Value: true if success; otherwise false
469 bool CARDbRadioPowerOn(struct vnt_private *priv)
473 pr_debug("chester power on\n");
474 if (priv->bRadioControlOff) {
475 if (priv->bHWRadioOff)
476 pr_debug("chester bHWRadioOff\n");
477 if (priv->bRadioControlOff)
478 pr_debug("chester bRadioControlOff\n");
481 if (!priv->bRadioOff) {
482 pr_debug("chester pbRadioOff\n");
485 BBvExitDeepSleep(priv, priv->byLocalID);
487 MACvRegBitsOn(priv->PortOffset, MAC_REG_HOSTCR, HOSTCR_RXON);
489 switch (priv->byRFType) {
491 MACvWordRegBitsOn(priv->PortOffset, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_TXPEINV);
492 MACvWordRegBitsOff(priv->PortOffset, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE1);
498 MACvWordRegBitsOn(priv->PortOffset, MAC_REG_SOFTPWRCTL, (SOFTPWRCTL_SWPE2 |
503 priv->bRadioOff = false;
504 pr_debug("chester power on\n");
505 MACvRegBitsOff(priv->PortOffset, MAC_REG_GPIOCTL0, LED_ACTSET); /* LED issue */
511 struct vnt_private *priv
515 struct vnt_tx_desc *pCurrTD;
517 /* initialize TD index */
518 priv->apTailTD[0] = priv->apCurrTD[0] = &(priv->apTD0Rings[0]);
519 priv->apTailTD[1] = priv->apCurrTD[1] = &(priv->apTD1Rings[0]);
521 for (uu = 0; uu < TYPE_MAXTD; uu++)
522 priv->iTDUsed[uu] = 0;
524 for (uu = 0; uu < priv->opts.tx_descs[0]; uu++) {
525 pCurrTD = &(priv->apTD0Rings[uu]);
526 pCurrTD->td0.owner = OWNED_BY_HOST;
527 /* init all Tx Packet pointer to NULL */
529 for (uu = 0; uu < priv->opts.tx_descs[1]; uu++) {
530 pCurrTD = &(priv->apTD1Rings[uu]);
531 pCurrTD->td0.owner = OWNED_BY_HOST;
532 /* init all Tx Packet pointer to NULL */
535 /* set MAC TD pointer */
536 MACvSetCurrTXDescAddr(TYPE_TXDMA0, priv, priv->td0_pool_dma);
538 MACvSetCurrTXDescAddr(TYPE_AC0DMA, priv, priv->td1_pool_dma);
540 /* set MAC Beacon TX pointer */
541 MACvSetCurrBCNTxDescAddr(priv->PortOffset,
542 (priv->tx_beacon_dma));
551 * priv - Pointer to the adapter
559 struct vnt_private *priv
563 struct vnt_rx_desc *pDesc;
565 /* initialize RD index */
566 priv->pCurrRD[0] = &(priv->aRD0Ring[0]);
567 priv->pCurrRD[1] = &(priv->aRD1Ring[0]);
569 /* init state, all RD is chip's */
570 for (uu = 0; uu < priv->opts.rx_descs0; uu++) {
571 pDesc = &(priv->aRD0Ring[uu]);
572 pDesc->rd0.res_count = cpu_to_le16(priv->rx_buf_sz);
573 pDesc->rd0.owner = OWNED_BY_NIC;
574 pDesc->rd1.req_count = cpu_to_le16(priv->rx_buf_sz);
577 /* init state, all RD is chip's */
578 for (uu = 0; uu < priv->opts.rx_descs1; uu++) {
579 pDesc = &(priv->aRD1Ring[uu]);
580 pDesc->rd0.res_count = cpu_to_le16(priv->rx_buf_sz);
581 pDesc->rd0.owner = OWNED_BY_NIC;
582 pDesc->rd1.req_count = cpu_to_le16(priv->rx_buf_sz);
585 /* set perPkt mode */
586 MACvRx0PerPktMode(priv->PortOffset);
587 MACvRx1PerPktMode(priv->PortOffset);
588 /* set MAC RD pointer */
589 MACvSetCurrRx0DescAddr(priv, priv->rd0_pool_dma);
591 MACvSetCurrRx1DescAddr(priv, priv->rd1_pool_dma);
595 * Description: Get response Control frame rate in CCK mode
599 * priv - The adapter to be set
600 * wRateIdx - Receiving data rate
604 * Return Value: response Control frame rate
606 static unsigned short CARDwGetCCKControlRate(struct vnt_private *priv,
607 unsigned short wRateIdx)
609 unsigned int ui = (unsigned int) wRateIdx;
611 while (ui > RATE_1M) {
612 if (priv->basic_rates & ((u32)0x1 << ui))
613 return (unsigned short)ui;
617 return (unsigned short)RATE_1M;
621 * Description: Get response Control frame rate in OFDM mode
625 * priv - The adapter to be set
626 * wRateIdx - Receiving data rate
630 * Return Value: response Control frame rate
632 static unsigned short CARDwGetOFDMControlRate(struct vnt_private *priv,
633 unsigned short wRateIdx)
635 unsigned int ui = (unsigned int) wRateIdx;
637 pr_debug("BASIC RATE: %X\n", priv->basic_rates);
639 if (!CARDbIsOFDMinBasicRate((void *)priv)) {
640 pr_debug("CARDwGetOFDMControlRate:(NO OFDM) %d\n", wRateIdx);
641 if (wRateIdx > RATE_24M)
645 while (ui > RATE_11M) {
646 if (priv->basic_rates & ((u32)0x1 << ui)) {
647 pr_debug("CARDwGetOFDMControlRate : %d\n", ui);
648 return (unsigned short)ui;
652 pr_debug("CARDwGetOFDMControlRate: 6M\n");
653 return (unsigned short)RATE_24M;
657 * Description: Set RSPINF
661 * priv - The adapter to be set
665 * Return Value: None.
667 void CARDvSetRSPINF(struct vnt_private *priv, u8 bb_type)
669 union vnt_phy_field_swap phy;
670 unsigned char byTxRate, byRsvTime; /* For OFDM */
673 spin_lock_irqsave(&priv->lock, flags);
676 MACvSelectPage1(priv->PortOffset);
679 vnt_get_phy_field(priv, 14,
680 CARDwGetCCKControlRate(priv, RATE_1M),
681 PK_TYPE_11B, &phy.field_read);
683 /* swap over to get correct write order */
684 swap(phy.swap[0], phy.swap[1]);
686 VNSvOutPortD(priv->PortOffset + MAC_REG_RSPINF_B_1, phy.field_write);
689 vnt_get_phy_field(priv, 14,
690 CARDwGetCCKControlRate(priv, RATE_2M),
691 PK_TYPE_11B, &phy.field_read);
693 swap(phy.swap[0], phy.swap[1]);
695 VNSvOutPortD(priv->PortOffset + MAC_REG_RSPINF_B_2, phy.field_write);
698 vnt_get_phy_field(priv, 14,
699 CARDwGetCCKControlRate(priv, RATE_5M),
700 PK_TYPE_11B, &phy.field_read);
702 swap(phy.swap[0], phy.swap[1]);
704 VNSvOutPortD(priv->PortOffset + MAC_REG_RSPINF_B_5, phy.field_write);
707 vnt_get_phy_field(priv, 14,
708 CARDwGetCCKControlRate(priv, RATE_11M),
709 PK_TYPE_11B, &phy.field_read);
711 swap(phy.swap[0], phy.swap[1]);
713 VNSvOutPortD(priv->PortOffset + MAC_REG_RSPINF_B_11, phy.field_write);
716 s_vCalculateOFDMRParameter(RATE_6M,
720 VNSvOutPortW(priv->PortOffset + MAC_REG_RSPINF_A_6, MAKEWORD(byTxRate, byRsvTime));
722 s_vCalculateOFDMRParameter(RATE_9M,
726 VNSvOutPortW(priv->PortOffset + MAC_REG_RSPINF_A_9, MAKEWORD(byTxRate, byRsvTime));
728 s_vCalculateOFDMRParameter(RATE_12M,
732 VNSvOutPortW(priv->PortOffset + MAC_REG_RSPINF_A_12, MAKEWORD(byTxRate, byRsvTime));
734 s_vCalculateOFDMRParameter(RATE_18M,
738 VNSvOutPortW(priv->PortOffset + MAC_REG_RSPINF_A_18, MAKEWORD(byTxRate, byRsvTime));
740 s_vCalculateOFDMRParameter(RATE_24M,
744 VNSvOutPortW(priv->PortOffset + MAC_REG_RSPINF_A_24, MAKEWORD(byTxRate, byRsvTime));
746 s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)priv, RATE_36M),
750 VNSvOutPortW(priv->PortOffset + MAC_REG_RSPINF_A_36, MAKEWORD(byTxRate, byRsvTime));
752 s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)priv, RATE_48M),
756 VNSvOutPortW(priv->PortOffset + MAC_REG_RSPINF_A_48, MAKEWORD(byTxRate, byRsvTime));
758 s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)priv, RATE_54M),
762 VNSvOutPortW(priv->PortOffset + MAC_REG_RSPINF_A_54, MAKEWORD(byTxRate, byRsvTime));
764 s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)priv, RATE_54M),
768 VNSvOutPortW(priv->PortOffset + MAC_REG_RSPINF_A_72, MAKEWORD(byTxRate, byRsvTime));
770 MACvSelectPage0(priv->PortOffset);
772 spin_unlock_irqrestore(&priv->lock, flags);
775 void CARDvUpdateBasicTopRate(struct vnt_private *priv)
777 unsigned char byTopOFDM = RATE_24M, byTopCCK = RATE_1M;
780 /* Determines the highest basic rate. */
781 for (ii = RATE_54M; ii >= RATE_6M; ii--) {
782 if ((priv->basic_rates) & ((u32)(1 << ii))) {
787 priv->byTopOFDMBasicRate = byTopOFDM;
789 for (ii = RATE_11M;; ii--) {
790 if ((priv->basic_rates) & ((u32)(1 << ii))) {
797 priv->byTopCCKBasicRate = byTopCCK;
800 bool CARDbIsOFDMinBasicRate(struct vnt_private *priv)
804 for (ii = RATE_54M; ii >= RATE_6M; ii--) {
805 if ((priv->basic_rates) & ((u32)BIT(ii)))
811 unsigned char CARDbyGetPktType(struct vnt_private *priv)
813 if (priv->byBBType == BB_TYPE_11A || priv->byBBType == BB_TYPE_11B)
814 return (unsigned char)priv->byBBType;
815 else if (CARDbIsOFDMinBasicRate((void *)priv))
822 * Description: Set NIC Loopback mode
826 * priv - The adapter to be set
827 * wLoopbackMode - Loopback mode to be set
833 void CARDvSetLoopbackMode(struct vnt_private *priv, unsigned short wLoopbackMode)
835 switch (wLoopbackMode) {
843 /* set MAC loopback */
844 MACvSetLoopbackMode(priv, LOBYTE(wLoopbackMode));
845 /* set Baseband loopback */
849 * Description: Software Reset NIC
853 * priv - The adapter to be reset
859 bool CARDbSoftwareReset(struct vnt_private *priv)
862 if (!MACbSafeSoftwareReset(priv))
869 * Description: Calculate TSF offset of two TSF input
870 * Get TSF Offset from RxBCN's TSF and local TSF
874 * priv - The adapter to be sync.
875 * qwTSF1 - Rx BCN's TSF
880 * Return Value: TSF Offset value
882 u64 CARDqGetTSFOffset(unsigned char byRxRate, u64 qwTSF1, u64 qwTSF2)
885 unsigned short wRxBcnTSFOffst;
887 wRxBcnTSFOffst = cwRXBCNTSFOff[byRxRate%MAX_RATE];
889 qwTSF2 += (u64)wRxBcnTSFOffst;
891 qwTSFOffset = qwTSF1 - qwTSF2;
897 * Description: Read NIC TSF counter
898 * Get local TSF counter
902 * priv - The adapter to be read
904 * qwCurrTSF - Current TSF counter
906 * Return Value: true if success; otherwise false
908 bool CARDbGetCurrentTSF(struct vnt_private *priv, u64 *pqwCurrTSF)
910 void __iomem *dwIoBase = priv->PortOffset;
912 unsigned char byData;
914 MACvRegBitsOn(dwIoBase, MAC_REG_TFTCTL, TFTCTL_TSFCNTRRD);
915 for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
916 VNSvInPortB(dwIoBase + MAC_REG_TFTCTL, &byData);
917 if (!(byData & TFTCTL_TSFCNTRRD))
920 if (ww == W_MAX_TIMEOUT)
922 VNSvInPortD(dwIoBase + MAC_REG_TSFCNTR, (u32 *)pqwCurrTSF);
923 VNSvInPortD(dwIoBase + MAC_REG_TSFCNTR + 4, (u32 *)pqwCurrTSF + 1);
929 * Description: Read NIC TSF counter
930 * Get NEXTTBTT from adjusted TSF and Beacon Interval
934 * qwTSF - Current TSF counter
935 * wbeaconInterval - Beacon Interval
937 * qwCurrTSF - Current TSF counter
939 * Return Value: TSF value of next Beacon
941 u64 CARDqGetNextTBTT(u64 qwTSF, unsigned short wBeaconInterval)
945 beacon_int = wBeaconInterval * 1024;
947 do_div(qwTSF, beacon_int);
956 * Description: Set NIC TSF counter for first Beacon time
957 * Get NEXTTBTT from adjusted TSF and Beacon Interval
962 * wBeaconInterval - Beacon Interval
968 void CARDvSetFirstNextTBTT(struct vnt_private *priv, unsigned short wBeaconInterval)
970 void __iomem *dwIoBase = priv->PortOffset;
973 CARDbGetCurrentTSF(priv, &qwNextTBTT); /* Get Local TSF counter */
975 qwNextTBTT = CARDqGetNextTBTT(qwNextTBTT, wBeaconInterval);
977 VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT, (u32)qwNextTBTT);
978 VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT + 4, (u32)(qwNextTBTT >> 32));
979 MACvRegBitsOn(dwIoBase, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN);
983 * Description: Sync NIC TSF counter for Beacon time
984 * Get NEXTTBTT and write to HW
988 * priv - The adapter to be set
989 * qwTSF - Current TSF counter
990 * wBeaconInterval - Beacon Interval
996 void CARDvUpdateNextTBTT(struct vnt_private *priv, u64 qwTSF, unsigned short wBeaconInterval)
998 void __iomem *dwIoBase = priv->PortOffset;
1000 qwTSF = CARDqGetNextTBTT(qwTSF, wBeaconInterval);
1002 VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT, (u32)qwTSF);
1003 VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT + 4, (u32)(qwTSF >> 32));
1004 MACvRegBitsOn(dwIoBase, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN);
1005 pr_debug("Card:Update Next TBTT[%8llx]\n", qwTSF);