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 //const u16 cwRXBCNTSFOff[MAX_RATE] =
63 //{17, 34, 96, 192, 34, 23, 17, 11, 8, 5, 4, 3};
65 static const u16 cwRXBCNTSFOff
[MAX_RATE
] =
66 {192, 96, 34, 17, 34, 23, 17, 11, 8, 5, 4, 3};
69 * Description: Set NIC media channel
73 * pDevice - The adapter to be set
74 * connection_channel - Channel to be set
78 void CARDbSetMediaChannel(struct vnt_private
*priv
, u32 connection_channel
)
81 if (priv
->byBBType
== BB_TYPE_11A
) {
82 if ((connection_channel
< (CB_MAX_CHANNEL_24G
+ 1)) ||
83 (connection_channel
> CB_MAX_CHANNEL
))
84 connection_channel
= (CB_MAX_CHANNEL_24G
+ 1);
86 if ((connection_channel
> CB_MAX_CHANNEL_24G
) ||
87 (connection_channel
== 0))
88 connection_channel
= 1;
92 MACvRegBitsOn(priv
, MAC_REG_MACCR
, MACCR_CLRNAV
);
94 /* Set Channel[7] = 0 to tell H/W channel is changing now. */
95 MACvRegBitsOff(priv
, MAC_REG_CHANNEL
, 0xb0);
97 vnt_control_out(priv
, MESSAGE_TYPE_SELECT_CHANNLE
,
98 connection_channel
, 0, 0, NULL
);
100 if (priv
->byBBType
== BB_TYPE_11A
) {
101 priv
->byCurPwr
= 0xff;
102 vnt_rf_set_txpower(priv
,
103 priv
->abyOFDMAPwrTbl
[connection_channel
-15], RATE_54M
);
104 } else if (priv
->byBBType
== BB_TYPE_11G
) {
105 priv
->byCurPwr
= 0xff;
106 vnt_rf_set_txpower(priv
,
107 priv
->abyOFDMPwrTbl
[connection_channel
-1], RATE_54M
);
109 priv
->byCurPwr
= 0xff;
110 vnt_rf_set_txpower(priv
,
111 priv
->abyCCKPwrTbl
[connection_channel
-1], RATE_1M
);
114 vnt_control_out_u8(priv
, MESSAGE_REQUEST_MACREG
, MAC_REG_CHANNEL
,
115 (u8
)(connection_channel
|0x80));
119 * Description: Get CCK mode basic rate
123 * priv - The adapter to be set
124 * rate_idx - Receiving data rate
128 * Return Value: response Control frame rate
131 static u16
swGetCCKControlRate(struct vnt_private
*priv
, u16 rate_idx
)
135 while (ui
> RATE_1M
) {
136 if (priv
->wBasicRate
& (1 << ui
))
145 * Description: Get OFDM mode basic rate
149 * priv - The adapter to be set
150 * rate_idx - Receiving data rate
154 * Return Value: response Control frame rate
157 static u16
swGetOFDMControlRate(struct vnt_private
*priv
, u16 rate_idx
)
161 dev_dbg(&priv
->usb
->dev
, "%s basic rate: %d\n",
162 __func__
, priv
->wBasicRate
);
164 if (!CARDbIsOFDMinBasicRate(priv
)) {
165 dev_dbg(&priv
->usb
->dev
, "%s (NO OFDM) %d\n",
167 if (rate_idx
> RATE_24M
)
172 while (ui
> RATE_11M
) {
173 if (priv
->wBasicRate
& (1 << ui
)) {
174 dev_dbg(&priv
->usb
->dev
, "%s rate: %d\n",
181 dev_dbg(&priv
->usb
->dev
, "%s basic rate: 24M\n", __func__
);
187 * Description: Calculate TxRate and RsvTime fields for RSPINF in OFDM mode.
192 * bb_type - Tx Packet type
194 * tx_rate - pointer to RSPINF TxRate field
195 * rsv_time- pointer to RSPINF RsvTime field
200 static void CARDvCalculateOFDMRParameter(u16 rate
, u8 bb_type
,
201 u8
*tx_rate
, u8
*rsv_time
)
206 if (bb_type
== BB_TYPE_11A
) {
215 if (bb_type
== BB_TYPE_11A
) {
224 if (bb_type
== BB_TYPE_11A
) {
233 if (bb_type
== BB_TYPE_11A
) {
242 if (bb_type
== BB_TYPE_11A
) {
251 if (bb_type
== BB_TYPE_11A
) {
260 if (bb_type
== BB_TYPE_11A
) {
270 if (bb_type
== BB_TYPE_11A
) {
282 * Description: Set RSPINF
286 * pDevice - The adapter to be set
290 * Return Value: None.
294 void CARDvSetRSPINF(struct vnt_private
*priv
, u8 bb_type
)
296 struct vnt_phy_field phy
[4];
297 u8 tx_rate
[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; /* For OFDM */
298 u8 rsv_time
[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
303 BBvCalculateParameter(priv
, 14,
304 swGetCCKControlRate(priv
, RATE_1M
), PK_TYPE_11B
, &phy
[0]);
307 BBvCalculateParameter(priv
, 14,
308 swGetCCKControlRate(priv
, RATE_2M
), PK_TYPE_11B
, &phy
[1]);
311 BBvCalculateParameter(priv
, 14,
312 swGetCCKControlRate(priv
, RATE_5M
), PK_TYPE_11B
, &phy
[2]);
315 BBvCalculateParameter(priv
, 14,
316 swGetCCKControlRate(priv
, RATE_11M
), PK_TYPE_11B
, &phy
[3]);
320 CARDvCalculateOFDMRParameter(RATE_6M
, bb_type
,
321 &tx_rate
[0], &rsv_time
[0]);
324 CARDvCalculateOFDMRParameter(RATE_9M
, bb_type
,
325 &tx_rate
[1], &rsv_time
[1]);
328 CARDvCalculateOFDMRParameter(RATE_12M
, bb_type
,
329 &tx_rate
[2], &rsv_time
[2]);
332 CARDvCalculateOFDMRParameter(RATE_18M
, bb_type
,
333 &tx_rate
[3], &rsv_time
[3]);
336 CARDvCalculateOFDMRParameter(RATE_24M
, bb_type
,
337 &tx_rate
[4], &rsv_time
[4]);
340 CARDvCalculateOFDMRParameter(swGetOFDMControlRate(priv
, RATE_36M
),
341 bb_type
, &tx_rate
[5], &rsv_time
[5]);
344 CARDvCalculateOFDMRParameter(swGetOFDMControlRate(priv
, RATE_48M
),
345 bb_type
, &tx_rate
[6], &rsv_time
[6]);
348 CARDvCalculateOFDMRParameter(swGetOFDMControlRate(priv
, RATE_54M
),
349 bb_type
, &tx_rate
[7], &rsv_time
[7]);
352 CARDvCalculateOFDMRParameter(swGetOFDMControlRate(priv
, RATE_54M
),
353 bb_type
, &tx_rate
[8], &rsv_time
[8]);
355 put_unaligned(phy
[0].len
, (u16
*)&data
[0]);
356 data
[2] = phy
[0].signal
;
357 data
[3] = phy
[0].service
;
359 put_unaligned(phy
[1].len
, (u16
*)&data
[4]);
360 data
[6] = phy
[1].signal
;
361 data
[7] = phy
[1].service
;
363 put_unaligned(phy
[2].len
, (u16
*)&data
[8]);
364 data
[10] = phy
[2].signal
;
365 data
[11] = phy
[2].service
;
367 put_unaligned(phy
[3].len
, (u16
*)&data
[12]);
368 data
[14] = phy
[3].signal
;
369 data
[15] = phy
[3].service
;
371 for (i
= 0; i
< 9; i
++) {
372 data
[16 + i
* 2] = tx_rate
[i
];
373 data
[16 + i
* 2 + 1] = rsv_time
[i
];
376 vnt_control_out(priv
, MESSAGE_TYPE_WRITE
,
377 MAC_REG_RSPINF_B_1
, MESSAGE_REQUEST_MACREG
, 34, &data
[0]);
381 * Description: Update IFS
385 * priv - The adapter to be set
389 * Return Value: None.
392 void vUpdateIFS(struct vnt_private
*priv
)
397 if (priv
->byPacketType
== PK_TYPE_11A
) {
398 priv
->uSlot
= C_SLOT_SHORT
;
399 priv
->uSIFS
= C_SIFS_A
;
400 priv
->uDIFS
= C_SIFS_A
+ 2 * C_SLOT_SHORT
;
401 priv
->uCwMin
= C_CWMIN_A
;
403 } else if (priv
->byPacketType
== PK_TYPE_11B
) {
404 priv
->uSlot
= C_SLOT_LONG
;
405 priv
->uSIFS
= C_SIFS_BG
;
406 priv
->uDIFS
= C_SIFS_BG
+ 2 * C_SLOT_LONG
;
407 priv
->uCwMin
= C_CWMIN_B
;
409 } else {/* PK_TYPE_11GA & PK_TYPE_11GB */
411 bool ofdm_rate
= false;
413 PWLAN_IE_SUPP_RATES item_rates
= NULL
;
415 priv
->uSIFS
= C_SIFS_BG
;
417 if (priv
->bShortSlotTime
)
418 priv
->uSlot
= C_SLOT_SHORT
;
420 priv
->uSlot
= C_SLOT_LONG
;
422 priv
->uDIFS
= C_SIFS_BG
+ 2 * priv
->uSlot
;
425 (PWLAN_IE_SUPP_RATES
)priv
->vnt_mgmt
.abyCurrSuppRates
;
427 for (ii
= 0; ii
< item_rates
->len
; ii
++) {
428 rate
= (u8
)(item_rates
->abyRates
[ii
] & 0x7f);
429 if (RATEwGetRateIdx(rate
) > RATE_11M
) {
435 if (ofdm_rate
== false) {
436 item_rates
= (PWLAN_IE_SUPP_RATES
)priv
->vnt_mgmt
437 .abyCurrExtSuppRates
;
438 for (ii
= 0; ii
< item_rates
->len
; ii
++) {
439 rate
= (u8
)(item_rates
->abyRates
[ii
] & 0x7f);
440 if (RATEwGetRateIdx(rate
) > RATE_11M
) {
447 if (ofdm_rate
== true) {
448 priv
->uCwMin
= C_CWMIN_A
;
451 priv
->uCwMin
= C_CWMIN_B
;
456 priv
->uCwMax
= C_CWMAX
;
457 priv
->uEIFS
= C_EIFS
;
459 data
[0] = (u8
)priv
->uSIFS
;
460 data
[1] = (u8
)priv
->uDIFS
;
461 data
[2] = (u8
)priv
->uEIFS
;
462 data
[3] = (u8
)priv
->uSlot
;
464 vnt_control_out(priv
, MESSAGE_TYPE_WRITE
, MAC_REG_SIFS
,
465 MESSAGE_REQUEST_MACREG
, 4, &data
[0]);
469 vnt_control_out(priv
, MESSAGE_TYPE_WRITE
, MAC_REG_CWMAXMIN0
,
470 MESSAGE_REQUEST_MACREG
, 1, &max_min
);
473 void CARDvUpdateBasicTopRate(struct vnt_private
*priv
)
475 u8 top_ofdm
= RATE_24M
, top_cck
= RATE_1M
;
478 /*Determines the highest basic rate.*/
479 for (i
= RATE_54M
; i
>= RATE_6M
; i
--) {
480 if (priv
->wBasicRate
& (u16
)(1 << i
)) {
486 priv
->byTopOFDMBasicRate
= top_ofdm
;
488 for (i
= RATE_11M
;; i
--) {
489 if (priv
->wBasicRate
& (u16
)(1 << i
)) {
497 priv
->byTopCCKBasicRate
= top_cck
;
501 * Description: Set NIC Tx Basic Rate
505 * pDevice - The adapter to be set
506 * wBasicRate - Basic Rate to be set
510 * Return Value: true if succeeded; false if failed.
513 void CARDbAddBasicRate(struct vnt_private
*priv
, u16 rate_idx
)
516 priv
->wBasicRate
|= (1 << rate_idx
);
518 /*Determines the highest basic rate.*/
519 CARDvUpdateBasicTopRate(priv
);
522 int CARDbIsOFDMinBasicRate(struct vnt_private
*priv
)
526 for (ii
= RATE_54M
; ii
>= RATE_6M
; ii
--) {
527 if ((priv
->wBasicRate
) & ((u16
)(1 << ii
)))
534 u8
CARDbyGetPktType(struct vnt_private
*priv
)
537 if (priv
->byBBType
== BB_TYPE_11A
|| priv
->byBBType
== BB_TYPE_11B
)
538 return (u8
)priv
->byBBType
;
539 else if (CARDbIsOFDMinBasicRate(priv
))
546 * Description: Calculate TSF offset of two TSF input
547 * Get TSF Offset from RxBCN's TSF and local TSF
552 * tsf1 - Rx BCN's TSF
557 * Return Value: TSF Offset value
560 u64
CARDqGetTSFOffset(u8 rx_rate
, u64 tsf1
, u64 tsf2
)
563 u16 rx_bcn_offset
= 0;
565 rx_bcn_offset
= cwRXBCNTSFOff
[rx_rate
% MAX_RATE
];
567 tsf2
+= (u64
)rx_bcn_offset
;
569 tsf_offset
= tsf1
- tsf2
;
575 * Description: Sync. TSF counter to BSS
576 * Get TSF offset and write to HW
580 * priv - The adapter to be sync.
581 * time_stamp - Rx BCN's TSF
582 * local_tsf - Local TSF
589 void CARDvAdjustTSF(struct vnt_private
*priv
, u8 rx_rate
,
590 u64 time_stamp
, u64 local_tsf
)
595 tsf_offset
= CARDqGetTSFOffset(rx_rate
, time_stamp
, local_tsf
);
597 data
[0] = (u8
)tsf_offset
;
598 data
[1] = (u8
)(tsf_offset
>> 8);
599 data
[2] = (u8
)(tsf_offset
>> 16);
600 data
[3] = (u8
)(tsf_offset
>> 24);
601 data
[4] = (u8
)(tsf_offset
>> 32);
602 data
[5] = (u8
)(tsf_offset
>> 40);
603 data
[6] = (u8
)(tsf_offset
>> 48);
604 data
[7] = (u8
)(tsf_offset
>> 56);
606 vnt_control_out(priv
, MESSAGE_TYPE_SET_TSFTBTT
,
607 MESSAGE_REQUEST_TSF
, 0, 8, data
);
610 * Description: Read NIC TSF counter
611 * Get local TSF counter
615 * priv - The adapter to be read
617 * current_tsf - Current TSF counter
619 * Return Value: true if success; otherwise false
622 bool CARDbGetCurrentTSF(struct vnt_private
*priv
, u64
*current_tsf
)
625 *current_tsf
= priv
->qwCurrTSF
;
631 * Description: Clear NIC TSF counter
632 * Clear local TSF counter
636 * priv - The adapter to be read
638 * Return Value: true if success; otherwise false
641 bool CARDbClearCurrentTSF(struct vnt_private
*priv
)
644 MACvRegBitsOn(priv
, MAC_REG_TFTCTL
, TFTCTL_TSFCNTRST
);
652 * Description: Read NIC TSF counter
653 * Get NEXTTBTT from adjusted TSF and Beacon Interval
657 * tsf - Current TSF counter
658 * beacon_interval - Beacon Interval
660 * tsf - Current TSF counter
662 * Return Value: TSF value of next Beacon
665 u64
CARDqGetNextTBTT(u64 tsf
, u16 beacon_interval
)
669 beacon_int
= beacon_interval
* 1024;
672 * ((local_current_TSF / beacon_interval) + 1) * beacon_interval
675 do_div(tsf
, beacon_int
);
684 * Description: Set NIC TSF counter for first Beacon time
685 * Get NEXTTBTT from adjusted TSF and Beacon Interval
690 * beacon_interval - Beacon Interval
697 void CARDvSetFirstNextTBTT(struct vnt_private
*priv
, u16 beacon_interval
)
702 CARDbClearCurrentTSF(priv
);
704 next_tbtt
= CARDqGetNextTBTT(next_tbtt
, beacon_interval
);
706 data
[0] = (u8
)next_tbtt
;
707 data
[1] = (u8
)(next_tbtt
>> 8);
708 data
[2] = (u8
)(next_tbtt
>> 16);
709 data
[3] = (u8
)(next_tbtt
>> 24);
710 data
[4] = (u8
)(next_tbtt
>> 32);
711 data
[5] = (u8
)(next_tbtt
>> 40);
712 data
[6] = (u8
)(next_tbtt
>> 48);
713 data
[7] = (u8
)(next_tbtt
>> 56);
715 vnt_control_out(priv
, MESSAGE_TYPE_SET_TSFTBTT
,
716 MESSAGE_REQUEST_TBTT
, 0, 8, data
);
722 * Description: Sync NIC TSF counter for Beacon time
723 * Get NEXTTBTT and write to HW
727 * priv - The adapter to be set
728 * tsf - Current TSF counter
729 * beacon_interval - Beacon Interval
736 void CARDvUpdateNextTBTT(struct vnt_private
*priv
, u64 tsf
,
741 tsf
= CARDqGetNextTBTT(tsf
, beacon_interval
);
744 data
[1] = (u8
)(tsf
>> 8);
745 data
[2] = (u8
)(tsf
>> 16);
746 data
[3] = (u8
)(tsf
>> 24);
747 data
[4] = (u8
)(tsf
>> 32);
748 data
[5] = (u8
)(tsf
>> 40);
749 data
[6] = (u8
)(tsf
>> 48);
750 data
[7] = (u8
)(tsf
>> 56);
752 vnt_control_out(priv
, MESSAGE_TYPE_SET_TSFTBTT
,
753 MESSAGE_REQUEST_TBTT
, 0, 8, data
);
755 dev_dbg(&priv
->usb
->dev
, "%s TBTT: %8llx\n", __func__
, tsf
);
761 * Description: Turn off Radio power
765 * priv - The adapter to be turned off
769 * Return Value: true if success; otherwise false
772 int CARDbRadioPowerOff(struct vnt_private
*priv
)
776 priv
->bRadioOff
= true;
778 switch (priv
->byRFType
) {
785 MACvRegBitsOff(priv
, MAC_REG_SOFTPWRCTL
,
786 (SOFTPWRCTL_SWPE2
| SOFTPWRCTL_SWPE3
));
790 MACvRegBitsOff(priv
, MAC_REG_HOSTCR
, HOSTCR_RXON
);
792 BBvSetDeepSleep(priv
);
798 * Description: Turn on Radio power
802 * priv - The adapter to be turned on
806 * Return Value: true if success; otherwise false
809 int CARDbRadioPowerOn(struct vnt_private
*priv
)
813 if (priv
->bHWRadioOff
== true || priv
->bRadioControlOff
== true)
816 priv
->bRadioOff
= false;
818 BBvExitDeepSleep(priv
);
820 MACvRegBitsOn(priv
, MAC_REG_HOSTCR
, HOSTCR_RXON
);
822 switch (priv
->byRFType
) {
829 MACvRegBitsOn(priv
, MAC_REG_SOFTPWRCTL
,
830 (SOFTPWRCTL_SWPE2
| SOFTPWRCTL_SWPE3
));
837 void CARDvSetBSSMode(struct vnt_private
*priv
)
839 if (priv
->byRFType
== RF_AIROHA7230
&& priv
->byBBType
== BB_TYPE_11A
)
840 MACvSetBBType(priv
, BB_TYPE_11G
);
842 MACvSetBBType(priv
, priv
->byBBType
);
844 priv
->byPacketType
= CARDbyGetPktType(priv
);
846 if (priv
->byBBType
== BB_TYPE_11A
)
847 vnt_control_out_u8(priv
, MESSAGE_REQUEST_BBREG
, 0x88, 0x03);
848 else if (priv
->byBBType
== BB_TYPE_11B
)
849 vnt_control_out_u8(priv
, MESSAGE_REQUEST_BBREG
, 0x88, 0x02);
850 else if (priv
->byBBType
== BB_TYPE_11G
)
851 vnt_control_out_u8(priv
, MESSAGE_REQUEST_BBREG
, 0x88, 0x08);
854 CARDvSetRSPINF(priv
, (u8
)priv
->byBBType
);
856 if (priv
->byBBType
== BB_TYPE_11A
) {
857 if (priv
->byRFType
== RF_AIROHA7230
) {
858 priv
->abyBBVGA
[0] = 0x20;
860 vnt_control_out_u8(priv
, MESSAGE_REQUEST_BBREG
,
861 0xe7, priv
->abyBBVGA
[0]);
864 priv
->abyBBVGA
[2] = 0x10;
865 priv
->abyBBVGA
[3] = 0x10;
867 if (priv
->byRFType
== RF_AIROHA7230
) {
868 priv
->abyBBVGA
[0] = 0x1c;
870 vnt_control_out_u8(priv
, MESSAGE_REQUEST_BBREG
,
871 0xe7, priv
->abyBBVGA
[0]);
874 priv
->abyBBVGA
[2] = 0x0;
875 priv
->abyBBVGA
[3] = 0x0;