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 * vUpdateIFS - Update slotTime,SIFS,DIFS, and EIFS
25 * CARDvUpdateBasicTopRate - Update BasicTopRate
26 * CARDbAddBasicRate - Add to BasicRateSet
27 * CARDbSetBasicRate - Set Basic Tx Rate
28 * CARDbIsOFDMinBasicRate - Check if any OFDM rate is in BasicRateSet
29 * CARDvSetLoopbackMode - Set Loopback mode
30 * CARDbSoftwareReset - Sortware reset NIC
31 * CARDqGetTSFOffset - Calculate TSFOffset
32 * CARDbGetCurrentTSF - Read Current NIC TSF counter
33 * CARDqGetNextTBTT - Calculate Next Beacon TSF counter
34 * CARDvSetFirstNextTBTT - Set NIC Beacon time
35 * CARDvUpdateNextTBTT - Sync. NIC Beacon time
36 * CARDbRadioPowerOff - Turn Off NIC Radio Power
37 * CARDbRadioPowerOn - Turn On NIC Radio Power
38 * CARDbSetWEPMode - Set NIC Wep mode
39 * CARDbSetTxPower - Set NIC tx power
42 * 06-10-2003 Bryan YC Fan: Re-write codes to support VT3253 spec.
43 * 08-26-2003 Kyle Hsu: Modify the definition type of dwIoBase.
44 * 09-01-2003 Bryan YC Fan: Add vUpdateIFS().
62 //static int msglevel =MSG_LEVEL_DEBUG;
63 static int msglevel =MSG_LEVEL_INFO;
65 //const u16 cwRXBCNTSFOff[MAX_RATE] =
66 //{17, 34, 96, 192, 34, 23, 17, 11, 8, 5, 4, 3};
68 static const u16 cwRXBCNTSFOff[MAX_RATE] =
69 {192, 96, 34, 17, 34, 23, 17, 11, 8, 5, 4, 3};
72 * Description: Set NIC media channel
76 * pDevice - The adapter to be set
77 * connection_channel - Channel to be set
81 void CARDbSetMediaChannel(struct vnt_private *priv, u32 connection_channel)
84 if (priv->byBBType == BB_TYPE_11A) {
85 if ((connection_channel < (CB_MAX_CHANNEL_24G + 1)) ||
86 (connection_channel > CB_MAX_CHANNEL))
87 connection_channel = (CB_MAX_CHANNEL_24G + 1);
89 if ((connection_channel > CB_MAX_CHANNEL_24G) ||
90 (connection_channel == 0))
91 connection_channel = 1;
95 MACvRegBitsOn(priv, MAC_REG_MACCR, MACCR_CLRNAV);
97 /* Set Channel[7] = 0 to tell H/W channel is changing now. */
98 MACvRegBitsOff(priv, MAC_REG_CHANNEL, 0xb0);
100 CONTROLnsRequestOut(priv, MESSAGE_TYPE_SELECT_CHANNLE,
101 connection_channel, 0, 0, NULL);
103 if (priv->byBBType == BB_TYPE_11A) {
104 priv->byCurPwr = 0xff;
106 priv->abyOFDMAPwrTbl[connection_channel-15], RATE_54M);
107 } else if (priv->byBBType == BB_TYPE_11G) {
108 priv->byCurPwr = 0xff;
110 priv->abyOFDMPwrTbl[connection_channel-1], RATE_54M);
112 priv->byCurPwr = 0xff;
114 priv->abyCCKPwrTbl[connection_channel-1], RATE_1M);
117 ControlvWriteByte(priv, MESSAGE_REQUEST_MACREG, MAC_REG_CHANNEL,
118 (u8)(connection_channel|0x80));
122 * Description: Get CCK mode basic rate
126 * pDevice - The adapter to be set
127 * wRateIdx - Receiving data rate
131 * Return Value: response Control frame rate
134 static u16 swGetCCKControlRate(struct vnt_private *pDevice, u16 wRateIdx)
138 while (ui > RATE_1M) {
139 if (pDevice->wBasicRate & (1 << ui))
148 * Description: Get OFDM mode basic rate
152 * pDevice - The adapter to be set
153 * wRateIdx - Receiving data rate
157 * Return Value: response Control frame rate
160 static u16 swGetOFDMControlRate(struct vnt_private *pDevice, u16 wRateIdx)
164 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BASIC RATE: %X\n",
165 pDevice->wBasicRate);
167 if (!CARDbIsOFDMinBasicRate(pDevice)) {
168 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
169 "swGetOFDMControlRate:(NO OFDM) %d\n", wRateIdx);
170 if (wRateIdx > RATE_24M)
175 while (ui > RATE_11M) {
176 if (pDevice->wBasicRate & (1 << ui)) {
177 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
178 "swGetOFDMControlRate: %d\n", ui);
184 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"swGetOFDMControlRate: 6M\n");
190 * Description: Calculate TxRate and RsvTime fields for RSPINF in OFDM mode.
195 * bb_type - Tx Packet type
197 * tx_rate - pointer to RSPINF TxRate field
198 * rsv_time- pointer to RSPINF RsvTime field
203 void CARDvCalculateOFDMRParameter(u16 rate, u8 bb_type,
204 u8 *tx_rate, u8 *rsv_time)
209 if (bb_type == BB_TYPE_11A) {
218 if (bb_type == BB_TYPE_11A) {
227 if (bb_type == BB_TYPE_11A) {
236 if (bb_type == BB_TYPE_11A) {
245 if (bb_type == BB_TYPE_11A) {
254 if (bb_type == BB_TYPE_11A) {
263 if (bb_type == BB_TYPE_11A) {
273 if (bb_type == BB_TYPE_11A) {
285 * Description: Set RSPINF
289 * pDevice - The adapter to be set
293 * Return Value: None.
297 void CARDvSetRSPINF(struct vnt_private *priv, u8 bb_type)
299 struct vnt_phy_field phy[4];
300 u8 tx_rate[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; /* For OFDM */
301 u8 rsv_time[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
306 BBvCalculateParameter(priv, 14,
307 swGetCCKControlRate(priv, RATE_1M), PK_TYPE_11B, &phy[0]);
310 BBvCalculateParameter(priv, 14,
311 swGetCCKControlRate(priv, RATE_2M), PK_TYPE_11B, &phy[1]);
314 BBvCalculateParameter(priv, 14,
315 swGetCCKControlRate(priv, RATE_5M), PK_TYPE_11B, &phy[2]);
318 BBvCalculateParameter(priv, 14,
319 swGetCCKControlRate(priv, RATE_11M), PK_TYPE_11B, &phy[3]);
323 CARDvCalculateOFDMRParameter(RATE_6M, bb_type,
324 &tx_rate[0], &rsv_time[0]);
327 CARDvCalculateOFDMRParameter(RATE_9M, bb_type,
328 &tx_rate[1], &rsv_time[1]);
331 CARDvCalculateOFDMRParameter(RATE_12M, bb_type,
332 &tx_rate[2], &rsv_time[2]);
335 CARDvCalculateOFDMRParameter(RATE_18M, bb_type,
336 &tx_rate[3], &rsv_time[3]);
339 CARDvCalculateOFDMRParameter(RATE_24M, bb_type,
340 &tx_rate[4], &rsv_time[4]);
343 CARDvCalculateOFDMRParameter(swGetOFDMControlRate(priv, RATE_36M),
344 bb_type, &tx_rate[5], &rsv_time[5]);
347 CARDvCalculateOFDMRParameter(swGetOFDMControlRate(priv, RATE_48M),
348 bb_type, &tx_rate[6], &rsv_time[6]);
351 CARDvCalculateOFDMRParameter(swGetOFDMControlRate(priv, RATE_54M),
352 bb_type, &tx_rate[7], &rsv_time[7]);
355 CARDvCalculateOFDMRParameter(swGetOFDMControlRate(priv, RATE_54M),
356 bb_type, &tx_rate[8], &rsv_time[8]);
358 put_unaligned(phy[0].len, (u16 *)&data[0]);
359 data[2] = phy[0].signal;
360 data[3] = phy[0].service;
362 put_unaligned(phy[1].len, (u16 *)&data[4]);
363 data[6] = phy[1].signal;
364 data[7] = phy[1].service;
366 put_unaligned(phy[2].len, (u16 *)&data[8]);
367 data[10] = phy[2].signal;
368 data[11] = phy[2].service;
370 put_unaligned(phy[3].len, (u16 *)&data[12]);
371 data[14] = phy[3].signal;
372 data[15] = phy[3].service;
374 for (i = 0; i < 9; i++) {
375 data[16 + i * 2] = tx_rate[i];
376 data[16 + i * 2 + 1] = rsv_time[i];
379 CONTROLnsRequestOut(priv, MESSAGE_TYPE_WRITE,
380 MAC_REG_RSPINF_B_1, MESSAGE_REQUEST_MACREG, 34, &data[0]);
384 * Description: Update IFS
388 * priv - The adapter to be set
392 * Return Value: None.
395 void vUpdateIFS(struct vnt_private *priv)
400 if (priv->byPacketType == PK_TYPE_11A) {
401 priv->uSlot = C_SLOT_SHORT;
402 priv->uSIFS = C_SIFS_A;
403 priv->uDIFS = C_SIFS_A + 2 * C_SLOT_SHORT;
404 priv->uCwMin = C_CWMIN_A;
406 } else if (priv->byPacketType == PK_TYPE_11B) {
407 priv->uSlot = C_SLOT_LONG;
408 priv->uSIFS = C_SIFS_BG;
409 priv->uDIFS = C_SIFS_BG + 2 * C_SLOT_LONG;
410 priv->uCwMin = C_CWMIN_B;
412 } else {/* PK_TYPE_11GA & PK_TYPE_11GB */
414 bool ofdm_rate = false;
416 PWLAN_IE_SUPP_RATES item_rates = NULL;
418 priv->uSIFS = C_SIFS_BG;
420 if (priv->bShortSlotTime)
421 priv->uSlot = C_SLOT_SHORT;
423 priv->uSlot = C_SLOT_LONG;
425 priv->uDIFS = C_SIFS_BG + 2 * priv->uSlot;
428 (PWLAN_IE_SUPP_RATES)priv->vnt_mgmt.abyCurrSuppRates;
430 for (ii = 0; ii < item_rates->len; ii++) {
431 rate = (u8)(item_rates->abyRates[ii] & 0x7f);
432 if (RATEwGetRateIdx(rate) > RATE_11M) {
438 if (ofdm_rate == false) {
439 item_rates = (PWLAN_IE_SUPP_RATES)priv->vnt_mgmt
440 .abyCurrExtSuppRates;
441 for (ii = 0; ii < item_rates->len; ii++) {
442 rate = (u8)(item_rates->abyRates[ii] & 0x7f);
443 if (RATEwGetRateIdx(rate) > RATE_11M) {
450 if (ofdm_rate == true) {
451 priv->uCwMin = C_CWMIN_A;
454 priv->uCwMin = C_CWMIN_B;
459 priv->uCwMax = C_CWMAX;
460 priv->uEIFS = C_EIFS;
462 data[0] = (u8)priv->uSIFS;
463 data[1] = (u8)priv->uDIFS;
464 data[2] = (u8)priv->uEIFS;
465 data[3] = (u8)priv->uSlot;
467 CONTROLnsRequestOut(priv, MESSAGE_TYPE_WRITE, MAC_REG_SIFS,
468 MESSAGE_REQUEST_MACREG, 4, &data[0]);
472 CONTROLnsRequestOut(priv, MESSAGE_TYPE_WRITE, MAC_REG_CWMAXMIN0,
473 MESSAGE_REQUEST_MACREG, 1, &max_min);
476 void CARDvUpdateBasicTopRate(struct vnt_private *priv)
478 u8 top_ofdm = RATE_24M, top_cck = RATE_1M;
481 /*Determines the highest basic rate.*/
482 for (i = RATE_54M; i >= RATE_6M; i--) {
483 if (priv->wBasicRate & (u16)(1 << i)) {
489 priv->byTopOFDMBasicRate = top_ofdm;
491 for (i = RATE_11M;; i--) {
492 if (priv->wBasicRate & (u16)(1 << i)) {
500 priv->byTopCCKBasicRate = top_cck;
504 * Description: Set NIC Tx Basic Rate
508 * pDevice - The adapter to be set
509 * wBasicRate - Basic Rate to be set
513 * Return Value: true if succeeded; false if failed.
516 void CARDbAddBasicRate(struct vnt_private *priv, u16 rate_idx)
519 priv->wBasicRate |= (1 << rate_idx);
521 /*Determines the highest basic rate.*/
522 CARDvUpdateBasicTopRate(priv);
525 int CARDbIsOFDMinBasicRate(struct vnt_private *pDevice)
529 for (ii = RATE_54M; ii >= RATE_6M; ii --) {
530 if ((pDevice->wBasicRate) & ((u16)(1<<ii)))
536 u8 CARDbyGetPktType(struct vnt_private *pDevice)
539 if (pDevice->byBBType == BB_TYPE_11A || pDevice->byBBType == BB_TYPE_11B) {
540 return (u8)pDevice->byBBType;
542 else if (CARDbIsOFDMinBasicRate(pDevice)) {
551 * Description: Calculate TSF offset of two TSF input
552 * Get TSF Offset from RxBCN's TSF and local TSF
556 * pDevice - The adapter to be sync.
557 * qwTSF1 - Rx BCN's TSF
562 * Return Value: TSF Offset value
565 u64 CARDqGetTSFOffset(u8 byRxRate, u64 qwTSF1, u64 qwTSF2)
568 u16 wRxBcnTSFOffst = 0;
570 wRxBcnTSFOffst = cwRXBCNTSFOff[byRxRate % MAX_RATE];
572 qwTSF2 += (u64)wRxBcnTSFOffst;
574 qwTSFOffset = qwTSF1 - qwTSF2;
580 * Description: Sync. TSF counter to BSS
581 * Get TSF offset and write to HW
585 * pDevice - The adapter to be sync.
586 * qwBSSTimestamp - Rx BCN's TSF
587 * qwLocalTSF - Local TSF
594 void CARDvAdjustTSF(struct vnt_private *pDevice, u8 byRxRate,
595 u64 qwBSSTimestamp, u64 qwLocalTSF)
600 qwTSFOffset = CARDqGetTSFOffset(byRxRate, qwBSSTimestamp, qwLocalTSF);
602 // HW's TSF add TSF Offset reg
604 pbyData[0] = (u8)qwTSFOffset;
605 pbyData[1] = (u8)(qwTSFOffset >> 8);
606 pbyData[2] = (u8)(qwTSFOffset >> 16);
607 pbyData[3] = (u8)(qwTSFOffset >> 24);
608 pbyData[4] = (u8)(qwTSFOffset >> 32);
609 pbyData[5] = (u8)(qwTSFOffset >> 40);
610 pbyData[6] = (u8)(qwTSFOffset >> 48);
611 pbyData[7] = (u8)(qwTSFOffset >> 56);
613 CONTROLnsRequestOut(pDevice,
614 MESSAGE_TYPE_SET_TSFTBTT,
623 * Description: Read NIC TSF counter
624 * Get local TSF counter
628 * pDevice - The adapter to be read
630 * qwCurrTSF - Current TSF counter
632 * Return Value: true if success; otherwise false
635 bool CARDbGetCurrentTSF(struct vnt_private *pDevice, u64 *pqwCurrTSF)
638 *pqwCurrTSF = pDevice->qwCurrTSF;
644 * Description: Clear NIC TSF counter
645 * Clear local TSF counter
649 * pDevice - The adapter to be read
651 * Return Value: true if success; otherwise false
654 bool CARDbClearCurrentTSF(struct vnt_private *pDevice)
657 MACvRegBitsOn(pDevice, MAC_REG_TFTCTL, TFTCTL_TSFCNTRST);
659 pDevice->qwCurrTSF = 0;
665 * Description: Read NIC TSF counter
666 * Get NEXTTBTT from adjusted TSF and Beacon Interval
670 * qwTSF - Current TSF counter
671 * wbeaconInterval - Beacon Interval
673 * qwCurrTSF - Current TSF counter
675 * Return Value: TSF value of next Beacon
678 u64 CARDqGetNextTBTT(u64 qwTSF, u16 wBeaconInterval)
682 uBeaconInterval = wBeaconInterval * 1024;
685 * ((local_current_TSF / beacon_interval) + 1) * beacon_interval
687 if (uBeaconInterval) {
688 do_div(qwTSF, uBeaconInterval);
690 qwTSF *= uBeaconInterval;
697 * Description: Set NIC TSF counter for first Beacon time
698 * Get NEXTTBTT from adjusted TSF and Beacon Interval
703 * wBeaconInterval - Beacon Interval
710 void CARDvSetFirstNextTBTT(struct vnt_private *pDevice, u16 wBeaconInterval)
715 CARDbClearCurrentTSF(pDevice);
716 //CARDbGetCurrentTSF(pDevice, &qwNextTBTT); //Get Local TSF counter
717 qwNextTBTT = CARDqGetNextTBTT(qwNextTBTT, wBeaconInterval);
720 pbyData[0] = (u8)qwNextTBTT;
721 pbyData[1] = (u8)(qwNextTBTT >> 8);
722 pbyData[2] = (u8)(qwNextTBTT >> 16);
723 pbyData[3] = (u8)(qwNextTBTT >> 24);
724 pbyData[4] = (u8)(qwNextTBTT >> 32);
725 pbyData[5] = (u8)(qwNextTBTT >> 40);
726 pbyData[6] = (u8)(qwNextTBTT >> 48);
727 pbyData[7] = (u8)(qwNextTBTT >> 56);
729 CONTROLnsRequestOut(pDevice,
730 MESSAGE_TYPE_SET_TSFTBTT,
731 MESSAGE_REQUEST_TBTT,
741 * Description: Sync NIC TSF counter for Beacon time
742 * Get NEXTTBTT and write to HW
746 * pDevice - The adapter to be set
747 * qwTSF - Current TSF counter
748 * wBeaconInterval - Beacon Interval
755 void CARDvUpdateNextTBTT(struct vnt_private *pDevice, u64 qwTSF,
760 qwTSF = CARDqGetNextTBTT(qwTSF, wBeaconInterval);
764 pbyData[0] = (u8)qwTSF;
765 pbyData[1] = (u8)(qwTSF >> 8);
766 pbyData[2] = (u8)(qwTSF >> 16);
767 pbyData[3] = (u8)(qwTSF >> 24);
768 pbyData[4] = (u8)(qwTSF >> 32);
769 pbyData[5] = (u8)(qwTSF >> 40);
770 pbyData[6] = (u8)(qwTSF >> 48);
771 pbyData[7] = (u8)(qwTSF >> 56);
773 CONTROLnsRequestOut(pDevice,
774 MESSAGE_TYPE_SET_TSFTBTT,
775 MESSAGE_REQUEST_TBTT,
781 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
782 "Card:Update Next TBTT[%8lx]\n", (unsigned long)qwTSF);
788 * Description: Turn off Radio power
792 * pDevice - The adapter to be turned off
796 * Return Value: true if success; otherwise false
799 int CARDbRadioPowerOff(struct vnt_private *pDevice)
803 //if (pDevice->bRadioOff == true)
806 pDevice->bRadioOff = true;
808 switch (pDevice->byRFType) {
812 case RF_VT3226: //RobertYu:20051111
814 case RF_VT3342A0: //RobertYu:20060609
815 MACvRegBitsOff(pDevice, MAC_REG_SOFTPWRCTL, (SOFTPWRCTL_SWPE2 | SOFTPWRCTL_SWPE3));
819 MACvRegBitsOff(pDevice, MAC_REG_HOSTCR, HOSTCR_RXON);
821 BBvSetDeepSleep(pDevice);
827 * Description: Turn on Radio power
831 * pDevice - The adapter to be turned on
835 * Return Value: true if success; otherwise false
838 int CARDbRadioPowerOn(struct vnt_private *pDevice)
842 if ((pDevice->bHWRadioOff == true) || (pDevice->bRadioControlOff == true)) {
846 //if (pDevice->bRadioOff == false)
849 pDevice->bRadioOff = false;
851 BBvExitDeepSleep(pDevice);
853 MACvRegBitsOn(pDevice, MAC_REG_HOSTCR, HOSTCR_RXON);
855 switch (pDevice->byRFType) {
859 case RF_VT3226: //RobertYu:20051111
861 case RF_VT3342A0: //RobertYu:20060609
862 MACvRegBitsOn(pDevice, MAC_REG_SOFTPWRCTL, (SOFTPWRCTL_SWPE2 | SOFTPWRCTL_SWPE3));
869 void CARDvSetBSSMode(struct vnt_private *pDevice)
871 // Set BB and packet type at the same time.//{{RobertYu:20050222, AL7230 have two TX PA output, only connet to b/g now
872 // so in 11a mode need to set the MAC Reg0x4C to 11b/g mode to turn on PA
873 if( (pDevice->byRFType == RF_AIROHA7230 ) && (pDevice->byBBType == BB_TYPE_11A) )
875 MACvSetBBType(pDevice, BB_TYPE_11G);
879 MACvSetBBType(pDevice, pDevice->byBBType);
881 pDevice->byPacketType = CARDbyGetPktType(pDevice);
883 if (pDevice->byBBType == BB_TYPE_11A) {
884 ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x88, 0x03);
885 } else if (pDevice->byBBType == BB_TYPE_11B) {
886 ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x88, 0x02);
887 } else if (pDevice->byBBType == BB_TYPE_11G) {
888 ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x88, 0x08);
892 CARDvSetRSPINF(pDevice, (u8)pDevice->byBBType);
894 if ( pDevice->byBBType == BB_TYPE_11A ) {
895 //request by Jack 2005-04-26
896 if (pDevice->byRFType == RF_AIROHA7230) {
897 pDevice->abyBBVGA[0] = 0x20;
898 ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xE7, pDevice->abyBBVGA[0]);
900 pDevice->abyBBVGA[2] = 0x10;
901 pDevice->abyBBVGA[3] = 0x10;
903 //request by Jack 2005-04-26
904 if (pDevice->byRFType == RF_AIROHA7230) {
905 pDevice->abyBBVGA[0] = 0x1C;
906 ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xE7, pDevice->abyBBVGA[0]);
908 pDevice->abyBBVGA[2] = 0x0;
909 pDevice->abyBBVGA[3] = 0x0;