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