Ejemplo n.º 1
0
static void _rtl92s_dm_ctrl_initgain_bytwoport( struct ieee80211_hw *hw )
{
	struct rtl_priv *rtlpriv = rtl_priv( hw );
	struct dig_t *dig = &rtlpriv->dm_digtable;

	if ( rtlpriv->mac80211.act_scanning )
		return;

	/* Decide the current status and if modify initial gain or not */
	if ( rtlpriv->mac80211.link_state >= MAC80211_LINKED ||
	    rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC )
		dig->cur_sta_cstate = DIG_STA_CONNECT;
	else
		dig->cur_sta_cstate = DIG_STA_DISCONNECT;

	dig->rssi_val = rtlpriv->dm.undec_sm_pwdb;

	/* Change dig mode to rssi */
	if ( dig->cur_sta_cstate != DIG_STA_DISCONNECT ) {
		if ( dig->dig_twoport_algorithm ==
		    DIG_TWO_PORT_ALGO_FALSE_ALARM ) {
			dig->dig_twoport_algorithm = DIG_TWO_PORT_ALGO_RSSI;
			rtl92s_phy_set_fw_cmd( hw, FW_CMD_DIG_MODE_SS );
		}
	}

	_rtl92s_dm_false_alarm_counter_statistics( hw );
	_rtl92s_dm_initial_gain_sta_beforeconnect( hw );

	dig->pre_sta_cstate = dig->cur_sta_cstate;
}
Ejemplo n.º 2
0
static void _rtl92s_dm_txpowertracking_callback_thermalmeter(
					struct ieee80211_hw *hw)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
	u8 thermalvalue = 0;

	rtlpriv->dm.txpower_trackinginit = true;

	thermalvalue = (u8)rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER, 0x1f);

	RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
		 ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x "
		  "eeprom_thermalmeter 0x%x\n", thermalvalue,
		  rtlpriv->dm.thermalvalue, rtlefuse->eeprom_thermalmeter));

	if (thermalvalue) {
		rtlpriv->dm.thermalvalue = thermalvalue;
		rtl92s_phy_set_fw_cmd(hw, FW_CMD_TXPWR_TRACK_THERMAL);
	}

	rtlpriv->dm.txpowercount = 0;
}
Ejemplo n.º 3
0
static void _rtl92s_dm_txpowertracking_callback_thermalmeter( 
					struct ieee80211_hw *hw )
{
	struct rtl_priv *rtlpriv = rtl_priv( hw );
	struct rtl_efuse *rtlefuse = rtl_efuse( rtl_priv( hw ) );
	u8 thermalvalue = 0;
	u32 fw_cmd = 0;

	rtlpriv->dm.txpower_trackinginit = true;

	thermalvalue = ( u8 )rtl_get_rfreg( hw, RF90_PATH_A, RF_T_METER, 0x1f );

	RT_TRACE( rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
		 "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermal meter 0x%x\n",
		 thermalvalue,
		 rtlpriv->dm.thermalvalue, rtlefuse->eeprom_thermalmeter );

	if ( thermalvalue ) {
		rtlpriv->dm.thermalvalue = thermalvalue;
		if ( hal_get_firmwareversion( rtlpriv ) >= 0x35 ) {
			rtl92s_phy_set_fw_cmd( hw, FW_CMD_TXPWR_TRACK_THERMAL );
		} else {
			fw_cmd = ( FW_TXPWR_TRACK_THERMAL |
				 ( rtlpriv->efuse.thermalmeter[0] << 8 ) |
				 ( thermalvalue << 16 ) );

			RT_TRACE( rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
				 "Write to FW Thermal Val = 0x%x\n", fw_cmd );

			rtl_write_dword( rtlpriv, WFM5, fw_cmd );
			rtl92s_phy_chk_fwcmd_iodone( hw );
		}
	}

	rtlpriv->dm.txpowercount = 0;
}
Ejemplo n.º 4
0
static void _rtl92s_dm_initial_gain_sta_beforeconnect( struct ieee80211_hw *hw )
{
	struct rtl_priv *rtlpriv = rtl_priv( hw );
	struct dig_t *digtable = &rtlpriv->dm_digtable;
	struct false_alarm_statistics *falsealm_cnt = &( rtlpriv->falsealm_cnt );
	static u8 initialized, force_write;
	u8 initial_gain = 0;

	if ( ( digtable->pre_sta_cstate == digtable->cur_sta_cstate ) ||
	    ( digtable->cur_sta_cstate == DIG_STA_BEFORE_CONNECT ) ) {
		if ( digtable->cur_sta_cstate == DIG_STA_BEFORE_CONNECT ) {
			if ( rtlpriv->psc.rfpwr_state != ERFON )
				return;

			if ( digtable->backoff_enable_flag )
				rtl92s_backoff_enable_flag( hw );
			else
				digtable->back_val = DM_DIG_BACKOFF_MAX;

			if ( ( digtable->rssi_val + 10 - digtable->back_val ) >
				digtable->rx_gain_max )
				digtable->cur_igvalue =
						digtable->rx_gain_max;
			else if ( ( digtable->rssi_val + 10 - digtable->back_val )
				 < digtable->rx_gain_min )
				digtable->cur_igvalue =
						digtable->rx_gain_min;
			else
				digtable->cur_igvalue = digtable->rssi_val + 10
					- digtable->back_val;

			if ( falsealm_cnt->cnt_all > 10000 )
				digtable->cur_igvalue =
					 ( digtable->cur_igvalue > 0x33 ) ?
					 digtable->cur_igvalue : 0x33;

			if ( falsealm_cnt->cnt_all > 16000 )
				digtable->cur_igvalue =
						 digtable->rx_gain_max;
		/* connected -> connected or disconnected -> disconnected  */
		} else {
			/* Firmware control DIG, do nothing in driver dm */
			return;
		}
		/* disconnected -> connected or connected ->
		 * disconnected or beforeconnect->( dis )connected */
	} else {
		/* Enable FW DIG */
		digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
		rtl92s_phy_set_fw_cmd( hw, FW_CMD_DIG_ENABLE );

		digtable->back_val = DM_DIG_BACKOFF_MAX;
		digtable->cur_igvalue = rtlpriv->phy.default_initialgain[0];
		digtable->pre_igvalue = 0;
		return;
	}

	/* Forced writing to prevent from fw-dig overwriting. */
	if ( digtable->pre_igvalue != rtl_get_bbreg( hw, ROFDM0_XAAGCCORE1,
						  MASKBYTE0 ) )
		force_write = 1;

	if ( ( digtable->pre_igvalue != digtable->cur_igvalue ) ||
	    !initialized || force_write ) {
		/* Disable FW DIG */
		rtl92s_phy_set_fw_cmd( hw, FW_CMD_DIG_DISABLE );

		initial_gain = ( u8 )digtable->cur_igvalue;

		/* Set initial gain. */
		rtl_set_bbreg( hw, ROFDM0_XAAGCCORE1, MASKBYTE0, initial_gain );
		rtl_set_bbreg( hw, ROFDM0_XBAGCCORE1, MASKBYTE0, initial_gain );
		digtable->pre_igvalue = digtable->cur_igvalue;
		initialized = 1;
		force_write = 0;
	}
}
Ejemplo n.º 5
0
static void _rtl92s_dm_refresh_rateadaptive_mask( struct ieee80211_hw *hw )
{
	struct rtl_priv *rtlpriv = rtl_priv( hw );
	struct rtl_hal *rtlhal = rtl_hal( rtl_priv( hw ) );
	struct rtl_mac *mac = rtl_mac( rtl_priv( hw ) );
	struct rate_adaptive *ra = &( rtlpriv->ra );
	struct ieee80211_sta *sta = NULL;
	u32 low_rssi_thresh = 0;
	u32 middle_rssi_thresh = 0;
	u32 high_rssi_thresh = 0;

	if ( is_hal_stop( rtlhal ) )
		return;

	if ( !rtlpriv->dm.useramask )
		return;

	if ( hal_get_firmwareversion( rtlpriv ) >= 61 &&
	    !rtlpriv->dm.inform_fw_driverctrldm ) {
		rtl92s_phy_set_fw_cmd( hw, FW_CMD_CTRL_DM_BY_DRIVER );
		rtlpriv->dm.inform_fw_driverctrldm = true;
	}

	if ( ( mac->link_state == MAC80211_LINKED ) &&
	    ( mac->opmode == NL80211_IFTYPE_STATION ) ) {
		switch ( ra->pre_ratr_state ) {
		case DM_RATR_STA_HIGH:
			high_rssi_thresh = 40;
			middle_rssi_thresh = 30;
			low_rssi_thresh = 20;
			break;
		case DM_RATR_STA_MIDDLE:
			high_rssi_thresh = 44;
			middle_rssi_thresh = 30;
			low_rssi_thresh = 20;
			break;
		case DM_RATR_STA_LOW:
			high_rssi_thresh = 44;
			middle_rssi_thresh = 34;
			low_rssi_thresh = 20;
			break;
		case DM_RATR_STA_ULTRALOW:
			high_rssi_thresh = 44;
			middle_rssi_thresh = 34;
			low_rssi_thresh = 24;
			break;
		default:
			high_rssi_thresh = 44;
			middle_rssi_thresh = 34;
			low_rssi_thresh = 24;
			break;
		}

		if ( rtlpriv->dm.undec_sm_pwdb > ( long )high_rssi_thresh ) {
			ra->ratr_state = DM_RATR_STA_HIGH;
		} else if ( rtlpriv->dm.undec_sm_pwdb >
			   ( long )middle_rssi_thresh ) {
			ra->ratr_state = DM_RATR_STA_LOW;
		} else if ( rtlpriv->dm.undec_sm_pwdb >
			   ( long )low_rssi_thresh ) {
			ra->ratr_state = DM_RATR_STA_LOW;
		} else {
			ra->ratr_state = DM_RATR_STA_ULTRALOW;
		}

		if ( ra->pre_ratr_state != ra->ratr_state ) {
			RT_TRACE( rtlpriv, COMP_RATE, DBG_LOUD,
				 "RSSI = %ld RSSI_LEVEL = %d PreState = %d, CurState = %d\n",
				 rtlpriv->dm.undec_sm_pwdb, ra->ratr_state,
				 ra->pre_ratr_state, ra->ratr_state );

			rcu_read_lock();
			sta = rtl_find_sta( hw, mac->bssid );
			if ( sta )
				rtlpriv->cfg->ops->update_rate_tbl( hw, sta,
							   ra->ratr_state );
			rcu_read_unlock();

			ra->pre_ratr_state = ra->ratr_state;
		}
	}
}
Ejemplo n.º 6
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;
}