/*
 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
 * All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * File: card.c
 * Purpose: Provide functions to setup NIC operation mode
 * Functions:
 *      vnt_set_rspinf - Set RSPINF
 *      vnt_update_ifs - Update slotTime,SIFS,DIFS, and EIFS
 *      vnt_update_top_rates - Update BasicTopRate
 *      vnt_add_basic_rate - Add to BasicRateSet
 *      vnt_ofdm_min_rate - Check if any OFDM rate is in BasicRateSet
 *      vnt_get_tsf_offset - Calculate TSFOffset
 *      vnt_get_current_tsf - Read Current NIC TSF counter
 *      vnt_get_next_tbtt - Calculate Next Beacon TSF counter
 *      vnt_reset_next_tbtt - Set NIC Beacon time
 *      vnt_update_next_tbtt - Sync. NIC Beacon time
 *      vnt_radio_power_off - Turn Off NIC Radio Power
 *      vnt_radio_power_on - Turn On NIC Radio Power
 *
 * Revision History:
 *      06-10-2003 Bryan YC Fan:  Re-write codes to support VT3253 spec.
 *      08-26-2003 Kyle Hsu:      Modify the definition type of dwIoBase.
 *      09-01-2003 Bryan YC Fan:  Add vnt_update_ifs().
 *
 */

#include "device.h"
#include "card.h"
#include "baseband.h"
#include "mac.h"
#include "desc.h"
#include "rf.h"
#include "power.h"
#include "key.h"
#include "usbpipe.h"

/* const u16 cwRXBCNTSFOff[MAX_RATE] =
   {17, 34, 96, 192, 34, 23, 17, 11, 8, 5, 4, 3}; */

static const u16 cwRXBCNTSFOff[MAX_RATE] = {
	192, 96, 34, 17, 34, 23, 17, 11, 8, 5, 4, 3
};

/*
 * Description: Set NIC media channel
 *
 * Parameters:
 *  In:
 *      pDevice             - The adapter to be set
 *      connection_channel  - Channel to be set
 *  Out:
 *      none
 */
void vnt_set_channel(struct vnt_private *priv, u32 connection_channel)
{

	if (connection_channel > CB_MAX_CHANNEL || !connection_channel)
		return;

	/* clear NAV */
	vnt_mac_reg_bits_on(priv, MAC_REG_MACCR, MACCR_CLRNAV);

	/* Set Channel[7] = 0 to tell H/W channel is changing now. */
	vnt_mac_reg_bits_off(priv, MAC_REG_CHANNEL, 0xb0);

	vnt_control_out(priv, MESSAGE_TYPE_SELECT_CHANNLE,
					connection_channel, 0, 0, NULL);

	vnt_control_out_u8(priv, MESSAGE_REQUEST_MACREG, MAC_REG_CHANNEL,
		(u8)(connection_channel|0x80));
}

/*
 * Description: Get CCK mode basic rate
 *
 * Parameters:
 *  In:
 *      priv		- The adapter to be set
 *      rate_idx	- Receiving data rate
 *  Out:
 *      none
 *
 * Return Value: response Control frame rate
 *
 */
static u16 vnt_get_cck_rate(struct vnt_private *priv, u16 rate_idx)
{
	u16 ui = rate_idx;

	while (ui > RATE_1M) {
		if (priv->basic_rates & (1 << ui))
			return ui;
		ui--;
	}

	return RATE_1M;
}

/*
 * Description: Get OFDM mode basic rate
 *
 * Parameters:
 *  In:
 *      priv		- The adapter to be set
 *      rate_idx	- Receiving data rate
 *  Out:
 *      none
 *
 * Return Value: response Control frame rate
 *
 */
static u16 vnt_get_ofdm_rate(struct vnt_private *priv, u16 rate_idx)
{
	u16 ui = rate_idx;

	dev_dbg(&priv->usb->dev, "%s basic rate: %d\n",
					__func__,  priv->basic_rates);

	if (!vnt_ofdm_min_rate(priv)) {
		dev_dbg(&priv->usb->dev, "%s (NO OFDM) %d\n",
						__func__, rate_idx);
		if (rate_idx > RATE_24M)
			rate_idx = RATE_24M;
		return rate_idx;
	}

	while (ui > RATE_11M) {
		if (priv->basic_rates & (1 << ui)) {
			dev_dbg(&priv->usb->dev, "%s rate: %d\n",
							__func__, ui);
			return ui;
		}
		ui--;
	}

	dev_dbg(&priv->usb->dev, "%s basic rate: 24M\n", __func__);

	return RATE_24M;
}

/*
 * Description: Calculate TxRate and RsvTime fields for RSPINF in OFDM mode.
 *
 * Parameters:
 * In:
 *	rate	- Tx Rate
 *	bb_type	- Tx Packet type
 * Out:
 *	tx_rate	- pointer to RSPINF TxRate field
 *	rsv_time- pointer to RSPINF RsvTime field
 *
 * Return Value: none
 *
 */
static void vnt_calculate_ofdm_rate(u16 rate, u8 bb_type,
					u8 *tx_rate, u8 *rsv_time)
{

	switch (rate) {
	case RATE_6M:
		if (bb_type == BB_TYPE_11A) {
			*tx_rate = 0x9b;
			*rsv_time = 24;
		} else {
			*tx_rate = 0x8b;
			*rsv_time = 30;
		}
			break;
	case RATE_9M:
		if (bb_type == BB_TYPE_11A) {
			*tx_rate = 0x9f;
			*rsv_time = 16;
		} else {
			*tx_rate = 0x8f;
			*rsv_time = 22;
		}
		break;
	case RATE_12M:
		if (bb_type == BB_TYPE_11A) {
			*tx_rate = 0x9a;
			*rsv_time = 12;
		} else {
			*tx_rate = 0x8a;
			*rsv_time = 18;
		}
		break;
	case RATE_18M:
		if (bb_type == BB_TYPE_11A) {
			*tx_rate = 0x9e;
			*rsv_time = 8;
		} else {
			*tx_rate = 0x8e;
			*rsv_time = 14;
		}
		break;
	case RATE_36M:
		if (bb_type == BB_TYPE_11A) {
			*tx_rate = 0x9d;
			*rsv_time = 4;
		} else {
			*tx_rate = 0x8d;
			*rsv_time = 10;
		}
		break;
	case RATE_48M:
		if (bb_type == BB_TYPE_11A) {
			*tx_rate = 0x98;
			*rsv_time = 4;
		} else {
			*tx_rate = 0x88;
			*rsv_time = 10;
		}
		break;
	case RATE_54M:
		if (bb_type == BB_TYPE_11A) {
			*tx_rate = 0x9c;
			*rsv_time = 4;
		} else {
			*tx_rate = 0x8c;
			*rsv_time = 10;
		}
		break;
	case RATE_24M:
	default:
		if (bb_type == BB_TYPE_11A) {
			*tx_rate = 0x99;
			*rsv_time = 8;
		} else {
			*tx_rate = 0x89;
			*rsv_time = 14;
		}
		break;
	}
}

/*
 * Description: Set RSPINF
 *
 * Parameters:
 *  In:
 *      pDevice             - The adapter to be set
 *  Out:
 *      none
 *
 * Return Value: None.
 *
 */

void vnt_set_rspinf(struct vnt_private *priv, u8 bb_type)
{
	struct vnt_phy_field phy[4];
	u8 tx_rate[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; /* For OFDM */
	u8 rsv_time[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
	u8 data[34];
	int i;

	/*RSPINF_b_1*/
	vnt_get_phy_field(priv, 14,
		vnt_get_cck_rate(priv, RATE_1M), PK_TYPE_11B, &phy[0]);

	/*RSPINF_b_2*/
	vnt_get_phy_field(priv, 14,
		vnt_get_cck_rate(priv, RATE_2M), PK_TYPE_11B, &phy[1]);

	/*RSPINF_b_5*/
	vnt_get_phy_field(priv, 14,
		vnt_get_cck_rate(priv, RATE_5M), PK_TYPE_11B, &phy[2]);

	/*RSPINF_b_11*/
	vnt_get_phy_field(priv, 14,
		vnt_get_cck_rate(priv, RATE_11M), PK_TYPE_11B, &phy[3]);


	/*RSPINF_a_6*/
	vnt_calculate_ofdm_rate(RATE_6M, bb_type, &tx_rate[0], &rsv_time[0]);

	/*RSPINF_a_9*/
	vnt_calculate_ofdm_rate(RATE_9M, bb_type, &tx_rate[1], &rsv_time[1]);

	/*RSPINF_a_12*/
	vnt_calculate_ofdm_rate(RATE_12M, bb_type, &tx_rate[2], &rsv_time[2]);

	/*RSPINF_a_18*/
	vnt_calculate_ofdm_rate(RATE_18M, bb_type, &tx_rate[3], &rsv_time[3]);

	/*RSPINF_a_24*/
	vnt_calculate_ofdm_rate(RATE_24M, bb_type, &tx_rate[4], &rsv_time[4]);

	/*RSPINF_a_36*/
	vnt_calculate_ofdm_rate(vnt_get_ofdm_rate(priv, RATE_36M),
					bb_type, &tx_rate[5], &rsv_time[5]);

	/*RSPINF_a_48*/
	vnt_calculate_ofdm_rate(vnt_get_ofdm_rate(priv, RATE_48M),
					bb_type, &tx_rate[6], &rsv_time[6]);

	/*RSPINF_a_54*/
	vnt_calculate_ofdm_rate(vnt_get_ofdm_rate(priv, RATE_54M),
					bb_type, &tx_rate[7], &rsv_time[7]);

	/*RSPINF_a_72*/
	vnt_calculate_ofdm_rate(vnt_get_ofdm_rate(priv, RATE_54M),
					bb_type, &tx_rate[8], &rsv_time[8]);

	put_unaligned(phy[0].len, (u16 *)&data[0]);
	data[2] = phy[0].signal;
	data[3] = phy[0].service;

	put_unaligned(phy[1].len, (u16 *)&data[4]);
	data[6] = phy[1].signal;
	data[7] = phy[1].service;

	put_unaligned(phy[2].len, (u16 *)&data[8]);
	data[10] = phy[2].signal;
	data[11] = phy[2].service;

	put_unaligned(phy[3].len, (u16 *)&data[12]);
	data[14] = phy[3].signal;
	data[15] = phy[3].service;

	for (i = 0; i < 9; i++) {
		data[16 + i * 2] = tx_rate[i];
		data[16 + i * 2 + 1] = rsv_time[i];
	}

	vnt_control_out(priv, MESSAGE_TYPE_WRITE,
		MAC_REG_RSPINF_B_1, MESSAGE_REQUEST_MACREG, 34, &data[0]);
}

/*
 * Description: Update IFS
 *
 * Parameters:
 *  In:
 *	priv - The adapter to be set
 * Out:
 *	none
 *
 * Return Value: None.
 *
 */
void vnt_update_ifs(struct vnt_private *priv)
{
	u8 max_min = 0;
	u8 data[4];

	if (priv->packet_type == PK_TYPE_11A) {
		priv->slot = C_SLOT_SHORT;
		priv->sifs = C_SIFS_A;
		priv->difs = C_SIFS_A + 2 * C_SLOT_SHORT;
		max_min = 4;
	} else if (priv->packet_type == PK_TYPE_11B) {
		priv->slot = C_SLOT_LONG;
		priv->sifs = C_SIFS_BG;
		priv->difs = C_SIFS_BG + 2 * C_SLOT_LONG;
		max_min = 5;
	} else {/* PK_TYPE_11GA & PK_TYPE_11GB */
		bool ofdm_rate = false;
		unsigned int ii = 0;

		priv->sifs = C_SIFS_BG;

		if (priv->short_slot_time)
			priv->slot = C_SLOT_SHORT;
		else
			priv->slot = C_SLOT_LONG;

		priv->difs = C_SIFS_BG + 2 * priv->slot;

		for (ii = RATE_54M; ii >= RATE_6M; ii--) {
			if (priv->basic_rates & ((u32)(0x1 << ii))) {
				ofdm_rate = true;
				break;
			}
		}

		if (ofdm_rate == true)
			max_min = 4;
		else
			max_min = 5;
	}

	priv->eifs = C_EIFS;

	switch (priv->rf_type) {
	case RF_VT3226D0:
		if (priv->bb_type != BB_TYPE_11B) {
			priv->sifs -= 1;
			priv->difs -= 1;
			break;
		}
	case RF_AIROHA7230:
	case RF_AL2230:
	case RF_AL2230S:
		if (priv->bb_type != BB_TYPE_11B)
			break;
	case RF_RFMD2959:
	case RF_VT3226:
	case RF_VT3342A0:
		priv->sifs -= 3;
		priv->difs -= 3;
		break;
	case RF_MAXIM2829:
		if (priv->bb_type == BB_TYPE_11A) {
			priv->sifs -= 5;
			priv->difs -= 5;
		} else {
			priv->sifs -= 2;
			priv->difs -= 2;
		}

		break;
	}

	data[0] = (u8)priv->sifs;
	data[1] = (u8)priv->difs;
	data[2] = (u8)priv->eifs;
	data[3] = (u8)priv->slot;

	vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_SIFS,
		MESSAGE_REQUEST_MACREG, 4, &data[0]);

	max_min |= 0xa0;

	vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_CWMAXMIN0,
		MESSAGE_REQUEST_MACREG, 1, &max_min);
}

void vnt_update_top_rates(struct vnt_private *priv)
{
	u8 top_ofdm = RATE_24M, top_cck = RATE_1M;
	u8 i;

	/*Determines the highest basic rate.*/
	for (i = RATE_54M; i >= RATE_6M; i--) {
		if (priv->basic_rates & (u16)(1 << i)) {
			top_ofdm = i;
			break;
		}
	}

	priv->top_ofdm_basic_rate = top_ofdm;

	for (i = RATE_11M;; i--) {
		if (priv->basic_rates & (u16)(1 << i)) {
			top_cck = i;
			break;
		}
		if (i == RATE_1M)
			break;
	}

	priv->top_cck_basic_rate = top_cck;
}

int vnt_ofdm_min_rate(struct vnt_private *priv)
{
	int ii;

	for (ii = RATE_54M; ii >= RATE_6M; ii--) {
		if ((priv->basic_rates) & ((u16)(1 << ii)))
			return true;
	}

	return false;
}

u8 vnt_get_pkt_type(struct vnt_private *priv)
{

	if (priv->bb_type == BB_TYPE_11A || priv->bb_type == BB_TYPE_11B)
		return (u8)priv->bb_type;
	else if (vnt_ofdm_min_rate(priv))
		return PK_TYPE_11GA;
	else
		return PK_TYPE_11GB;
}

/*
 * Description: Calculate TSF offset of two TSF input
 *              Get TSF Offset from RxBCN's TSF and local TSF
 *
 * Parameters:
 *  In:
 *      rx_rate	- rx rate.
 *      tsf1	- Rx BCN's TSF
 *      tsf2	- Local TSF
 *  Out:
 *      none
 *
 * Return Value: TSF Offset value
 *
 */
u64 vnt_get_tsf_offset(u8 rx_rate, u64 tsf1, u64 tsf2)
{
	u64 tsf_offset = 0;
	u16 rx_bcn_offset = 0;

	rx_bcn_offset = cwRXBCNTSFOff[rx_rate % MAX_RATE];

	tsf2 += (u64)rx_bcn_offset;

	tsf_offset = tsf1 - tsf2;

	return tsf_offset;
}

/*
 * Description: Sync. TSF counter to BSS
 *              Get TSF offset and write to HW
 *
 * Parameters:
 *  In:
 *      priv		- The adapter to be sync.
 *      time_stamp	- Rx BCN's TSF
 *      local_tsf	- Local TSF
 *  Out:
 *      none
 *
 * Return Value: none
 *
 */
void vnt_adjust_tsf(struct vnt_private *priv, u8 rx_rate,
		u64 time_stamp, u64 local_tsf)
{
	u64 tsf_offset = 0;
	u8 data[8];

	tsf_offset = vnt_get_tsf_offset(rx_rate, time_stamp, local_tsf);

	data[0] = (u8)tsf_offset;
	data[1] = (u8)(tsf_offset >> 8);
	data[2] = (u8)(tsf_offset >> 16);
	data[3] = (u8)(tsf_offset >> 24);
	data[4] = (u8)(tsf_offset >> 32);
	data[5] = (u8)(tsf_offset >> 40);
	data[6] = (u8)(tsf_offset >> 48);
	data[7] = (u8)(tsf_offset >> 56);

	vnt_control_out(priv, MESSAGE_TYPE_SET_TSFTBTT,
		MESSAGE_REQUEST_TSF, 0, 8, data);
}
/*
 * Description: Read NIC TSF counter
 *              Get local TSF counter
 *
 * Parameters:
 *  In:
 *	priv		- The adapter to be read
 *  Out:
 *	current_tsf	- Current TSF counter
 *
 * Return Value: true if success; otherwise false
 *
 */
bool vnt_get_current_tsf(struct vnt_private *priv, u64 *current_tsf)
{

	*current_tsf = priv->current_tsf;

	return true;
}

/*
 * Description: Clear NIC TSF counter
 *              Clear local TSF counter
 *
 * Parameters:
 *  In:
 *      priv	- The adapter to be read
 *
 * Return Value: true if success; otherwise false
 *
 */
bool vnt_clear_current_tsf(struct vnt_private *priv)
{

	vnt_mac_reg_bits_on(priv, MAC_REG_TFTCTL, TFTCTL_TSFCNTRST);

	priv->current_tsf = 0;

	return true;
}

/*
 * Description: Read NIC TSF counter
 *              Get NEXTTBTT from adjusted TSF and Beacon Interval
 *
 * Parameters:
 *  In:
 *      tsf		- Current TSF counter
 *      beacon_interval - Beacon Interval
 *  Out:
 *      tsf		- Current TSF counter
 *
 * Return Value: TSF value of next Beacon
 *
 */
u64 vnt_get_next_tbtt(u64 tsf, u16 beacon_interval)
{
	u32 beacon_int;

	beacon_int = beacon_interval * 1024;

	/* Next TBTT =
	*	((local_current_TSF / beacon_interval) + 1) * beacon_interval
	*/
	if (beacon_int) {
		do_div(tsf, beacon_int);
		tsf += 1;
		tsf *= beacon_int;
	}

	return tsf;
}

/*
 * Description: Set NIC TSF counter for first Beacon time
 *              Get NEXTTBTT from adjusted TSF and Beacon Interval
 *
 * Parameters:
 *  In:
 *      dwIoBase        - IO Base
 *	beacon_interval - Beacon Interval
 *  Out:
 *      none
 *
 * Return Value: none
 *
 */
void vnt_reset_next_tbtt(struct vnt_private *priv, u16 beacon_interval)
{
	u64 next_tbtt = 0;
	u8 data[8];

	vnt_clear_current_tsf(priv);

	next_tbtt = vnt_get_next_tbtt(next_tbtt, beacon_interval);

	data[0] = (u8)next_tbtt;
	data[1] = (u8)(next_tbtt >> 8);
	data[2] = (u8)(next_tbtt >> 16);
	data[3] = (u8)(next_tbtt >> 24);
	data[4] = (u8)(next_tbtt >> 32);
	data[5] = (u8)(next_tbtt >> 40);
	data[6] = (u8)(next_tbtt >> 48);
	data[7] = (u8)(next_tbtt >> 56);

	vnt_control_out(priv, MESSAGE_TYPE_SET_TSFTBTT,
		MESSAGE_REQUEST_TBTT, 0, 8, data);
}

/*
 * Description: Sync NIC TSF counter for Beacon time
 *              Get NEXTTBTT and write to HW
 *
 * Parameters:
 *  In:
 *	priv		- The adapter to be set
 *      tsf		- Current TSF counter
 *      beacon_interval - Beacon Interval
 *  Out:
 *      none
 *
 * Return Value: none
 *
 */
void vnt_update_next_tbtt(struct vnt_private *priv, u64 tsf,
			u16 beacon_interval)
{
	u8 data[8];

	tsf = vnt_get_next_tbtt(tsf, beacon_interval);

	data[0] = (u8)tsf;
	data[1] = (u8)(tsf >> 8);
	data[2] = (u8)(tsf >> 16);
	data[3] = (u8)(tsf >> 24);
	data[4] = (u8)(tsf >> 32);
	data[5] = (u8)(tsf >> 40);
	data[6] = (u8)(tsf >> 48);
	data[7] = (u8)(tsf >> 56);

	vnt_control_out(priv, MESSAGE_TYPE_SET_TSFTBTT,
			MESSAGE_REQUEST_TBTT, 0, 8, data);

	dev_dbg(&priv->usb->dev, "%s TBTT: %8llx\n", __func__, tsf);
}

/*
 * Description: Turn off Radio power
 *
 * Parameters:
 *  In:
 *      priv         - The adapter to be turned off
 *  Out:
 *      none
 *
 * Return Value: true if success; otherwise false
 *
 */
int vnt_radio_power_off(struct vnt_private *priv)
{
	int ret = true;

	switch (priv->rf_type) {
	case RF_AL2230:
	case RF_AL2230S:
	case RF_AIROHA7230:
	case RF_VT3226:
	case RF_VT3226D0:
	case RF_VT3342A0:
		vnt_mac_reg_bits_off(priv, MAC_REG_SOFTPWRCTL,
				(SOFTPWRCTL_SWPE2 | SOFTPWRCTL_SWPE3));
		break;
	}

	vnt_mac_reg_bits_off(priv, MAC_REG_HOSTCR, HOSTCR_RXON);

	vnt_set_deep_sleep(priv);

	vnt_mac_reg_bits_on(priv, MAC_REG_GPIOCTL1, GPIO3_INTMD);

	return ret;
}

/*
 * Description: Turn on Radio power
 *
 * Parameters:
 *  In:
 *      priv         - The adapter to be turned on
 *  Out:
 *      none
 *
 * Return Value: true if success; otherwise false
 *
 */
int vnt_radio_power_on(struct vnt_private *priv)
{
	int ret = true;

	vnt_exit_deep_sleep(priv);

	vnt_mac_reg_bits_on(priv, MAC_REG_HOSTCR, HOSTCR_RXON);

	switch (priv->rf_type) {
	case RF_AL2230:
	case RF_AL2230S:
	case RF_AIROHA7230:
	case RF_VT3226:
	case RF_VT3226D0:
	case RF_VT3342A0:
		vnt_mac_reg_bits_on(priv, MAC_REG_SOFTPWRCTL,
			(SOFTPWRCTL_SWPE2 | SOFTPWRCTL_SWPE3));
		break;
	}

	vnt_mac_reg_bits_off(priv, MAC_REG_GPIOCTL1, GPIO3_INTMD);

	return ret;
}

void vnt_set_bss_mode(struct vnt_private *priv)
{
	if (priv->rf_type == RF_AIROHA7230 && priv->bb_type == BB_TYPE_11A)
		vnt_mac_set_bb_type(priv, BB_TYPE_11G);
	else
		vnt_mac_set_bb_type(priv, priv->bb_type);

	priv->packet_type = vnt_get_pkt_type(priv);

	if (priv->bb_type == BB_TYPE_11A)
		vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x88, 0x03);
	else if (priv->bb_type == BB_TYPE_11B)
		vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x88, 0x02);
	else if (priv->bb_type == BB_TYPE_11G)
		vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x88, 0x08);

	vnt_update_ifs(priv);
	vnt_set_rspinf(priv, (u8)priv->bb_type);

	if (priv->bb_type == BB_TYPE_11A) {
		if (priv->rf_type == RF_AIROHA7230) {
			priv->bb_vga[0] = 0x20;

			vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG,
						0xe7, priv->bb_vga[0]);
		}

		priv->bb_vga[2] = 0x10;
		priv->bb_vga[3] = 0x10;
	} else {
		if (priv->rf_type == RF_AIROHA7230) {
			priv->bb_vga[0] = 0x1c;

			vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG,
						0xe7, priv->bb_vga[0]);
		}

		priv->bb_vga[2] = 0x0;
		priv->bb_vga[3] = 0x0;
	}

	vnt_set_vga_gain_offset(priv, priv->bb_vga[0]);
}
