Пример #1
0
void rtl8822be_tx_polling(struct ieee80211_hw *hw, u8 hw_queue)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);

	if (hw_queue == BEACON_QUEUE) {
		/* kick start */
		rtl_write_byte(
			rtlpriv, REG_RX_RXBD_NUM_8822B + 1,
			rtl_read_byte(rtlpriv, REG_RX_RXBD_NUM_8822B + 1) |
				BIT(4));
	}
}
Пример #2
0
Файл: led.c Проект: 020gzh/linux
void rtl8812ae_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled)
{
	u16 ledreg = REG_LEDCFG1;
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);

	switch (pled->ledpin) {
	case LED_PIN_LED0:
		ledreg = REG_LEDCFG1;
		break;

	case LED_PIN_LED1:
		ledreg = REG_LEDCFG2;
		break;

	case LED_PIN_GPIO0:
	default:
		break;
	}

	RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD,
		 "In SwLedOff,LedAddr:%X LEDPIN=%d\n",
		 ledreg, pled->ledpin);
	/*Open-drain arrangement for controlling the LED*/
	if (pcipriv->ledctl.led_opendrain) {
		u8 ledcfg = rtl_read_byte(rtlpriv, ledreg);

		ledreg &= 0xd0; /* Set to software control.*/
		rtl_write_byte(rtlpriv, ledreg, (ledcfg | BIT(3)));

		/*Open-drain arrangement*/
		ledcfg = rtl_read_byte(rtlpriv, REG_MAC_PINMUX_CFG);
		ledcfg &= 0xFE;/*Set GPIO[8] to input mode*/
		rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, ledcfg);
	} else {
		rtl_write_byte(rtlpriv, ledreg, 0x28);
	}

	pled->ledon = false;
}
Пример #3
0
void rtl8821au_firmware_selfreset(struct rtl_priv *rtlpriv)
{
	struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
	uint8_t u1bTmp, u1bTmp2;

	/* Reset MCU IO Wrapper- sugggest by SD1-Gimmy */
	if (IS_HARDWARE_TYPE_8812(rtlhal)) {
		u1bTmp2 = rtl_read_byte(rtlpriv, REG_RSV_CTRL+1);
		rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, u1bTmp2&(~BIT3));
	} else if (IS_HARDWARE_TYPE_8821(rtlhal)) {
		u1bTmp2 = rtl_read_byte(rtlpriv, REG_RSV_CTRL+1);
		rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, u1bTmp2&(~BIT0));
	}

	u1bTmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN+1);
	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN+1, u1bTmp&(~BIT2));

	/* Enable MCU IO Wrapper */
	if (IS_HARDWARE_TYPE_8812(rtlhal)) {
		u1bTmp2 = rtl_read_byte(rtlpriv, REG_RSV_CTRL+1);
		rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, u1bTmp2 | (BIT3));
	} else if (IS_HARDWARE_TYPE_8821(rtlhal)) {
		u1bTmp2 = rtl_read_byte(rtlpriv, REG_RSV_CTRL+1);
		rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, u1bTmp2 | (BIT0));
	}

	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN+1, u1bTmp|(BIT2));

	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, " _8051Reset8812(): 8051 reset success .\n");
}
Пример #4
0
Файл: led.c Проект: 020gzh/linux
void rtl8821ae_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
	u8 ledcfg;

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

	ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2);

	switch (pled->ledpin) {
	case LED_PIN_GPIO0:
		break;
	case LED_PIN_LED0:
		ledcfg &= 0xf0;
		if (pcipriv->ledctl.led_opendrain) {
			ledcfg &= 0x90; /* Set to software control. */
			rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg|BIT(3)));
			ledcfg = rtl_read_byte(rtlpriv, REG_MAC_PINMUX_CFG);
			ledcfg &= 0xFE;
			rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, ledcfg);
		} else {
			ledcfg &= ~BIT(6);
			rtl_write_byte(rtlpriv, REG_LEDCFG2,
				       (ledcfg | BIT(3) | BIT(5)));
		}
		break;
	case LED_PIN_LED1:
		ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG1);
		ledcfg &= 0x10; /* Set to software control. */
		rtl_write_byte(rtlpriv, REG_LEDCFG1, ledcfg|BIT(3));
		break;
	default:
		RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
			 "switch case not process\n");
		break;
	}
	pled->ledon = false;
}
Пример #5
0
void rtl8723ae_firmware_selfreset(struct ieee80211_hw *hw)
{
	u8 u1b_tmp;
	u8 delay = 100;
	struct rtl_priv *rtlpriv = rtl_priv(hw);

	rtl_write_byte(rtlpriv, REG_HMETFR + 3, 0x20);
	u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);

	while (u1b_tmp & BIT(2)) {
		delay--;
		if (delay == 0)
			break;
		udelay(50);
		u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
	}
	if (delay == 0) {
		u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
		rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1,
			       u1b_tmp&(~BIT(2)));
	}
}
Пример #6
0
void rtl8723_enable_fw_download(struct ieee80211_hw *hw, bool enable)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	u8 tmp;

	if (enable) {
		tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
		rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1,
			       tmp | 0x04);

		tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
		rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp | 0x01);

		tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL + 2);
		rtl_write_byte(rtlpriv, REG_MCUFWDL + 2, tmp & 0xf7);
	} else {
		tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
		rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp & 0xfe);

		rtl_write_byte(rtlpriv, REG_MCUFWDL + 1, 0x00);
	}
}
Пример #7
0
static void rtl92d_early_mode_enabled(struct rtl_priv *rtlpriv)
{
	if ((rtlpriv->mac80211.link_state >= MAC80211_LINKED) &&
	    (rtlpriv->mac80211.vendor == PEER_CISCO)) {
		RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
			 ("IOT_PEER = CISCO\n"));
		if (de_digtable.last_min_undecorated_pwdb_for_dm >= 50
		    && de_digtable.min_undecorated_pwdb_for_dm < 50) {
			rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL, 0x00);
			RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
				 ("Early Mode Off\n"));
		} else if (de_digtable.last_min_undecorated_pwdb_for_dm <= 55 &&
			   de_digtable.min_undecorated_pwdb_for_dm > 55) {
			rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL, 0x0f);
			RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
				 ("Early Mode On\n"));
		}
	} else if (!(rtl_read_byte(rtlpriv, REG_EARLY_MODE_CONTROL) & 0xf)) {
		rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL, 0x0f);
		RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("Early Mode On\n"));
	}
}
Пример #8
0
void rtl88ee_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
	u8 ledcfg;
	u8 val;

	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_byte(rtlpriv, REG_LEDCFG2);
		ledcfg &= 0xf0;
		val = ledcfg | BIT(3) | BIT(5) | BIT(6);
		if (pcipriv->ledctl.led_opendrain == true) {
			rtl_write_byte(rtlpriv, REG_LEDCFG2, val);
			ledcfg = rtl_read_byte(rtlpriv, REG_MAC_PINMUX_CFG);
			val = ledcfg & 0xFE;
			rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, val);
		} else {
			rtl_write_byte(rtlpriv, REG_LEDCFG2, val);
		}
		break;
	case LED_PIN_LED1:
		ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG1);
		ledcfg &= 0x10;
		rtl_write_byte(rtlpriv, REG_LEDCFG1, (ledcfg | BIT(3)));
		break;
	default:
		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
			 "switch case not processed\n");
		break;
	}
	pled->ledon = false;
}
Пример #9
0
void _rtl92cu_phy_lc_calibrate( struct ieee80211_hw *hw, bool is2t )
{
	u8 tmpreg;
	u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal;
	struct rtl_priv *rtlpriv = rtl_priv( hw );

	tmpreg = rtl_read_byte( rtlpriv, 0xd03 );

	if ( ( tmpreg & 0x70 ) != 0 )
		rtl_write_byte( rtlpriv, 0xd03, tmpreg & 0x8F );
	else
		rtl_write_byte( rtlpriv, REG_TXPAUSE, 0xFF );

	if ( ( tmpreg & 0x70 ) != 0 ) {
		rf_a_mode = rtl_get_rfreg( hw, RF90_PATH_A, 0x00, MASK12BITS );
		if ( is2t )
			rf_b_mode = rtl_get_rfreg( hw, RF90_PATH_B, 0x00,
						  MASK12BITS );
		rtl_set_rfreg( hw, RF90_PATH_A, 0x00, MASK12BITS,
			      ( rf_a_mode & 0x8FFFF ) | 0x10000 );
		if ( is2t )
			rtl_set_rfreg( hw, RF90_PATH_B, 0x00, MASK12BITS,
				      ( rf_b_mode & 0x8FFFF ) | 0x10000 );
	}
	lc_cal = rtl_get_rfreg( hw, RF90_PATH_A, 0x18, MASK12BITS );
	rtl_set_rfreg( hw, RF90_PATH_A, 0x18, MASK12BITS, lc_cal | 0x08000 );
	mdelay( 100 );
	if ( ( tmpreg & 0x70 ) != 0 ) {
		rtl_write_byte( rtlpriv, 0xd03, tmpreg );
		rtl_set_rfreg( hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode );
		if ( is2t )
			rtl_set_rfreg( hw, RF90_PATH_B, 0x00, MASK12BITS,
				      rf_b_mode );
	} else {
		rtl_write_byte( rtlpriv, REG_TXPAUSE, 0x00 );
	}
}
Пример #10
0
int rtl8723_download_fw(struct ieee80211_hw *hw,
			bool is_8723be, int max_count)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
	struct rtlwifi_firmware_header *pfwheader;
	u8 *pfwdata;
	u32 fwsize;
	int err;
	enum version_8723e version = rtlhal->version;
	int max_page;

	if (!rtlhal->pfirmware)
		return 1;

	pfwheader = (struct rtlwifi_firmware_header *)rtlhal->pfirmware;
	pfwdata = rtlhal->pfirmware;
	fwsize = rtlhal->fwsize;

	if (!is_8723be)
		max_page = 6;
	else
		max_page = 8;
	if (rtlpriv->cfg->ops->is_fw_header(pfwheader)) {
		RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD,
			 "Firmware Version(%d), Signature(%#x), Size(%d)\n",
			 pfwheader->version, pfwheader->signature,
			 (int)sizeof(struct rtlwifi_firmware_header));

		pfwdata = pfwdata + sizeof(struct rtlwifi_firmware_header);
		fwsize = fwsize - sizeof(struct rtlwifi_firmware_header);
	}

	if (rtl_read_byte(rtlpriv, REG_MCUFWDL)&BIT(7)) {
		if (is_8723be)
			rtl8723be_firmware_selfreset(hw);
		else
			rtl8723ae_firmware_selfreset(hw);
		rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00);
	}
	rtl8723_enable_fw_download(hw, true);
	rtl8723_write_fw(hw, version, pfwdata, fwsize, max_page);
	rtl8723_enable_fw_download(hw, false);

	err = rtl8723_fw_free_to_go(hw, is_8723be, max_count);
	if (err)
		pr_err("Firmware is not ready to run!\n");
	return 0;
}
Пример #11
0
void rtl92de_sw_led_on( struct ieee80211_hw *hw, struct rtl_led *pled )
{
	u8 ledcfg;
	struct rtl_priv *rtlpriv = rtl_priv( hw );

	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_byte( rtlpriv, REG_LEDCFG2 );

		if ( ( rtlpriv->efuse.eeprom_did == 0x8176 ) ||
			( rtlpriv->efuse.eeprom_did == 0x8193 ) )
			/* BIT7 of REG_LEDCFG2 should be set to
			 * make sure we could emit the led2. */
			rtl_write_byte( rtlpriv, REG_LEDCFG2, ( ledcfg & 0xf0 ) |
				       BIT( 7 ) | BIT( 5 ) | BIT( 6 ) );
		else
			rtl_write_byte( rtlpriv, REG_LEDCFG2, ( ledcfg & 0xf0 ) |
				       BIT( 7 ) | BIT( 5 ) );
		break;
	case LED_PIN_LED1:
		ledcfg = rtl_read_byte( rtlpriv, REG_LEDCFG1 );

		rtl_write_byte( rtlpriv, REG_LEDCFG2, ( ledcfg & 0x0f ) | BIT( 5 ) );
		break;
	default:
		pr_err( "switch case %#x not processed\n",
		       pled->ledpin );
		break;
	}
	pled->ledon = true;
}
Пример #12
0
static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	u32 i;
	u32 arraylength;
	u32 *ptrarray;

	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read Rtl819XMACPHY_Array\n");
	arraylength = MAC_2T_ARRAYLENGTH;
	ptrarray = RTL8192CEMAC_2T_ARRAY;
	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Img:RTL8192CEMAC_2T_ARRAY\n");
	for (i = 0; i < arraylength; i = i + 2)
		rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]);
	return true;
}
Пример #13
0
bool _rtl92cu_phy_config_mac_with_headerfile( struct ieee80211_hw *hw )
{
	struct rtl_priv *rtlpriv = rtl_priv( hw );
	struct rtl_phy *rtlphy = &( rtlpriv->phy );
	u32 i;
	u32 arraylength;
	u32 *ptrarray;

	RT_TRACE( rtlpriv, COMP_INIT, DBG_TRACE, "Read Rtl819XMACPHY_Array\n" );
	arraylength =  rtlphy->hwparam_tables[MAC_REG].length ;
	ptrarray = rtlphy->hwparam_tables[MAC_REG].pdata;
	RT_TRACE( rtlpriv, COMP_INIT, DBG_TRACE, "Img:RTL8192CEMAC_2T_ARRAY\n" );
	for ( i = 0; i < arraylength; i = i + 2 )
		rtl_write_byte( rtlpriv, ptrarray[i], ( u8 ) ptrarray[i + 1] );
	return true;
}
Пример #14
0
Файл: mac.c Проект: 7799/linux
/*-------------------------------------------------------------------------
 * HW MAC Address
 *-------------------------------------------------------------------------*/
void rtl92c_set_mac_addr(struct ieee80211_hw *hw, const u8 *addr)
{
	u32 i;
	struct rtl_priv *rtlpriv = rtl_priv(hw);

	for (i = 0 ; i < ETH_ALEN ; i++)
		rtl_write_byte(rtlpriv, (REG_MACID + i), *(addr+i));

	RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
		 "MAC Address: %02X-%02X-%02X-%02X-%02X-%02X\n",
		 rtl_read_byte(rtlpriv, REG_MACID),
		 rtl_read_byte(rtlpriv, REG_MACID+1),
		 rtl_read_byte(rtlpriv, REG_MACID+2),
		 rtl_read_byte(rtlpriv, REG_MACID+3),
		 rtl_read_byte(rtlpriv, REG_MACID+4),
		 rtl_read_byte(rtlpriv, REG_MACID+5));
}
Пример #15
0
static void rtl92d_dm_pwdb_monitor(struct ieee80211_hw *hw)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);

	/* AP & ADHOC & MESH will return tmp */
	if (rtlpriv->mac80211.opmode != NL80211_IFTYPE_STATION)
		return;
	/* Indicate Rx signal strength to FW. */
	if (rtlpriv->dm.useramask) {
		u32 temp = rtlpriv->dm.undecorated_smoothed_pwdb;

		temp <<= 16;
		temp |= 0x100;
		/* fw v12 cmdid 5:use max macid ,for nic ,
		 * default macid is 0 ,max macid is 1 */
		rtl92d_fill_h2c_cmd(hw, H2C_RSSI_REPORT, 3, (u8 *) (&temp));
	} else {
		rtl_write_byte(rtlpriv, 0x4fe,
			       (u8) rtlpriv->dm.undecorated_smoothed_pwdb);
	}
}
Пример #16
0
Файл: mac.c Проект: 7799/linux
void rtl92c_init_beacon_max_error(struct ieee80211_hw *hw, bool infra_mode)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);

	rtl_write_byte(rtlpriv, REG_BCN_MAX_ERR, 0xFF);
}
Пример #17
0
Файл: mac.c Проект: 7799/linux
void rtl92c_init_driver_info_size(struct ieee80211_hw *hw, u8 size)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	rtl_write_byte(rtlpriv, REG_RX_DRVINFO_SZ, size);
}
Пример #18
0
/*
*	Description:
*		This routine deal with the Power Configuration CMDs
*		 parsing for RTL8723/RTL8188E Series IC.
*	Assumption:
*		We should follow specific format which was released from HW SD.
*
*	2011.07.07, added by Roger.
*/
bool rtl_hal_pwrseqcmdparsing(struct rtl_priv *rtlpriv, u8 cut_version,
			u8 fab_version, u8 interface_type,
			struct wlan_pwr_cfg	pwrcfgcmd[])

{
	struct wlan_pwr_cfg pwr_cfg_cmd = {0};
	bool b_polling_bit = false;
	u32 ary_idx = 0;
	u8 value = 0;
	u32 offset = 0;
	u32 polling_count = 0;
	u32 max_polling_cnt = 5000;

	do {
		pwr_cfg_cmd = pwrcfgcmd[ary_idx];
		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
			"rtl_hal_pwrseqcmdparsing(): offset(%#x),cut_msk(%#x), fab_msk(%#x), interface_msk(%#x), base(%#x), cmd(%#x), msk(%#x), value(%#x)\n",
			GET_PWR_CFG_OFFSET(pwr_cfg_cmd),
				GET_PWR_CFG_CUT_MASK(pwr_cfg_cmd),
			GET_PWR_CFG_FAB_MASK(pwr_cfg_cmd),
				GET_PWR_CFG_INTF_MASK(pwr_cfg_cmd),
			GET_PWR_CFG_BASE(pwr_cfg_cmd),
				GET_PWR_CFG_CMD(pwr_cfg_cmd),
			GET_PWR_CFG_MASK(pwr_cfg_cmd),
				GET_PWR_CFG_VALUE(pwr_cfg_cmd));

		if ((GET_PWR_CFG_FAB_MASK(pwr_cfg_cmd)&fab_version)
			&& (GET_PWR_CFG_CUT_MASK(pwr_cfg_cmd)&cut_version)
			&& (GET_PWR_CFG_INTF_MASK(pwr_cfg_cmd)&interface_type)) {
			switch (GET_PWR_CFG_CMD(pwr_cfg_cmd)) {
			case PWR_CMD_READ:
				RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
					"rtl_hal_pwrseqcmdparsing(): PWR_CMD_READ\n");
				break;

			case PWR_CMD_WRITE: {
				RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
					"rtl_hal_pwrseqcmdparsing(): PWR_CMD_WRITE\n");
				offset = GET_PWR_CFG_OFFSET(pwr_cfg_cmd);

					/*Read the value from system register*/
					value = rtl_read_byte(rtlpriv, offset);
					value = value & (~(GET_PWR_CFG_MASK(pwr_cfg_cmd)));
					value = value | (GET_PWR_CFG_VALUE(pwr_cfg_cmd)
							& GET_PWR_CFG_MASK(pwr_cfg_cmd));

					/*Write the value back to sytem register*/
					rtl_write_byte(rtlpriv, offset, value);
				}
				break;

			case PWR_CMD_POLLING:
				RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
					"rtl_hal_pwrseqcmdparsing(): PWR_CMD_POLLING\n");
				b_polling_bit = false;
				offset = GET_PWR_CFG_OFFSET(pwr_cfg_cmd);

				do {
					value = rtl_read_byte(rtlpriv, offset);

					value = value & GET_PWR_CFG_MASK(pwr_cfg_cmd);
					if (value == (GET_PWR_CFG_VALUE(pwr_cfg_cmd)
							& GET_PWR_CFG_MASK(pwr_cfg_cmd)))
						b_polling_bit = true;
					else
						udelay(10);

					if (polling_count++ > max_polling_cnt) {
						RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
							 "polling fail in pwrseqcmd\n");
						return false;
					}
				} while (!b_polling_bit);

				break;

			case PWR_CMD_DELAY:
				RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
					"rtl_hal_pwrseqcmdparsing(): PWR_CMD_DELAY\n");
				if (GET_PWR_CFG_VALUE(pwr_cfg_cmd) == PWRSEQ_DELAY_US)
					udelay(GET_PWR_CFG_OFFSET(pwr_cfg_cmd));
				else
					mdelay(GET_PWR_CFG_OFFSET(pwr_cfg_cmd));
				break;

			case PWR_CMD_END:
				RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
					"rtl_hal_pwrseqcmdparsing(): PWR_CMD_END\n");
				return true;
				break;

			default:
				RT_ASSERT(false,
					"rtl_hal_pwrseqcmdparsing(): Unknown CMD!!\n");
				break;
			}

		}

		ary_idx++;
	} while (1);

	return true;
}
Пример #19
0
void rtl92su_read_eeprom_info(struct ieee80211_hw *hw)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv);
	struct rtl_phy *rtlphy = &(rtlpriv->phy);
	struct r92su_eeprom eeprom;
	u16 i, eeprom_id;
	u8 tempval;
	u8 rf_path, index;

	rtl92s_read_eeprom_info(hw);

	switch (rtlefuse->epromtype) {
	case EEPROM_BOOT_EFUSE:
		rtl_efuse_shadow_map_update(hw);
		break;

	case EEPROM_93C46:
		pr_err("RTL819X Not boot from eeprom, check it !!\n");
		return;

	default:
		pr_warn("rtl92su: no efuse data\n\n");
		return;
	}

	memcpy(&eeprom, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0],
	       HWSET_MAX_SIZE_92S);

	RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, "MAP",
		      &eeprom, sizeof(eeprom));
	eeprom_id = le16_to_cpu(eeprom.id);

	if (eeprom_id != RTL8190_EEPROM_ID) {
		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
			 "EEPROM ID(%#x) is invalid!!\n", eeprom_id);
		rtlefuse->autoload_failflag = true;
		return;
	}

	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n");
	rtlefuse->autoload_failflag = false;

	rtl92s_get_IC_Inferiority(hw);

	/* Read IC Version && Channel Plan */
	/* VID, DID	 SE	0xA-D */
	rtlefuse->eeprom_vid = le16_to_cpu(eeprom.vid);
	rtlefuse->eeprom_did = le16_to_cpu(eeprom.did);
	rtlefuse->eeprom_svid = 0;
	rtlefuse->eeprom_smid = 0;
	rtlefuse->eeprom_version = eeprom.version;

	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
		 "EEPROMId = 0x%4x\n", eeprom_id);
	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
		 "EEPROM VID = 0x%4x\n", rtlefuse->eeprom_vid);
	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
		 "EEPROM DID = 0x%4x\n", rtlefuse->eeprom_did);
	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
		 "EEPROM SVID = 0x%4x\n", rtlefuse->eeprom_svid);
	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
		 "EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid);

	ether_addr_copy(rtlefuse->dev_addr, eeprom.mac_addr);

	for (i = 0; i < 6; i++)
		rtl_write_byte(rtlpriv, MACIDR0 + i, rtlefuse->dev_addr[i]);

	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "%pM\n", rtlefuse->dev_addr);

	/* Get Tx Power Level by Channel */
	/* Read Tx power of Channel 1 ~ 14 from EEPROM. */
	/* 92S suupport RF A & B */
	for (rf_path = 0; rf_path < RF_PATH; rf_path++) {
		for (i = 0; i < CHAN_SET; i++) {
			/* Read CCK RF A & B Tx power  */
			rtlefuse->eeprom_chnlarea_txpwr_cck[rf_path][i] =
				eeprom.tx_pwr_cck[rf_path][i];

			/* Read OFDM RF A & B Tx power for 1T */
			rtlefuse->eeprom_chnlarea_txpwr_ht40_1s[rf_path][i] =
				eeprom.tx_pwr_ht40_1t[rf_path][i];

			/* Read OFDM RF A & B Tx power for 2T */
			rtlefuse->eprom_chnl_txpwr_ht40_2sdf[rf_path][i] =
				eeprom.tx_pwr_ht40_2t[rf_path][i];
		}
	}

	for (rf_path = 0; rf_path < RF_PATH; rf_path++) {
		for (i = 0; i < CHAN_SET; i++) {
			/* Read Power diff limit. */
			rtlefuse->eeprom_pwrgroup[rf_path][i] =
				eeprom.tx_pwr_edge[rf_path][i];
		}
	}

	for (rf_path = 0; rf_path < RF_PATH; rf_path++)
		for (i = 0; i < CHAN_SET; i++)
			RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
				"RF(%d) EEPROM CCK Area(%d) = 0x%x\n",
				rf_path, i,
				rtlefuse->eeprom_chnlarea_txpwr_cck
				[rf_path][i]);
	for (rf_path = 0; rf_path < RF_PATH; rf_path++)
		for (i = 0; i < CHAN_SET; i++)
			RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
				"RF(%d) EEPROM HT40 1S Area(%d) = 0x%x\n",
				rf_path, i,
				rtlefuse->eeprom_chnlarea_txpwr_ht40_1s
				[rf_path][i]);
	for (rf_path = 0; rf_path < RF_PATH; rf_path++)
		for (i = 0; i < CHAN_SET; i++)
			RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
				"RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n",
				rf_path, i,
				rtlefuse->eprom_chnl_txpwr_ht40_2sdf
				[rf_path][i]);

	for (rf_path = 0; rf_path < RF_PATH; rf_path++) {

		/* Assign dedicated channel tx power */
		for (i = 0; i < 14; i++)	{
			/* channel 1~3 use the same Tx Power Level. */
			if (i < 3)
				index = 0;
			/* Channel 4-8 */
			else if (i < 8)
				index = 1;
			/* Channel 9-14 */
			else
				index = 2;

			/* Record A & B CCK /OFDM - 1T/2T Channel area
			 * tx power */
			rtlefuse->txpwrlevel_cck[rf_path][i]  =
				rtlefuse->eeprom_chnlarea_txpwr_cck
							[rf_path][index];
			rtlefuse->txpwrlevel_ht40_1s[rf_path][i]  =
				rtlefuse->eeprom_chnlarea_txpwr_ht40_1s
							[rf_path][index];
			rtlefuse->txpwrlevel_ht40_2s[rf_path][i]  =
				rtlefuse->eprom_chnl_txpwr_ht40_2sdf
							[rf_path][index];
		}

		for (i = 0; i < 14; i++) {
			RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
				"RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = [0x%x / 0x%x / 0x%x]\n",
				rf_path, i,
				rtlefuse->txpwrlevel_cck[rf_path][i],
				rtlefuse->txpwrlevel_ht40_1s[rf_path][i],
				rtlefuse->txpwrlevel_ht40_2s[rf_path][i]);
		}
	}

	for (rf_path = 0; rf_path < 2; rf_path++) {
		/* Fill Pwr group */
		for (i = 0; i < 14; i++) {
			/* Chanel 1-3 */
			if (i < 3)
				index = 0;
			/* Channel 4-8 */
			else if (i < 8)
				index = 1;
			/* Channel 9-13 */
			else
				index = 2;

			rtlefuse->pwrgroup_ht20[rf_path][i] =
				(rtlefuse->eeprom_pwrgroup[rf_path][index] &
				0xf);
			rtlefuse->pwrgroup_ht40[rf_path][i] =
				((rtlefuse->eeprom_pwrgroup[rf_path][index] &
				0xf0) >> 4);

			RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
				"RF-%d pwrgroup_ht20[%d] = 0x%x\n",
				rf_path, i,
				rtlefuse->pwrgroup_ht20[rf_path][i]);
			RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
				"RF-%d pwrgroup_ht40[%d] = 0x%x\n",
				rf_path, i,
				rtlefuse->pwrgroup_ht40[rf_path][i]);
			}
	}

	for (i = 0; i < 14; i++) {
		/* Read tx power difference between HT OFDM 20/40 MHZ */
		/* channel 1-3 */
		if (i < 3)
			index = 0;
		/* Channel 4-8 */
		else if (i < 8)
			index = 1;
		/* Channel 9-14 */
		else
			index = 2;

		tempval = eeprom.tx_pwr_ht20_diff[index] & 0xff;
		rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] = (tempval & 0xF);
		rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] =
						 ((tempval >> 4) & 0xF);

		/* Read OFDM<->HT tx power diff */
		/* Channel 1-3 */
		if (i < 3)
			tempval = eeprom.tx_pwr_ofdm_diff[0];
		/* Channel 4-8 */
		else if (i < 8)
			tempval = eeprom.tx_pwr_ofdm_diff_cont;
		/* Channel 9-14 */
		else
			tempval = eeprom.tx_pwr_ofdm_diff[1];

		rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i] =
				 (tempval & 0xF);
		rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i] =
				 ((tempval >> 4) & 0xF);

		tempval = eeprom.tx_pwr_edge_chk;
		rtlefuse->txpwr_safetyflag = (tempval & 0x01);
	}

	rtlefuse->eeprom_regulatory = 0;
	if (rtlefuse->eeprom_version >= 2) {
		/* BIT(0)~2 */
		if (rtlefuse->eeprom_version >= 4)
			rtlefuse->eeprom_regulatory =
				 (eeprom.regulatory & 0x7);
		else /* BIT(0) */
			rtlefuse->eeprom_regulatory =
				 (eeprom.regulatory & 0x1);
	}
	RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
		"eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory);

	for (i = 0; i < 14; i++)
		RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
			"RF-A Ht20 to HT40 Diff[%d] = 0x%x\n",
			i, rtlefuse->txpwr_ht20diff[RF90_PATH_A][i]);
	for (i = 0; i < 14; i++)
		RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
			"RF-A Legacy to Ht40 Diff[%d] = 0x%x\n",
			i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i]);
	for (i = 0; i < 14; i++)
		RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
			"RF-B Ht20 to HT40 Diff[%d] = 0x%x\n",
			i, rtlefuse->txpwr_ht20diff[RF90_PATH_B][i]);
	for (i = 0; i < 14; i++)
		RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
			"RF-B Legacy to HT40 Diff[%d] = 0x%x\n",
			i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i]);

	RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
		"TxPwrSafetyFlag = %d\n", rtlefuse->txpwr_safetyflag);

	/* Read RF-indication and Tx Power gain
	 * index diff of legacy to HT OFDM rate. */
	tempval = eeprom.rf_ind_power_diff & 0xff;
	rtlefuse->eeprom_txpowerdiff = tempval;
	rtlefuse->legacy_httxpowerdiff =
		rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][0];

	RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
		"TxPowerDiff = %#x\n", rtlefuse->eeprom_txpowerdiff);

	/* Get TSSI value for each path. */
	rtlefuse->eeprom_tssi[RF90_PATH_A] = eeprom.tssi[RF90_PATH_A];
	rtlefuse->eeprom_tssi[RF90_PATH_B] = eeprom.tssi[RF90_PATH_B];

	RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, "TSSI_A = 0x%x, TSSI_B = 0x%x\n",
		rtlefuse->eeprom_tssi[RF90_PATH_A],
		rtlefuse->eeprom_tssi[RF90_PATH_B]);

	/* Read antenna tx power offset of B/C/D to A  from EEPROM */
	/* and read ThermalMeter from EEPROM */
	tempval = eeprom.thermal_meter;
	rtlefuse->eeprom_thermalmeter = tempval;
	RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
		"thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter);

	/* ThermalMeter, BIT(0)~3 for RFIC1, BIT(4)~7 for RFIC2 */
	rtlefuse->thermalmeter[0] = (rtlefuse->eeprom_thermalmeter & 0x1f);
	rtlefuse->tssi_13dbm = rtlefuse->eeprom_thermalmeter * 100;

	/* Read CrystalCap from EEPROM */
	rtlefuse->eeprom_crystalcap = eeprom.crystal_cap >> 4;
	/* CrystalCap, BIT(12)~15 */
	rtlefuse->crystalcap = rtlefuse->eeprom_crystalcap;

	/* Read IC Version && Channel Plan */
	/* Version ID, Channel plan */
	rtlefuse->eeprom_channelplan = eeprom.channel_plan;
	rtlefuse->txpwr_fromeprom = true;
	RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
		"EEPROM ChannelPlan = 0x%4x\n", rtlefuse->eeprom_channelplan);

	/* Read Customer ID or Board Type!!! */
	tempval = eeprom.board_type;
	/* Change RF type definition */
	if (tempval == 0)
		rtlphy->rf_type = RF_1T1R;
	else if (tempval == 1)
		rtlphy->rf_type = RF_1T2R;
	else if (tempval == 2)
		rtlphy->rf_type = RF_2T2R;
	else if (tempval == 3)
		rtlphy->rf_type = RF_1T1R;

	/* 1T2R but 1SS (1x1 receive combining) */
	rtlefuse->b1x1_recvcombine = false;
	if (rtlphy->rf_type == RF_1T2R) {
		tempval = rtl_read_byte(rtlpriv, 0x07);
		if (!(tempval & BIT(0))) {
			rtlefuse->b1x1_recvcombine = true;
			RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
				 "RF_TYPE=1T2R but only 1SS\n");
		}
	}
	rtlefuse->b1ss_support = rtlefuse->b1x1_recvcombine;
	rtlefuse->eeprom_oemid = eeprom.custom_id;

	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "EEPROM Customer ID: 0x%2x\n",
		 rtlefuse->eeprom_oemid);

	/* set channel plan to world wide 13 */
	rtlefuse->channel_plan = COUNTRY_CODE_WORLD_WIDE_13;
}
Пример #20
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;
}
Пример #21
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");
}
Пример #22
0
void rtl92ce_phy_set_bw_mode_callback(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_mac *mac = rtl_mac(rtl_priv(hw));
	u8 reg_bw_opmode;
	u8 reg_prsr_rsc;

	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
		 ("Switch to %s bandwidth\n",
		  rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
		  "20MHz" : "40MHz"))

	if (is_hal_stop(rtlhal)) {
		rtlphy->set_bwmode_inprogress = false;
		return;
	}

	reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE);
	reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2);

	switch (rtlphy->current_chan_bw) {
	case HT_CHANNEL_WIDTH_20:
		reg_bw_opmode |= BW_OPMODE_20MHZ;
		rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
		break;
	case HT_CHANNEL_WIDTH_20_40:
		reg_bw_opmode &= ~BW_OPMODE_20MHZ;
		rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
		reg_prsr_rsc =
		    (reg_prsr_rsc & 0x90) | (mac->cur_40_prime_sc << 5);
		rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc);
		break;
	default:
		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
			 ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw));
		break;
	}

	switch (rtlphy->current_chan_bw) {
	case HT_CHANNEL_WIDTH_20:
		rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0);
		rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0);
		rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1);
		break;
	case HT_CHANNEL_WIDTH_20_40:
		rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1);
		rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1);

		rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND,
			      (mac->cur_40_prime_sc >> 1));
		rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc);
		rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 0);

		rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)),
			      (mac->cur_40_prime_sc ==
			       HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
		break;
	default:
		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
			 ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw));
		break;
	}
	rtl92ce_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
	rtlphy->set_bwmode_inprogress = false;
	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n"));
}
Пример #23
0
/*****************************************
* H2C Msg format :
* 0x1DF - 0x1D0
*| 31 - 8	| 7-5 	 4 - 0	|
*| h2c_msg 	|Class_ID CMD_ID	|
*
* Extend 0x1FF - 0x1F0
*|31 - 0	  |
*|ext_msg|
******************************************/
static void _rtl8821au_fill_h2c_cmd(struct rtl_priv *rtlpriv, 
					u8 element_id, u32 cmd_len, 
					u8 *cmdbuffer)
{
	struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
	uint8_t bcmd_down = _FALSE;
	int32_t retry_cnts = 100;
	uint8_t h2c_box_num;
	uint32_t msgbox_addr;
	uint32_t msgbox_ex_addr;
	uint8_t cmd_idx, ext_cmd_len;
	uint32_t h2c_cmd = 0;
	uint32_t h2c_cmd_ex = 0;
	int _unused;

	_unused = mutex_lock_interruptible(&(rtl_usbdev(rtlpriv)->h2c_fwcmd_mutex));

	if (!cmdbuffer) {
		goto exit;
	}
	if (cmd_len > RTL8812_MAX_CMD_LEN) {
		goto exit;
	}

	if (rtlpriv->bSurpriseRemoved == _TRUE)
		goto exit;

	/* pay attention to if  race condition happened in  H2C cmd setting. */
	do {
		h2c_box_num = rtlhal->last_hmeboxnum;

		if (!_is_fw_read_cmd_down(rtlpriv, h2c_box_num)) {
			RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, " fw read cmd failed...\n");
			goto exit;
		}

		*(uint8_t *)(&h2c_cmd) = element_id;

		if (cmd_len <= 3) {
			memcpy((uint8_t *)(&h2c_cmd)+1, cmdbuffer, cmd_len);
		} else {
			memcpy((uint8_t *)(&h2c_cmd)+1, cmdbuffer, 3);
			ext_cmd_len = cmd_len-3;
			memcpy((uint8_t *)(&h2c_cmd_ex), cmdbuffer+3, ext_cmd_len);

			/* Write Ext command */
			msgbox_ex_addr = REG_HMEBOX_EXT0_8812 + (h2c_box_num * RTL8812_EX_MESSAGE_BOX_SIZE);
#ifdef CONFIG_H2C_EF
			for (cmd_idx = 0; cmd_idx < ext_cmd_len; cmd_idx++) {
				rtl_write_byte(rtlpriv, msgbox_ex_addr+cmd_idx, *((uint8_t *)(&h2c_cmd_ex)+cmd_idx));
			}
#else
			h2c_cmd_ex = le32_to_cpu(h2c_cmd_ex);
			rtl_write_dword(rtlpriv, msgbox_ex_addr, h2c_cmd_ex);
#endif
		}
		/* Write command */
		msgbox_addr = REG_HMEBOX_0 + (h2c_box_num * RTL8812_MESSAGE_BOX_SIZE);
#ifdef CONFIG_H2C_EF
		for (cmd_idx = 0; cmd_idx < RTL8812_MESSAGE_BOX_SIZE; cmd_idx++) {
			rtl_write_byte(rtlpriv, msgbox_addr+cmd_idx, *((uint8_t *)(&h2c_cmd)+cmd_idx));
		}
#else
		h2c_cmd = le32_to_cpu(h2c_cmd);
		rtl_write_dword(rtlpriv, msgbox_addr, h2c_cmd);
#endif

		bcmd_down = _TRUE;

	/*
	 * 	DBG_8192C("MSG_BOX:%d,CmdLen(%d), reg:0x%x =>h2c_cmd:0x%x, reg:0x%x =>h2c_cmd_ex:0x%x ..\n"
	 * 	 	,pHalData->LastHMEBoxNum ,CmdLen,msgbox_addr,h2c_cmd,msgbox_ex_addr,h2c_cmd_ex);
	 */

		rtlhal->last_hmeboxnum = (h2c_box_num+1) % RTL8812_MAX_H2C_BOX_NUMS;

	} while ((!bcmd_down) && (retry_cnts--));

exit:

	mutex_unlock(&(rtl_usbdev(rtlpriv)->h2c_fwcmd_mutex));
}
Пример #24
0
bool rtl92su_phy_set_rf_power_state(struct ieee80211_hw *hw,
				    enum rf_pwrstate rfpwr_state)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
	bool bresult = true;

	if (rfpwr_state == ppsc->rfpwr_state)
		return false;

	switch (rfpwr_state) {
	case ERFON:{
			if ((ppsc->rfpwr_state == ERFOFF) &&
			    RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {

				bool rtstatus;
				u32 InitializeCount = 0;

				do {
					InitializeCount++;
					RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
						 "IPS Set eRf nic enable\n");
					rtstatus = rtl_ps_enable_nic(hw);
				} while (!rtstatus && (InitializeCount < 10));

				RT_CLEAR_PS_LEVEL(ppsc,
						  RT_RF_OFF_LEVL_HALT_NIC);
			} else {
				RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
					 "awake, slept:%d ms state_inap:%x\n",
					 jiffies_to_msecs(jiffies -
							  ppsc->
							  last_sleep_jiffies),
					 rtlpriv->psc.state_inap);
				ppsc->last_awake_jiffies = jiffies;

				rtl_write_word(rtlpriv, CMDR, 0x37FC);
				rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
				rtl_write_byte(rtlpriv, REG_RFPGA0_CCA, 0x3);
				rtl_write_byte(rtlpriv, REG_SPS1_CTRL, 0x64);
			}
			break;
		}
	case ERFOFF:{
			if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
				RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
					 "IPS Set eRf nic disable\n");
				rtl_ps_disable_nic(hw);
				RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
			}
			break;
		}
	case ERFSLEEP:
			if (ppsc->rfpwr_state == ERFOFF)
				return false;

			RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
				 "Set ERFSLEEP awaked:%d ms\n",
				 jiffies_to_msecs(jiffies -
						  ppsc->last_awake_jiffies));

			RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
				 "sleep awaked:%d ms state_inap:%x\n",
				 jiffies_to_msecs(jiffies -
						  ppsc->last_awake_jiffies),
				 rtlpriv->psc.state_inap);
			ppsc->last_sleep_jiffies = jiffies;
			rtl92s_phy_set_rf_sleep(hw);
			break;
	default:
		pr_err("switch case %#x not processed\n", rfpwr_state);
		bresult = false;
		break;
	}

	if (bresult)
		ppsc->rfpwr_state = rfpwr_state;

	return bresult;
}
Пример #25
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;
}
Пример #26
0
/* taken from 8190n */
static int _rtl92su_macconfig_before_fwdownload3(struct ieee80211_hw *hw)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv);
	unsigned int tries = 20;
	u8 tmpu1b;
	u16 tmpu2b;

	/* Prevent EFUSE leakage */
	rtl_write_byte(rtlpriv, REG_EFUSE_TEST + 3, 0xb0);
	msleep(20);
	rtl_write_byte(rtlpriv, REG_EFUSE_TEST + 3, 0x30);

	/* Set control path switch to HW control and reset digital core,
	 * CPU core and MAC I/O core. */
	tmpu2b = rtl_read_word(rtlpriv, REG_SYS_CLKR);
	if (tmpu2b & SYS_FWHW_SEL) {
		tmpu2b &= ~(SYS_SWHW_SEL | SYS_FWHW_SEL);

		/* Set failed, return to prevent hang. */
		if (!rtl92s_halset_sysclk(hw, tmpu2b))
			return -EIO;
	}

	/* Reset MAC-IO and CPU and Core Digital BIT(10)/11/15 */
	tmpu1b = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
	tmpu1b &= 0x73;
	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmpu1b);
	/* wait for BIT 10/11/15 to pull high automatically!! */
	mdelay(1);

	rtl_write_byte(rtlpriv, REG_SPS0_CTRL + 1, 0x53);
	rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x57);

	/* Enable AFE Macro Block's Bandgap */
	tmpu1b = rtl_read_byte(rtlpriv, REG_AFE_MISC);
	tmpu1b |= AFE_BGEN;
	rtl_write_byte(rtlpriv, REG_AFE_MISC, tmpu1b);
	mdelay(1);

	/* Enable AFE Mbias */
	tmpu1b = rtl_read_byte(rtlpriv, REG_AFE_MISC);
	tmpu1b |= AFE_BGEN | AFE_MBEN | AFE_MISC_I32_EN;
	rtl_write_byte(rtlpriv, REG_AFE_MISC, tmpu1b);
	mdelay(1);

	/* Enable LDOA15 block	*/
	tmpu1b = rtl_read_byte(rtlpriv, REG_LDOA15_CTRL);
	tmpu1b |= LDA15_EN;
	rtl_write_byte(rtlpriv, REG_LDOA15_CTRL, tmpu1b);

	/* Enable LDOV12D block */
	tmpu1b = rtl_read_byte(rtlpriv, REG_LDOV12D_CTRL);
	tmpu1b |= LDV12_EN;
	rtl_write_byte(rtlpriv, REG_LDOV12D_CTRL, tmpu1b);

	/* Set Digital Vdd to Retention isolation Path. */
	tmpu2b = rtl_read_word(rtlpriv, REG_SYS_ISO_CTRL);
	tmpu2b |= ISO_PWC_DV2RP;
	rtl_write_word(rtlpriv, REG_SYS_ISO_CTRL, tmpu2b);

	/* For warm reboot NIC disappear bug.
	 * Also known as: Engineer Packet CP test Enable */
	tmpu2b = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
	tmpu2b |= BIT(13);
	rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, tmpu2b);

	/* Support 64k IMEM */
	tmpu1b = rtl_read_byte(rtlpriv, REG_SYS_ISO_CTRL + 1);
	tmpu1b &= 0x68;
	rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL + 1, tmpu1b);

	/* Enable AFE clock source */
	tmpu1b = rtl_read_byte(rtlpriv, REG_AFE_XTAL_CTRL);
	tmpu1b |= BIT(0);
	rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL, tmpu1b);
	/* Delay 1.5ms */
	mdelay(2);
	tmpu1b = rtl_read_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1);
	tmpu1b &= ~BIT(2);
	rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, tmpu1b);

	/* Enable AFE PLL Macro Block *
	 * We need to delay 100u before enabling PLL. */
	udelay(200);
	tmpu1b = rtl_read_byte(rtlpriv, REG_AFE_PLL_CTRL);
	tmpu1b |= BIT(0) | BIT(4);
	rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, tmpu1b);

	/* for divider reset
	 * The clock will be stable with 500us delay after the PLL reset */
	udelay(500);
	rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, (tmpu1b | BIT(0) |
		       BIT(4) | BIT(6)));
	udelay(500);
	rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, (tmpu1b | BIT(0) | BIT(4)));
	udelay(500);

	/* Release isolation AFE PLL & MD */
	tmpu1b = rtl_read_byte(rtlpriv, REG_SYS_ISO_CTRL);
	tmpu1b &= 0xee;
	rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL, tmpu1b);

	/* Switch to 40MHz clock */
	rtl_write_byte(rtlpriv, REG_SYS_CLKR, 0x00);

	/* Disable CPU clock and 80MHz SSC to fix FW download timing issue */
	tmpu1b = rtl_read_byte(rtlpriv, REG_SYS_CLKR);
	tmpu1b |= 0xa0;
	rtl_write_byte(rtlpriv, REG_SYS_CLKR, tmpu1b);

	/* Enable MAC clock */
	tmpu2b = rtl_read_word(rtlpriv, REG_SYS_CLKR);
	tmpu2b |= BIT(12) | SYS_MAC_CLK_EN;
	rtl_write_word(rtlpriv, REG_SYS_CLKR, tmpu2b);

	rtl_write_byte(rtlpriv, REG_PMC_FSM, 0x02);

	/* Enable Core digital and enable IOREG R/W */
	tmpu2b = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
	tmpu2b |= FEN_DCORE;
	rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, tmpu2b);

	/* enable REG_EN */
	tmpu2b = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
	tmpu2b |= FEN_MREGEN;
	rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, tmpu2b);

	/* Switch the control path to FW */
	tmpu2b = rtl_read_word(rtlpriv, REG_SYS_CLKR);
	tmpu2b |= SYS_FWHW_SEL;
	tmpu2b &= ~SYS_SWHW_SEL;
	rtl_write_word(rtlpriv, REG_SYS_CLKR, tmpu2b);

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

	rtl_write_word(rtlpriv, REG_CR, HCI_TXDMA_EN |
		HCI_RXDMA_EN | TXDMA_EN | RXDMA_EN | FW2HW_EN |
		DDMA_EN | MACTXEN | MACRXEN | SCHEDULE_EN |
		BB_GLB_RSTN | BBRSTN);

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

	/* Fix 8051 ROM incorrect code operation */
	rtl_write_byte(rtlpriv, REG_USB_MAGIC, USB_MAGIC_BIT7);

	/* To make sure that TxDMA can ready to download FW. */
	/* We should reset TxDMA if IMEM RPT was not ready. */
	do {
		tmpu1b = rtl_read_byte(rtlpriv, REG_TCR);
		if ((tmpu1b & TXDMA_INIT_VALUE) == TXDMA_INIT_VALUE)
			break;
		msleep(20);
	} while (--tries);

	if (tries == 0) {
		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
			 "Polling TXDMA_INIT_VALUE timeout!! Current TCR(%#x)\n",
			 tmpu1b);
		tmpu1b = rtl_read_byte(rtlpriv, REG_CR);
		rtl_write_byte(rtlpriv, REG_CR, tmpu1b & (~TXDMA_EN));
		msleep(20);
		/* Reset TxDMA */
		rtl_write_byte(rtlpriv, REG_CR, tmpu1b | TXDMA_EN);
	}

	/* After MACIO reset,we must refresh LED state. */
	if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS ||
	    ppsc->rfoff_reason == 0) {
		enum rf_pwrstate rfpwr_state_toset;
		struct rtl_usb_priv *usbpriv = rtl_usbpriv(hw);
		struct rtl_led *pLed0 = &(usbpriv->ledctl.sw_led0);
		rfpwr_state_toset = rtl92s_rf_onoff_detect(hw);
		if (rfpwr_state_toset == ERFON)
			rtl92s_sw_led_on(hw, pLed0);
	}
	return 0;
}
Пример #27
0
static void _rtl8723e_write_ofdm_power_reg( struct ieee80211_hw *hw,
					   u8 index, u32 *pvalue )
{
	struct rtl_priv *rtlpriv = rtl_priv( hw );
	struct rtl_phy *rtlphy = &rtlpriv->phy;

	u16 regoffset_a[6] = {
		RTXAGC_A_RATE18_06, RTXAGC_A_RATE54_24,
		RTXAGC_A_MCS03_MCS00, RTXAGC_A_MCS07_MCS04,
		RTXAGC_A_MCS11_MCS08, RTXAGC_A_MCS15_MCS12
	};
	u16 regoffset_b[6] = {
		RTXAGC_B_RATE18_06, RTXAGC_B_RATE54_24,
		RTXAGC_B_MCS03_MCS00, RTXAGC_B_MCS07_MCS04,
		RTXAGC_B_MCS11_MCS08, RTXAGC_B_MCS15_MCS12
	};
	u8 i, rf, pwr_val[4];
	u32 writeval;
	u16 regoffset;

	for ( rf = 0; rf < 2; rf++ ) {
		writeval = pvalue[rf];
		for ( i = 0; i < 4; i++ ) {
			pwr_val[i] = ( u8 )( ( writeval & ( 0x7f <<
					   ( i * 8 ) ) ) >> ( i * 8 ) );

			if ( pwr_val[i] > RF6052_MAX_TX_PWR )
				pwr_val[i] = RF6052_MAX_TX_PWR;
		}
		writeval = ( pwr_val[3] << 24 ) | ( pwr_val[2] << 16 ) |
		    ( pwr_val[1] << 8 ) | pwr_val[0];

		if ( rf == 0 )
			regoffset = regoffset_a[index];
		else
			regoffset = regoffset_b[index];
		rtl_set_bbreg( hw, regoffset, MASKDWORD, writeval );

		RTPRINT( rtlpriv, FPHY, PHY_TXPWR,
			"Set 0x%x = %08x\n", regoffset, writeval );

		if ( ( ( get_rf_type( rtlphy ) == RF_2T2R ) &&
		     ( regoffset == RTXAGC_A_MCS15_MCS12 ||
		      regoffset == RTXAGC_B_MCS15_MCS12 ) ) ||
		    ( ( get_rf_type( rtlphy ) != RF_2T2R ) &&
		     ( regoffset == RTXAGC_A_MCS07_MCS04 ||
		      regoffset == RTXAGC_B_MCS07_MCS04 ) ) ) {

			writeval = pwr_val[3];
			if ( regoffset == RTXAGC_A_MCS15_MCS12 ||
			    regoffset == RTXAGC_A_MCS07_MCS04 )
				regoffset = 0xc90;
			if ( regoffset == RTXAGC_B_MCS15_MCS12 ||
			    regoffset == RTXAGC_B_MCS07_MCS04 )
				regoffset = 0xc98;

			for ( i = 0; i < 3; i++ ) {
				writeval = ( writeval > 6 ) ? ( writeval - 6 ) : 0;
				rtl_write_byte( rtlpriv, ( u32 ) ( regoffset + i ),
					       ( u8 )writeval );
			}
		}
	}
}
Пример #28
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;
}