Beispiel #1
0
int rtl8723_fw_free_to_go(struct ieee80211_hw *hw, bool is_8723be,
			  int max_count)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	int err = -EIO;
	u32 counter = 0;
	u32 value32;

	do {
		value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
	} while ((counter++ < max_count) &&
		 (!(value32 & FWDL_CHKSUM_RPT)));

	if (counter >= max_count) {
		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
			 "chksum report fail ! REG_MCUFWDL:0x%08x .\n",
			 value32);
		goto exit;
	}
	RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
		 "Checksum report OK ! REG_MCUFWDL:0x%08x .\n", value32);

	value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL) | MCUFWDL_RDY;
	value32 &= ~WINTINI_RDY;
	rtl_write_dword(rtlpriv, REG_MCUFWDL, value32);

	if (is_8723be)
		rtl8723be_firmware_selfreset(hw);
	counter = 0;

	do {
		value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
		if (value32 & WINTINI_RDY) {
			RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
				 "Polling FW ready success!! REG_MCUFWDL:0x%08x .\n",
				 value32);
			err = 0;
			goto exit;
		}

		mdelay(FW_8192C_POLLING_DELAY);

	} while (counter++ < max_count);

	RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
		 "Polling FW ready fail!! REG_MCUFWDL:0x%08x .\n",
		 value32);

exit:
	return err;
}
Beispiel #2
0
bool rtl92cu_phy_bb_config( struct ieee80211_hw *hw )
{
	bool rtstatus = true;
	struct rtl_priv *rtlpriv = rtl_priv( hw );
	struct rtl_hal *rtlhal = rtl_hal( rtl_priv( hw ) );
	u16 regval;
	u32 regval32;
	u8 b_reg_hwparafile = 1;

	_rtl92c_phy_init_bb_rf_register_definition( hw );
	regval = rtl_read_word( rtlpriv, REG_SYS_FUNC_EN );
	rtl_write_word( rtlpriv, REG_SYS_FUNC_EN, regval | BIT( 13 ) |
		       BIT( 0 ) | BIT( 1 ) );
	rtl_write_byte( rtlpriv, REG_AFE_PLL_CTRL, 0x83 );
	rtl_write_byte( rtlpriv, REG_AFE_PLL_CTRL + 1, 0xdb );
	rtl_write_byte( rtlpriv, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB );
	if ( IS_HARDWARE_TYPE_8192CE( rtlhal ) ) {
		rtl_write_byte( rtlpriv, REG_SYS_FUNC_EN, FEN_PPLL | FEN_PCIEA |
			       FEN_DIO_PCIE |	FEN_BB_GLB_RSTn | FEN_BBRSTB );
	} else if ( IS_HARDWARE_TYPE_8192CU( rtlhal ) ) {
		rtl_write_byte( rtlpriv, REG_SYS_FUNC_EN, FEN_USBA | FEN_USBD |
			       FEN_BB_GLB_RSTn | FEN_BBRSTB );
	}
	regval32 = rtl_read_dword( rtlpriv, 0x87c );
	rtl_write_dword( rtlpriv, 0x87c, regval32 & ( ~BIT( 31 ) ) );
	if ( IS_HARDWARE_TYPE_8192CU( rtlhal ) )
		rtl_write_byte( rtlpriv, REG_LDOHCI12_CTRL, 0x0f );
	rtl_write_byte( rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80 );
	if ( b_reg_hwparafile == 1 )
		rtstatus = _rtl92c_phy_bb8192c_config_parafile( hw );
	return rtstatus;
}
Beispiel #3
0
void rtl92ee_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	u32 ledcfg;

	RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD,
		 "LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin);

	switch (pled->ledpin) {
	case LED_PIN_GPIO0:
		break;
	case LED_PIN_LED0:

		ledcfg = rtl_read_dword(rtlpriv , REG_GPIO_PIN_CTRL);
		ledcfg |= ~BIT(21);
		ledcfg &= ~BIT(29);
		rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, ledcfg);

		break;
	case LED_PIN_LED1:

		break;
	default:
		RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
			 "switch case not process\n");
		break;
	}
	pled->ledon = false;
}
Beispiel #4
0
u32 halbtc_read_4byte(void *bt_context, u32 reg_addr)
{
	struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
	struct rtl_priv *rtlpriv = btcoexist->adapter;
	
	return	rtl_read_dword(rtlpriv, reg_addr);
}
Beispiel #5
0
u16 rtl8822be_rx_desc_buff_remained_cnt(struct ieee80211_hw *hw, u8 queue_index)
{
	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	u16 desc_idx_hw = 0, desc_idx_host = 0, remind_cnt = 0;
	u32 tmp_4byte = 0;

	u32 rw_mask = 0x1ff;

	tmp_4byte = rtl_read_dword(rtlpriv, REG_RXQ_RXBD_IDX_8822B);
	desc_idx_hw = (u16)((tmp_4byte >> 16) & rw_mask);
	desc_idx_host = (u16)(tmp_4byte & rw_mask);

	/* may be no data, donot rx */
	if (desc_idx_hw == desc_idx_host)
		return 0;

	remind_cnt =
		(desc_idx_hw > desc_idx_host) ?
			(desc_idx_hw - desc_idx_host) :
			(RX_DESC_NUM_8822BE - (desc_idx_host - desc_idx_hw));

	rtlpci->rx_ring[queue_index].next_rx_rp = desc_idx_host;

	return remind_cnt;
}
Beispiel #6
0
bool rtl_btc_is_disable_edca_turbo(struct rtl_priv *rtlpriv)
{
	bool bt_change_edca = false;
	u32 cur_edca_val;
	u32 edca_bt_hs_uplink = 0x5ea42b, edca_bt_hs_downlink = 0x5ea42b;
	u32 edca_hs;
	u32 edca_addr = 0x504;

	cur_edca_val = rtl_read_dword(rtlpriv, edca_addr);
	if (halbtc_is_wifi_uplink(rtlpriv)) {
		if (cur_edca_val != edca_bt_hs_uplink) {
			edca_hs = edca_bt_hs_uplink;
			bt_change_edca = true;
		}
	} else {
		if (cur_edca_val != edca_bt_hs_downlink) {
			edca_hs = edca_bt_hs_downlink;
			bt_change_edca = true;
		}
	}

	if (bt_change_edca)
		rtl_write_dword(rtlpriv, edca_addr, edca_hs);

	return true;
}
Beispiel #7
0
bool rtl92c_phy_bb_config(struct ieee80211_hw *hw)
{
	bool rtstatus = true;
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	u16 regval;
	u32 regvaldw;
	u8 reg_hwparafile = 1;

	_rtl92c_phy_init_bb_rf_register_definition(hw);
	regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
	rtl_write_word(rtlpriv, REG_SYS_FUNC_EN,
		       regval | BIT(13) | BIT(0) | BIT(1));
	rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x83);
	rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL + 1, 0xdb);
	rtl_write_byte(rtlpriv, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB);
	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN,
		       FEN_PPLL | FEN_PCIEA | FEN_DIO_PCIE |
		       FEN_BB_GLB_RSTn | FEN_BBRSTB);
	rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80);
	regvaldw = rtl_read_dword(rtlpriv, REG_LEDCFG0);
	rtl_write_dword(rtlpriv, REG_LEDCFG0, regvaldw | BIT(23));
	if (reg_hwparafile == 1)
		rtstatus = _rtl92c_phy_bb8192c_config_parafile(hw);
	return rtstatus;
}
Beispiel #8
0
static void _r92su_fw_reg_ready(struct rtl_priv *rtlpriv)
{
	unsigned int delay_count = 10;
	do {
		if (rtl_read_dword(rtlpriv, RF_BB_CMD_ADDR) == 0)
			break;
		udelay(5);
	} while (delay_count--);
}
Beispiel #9
0
static int rtl_proc_get_cam_register_1(char *page, char **start,
		off_t offset, int count, int *eof, void *data)
{
	struct ieee80211_hw *hw = data;
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	u32 target_cmd = 0;
	u32 target_val=0;
	u8 entry_i=0;
	u32 ulstatus;
	int len = 0;
	int i = 100, j = 0;

	/* This dump the current register page */
	len += snprintf(page + len, count - len,
		"\n#################### SECURITY CAM (0-10) ##################\n ");

	for (j = 0; j < 11; j++) {
		len += snprintf(page + len, count - len, "\nD:  %2x > ", j);
	 	for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) {
	   		/* polling bit, and No Write enable, and address  */
			target_cmd = entry_i + CAM_CONTENT_COUNT * j;
			target_cmd = target_cmd | BIT(31);

			/* Check polling bit is clear */
			while ((i--) >= 0) {
				ulstatus = rtl_read_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM]);
				if (ulstatus & BIT(31)) {
					continue;
				} else {
					break;
				}
			}

	  		rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], target_cmd);
	  	 	target_val = rtl_read_dword(rtlpriv, rtlpriv->cfg->maps[RCAMO]);
			len += snprintf(page + len, count - len, "%8.8x ", target_val);
	 	}
	}

	len += snprintf(page + len, count - len,"\n");
	*eof = 1;
	return len;
}
Beispiel #10
0
static int rtl_proc_get_cam_register_1(struct seq_file *m, void *v)
{
	struct ieee80211_hw *hw = m->private;
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	u32 target_cmd = 0;
	u32 target_val=0;
	u8 entry_i=0;
	u32 ulstatus;
	int i = 100, j = 0;

	/* This dump the current register page */
	seq_puts(m,
	    "\n#################### SECURITY CAM (0-10) ##################\n ");

	for (j = 0; j < 11; j++) {
		seq_printf(m, "\nD:  %2x > ", j);
	 	for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) {
	   		/* polling bit, and No Write enable, and address  */
			target_cmd = entry_i + CAM_CONTENT_COUNT * j;
			target_cmd = target_cmd | BIT(31);

			/* Check polling bit is clear */
			while ((i--) >= 0) {
				ulstatus = rtl_read_dword(rtlpriv,
						rtlpriv->cfg->maps[RWCAM]);
				if (ulstatus & BIT(31)) {
					continue;
				} else {
					break;
				}
			}

	  		rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM],
					target_cmd);
	  	 	target_val = rtl_read_dword(rtlpriv,
						    rtlpriv->cfg->maps[RCAMO]);
			seq_printf(m, "%8.8x ", target_val);
	 	}
	}
	seq_puts(m, "\n");
	return 0;
}
Beispiel #11
0
void rtl92s_fw_iocmd_data(struct ieee80211_hw *hw, u32* cmd, u8 flag)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);

	if (flag == 0) {
		/* set */
		rtl_write_dword(rtlpriv, REG_IOCMD_DATA, *cmd);
	} else {
		/* query */
		*cmd = rtl_read_dword(rtlpriv, REG_IOCMD_DATA);
	}
}
Beispiel #12
0
static int rtl_proc_get_cam_register_3(struct seq_file *m, void *v)
{
	struct ieee80211_hw *hw = m->private;
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	u32 target_cmd = 0;
	u32 target_val = 0;
	u8 entry_i = 0;
	u32 ulstatus;
	int i = 100, j = 0;

	/* This dump the current register page */
	seq_puts(m,
	    "\n################### SECURITY CAM (22-31) ##################\n ");

	for (j = 22; j < TOTAL_CAM_ENTRY; j++) {
		seq_printf(m, "\nD:  %2x > ", j);
	 	for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) {
			target_cmd = entry_i+CAM_CONTENT_COUNT*j;
			target_cmd = target_cmd | BIT(31);

			while ((i--) >= 0) {
				ulstatus = rtl_read_dword(rtlpriv,
						rtlpriv->cfg->maps[RWCAM]);
				if (ulstatus & BIT(31)) {
					continue;
				} else {
					break;
				}
			}

	  		rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM],
					target_cmd);
	  	 	target_val = rtl_read_dword(rtlpriv,
						    rtlpriv->cfg->maps[RCAMO]);
			seq_printf(m, "%8.8x ", target_val);
	 	}
	}
	seq_puts(m, "\n");
	return 0;
}
Beispiel #13
0
u8 rtl92s_fw_iocmd(struct ieee80211_hw *hw, const u32 cmd)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	int pollcount = 50;

	rtl_write_dword(rtlpriv, REG_IOCMD_CTRL, cmd);
	msleep(100);
	while (rtl_read_dword(rtlpriv, REG_IOCMD_CTRL) && pollcount > 0) {
		pollcount--;
		msleep(20);
	}

	return !!pollcount;
}
Beispiel #14
0
void rtl92su_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	u32 reg_rcr = rtl_read_dword(rtlpriv, RCR);

	if (rtlpriv->psc.rfpwr_state != ERFON)
		return;

	if (check_bssid)
		reg_rcr |= RCR_CBSSID;
	else
		reg_rcr &= ~RCR_CBSSID;
	rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
				      (u8 *) (&reg_rcr));
}
Beispiel #15
0
static int rtl_proc_get_mac_0(struct seq_file *m, void *v)
{
	struct ieee80211_hw *hw = m->private;
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	int i, n, page;
	int max = 0xff;
	page = 0x000;

	for (n = 0; n <= max; ) {
		seq_printf(m, "\n%8.8x  ", n + page);
		for (i = 0; i < 4 && n <= max; i++, n += 4)
			seq_printf(m, "%8.8x    ",
				   rtl_read_dword(rtlpriv, (page | n)));
	}
	seq_puts(m, "\n");
	return 0;
}
Beispiel #16
0
int rtw_ips_leave(struct rtl_priv * rtlpriv)
{
	struct pwrctrl_priv *pwrpriv = &rtlpriv->pwrctrlpriv;
	struct security_priv* psecuritypriv=&(rtlpriv->securitypriv);
	struct mlme_priv *pmlmepriv = &(rtlpriv->mlmepriv);
	int result = _SUCCESS;
	sint keyid;

	down(&pwrpriv->lock);

	if ((pwrpriv->rf_pwrstate == rf_off) &&(!pwrpriv->bips_processing)) {
		pwrpriv->bips_processing = _TRUE;
		pwrpriv->change_rfpwrstate = rf_on;
		pwrpriv->ips_leave_cnts++;
		DBG_871X("==>ips_leave cnts:%d\n",pwrpriv->ips_leave_cnts);

		if ((result = rtw_ips_pwr_up(rtlpriv)) == _SUCCESS) {
			pwrpriv->rf_pwrstate = rf_on;
		}
		DBG_871X_LEVEL(_drv_always_, "nolinked power save leave\n");

		if ((_WEP40_ == psecuritypriv->dot11PrivacyAlgrthm)
		   ||(_WEP104_ == psecuritypriv->dot11PrivacyAlgrthm)) {
			DBG_871X("==>%s,channel(%d),processing(%x)\n",__FUNCTION__,rtlpriv->mlmeextpriv.cur_channel,pwrpriv->bips_processing);
			set_channel_bwmode(rtlpriv, rtlpriv->mlmeextpriv.cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
			for (keyid = 0; keyid < 4; keyid++) {
				if (pmlmepriv->key_mask & BIT(keyid)) {
					if (keyid == psecuritypriv->dot11PrivacyKeyIndex)
						result=rtw_set_key(rtlpriv,psecuritypriv, keyid, 1);
					else
						result=rtw_set_key(rtlpriv,psecuritypriv, keyid, 0);
				}
			}
		}

		DBG_871X("==> ips_leave.....LED(0x%08x)...\n",rtl_read_dword(rtlpriv,0x4c));
		pwrpriv->bips_processing = _FALSE;

		pwrpriv->bpower_saving = _FALSE;
	}

	up(&pwrpriv->lock);

	return result;
}
Beispiel #17
0
int rtw_ips_leave(struct rtl_priv * rtlpriv)
{
	struct pwrctrl_priv *pwrpriv = &rtlpriv->pwrctrlpriv;
	struct security_priv* psecuritypriv=&(rtlpriv->securitypriv);
	struct mlme_priv *pmlmepriv = &(rtlpriv->mlmepriv);
	int result = _SUCCESS;
	int keyid;

	down(&pwrpriv->lock);

	if ((pwrpriv->rf_pwrstate == ERFOFF) &&(!pwrpriv->bips_processing)) {
		pwrpriv->bips_processing = true;
		pwrpriv->change_rfpwrstate = ERFON;
		pwrpriv->ips_leave_cnts++;
		RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, "==>ips_leave cnts:%d\n",pwrpriv->ips_leave_cnts);

		if ((result = rtw_ips_pwr_up(rtlpriv)) == _SUCCESS) {
			pwrpriv->rf_pwrstate = ERFON;
		}
		RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, "nolinked power save leave\n");

		if ((WEP40_ENCRYPTION == psecuritypriv->dot11PrivacyAlgrthm)
		   ||(WEP104_ENCRYPTION == psecuritypriv->dot11PrivacyAlgrthm)) {
			RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, "==>%s,channel(%d),processing(%x)\n",__FUNCTION__,rtlpriv->mlmeextpriv.cur_channel,pwrpriv->bips_processing);
			set_channel_bwmode(rtlpriv, rtlpriv->mlmeextpriv.cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
			for (keyid = 0; keyid < 4; keyid++) {
				if (pmlmepriv->key_mask & BIT(keyid)) {
					if (keyid == psecuritypriv->dot11PrivacyKeyIndex)
						result=rtw_set_key(rtlpriv,psecuritypriv, keyid, 1);
					else
						result=rtw_set_key(rtlpriv,psecuritypriv, keyid, 0);
				}
			}
		}

		RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, "==> ips_leave.....LED(0x%08x)...\n",rtl_read_dword(rtlpriv,0x4c));
		pwrpriv->bips_processing = false;

		pwrpriv->bpower_saving = false;
	}

	up(&pwrpriv->lock);

	return result;
}
Beispiel #18
0
/* Turn on AAP (RCR:bit 0) for promicuous mode. */
void rtl92su_allow_all_destaddr(struct ieee80211_hw *hw,
				bool allow_all_da, bool write_into_reg)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	u32 reg_rcr = rtl_read_dword(rtlpriv, RCR);

	if (allow_all_da) /* Set BIT0 */
		reg_rcr |= RCR_AAP;
	else /* Clear BIT0 */
		reg_rcr &= ~RCR_AAP;

	if (write_into_reg)
		rtl_write_dword(rtlpriv, RCR, reg_rcr);

	RT_TRACE(rtlpriv, COMP_TURBO | COMP_INIT, DBG_LOUD,
		 "receive_config=0x%08X, write_into_reg=%d\n",
		 reg_rcr, write_into_reg);
}
Beispiel #19
0
Datei: mac.c Projekt: 7799/linux
void rtl92c_init_adaptive_ctrl(struct ieee80211_hw *hw)
{
	u16	value16;
	u32	value32;
	struct rtl_priv *rtlpriv = rtl_priv(hw);

	/* Response Rate Set */
	value32 = rtl_read_dword(rtlpriv, REG_RRSR);
	value32 &= ~RATE_BITMAP_ALL;
	value32 |= RATE_RRSR_CCK_ONLY_1M;
	rtl_write_dword(rtlpriv, REG_RRSR, value32);
	/* SIFS (used in NAV) */
	value16 = _SPEC_SIFS_CCK(0x10) | _SPEC_SIFS_OFDM(0x10);
	rtl_write_word(rtlpriv,  REG_SPEC_SIFS, value16);
	/* Retry Limit */
	value16 = _LRL(0x30) | _SRL(0x30);
	rtl_write_dword(rtlpriv,  REG_RL, value16);
}
Beispiel #20
0
static int rtl_proc_get_mac_1(char *page, char **start,
		off_t offset, int count, int *eof, void *data)
{
	struct ieee80211_hw *hw = data;
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	int len = 0;
	int i, n, page0;
	int max = 0xff;
	page0 = 0x100;

	for (n = 0; n <= max; ) {
		len += snprintf(page + len, count - len, "\n%8.8x  ", n + page0);
		for (i = 0; i < 4 && n <= max; i++, n += 4)
			len += snprintf(page + len, count - len,
				"%8.8x    ", rtl_read_dword(rtlpriv, (page0 | n)));
	}

	len += snprintf(page + len, count - len, "\n");
	*eof = 1;
	return len;

}
Beispiel #21
0
Datei: mac.c Projekt: 7799/linux
/**
 * writeLLT - LLT table write access
 * @io: io callback
 * @address: LLT logical address.
 * @data: LLT data content
 *
 * Realtek hardware access function.
 *
 */
bool rtl92c_llt_write(struct ieee80211_hw *hw, u32 address, u32 data)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	bool status = true;
	long count = 0;
	u32 value = _LLT_INIT_ADDR(address) |
	    _LLT_INIT_DATA(data) | _LLT_OP(_LLT_WRITE_ACCESS);

	rtl_write_dword(rtlpriv, REG_LLT_INIT, value);
	do {
		value = rtl_read_dword(rtlpriv, REG_LLT_INIT);
		if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value))
			break;
		if (count > POLLING_LLT_THRESHOLD) {
			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
				 "Failed to polling write LLT done at address %d! _LLT_OP_VALUE(%x)\n",
				 address, _LLT_OP_VALUE(value));
			status = false;
			break;
		}
	} while (++count);
	return status;
}
Beispiel #22
0
Datei: mac.c Projekt: 7799/linux
void rtl92c_read_chip_version(struct ieee80211_hw *hw)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	struct rtl_phy *rtlphy = &(rtlpriv->phy);
	struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
	enum version_8192c chip_version = VERSION_UNKNOWN;
	const char *versionid;
	u32 value32;

	value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG);
	if (value32 & TRP_VAUX_EN) {
		chip_version = (value32 & TYPE_ID) ? VERSION_TEST_CHIP_92C :
			       VERSION_TEST_CHIP_88C;
	} else {
		/* Normal mass production chip. */
		chip_version = NORMAL_CHIP;
		chip_version |= ((value32 & TYPE_ID) ? CHIP_92C : 0);
		chip_version |= ((value32 & VENDOR_ID) ? CHIP_VENDOR_UMC : 0);
		/* RTL8723 with BT function. */
		chip_version |= ((value32 & BT_FUNC) ? CHIP_8723 : 0);
		if (IS_VENDOR_UMC(chip_version))
			chip_version |= ((value32 & CHIP_VER_RTL_MASK) ?
					 CHIP_VENDOR_UMC_B_CUT : 0);
		if (IS_92C_SERIAL(chip_version)) {
			value32 = rtl_read_dword(rtlpriv, REG_HPON_FSM);
			chip_version |= ((CHIP_BONDING_IDENTIFIER(value32) ==
				 CHIP_BONDING_92C_1T2R) ? CHIP_92C_1T2R : 0);
		} else if (IS_8723_SERIES(chip_version)) {
			value32 = rtl_read_dword(rtlpriv, REG_GPIO_OUTSTS);
			chip_version |= ((value32 & RF_RL_ID) ?
					  CHIP_8723_DRV_REV : 0);
		}
	}
	rtlhal->version  = (enum version_8192c)chip_version;
	pr_info("Chip version 0x%x\n", chip_version);
	switch (rtlhal->version) {
	case VERSION_NORMAL_TSMC_CHIP_92C_1T2R:
		versionid = "NORMAL_B_CHIP_92C";
		break;
	case VERSION_NORMAL_TSMC_CHIP_92C:
		versionid = "NORMAL_TSMC_CHIP_92C";
		break;
	case VERSION_NORMAL_TSMC_CHIP_88C:
		versionid = "NORMAL_TSMC_CHIP_88C";
		break;
	case VERSION_NORMAL_UMC_CHIP_92C_1T2R_A_CUT:
		versionid = "NORMAL_UMC_CHIP_i92C_1T2R_A_CUT";
		break;
	case VERSION_NORMAL_UMC_CHIP_92C_A_CUT:
		versionid = "NORMAL_UMC_CHIP_92C_A_CUT";
		break;
	case VERSION_NORMAL_UMC_CHIP_88C_A_CUT:
		versionid = "NORMAL_UMC_CHIP_88C_A_CUT";
		break;
	case VERSION_NORMAL_UMC_CHIP_92C_1T2R_B_CUT:
		versionid = "NORMAL_UMC_CHIP_92C_1T2R_B_CUT";
		break;
	case VERSION_NORMAL_UMC_CHIP_92C_B_CUT:
		versionid = "NORMAL_UMC_CHIP_92C_B_CUT";
		break;
	case VERSION_NORMAL_UMC_CHIP_88C_B_CUT:
		versionid = "NORMAL_UMC_CHIP_88C_B_CUT";
		break;
	case VERSION_NORMA_UMC_CHIP_8723_1T1R_A_CUT:
		versionid = "NORMAL_UMC_CHIP_8723_1T1R_A_CUT";
		break;
	case VERSION_NORMA_UMC_CHIP_8723_1T1R_B_CUT:
		versionid = "NORMAL_UMC_CHIP_8723_1T1R_B_CUT";
		break;
	case VERSION_TEST_CHIP_92C:
		versionid = "TEST_CHIP_92C";
		break;
	case VERSION_TEST_CHIP_88C:
		versionid = "TEST_CHIP_88C";
		break;
	default:
		versionid = "UNKNOWN";
		break;
	}
	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
		 "Chip Version ID: %s\n", versionid);

	if (IS_92C_SERIAL(rtlhal->version))
		rtlphy->rf_type =
			 (IS_92C_1T2R(rtlhal->version)) ? RF_1T2R : RF_2T2R;
	else
		rtlphy->rf_type = RF_1T1R;
	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
		 "Chip RF Type: %s\n",
		 rtlphy->rf_type == RF_2T2R ? "RF_2T2R" : "RF_1T1R");
	if (get_rf_type(rtlphy) == RF_1T1R)
		rtlpriv->dm.rfpath_rxenable[0] = true;
	else
		rtlpriv->dm.rfpath_rxenable[0] =
		    rtlpriv->dm.rfpath_rxenable[1] = true;
	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "VersionID = 0x%4x\n",
		 rtlhal->version);
}
Beispiel #23
0
Datei: mac.c Projekt: 7799/linux
u32 rtl92c_get_txdma_status(struct ieee80211_hw *hw)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);

	return rtl_read_dword(rtlpriv, REG_TXDMA_STATUS);
}
Beispiel #24
0
static int _rtl92s_firmware_checkready(struct ieee80211_hw *hw,
		u8 loadfw_status)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
	struct rt_firmware *firmware = (struct rt_firmware *)rtlhal->pfirmware;
	u32 tmpu4b;
	u8 cpustatus = 0;
	int err = 0;
	int pollingcnt = 1000;

	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
		 "LoadStaus(%d)\n", loadfw_status);

	firmware->fwstatus = (enum fw_status)loadfw_status;

	switch (loadfw_status) {
	case FW_STATUS_LOAD_IMEM:
		/* Polling IMEM code done. */
		do {
			cpustatus = rtl_read_byte(rtlpriv, REG_TCR);
			if (cpustatus & IMEM_CODE_DONE)
				break;
			udelay(5);
		} while (pollingcnt--);

		if (!(cpustatus & IMEM_CHK_RPT) || (pollingcnt <= 0)) {
			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
				 "FW_STATUS_LOAD_IMEM FAIL CPU, Status=%x\n",
				 cpustatus);
			err = -EAGAIN;
			goto status_check_fail;
		}
		break;

	case FW_STATUS_LOAD_EMEM:
		/* Check Put Code OK and Turn On CPU */
		/* Polling EMEM code done. */
		do {
			cpustatus = rtl_read_byte(rtlpriv, REG_TCR);
			if (cpustatus & EMEM_CODE_DONE)
				break;
			udelay(5);
		} while (pollingcnt--);

		if (!(cpustatus & EMEM_CHK_RPT) || (pollingcnt <= 0)) {
			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
				 "FW_STATUS_LOAD_EMEM FAIL CPU, Status=%x\n",
				 cpustatus);
			err = -EAGAIN;
			goto status_check_fail;
		}

		/* Turn On CPU */
		err = _rtl92s_firmware_enable_cpu(hw);
		if (err) {
			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
				 "Enable CPU fail!\n");
			err = -EAGAIN;
			goto status_check_fail;
		}
		break;

	case FW_STATUS_LOAD_DMEM:
		/* Polling DMEM code done */
		do {
			cpustatus = rtl_read_byte(rtlpriv, REG_TCR);
			if (cpustatus & DMEM_CODE_DONE)
				break;
			udelay(5);
		} while (pollingcnt--);

		if (!(cpustatus & DMEM_CODE_DONE) || (pollingcnt <= 0)) {
			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
				 "Polling DMEM code done fail ! cpustatus(%#x)\n",
				 cpustatus);
			err = -EAGAIN;
			goto status_check_fail;
		}

		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
			 "DMEM code download success, cpustatus(%#x)\n",
			 cpustatus);

		/* Prevent Delay too much and being scheduled out */
		/* Polling Load Firmware ready */
		pollingcnt = 30;
		do {
			cpustatus = rtl_read_byte(rtlpriv, REG_TCR);
			if (cpustatus & FWRDY)
				break;
			msleep(100);
		} while (pollingcnt--);

		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
			 "Polling Load Firmware ready, cpustatus(%x)\n",
			 cpustatus);

		if (((cpustatus & LOAD_FW_READY) != LOAD_FW_READY) ||
		    (pollingcnt <= 0)) {
			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
				 "Polling Load Firmware ready fail ! cpustatus(%x)\n",
				 cpustatus);
			err = -EAGAIN;
			goto status_check_fail;
		}

		/* If right here, we can set TCR/RCR to desired value  */
		/* and config MAC lookback mode to normal mode */
		tmpu4b = rtl_read_dword(rtlpriv, REG_TCR);
		rtl_write_dword(rtlpriv, REG_TCR, (tmpu4b & (~TCR_ICV)));

		tmpu4b = rtl_read_dword(rtlpriv, REG_RCR);
		rtl_write_dword(rtlpriv, REG_RCR, (tmpu4b |
			RCR_APP_PHYST_RXFF | RCR_APP_ICV | RCR_APP_MIC));

		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
			 "Current RCR settings(%#x)\n", tmpu4b);

		/* Set to normal mode. */
		rtl_write_byte(rtlpriv, REG_LBKMD_SEL, LBK_NORMAL);
		break;

	default:
		RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
			 "Unknown status check!\n");
		err = -EINVAL;
		break;
	}

status_check_fail:
	if (err) {
		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
		 "loadfw_status(%d), err(%d)\n",
			 loadfw_status, err);
	}

	return err;
}
Beispiel #25
0
static void _rtl92su_macconfig_after_fwdownload(struct ieee80211_hw *hw)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
	u8 i, tmpu1b;

	/* 1. System Configure Register (Offset: 0x0000 - 0x003F) */

	/* 2. Command Control Register (Offset: 0x0040 - 0x004F) */
	/* Turn on 0x40 Command register */
	rtl_write_word(rtlpriv, REG_CR, (BBRSTN | BB_GLB_RSTN |
			SCHEDULE_EN | MACRXEN | MACTXEN | DDMA_EN | FW2HW_EN |
			RXDMA_EN | TXDMA_EN | HCI_RXDMA_EN | HCI_TXDMA_EN));

	/* Set TCR TX DMA pre 2 FULL enable bit	*/
	rtl_write_dword(rtlpriv, REG_TCR, rtl_read_dword(rtlpriv, TCR) |
			TXDMAPRE2FULL);

	/* 3. MACID Setting Register (Offset: 0x0050 - 0x007F) */

	/* 4. Timing Control Register  (Offset: 0x0080 - 0x009F) */
	/* Set CCK/OFDM SIFS */
	/* CCK SIFS shall always be 10us. */
	rtl_write_word(rtlpriv, REG_SIFS_CCK, 0x0a0a);
	rtl_write_word(rtlpriv, REG_SIFS_OFDM, 0x1010);

	/* Set AckTimeout */
	rtl_write_byte(rtlpriv, REG_ACK_TIMEOUT, 0x40);

	/* Beacon related */
	rtl_write_word(rtlpriv, REG_BCN_INTERVAL, 100);
	rtl_write_word(rtlpriv, REG_ATIMWND, 2);

	/* 5. FIFO Control Register (Offset: 0x00A0 - 0x015F) */
	/* 5.1 Initialize Number of Reserved Pages in Firmware Queue */
	/* Firmware allocate now, associate with FW internal setting.!!! */
	/* Setting TX/RX page size*/
	rtl_write_byte(rtlpriv, REG_PBP, 0x22);

	/* 5.2 Setting TX/RX page size 0/1/2/3/4=64/128/256/512/1024 */
	/* 5.3 Set driver info, we only accept PHY status now. */

	/* 5.4 Set RXDMA arbitration to control RXDMA/MAC/FW R/W for RXFIFO
	 * tmpu1b = rtl_read_byte(rtlpriv, REG_RXDMA_RXCTRL);
	 * tmpu1b |= RXDMA_AGG_EN;
	 * rtl_write_byte(rtlpriv, REG_RXDMA_RXCTRL, tmpu1b);
	 *
	 * NB: rx-streaming is not implemented.
	 */

	rtl_write_byte(rtlpriv, REG_RXDMA_AGG_PG_TH, 0x1);

	/* 6. Adaptive Control Register  (Offset: 0x0160 - 0x01CF) */
	/* Set RRSR to all legacy rate and HT rate
	 * CCK rate is supported by default.
	 * CCK rate will be filtered out only when associated
	 * AP does not support it.
	 * Only enable ACK rate to OFDM 24M
	 * Disable RRSR for CCK rate in A-Cut	*/

	if (rtlhal->version == VERSION_8192S_ACUT)
		rtl_write_byte(rtlpriv, REG_RRSR, 0xf0);
	else if (rtlhal->version == VERSION_8192S_BCUT)
		rtl_write_byte(rtlpriv, REG_RRSR, 0xff);
	rtl_write_byte(rtlpriv, REG_RRSR + 1, 0x01);
	rtl_write_byte(rtlpriv, REG_RRSR + 2, 0x00);

	/* A-Cut IC do not support CCK rate. We forbid ARFR to */
	/* fallback to CCK rate */
	for (i = 0; i < 8; i++) {
		/*Disable RRSR for CCK rate in A-Cut */
		if (rtlhal->version == VERSION_8192S_ACUT)
			rtl_write_dword(rtlpriv, REG_ARFR0 + i * 4, 0x1f0ff0f0);
	}

	/* Different rate use different AMPDU size */
	/* MCS32/ MCS15_SG use max AMPDU size 15*2=30K */
	rtl_write_byte(rtlpriv, REG_AGGLEN_LMT_H, 0x0f);
	/* MCS0/1/2/3 use max AMPDU size 4*2=8K */
	rtl_write_word(rtlpriv, REG_AGGLEN_LMT_L, 0x5221);
	/* MCS4/5 use max AMPDU size 8*2=16K 6/7 use 10*2=20K */
	rtl_write_word(rtlpriv, REG_AGGLEN_LMT_L + 2, 0xbbb5);
	/* MCS8/9 use max AMPDU size 8*2=16K 10/11 use 10*2=20K */
	rtl_write_word(rtlpriv, REG_AGGLEN_LMT_L + 4, 0xb551);
	/* MCS12/13/14/15 use max AMPDU size 15*2=30K */
	rtl_write_word(rtlpriv, REG_AGGLEN_LMT_L + 6, 0xfffb);

	/* Set Data / Response auto rate fallack retry count */
	rtl_write_dword(rtlpriv, REG_DARFRC, 0x01000000);
	rtl_write_dword(rtlpriv, REG_DARFRC + 4, 0x07060504);
	rtl_write_dword(rtlpriv, REG_RARFRC, 0x01000000);
	rtl_write_dword(rtlpriv, REG_RARFRC + 4, 0x07060605);

	/* 7. EDCA Setting Register (Offset: 0x01D0 - 0x01FF) */
	/* Set all rate to support SG */
	rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, 0xa44f);
	rtl_write_word(rtlpriv, REG_SG_RATE, 0xFFFF);

	/* 8. WMAC, BA, and CCX related Register (Offset: 0x0200 - 0x023F) */
	/* Set NAV protection length */
	rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0080);
	/* CF-END Threshold */
	rtl_write_byte(rtlpriv, REG_CFEND_TH, 0xFF);
	/* Set AMPDU minimum space */
	rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, 0x07);
	/* Set TXOP stall control for several queue/HI/BCN/MGT/ */
	rtl_write_byte(rtlpriv, REG_TXOP_STALL_CTRL, 0x00);

	/* 9. Security Control Register (Offset: 0x0240 - 0x025F) */
	/* 10. Power Save Control Register (Offset: 0x0260 - 0x02DF) */
	/* 11. General Purpose Register (Offset: 0x02E0 - 0x02FF) */
	/* 12. Host Interrupt Status Register (Offset: 0x0300 - 0x030F) */
	/* 13. Test Mode and Debug Control Register (Offset: 0x0310 - 0x034F) */

	/* 14. Set driver info, we only accept PHY status now. */
	rtl_write_byte(rtlpriv, REG_RX_DRVINFO_SZ, 4);

	tmpu1b = rtl_read_byte(rtlpriv, REG_LD_RQPN);
	/* tmpu1b |= BIT(6)|BIT(7);
	 * tmpu1b |= BIT(5); // Only for USBEP_FOUR */
	tmpu1b |= 0xa0;
	rtl_write_byte(rtlpriv, REG_LD_RQPN, tmpu1b);

	rtl_write_byte(rtlpriv, REG_USB_DMA_AGG_TO, 0x0a);

	/* Fix the RX FIFO issue(USB error) */
	tmpu1b = rtl_read_byte(rtlpriv, REG_USB_AGG_TO);
	tmpu1b |= BIT(7);
	rtl_write_byte(rtlpriv, REG_USB_AGG_TO, tmpu1b);

	tmpu1b = rtl_read_byte(rtlpriv, REG_SYS_ISO_CTRL + 1);
	tmpu1b &= 0xFE;
	rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL + 1, tmpu1b);

	/* Disable DIG as default */
	tmpu1b = rtl_read_byte(rtlpriv, REG_LBUS_MON_ADDR);
	tmpu1b &= ~BIT(0);
	rtl_write_byte(rtlpriv, REG_LBUS_MON_ADDR, tmpu1b);

	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "OK\n");
}
Beispiel #26
0
static bool _rtl92s_firmware_checkready( struct ieee80211_hw *hw,
		u8 loadfw_status )
{
	struct rtl_priv *rtlpriv = rtl_priv( hw );
	struct rtl_hal *rtlhal = rtl_hal( rtl_priv( hw ) );
	struct rt_firmware *pfirmware = ( struct rt_firmware * )rtlhal->pfirmware;
	u32 tmpu4b;
	u8 cpustatus = 0;
	short pollingcnt = 1000;
	bool rtstatus = true;

	RT_TRACE( COMP_INIT, DBG_LOUD, ( "LoadStaus(%d)\n", loadfw_status ) );

	pfirmware->fwstatus = ( enum fw_status )loadfw_status;

	switch ( loadfw_status ) {
	case FW_STATUS_LOAD_IMEM:
		/* Polling IMEM code done. */
		do {
			cpustatus = rtl_read_byte( rtlpriv, TCR );
			if ( cpustatus & IMEM_CODE_DONE )
				break;
			udelay( 5 );
		} while ( pollingcnt-- );

		if ( !( cpustatus & IMEM_CHK_RPT ) || ( pollingcnt <= 0 ) ) {
			RT_TRACE( COMP_ERR, DBG_EMERG, ( "FW_STATUS_LOAD_IMEM"
				" FAIL CPU, Status=%x\r\n",	cpustatus ) );
			goto status_check_fail;
		}
		break;

	case FW_STATUS_LOAD_EMEM:
		/* Check Put Code OK and Turn On CPU */
		/* Polling EMEM code done. */
		do {
			cpustatus = rtl_read_byte( rtlpriv, TCR );
			if ( cpustatus & EMEM_CODE_DONE )
				break;
			udelay( 5 );
		} while ( pollingcnt-- );

		if ( !( cpustatus & EMEM_CHK_RPT ) || ( pollingcnt <= 0 ) ) {
			RT_TRACE( COMP_ERR, DBG_EMERG, ( "FW_STATUS_LOAD_EMEM"
				" FAIL CPU, Status=%x\r\n", cpustatus ) );
			goto status_check_fail;
		}

		/* Turn On CPU */
		rtstatus = _rtl92s_firmware_enable_cpu( hw );
		if ( rtstatus != true ) {
			RT_TRACE( COMP_ERR, DBG_EMERG, ( "Enable CPU fail ! \n" ) );
			goto status_check_fail;
		}
		break;

	case FW_STATUS_LOAD_DMEM:
		/* Polling DMEM code done */
		do {
			cpustatus = rtl_read_byte( rtlpriv, TCR );
			if ( cpustatus & DMEM_CODE_DONE )
				break;
			udelay( 5 );
		} while ( pollingcnt-- );

		if ( !( cpustatus & DMEM_CODE_DONE ) || ( pollingcnt <= 0 ) ) {
			RT_TRACE( COMP_ERR, DBG_EMERG, ( "Polling  DMEM code done"
				" fail ! cpustatus(%#x)\n",	cpustatus ) );
			goto status_check_fail;
		}

		RT_TRACE( COMP_INIT, DBG_LOUD, ( "DMEM code download success,"
			" cpustatus(%#x)\n", cpustatus ) );

		/* Prevent Delay too much and being scheduled out */
		/* Polling Load Firmware ready */
		pollingcnt = 2000;
		do {
			cpustatus = rtl_read_byte( rtlpriv, TCR );
			if( cpustatus & FWRDY )
				break;
			udelay( 40 );
		} while ( pollingcnt-- );

		RT_TRACE( COMP_INIT, DBG_LOUD, ( "Polling Load Firmware ready,"
			" cpustatus(%x)\n",	cpustatus ) );

		if ( ( ( cpustatus & LOAD_FW_READY ) != LOAD_FW_READY ) ||
			( pollingcnt <= 0 ) ) {
			RT_TRACE( COMP_ERR, DBG_EMERG, ( "Polling Load Firmware"
				" ready fail ! cpustatus(%x)\n", cpustatus ) );
			goto status_check_fail;
		}

		/* If right here, we can set TCR/RCR to desired value  */
		/* and config MAC lookback mode to normal mode */
		tmpu4b = rtl_read_dword( rtlpriv, TCR );
		rtl_write_dword( rtlpriv, TCR, ( tmpu4b & ( ~TCR_ICV ) ) );

		tmpu4b = rtl_read_dword( rtlpriv, RCR );
		rtl_write_dword( rtlpriv, RCR, ( tmpu4b | RCR_APPFCS | RCR_APP_ICV |
				RCR_APP_MIC ) );

		RT_TRACE( COMP_INIT, DBG_LOUD, ( "Current RCR settings(%#x)\n",
				tmpu4b ) );

		/* Set to normal mode. */
		rtl_write_byte( rtlpriv, LBKMD_SEL, LBK_NORMAL );
		break;

	default :
		RT_TRACE( COMP_INIT, DBG_EMERG, ( "Unknown status check!\n" ) );
		rtstatus = false;
		break;
	}

status_check_fail:
	RT_TRACE( COMP_INIT, DBG_LOUD, ( "loadfw_status(%d), "
			"rtstatus(%x)\n", loadfw_status, rtstatus ) );
	return rtstatus;
}
Beispiel #27
0
int rtl92su_hw_init(struct ieee80211_hw *hw)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
	struct rtl_phy *rtlphy = &(rtlpriv->phy);
	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
	int err = 0;
	bool rtstatus = true;
	u8 i;

	int wdcapra_add[] = {
		REG_EDCA_BE_PARAM, REG_EDCA_BK_PARAM,
		REG_EDCA_VI_PARAM, REG_EDCA_VO_PARAM};
	u8 secr_value = 0x0;

	/* 1. MAC Initialize */
	/* Before FW download, we have to set some MAC register */
	err = _rtl92su_macconfig_before_fwdownload(hw);
	if (err) {
		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
		 "Failed to get the device ready for the firmware (%d)\n",
		err);
		return err;
	}

	rtlhal->version = (enum version_8192s)((rtl_read_dword(rtlpriv,
			REG_PMC_FSM) >> 16) & 0xF);

	/* 2. download firmware */
	rtstatus = rtl92s_download_fw(hw);
	if (!rtstatus) {
		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
			 "Failed to download FW. Init HW without FW now... Please copy FW into /lib/firmware/rtlwifi\n");
		return -ENOENT;
	}

	/* After FW download, we have to reset MAC register */
	_rtl92su_macconfig_after_fwdownload(hw);

	/*Retrieve default FW Cmd IO map. */
	rtlhal->fwcmd_iomap =	rtl_read_word(rtlpriv, REG_LBUS_MON_ADDR);
	rtlhal->fwcmd_ioparam = rtl_read_dword(rtlpriv, REG_LBUS_ADDR_MASK);

	/* 3. Initialize MAC/PHY Config by MACPHY_reg.txt */
	rtstatus = rtl92s_phy_mac_config(hw);
	if (!rtstatus) {
		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "MAC Config failed\n");
		return -EINVAL;
	}

	/* because last function modify RCR, so we update
	 * rcr var here, or TP will unstable for receive_config
	 * is wrong, RX RCR_ACRC32 will cause TP unstabel & Rx
	 * RCR_APP_ICV will cause mac80211 unassoc for cisco 1252
	 */

	/* Make sure BB/RF write OK. We should prevent enter IPS. radio off. */
	/* We must set flag avoid BB/RF config period later!! */
	rtl_write_word(rtlpriv, CMDR, 0x37FC);

	/* 4. Initialize BB After MAC Config PHY_reg.txt, AGC_Tab.txt */
	rtstatus = rtl92s_phy_bb_config(hw);
	if (!rtstatus) {
		RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, "BB Config failed\n");
		return -ENODEV;
	}

	/* 5. Initiailze RF RAIO_A.txt RF RAIO_B.txt */
	/* Before initalizing RF. We can not use FW to do RF-R/W. */
	rtlphy->rf_mode = RF_OP_BY_SW_3WIRE;

	/* Before RF-R/W we must execute the IO from Scott's suggestion. */
	rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0xDB);
	if (rtlhal->version == VERSION_8192S_ACUT)
		rtl_write_byte(rtlpriv, REG_SPS1_CTRL + 3, 0x07);
	else
		rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x07);

	rtstatus = rtl92s_phy_rf_config(hw);
	if (!rtstatus) {
		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "RF Config failed\n");
		return -EOPNOTSUPP;
	}

	/* After read predefined TXT, we must set BB/MAC/RF
	 * register as our requirement */
	rtlphy->rfreg_chnlval[0] = rtl92s_phy_query_rf_reg(hw,
							   (enum radio_path)0,
							   RF_CHNLBW,
							   RFREG_OFFSET_MASK);
	rtlphy->rfreg_chnlval[1] = rtl92s_phy_query_rf_reg(hw,
							   (enum radio_path)1,
							   RF_CHNLBW,
							   RFREG_OFFSET_MASK);

	/*---- Set CCK and OFDM Block "ON"----*/
	rtl_set_bbreg(hw, REG_RFPGA0_RFMOD, BCCKEN, 0x1);
	rtl_set_bbreg(hw, REG_RFPGA0_RFMOD, BOFDMEN, 0x1);

	/*3 Set Hardware(Do nothing now) */
	_rtl92su_hw_configure(hw);

	/* Read EEPROM TX power index and PHY_REG_PG.txt to capture correct */
	/* TX power index for different rate set. */
	/* Get original hw reg values */
	rtl92s_phy_get_hw_reg_originalvalue(hw);
	/* Write correct tx power index */
	rtl92s_phy_set_txpower(hw, rtlphy->current_channel);

	/* We must set MAC address after firmware download. */
	for (i = 0; i < 6; i++)
		rtl_write_byte(rtlpriv, MACIDR0 + i, rtlefuse->dev_addr[i]);

	/* We enable high power and RA related mechanism after NIC
	 * initialized. */
	if (hal_get_firmwareversion(rtlpriv) >= 0x35) {
		/* Fw v.53 and later. */
		rtl92s_phy_set_fw_cmd(hw, FW_CMD_RA_INIT);
	} else if (hal_get_firmwareversion(rtlpriv) == 0x34) {
		/* Fw v.52. */
		rtl_write_dword(rtlpriv, REG_WFM5, FW_RA_INIT);
		rtl92s_phy_chk_fwcmd_iodone(hw);
	} else {
		/* Compatible earlier FW version. */
		rtl_write_dword(rtlpriv, REG_WFM5, FW_RA_RESET);
		rtl92s_phy_chk_fwcmd_iodone(hw);
		rtl_write_dword(rtlpriv, REG_WFM5, FW_RA_ACTIVE);
		rtl92s_phy_chk_fwcmd_iodone(hw);
		rtl_write_dword(rtlpriv, REG_WFM5, FW_RA_REFRESH);
		rtl92s_phy_chk_fwcmd_iodone(hw);
	}

	/* Security related
	 * 1. Clear all H/W keys.
	 * 2. Enable H/W encryption/decryption. */
	rtl_cam_reset_all_entry(hw);
	secr_value |= SCR_TXENCENABLE;
	secr_value |= SCR_RXENCENABLE;
	secr_value |= SCR_NOSKMC;
	rtl_write_byte(rtlpriv, REG_SECR, secr_value);

	for (i = 0; i < 4; i++)
		rtl_write_dword(rtlpriv, wdcapra_add[i], 0x5e4322);

	if (rtlphy->rf_type == RF_1T2R) {
		bool mrc2set = true;
		/* Turn on B-Path */
		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_MRC, (u8 *)&mrc2set);
	}

	rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_ON);
	rtl92s_dm_init(hw);
	return err;
}