card.c revision 9fe109c153f6ffff4186dc7d0275e2a84df6b1e6
1/*
2 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
3 * All rights reserved.
4 *
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.
9 *
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.
14 *
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.
18 *
19 * File: card.c
20 * Purpose: Provide functions to setup NIC operation mode
21 * Functions:
22 *      s_vSafeResetTx - Rest Tx
23 *      vnt_set_rspinf - Set RSPINF
24 *      vnt_update_ifs - Update slotTime,SIFS,DIFS, and EIFS
25 *      vnt_update_top_rates - Update BasicTopRate
26 *      vnt_add_basic_rate - Add to BasicRateSet
27 *      CARDbSetBasicRate - Set Basic Tx Rate
28 *      vnt_ofdm_min_rate - Check if any OFDM rate is in BasicRateSet
29 *      CARDvSetLoopbackMode - Set Loopback mode
30 *      CARDbSoftwareReset - Sortware reset NIC
31 *      vnt_get_tsf_offset - Calculate TSFOffset
32 *      vnt_get_current_tsf - Read Current NIC TSF counter
33 *      vnt_get_next_tbtt - Calculate Next Beacon TSF counter
34 *      vnt_reset_next_tbtt - Set NIC Beacon time
35 *      vnt_update_next_tbtt - Sync. NIC Beacon time
36 *      vnt_radio_power_off - Turn Off NIC Radio Power
37 *      vnt_radio_power_on - Turn On NIC Radio Power
38 *      CARDbSetWEPMode - Set NIC Wep mode
39 *      CARDbSetTxPower - Set NIC tx power
40 *
41 * Revision History:
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 vnt_update_ifs().
45 *
46 */
47
48#include "device.h"
49#include "card.h"
50#include "baseband.h"
51#include "mac.h"
52#include "desc.h"
53#include "rf.h"
54#include "power.h"
55#include "key.h"
56#include "usbpipe.h"
57
58//const u16 cwRXBCNTSFOff[MAX_RATE] =
59//{17, 34, 96, 192, 34, 23, 17, 11, 8, 5, 4, 3};
60
61static const u16 cwRXBCNTSFOff[MAX_RATE] =
62{192, 96, 34, 17, 34, 23, 17, 11, 8, 5, 4, 3};
63
64/*
65 * Description: Set NIC media channel
66 *
67 * Parameters:
68 *  In:
69 *      pDevice             - The adapter to be set
70 *      connection_channel  - Channel to be set
71 *  Out:
72 *      none
73 */
74void vnt_set_channel(struct vnt_private *priv, u32 connection_channel)
75{
76
77	if (connection_channel > CB_MAX_CHANNEL || !connection_channel)
78		return;
79
80	/* clear NAV */
81	vnt_mac_reg_bits_on(priv, MAC_REG_MACCR, MACCR_CLRNAV);
82
83	/* Set Channel[7] = 0 to tell H/W channel is changing now. */
84	vnt_mac_reg_bits_off(priv, MAC_REG_CHANNEL, 0xb0);
85
86	vnt_control_out(priv, MESSAGE_TYPE_SELECT_CHANNLE,
87					connection_channel, 0, 0, NULL);
88
89	vnt_control_out_u8(priv, MESSAGE_REQUEST_MACREG, MAC_REG_CHANNEL,
90		(u8)(connection_channel|0x80));
91}
92
93/*
94 * Description: Get CCK mode basic rate
95 *
96 * Parameters:
97 *  In:
98 *      priv		- The adapter to be set
99 *      rate_idx	- Receiving data rate
100 *  Out:
101 *      none
102 *
103 * Return Value: response Control frame rate
104 *
105 */
106static u16 vnt_get_cck_rate(struct vnt_private *priv, u16 rate_idx)
107{
108	u16 ui = rate_idx;
109
110	while (ui > RATE_1M) {
111		if (priv->wBasicRate & (1 << ui))
112			return ui;
113		ui--;
114	}
115
116	return RATE_1M;
117}
118
119/*
120 * Description: Get OFDM mode basic rate
121 *
122 * Parameters:
123 *  In:
124 *      priv		- The adapter to be set
125 *      rate_idx	- Receiving data rate
126 *  Out:
127 *      none
128 *
129 * Return Value: response Control frame rate
130 *
131 */
132static u16 vnt_get_ofdm_rate(struct vnt_private *priv, u16 rate_idx)
133{
134	u16 ui = rate_idx;
135
136	dev_dbg(&priv->usb->dev, "%s basic rate: %d\n",
137					__func__,  priv->wBasicRate);
138
139	if (!vnt_ofdm_min_rate(priv)) {
140		dev_dbg(&priv->usb->dev, "%s (NO OFDM) %d\n",
141						__func__, rate_idx);
142		if (rate_idx > RATE_24M)
143			rate_idx = RATE_24M;
144		return rate_idx;
145	}
146
147	while (ui > RATE_11M) {
148		if (priv->wBasicRate & (1 << ui)) {
149			dev_dbg(&priv->usb->dev, "%s rate: %d\n",
150							__func__, ui);
151			return ui;
152		}
153		ui--;
154	}
155
156	dev_dbg(&priv->usb->dev, "%s basic rate: 24M\n", __func__);
157
158	return RATE_24M;
159}
160
161/*
162 * Description: Calculate TxRate and RsvTime fields for RSPINF in OFDM mode.
163 *
164 * Parameters:
165 * In:
166 *	rate	- Tx Rate
167 *	bb_type	- Tx Packet type
168 * Out:
169 *	tx_rate	- pointer to RSPINF TxRate field
170 *	rsv_time- pointer to RSPINF RsvTime field
171 *
172 * Return Value: none
173 *
174 */
175static void vnt_calculate_ofdm_rate(u16 rate, u8 bb_type,
176					u8 *tx_rate, u8 *rsv_time)
177{
178
179	switch (rate) {
180	case RATE_6M:
181		if (bb_type == BB_TYPE_11A) {
182			*tx_rate = 0x9b;
183			*rsv_time = 24;
184		} else {
185			*tx_rate = 0x8b;
186			*rsv_time = 30;
187		}
188			break;
189	case RATE_9M:
190		if (bb_type == BB_TYPE_11A) {
191			*tx_rate = 0x9f;
192			*rsv_time = 16;
193		} else {
194			*tx_rate = 0x8f;
195			*rsv_time = 22;
196		}
197		break;
198	case RATE_12M:
199		if (bb_type == BB_TYPE_11A) {
200			*tx_rate = 0x9a;
201			*rsv_time = 12;
202		} else {
203			*tx_rate = 0x8a;
204			*rsv_time = 18;
205		}
206		break;
207	case RATE_18M:
208		if (bb_type == BB_TYPE_11A) {
209			*tx_rate = 0x9e;
210			*rsv_time = 8;
211		} else {
212			*tx_rate = 0x8e;
213			*rsv_time = 14;
214		}
215		break;
216	case RATE_36M:
217		if (bb_type == BB_TYPE_11A) {
218			*tx_rate = 0x9d;
219			*rsv_time = 4;
220		} else {
221			*tx_rate = 0x8d;
222			*rsv_time = 10;
223		}
224		break;
225	case RATE_48M:
226		if (bb_type == BB_TYPE_11A) {
227			*tx_rate = 0x98;
228			*rsv_time = 4;
229		} else {
230			*tx_rate = 0x88;
231			*rsv_time = 10;
232		}
233		break;
234	case RATE_54M:
235		if (bb_type == BB_TYPE_11A) {
236			*tx_rate = 0x9c;
237			*rsv_time = 4;
238		} else {
239			*tx_rate = 0x8c;
240			*rsv_time = 10;
241		}
242		break;
243	case RATE_24M:
244	default:
245		if (bb_type == BB_TYPE_11A) {
246			*tx_rate = 0x99;
247			*rsv_time = 8;
248		} else {
249			*tx_rate = 0x89;
250			*rsv_time = 14;
251		}
252		break;
253	}
254}
255
256/*
257 * Description: Set RSPINF
258 *
259 * Parameters:
260 *  In:
261 *      pDevice             - The adapter to be set
262 *  Out:
263 *      none
264 *
265 * Return Value: None.
266 *
267 */
268
269void vnt_set_rspinf(struct vnt_private *priv, u8 bb_type)
270{
271	struct vnt_phy_field phy[4];
272	u8 tx_rate[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; /* For OFDM */
273	u8 rsv_time[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
274	u8 data[34];
275	int i;
276
277	/*RSPINF_b_1*/
278	vnt_get_phy_field(priv, 14,
279		vnt_get_cck_rate(priv, RATE_1M), PK_TYPE_11B, &phy[0]);
280
281	/*RSPINF_b_2*/
282	vnt_get_phy_field(priv, 14,
283		vnt_get_cck_rate(priv, RATE_2M), PK_TYPE_11B, &phy[1]);
284
285	/*RSPINF_b_5*/
286	vnt_get_phy_field(priv, 14,
287		vnt_get_cck_rate(priv, RATE_5M), PK_TYPE_11B, &phy[2]);
288
289	/*RSPINF_b_11*/
290	vnt_get_phy_field(priv, 14,
291		vnt_get_cck_rate(priv, RATE_11M), PK_TYPE_11B, &phy[3]);
292
293
294	/*RSPINF_a_6*/
295	vnt_calculate_ofdm_rate(RATE_6M, bb_type, &tx_rate[0], &rsv_time[0]);
296
297	/*RSPINF_a_9*/
298	vnt_calculate_ofdm_rate(RATE_9M, bb_type, &tx_rate[1], &rsv_time[1]);
299
300	/*RSPINF_a_12*/
301	vnt_calculate_ofdm_rate(RATE_12M, bb_type, &tx_rate[2], &rsv_time[2]);
302
303	/*RSPINF_a_18*/
304	vnt_calculate_ofdm_rate(RATE_18M, bb_type, &tx_rate[3], &rsv_time[3]);
305
306	/*RSPINF_a_24*/
307	vnt_calculate_ofdm_rate(RATE_24M, bb_type, &tx_rate[4], &rsv_time[4]);
308
309	/*RSPINF_a_36*/
310	vnt_calculate_ofdm_rate(vnt_get_ofdm_rate(priv, RATE_36M),
311					bb_type, &tx_rate[5], &rsv_time[5]);
312
313	/*RSPINF_a_48*/
314	vnt_calculate_ofdm_rate(vnt_get_ofdm_rate(priv, RATE_48M),
315					bb_type, &tx_rate[6], &rsv_time[6]);
316
317	/*RSPINF_a_54*/
318	vnt_calculate_ofdm_rate(vnt_get_ofdm_rate(priv, RATE_54M),
319					bb_type, &tx_rate[7], &rsv_time[7]);
320
321	/*RSPINF_a_72*/
322	vnt_calculate_ofdm_rate(vnt_get_ofdm_rate(priv, RATE_54M),
323					bb_type, &tx_rate[8], &rsv_time[8]);
324
325	put_unaligned(phy[0].len, (u16 *)&data[0]);
326	data[2] = phy[0].signal;
327	data[3] = phy[0].service;
328
329	put_unaligned(phy[1].len, (u16 *)&data[4]);
330	data[6] = phy[1].signal;
331	data[7] = phy[1].service;
332
333	put_unaligned(phy[2].len, (u16 *)&data[8]);
334	data[10] = phy[2].signal;
335	data[11] = phy[2].service;
336
337	put_unaligned(phy[3].len, (u16 *)&data[12]);
338	data[14] = phy[3].signal;
339	data[15] = phy[3].service;
340
341	for (i = 0; i < 9; i++) {
342		data[16 + i * 2] = tx_rate[i];
343		data[16 + i * 2 + 1] = rsv_time[i];
344	}
345
346	vnt_control_out(priv, MESSAGE_TYPE_WRITE,
347		MAC_REG_RSPINF_B_1, MESSAGE_REQUEST_MACREG, 34, &data[0]);
348}
349
350/*
351 * Description: Update IFS
352 *
353 * Parameters:
354 *  In:
355 *	priv - The adapter to be set
356 * Out:
357 *	none
358 *
359 * Return Value: None.
360 *
361 */
362void vnt_update_ifs(struct vnt_private *priv)
363{
364	u8 max_min = 0;
365	u8 data[4];
366
367	if (priv->byPacketType == PK_TYPE_11A) {
368		priv->uSlot = C_SLOT_SHORT;
369		priv->uSIFS = C_SIFS_A;
370		priv->uDIFS = C_SIFS_A + 2 * C_SLOT_SHORT;
371		priv->uCwMin = C_CWMIN_A;
372		max_min = 4;
373	} else if (priv->byPacketType == PK_TYPE_11B) {
374		priv->uSlot = C_SLOT_LONG;
375		priv->uSIFS = C_SIFS_BG;
376		priv->uDIFS = C_SIFS_BG + 2 * C_SLOT_LONG;
377		priv->uCwMin = C_CWMIN_B;
378		max_min = 5;
379	} else {/* PK_TYPE_11GA & PK_TYPE_11GB */
380		bool ofdm_rate = false;
381		unsigned int ii = 0;
382
383		priv->uSIFS = C_SIFS_BG;
384
385		if (priv->bShortSlotTime)
386			priv->uSlot = C_SLOT_SHORT;
387		else
388			priv->uSlot = C_SLOT_LONG;
389
390		priv->uDIFS = C_SIFS_BG + 2 * priv->uSlot;
391
392		for (ii = RATE_54M; ii >= RATE_6M; ii--) {
393			if (priv->wBasicRate & ((u32)(0x1 << ii))) {
394				ofdm_rate = true;
395				break;
396			}
397		}
398
399		if (ofdm_rate == true) {
400			priv->uCwMin = C_CWMIN_A;
401			max_min = 4;
402		} else {
403			priv->uCwMin = C_CWMIN_B;
404			max_min = 5;
405			}
406	}
407
408	priv->uCwMax = C_CWMAX;
409	priv->uEIFS = C_EIFS;
410
411	switch (priv->byRFType) {
412	case RF_VT3226D0:
413		if (priv->byBBType != BB_TYPE_11B) {
414			priv->uSIFS -= 1;
415			priv->uDIFS -= 1;
416			break;
417		}
418	case RF_AIROHA7230:
419	case RF_AL2230:
420	case RF_AL2230S:
421		if (priv->byBBType != BB_TYPE_11B)
422			break;
423	case RF_RFMD2959:
424	case RF_VT3226:
425	case RF_VT3342A0:
426		priv->uSIFS -= 3;
427		priv->uDIFS -= 3;
428		break;
429	case RF_MAXIM2829:
430		if (priv->byBBType == BB_TYPE_11A) {
431			priv->uSIFS -= 5;
432			priv->uDIFS -= 5;
433		} else {
434			priv->uSIFS -= 2;
435			priv->uDIFS -= 2;
436		}
437
438		break;
439	}
440
441	data[0] = (u8)priv->uSIFS;
442	data[1] = (u8)priv->uDIFS;
443	data[2] = (u8)priv->uEIFS;
444	data[3] = (u8)priv->uSlot;
445
446	vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_SIFS,
447		MESSAGE_REQUEST_MACREG, 4, &data[0]);
448
449	max_min |= 0xa0;
450
451	vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_CWMAXMIN0,
452		MESSAGE_REQUEST_MACREG, 1, &max_min);
453}
454
455void vnt_update_top_rates(struct vnt_private *priv)
456{
457	u8 top_ofdm = RATE_24M, top_cck = RATE_1M;
458	u8 i;
459
460	/*Determines the highest basic rate.*/
461	for (i = RATE_54M; i >= RATE_6M; i--) {
462		if (priv->wBasicRate & (u16)(1 << i)) {
463			top_ofdm = i;
464			break;
465		}
466	}
467
468	priv->byTopOFDMBasicRate = top_ofdm;
469
470	for (i = RATE_11M;; i--) {
471		if (priv->wBasicRate & (u16)(1 << i)) {
472			top_cck = i;
473			break;
474		}
475		if (i == RATE_1M)
476			break;
477	}
478
479	priv->byTopCCKBasicRate = top_cck;
480 }
481
482int vnt_ofdm_min_rate(struct vnt_private *priv)
483{
484	int ii;
485
486	for (ii = RATE_54M; ii >= RATE_6M; ii--) {
487		if ((priv->wBasicRate) & ((u16)(1 << ii)))
488			return true;
489	}
490
491	return false;
492}
493
494u8 vnt_get_pkt_type(struct vnt_private *priv)
495{
496
497	if (priv->byBBType == BB_TYPE_11A || priv->byBBType == BB_TYPE_11B)
498		return (u8)priv->byBBType;
499	else if (vnt_ofdm_min_rate(priv))
500		return PK_TYPE_11GA;
501	else
502		return PK_TYPE_11GB;
503}
504
505/*
506 * Description: Calculate TSF offset of two TSF input
507 *              Get TSF Offset from RxBCN's TSF and local TSF
508 *
509 * Parameters:
510 *  In:
511 *      rx_rate	- rx rate.
512 *      tsf1	- Rx BCN's TSF
513 *      tsf2	- Local TSF
514 *  Out:
515 *      none
516 *
517 * Return Value: TSF Offset value
518 *
519 */
520u64 vnt_get_tsf_offset(u8 rx_rate, u64 tsf1, u64 tsf2)
521{
522	u64 tsf_offset = 0;
523	u16 rx_bcn_offset = 0;
524
525	rx_bcn_offset = cwRXBCNTSFOff[rx_rate % MAX_RATE];
526
527	tsf2 += (u64)rx_bcn_offset;
528
529	tsf_offset = tsf1 - tsf2;
530
531	return tsf_offset;
532}
533
534/*
535 * Description: Sync. TSF counter to BSS
536 *              Get TSF offset and write to HW
537 *
538 * Parameters:
539 *  In:
540 *      priv		- The adapter to be sync.
541 *      time_stamp	- Rx BCN's TSF
542 *      local_tsf	- Local TSF
543 *  Out:
544 *      none
545 *
546 * Return Value: none
547 *
548 */
549void vnt_adjust_tsf(struct vnt_private *priv, u8 rx_rate,
550		u64 time_stamp, u64 local_tsf)
551{
552	u64 tsf_offset = 0;
553	u8 data[8];
554
555	tsf_offset = vnt_get_tsf_offset(rx_rate, time_stamp, local_tsf);
556
557	data[0] = (u8)tsf_offset;
558	data[1] = (u8)(tsf_offset >> 8);
559	data[2] = (u8)(tsf_offset >> 16);
560	data[3] = (u8)(tsf_offset >> 24);
561	data[4] = (u8)(tsf_offset >> 32);
562	data[5] = (u8)(tsf_offset >> 40);
563	data[6] = (u8)(tsf_offset >> 48);
564	data[7] = (u8)(tsf_offset >> 56);
565
566	vnt_control_out(priv, MESSAGE_TYPE_SET_TSFTBTT,
567		MESSAGE_REQUEST_TSF, 0, 8, data);
568}
569/*
570 * Description: Read NIC TSF counter
571 *              Get local TSF counter
572 *
573 * Parameters:
574 *  In:
575 *	priv		- The adapter to be read
576 *  Out:
577 *	current_tsf	- Current TSF counter
578 *
579 * Return Value: true if success; otherwise false
580 *
581 */
582bool vnt_get_current_tsf(struct vnt_private *priv, u64 *current_tsf)
583{
584
585	*current_tsf = priv->qwCurrTSF;
586
587	return true;
588}
589
590/*
591 * Description: Clear NIC TSF counter
592 *              Clear local TSF counter
593 *
594 * Parameters:
595 *  In:
596 *      priv	- The adapter to be read
597 *
598 * Return Value: true if success; otherwise false
599 *
600 */
601bool vnt_clear_current_tsf(struct vnt_private *priv)
602{
603
604	vnt_mac_reg_bits_on(priv, MAC_REG_TFTCTL, TFTCTL_TSFCNTRST);
605
606	priv->qwCurrTSF = 0;
607
608	return true;
609}
610
611/*
612 * Description: Read NIC TSF counter
613 *              Get NEXTTBTT from adjusted TSF and Beacon Interval
614 *
615 * Parameters:
616 *  In:
617 *      tsf		- Current TSF counter
618 *      beacon_interval - Beacon Interval
619 *  Out:
620 *      tsf		- Current TSF counter
621 *
622 * Return Value: TSF value of next Beacon
623 *
624 */
625u64 vnt_get_next_tbtt(u64 tsf, u16 beacon_interval)
626{
627	u32 beacon_int;
628
629	beacon_int = beacon_interval * 1024;
630
631	/* Next TBTT =
632	*	((local_current_TSF / beacon_interval) + 1) * beacon_interval
633	*/
634	if (beacon_int) {
635		do_div(tsf, beacon_int);
636		tsf += 1;
637		tsf *= beacon_int;
638	}
639
640	return tsf;
641}
642
643/*
644 * Description: Set NIC TSF counter for first Beacon time
645 *              Get NEXTTBTT from adjusted TSF and Beacon Interval
646 *
647 * Parameters:
648 *  In:
649 *      dwIoBase        - IO Base
650 *	beacon_interval - Beacon Interval
651 *  Out:
652 *      none
653 *
654 * Return Value: none
655 *
656 */
657void vnt_reset_next_tbtt(struct vnt_private *priv, u16 beacon_interval)
658{
659	u64 next_tbtt = 0;
660	u8 data[8];
661
662	vnt_clear_current_tsf(priv);
663
664	next_tbtt = vnt_get_next_tbtt(next_tbtt, beacon_interval);
665
666	data[0] = (u8)next_tbtt;
667	data[1] = (u8)(next_tbtt >> 8);
668	data[2] = (u8)(next_tbtt >> 16);
669	data[3] = (u8)(next_tbtt >> 24);
670	data[4] = (u8)(next_tbtt >> 32);
671	data[5] = (u8)(next_tbtt >> 40);
672	data[6] = (u8)(next_tbtt >> 48);
673	data[7] = (u8)(next_tbtt >> 56);
674
675	vnt_control_out(priv, MESSAGE_TYPE_SET_TSFTBTT,
676		MESSAGE_REQUEST_TBTT, 0, 8, data);
677
678	return;
679}
680
681/*
682 * Description: Sync NIC TSF counter for Beacon time
683 *              Get NEXTTBTT and write to HW
684 *
685 * Parameters:
686 *  In:
687 *	priv		- The adapter to be set
688 *      tsf		- Current TSF counter
689 *      beacon_interval - Beacon Interval
690 *  Out:
691 *      none
692 *
693 * Return Value: none
694 *
695 */
696void vnt_update_next_tbtt(struct vnt_private *priv, u64 tsf,
697			u16 beacon_interval)
698{
699	u8 data[8];
700
701	tsf = vnt_get_next_tbtt(tsf, beacon_interval);
702
703	data[0] = (u8)tsf;
704	data[1] = (u8)(tsf >> 8);
705	data[2] = (u8)(tsf >> 16);
706	data[3] = (u8)(tsf >> 24);
707	data[4] = (u8)(tsf >> 32);
708	data[5] = (u8)(tsf >> 40);
709	data[6] = (u8)(tsf >> 48);
710	data[7] = (u8)(tsf >> 56);
711
712	vnt_control_out(priv, MESSAGE_TYPE_SET_TSFTBTT,
713		MESSAGE_REQUEST_TBTT, 0, 8, data);
714
715	dev_dbg(&priv->usb->dev, "%s TBTT: %8llx\n", __func__, tsf);
716
717	return;
718}
719
720/*
721 * Description: Turn off Radio power
722 *
723 * Parameters:
724 *  In:
725 *      priv         - The adapter to be turned off
726 *  Out:
727 *      none
728 *
729 * Return Value: true if success; otherwise false
730 *
731 */
732int vnt_radio_power_off(struct vnt_private *priv)
733{
734	int ret = true;
735
736	priv->bRadioOff = true;
737
738	switch (priv->byRFType) {
739	case RF_AL2230:
740	case RF_AL2230S:
741	case RF_AIROHA7230:
742	case RF_VT3226:
743	case RF_VT3226D0:
744	case RF_VT3342A0:
745		vnt_mac_reg_bits_off(priv, MAC_REG_SOFTPWRCTL,
746				(SOFTPWRCTL_SWPE2 | SOFTPWRCTL_SWPE3));
747		break;
748	}
749
750	vnt_mac_reg_bits_off(priv, MAC_REG_HOSTCR, HOSTCR_RXON);
751
752	BBvSetDeepSleep(priv);
753
754	return ret;
755}
756
757/*
758 * Description: Turn on Radio power
759 *
760 * Parameters:
761 *  In:
762 *      priv         - The adapter to be turned on
763 *  Out:
764 *      none
765 *
766 * Return Value: true if success; otherwise false
767 *
768 */
769int vnt_radio_power_on(struct vnt_private *priv)
770{
771	int ret = true;
772
773	if (priv->bHWRadioOff == true || priv->bRadioControlOff == true)
774		return false;
775
776	priv->bRadioOff = false;
777
778	BBvExitDeepSleep(priv);
779
780	vnt_mac_reg_bits_on(priv, MAC_REG_HOSTCR, HOSTCR_RXON);
781
782	switch (priv->byRFType) {
783	case RF_AL2230:
784	case RF_AL2230S:
785	case RF_AIROHA7230:
786	case RF_VT3226:
787	case RF_VT3226D0:
788	case RF_VT3342A0:
789		vnt_mac_reg_bits_on(priv, MAC_REG_SOFTPWRCTL,
790			(SOFTPWRCTL_SWPE2 | SOFTPWRCTL_SWPE3));
791		break;
792	}
793
794	return ret;
795}
796
797void vnt_set_bss_mode(struct vnt_private *priv)
798{
799	if (priv->byRFType == RF_AIROHA7230 && priv->byBBType == BB_TYPE_11A)
800		vnt_mac_set_bb_type(priv, BB_TYPE_11G);
801	else
802		vnt_mac_set_bb_type(priv, priv->byBBType);
803
804	priv->byPacketType = vnt_get_pkt_type(priv);
805
806	if (priv->byBBType == BB_TYPE_11A)
807		vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x88, 0x03);
808	else if (priv->byBBType == BB_TYPE_11B)
809		vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x88, 0x02);
810	else if (priv->byBBType == BB_TYPE_11G)
811		vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x88, 0x08);
812
813	vnt_update_ifs(priv);
814	vnt_set_rspinf(priv, (u8)priv->byBBType);
815
816	if (priv->byBBType == BB_TYPE_11A) {
817		if (priv->byRFType == RF_AIROHA7230) {
818			priv->abyBBVGA[0] = 0x20;
819
820			vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG,
821						0xe7, priv->abyBBVGA[0]);
822		}
823
824		priv->abyBBVGA[2] = 0x10;
825		priv->abyBBVGA[3] = 0x10;
826	} else {
827		if (priv->byRFType == RF_AIROHA7230) {
828			priv->abyBBVGA[0] = 0x1c;
829
830			vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG,
831						0xe7, priv->abyBBVGA[0]);
832		}
833
834		priv->abyBBVGA[2] = 0x0;
835		priv->abyBBVGA[3] = 0x0;
836	}
837
838	BBvSetVGAGainOffset(priv, priv->abyBBVGA[0]);
839}
840