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