예제 #1
0
파일: rf.c 프로젝트: 303750856/linux-3.1
void rtl92s_phy_rf6052_set_ccktxpower(struct ieee80211_hw *hw, u8 pwrlevel)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
	u32 txagc = 0;
	bool dont_inc_cck_or_turboscanoff = false;

	if (((rtlefuse->eeprom_version >= 2) &&
	      (rtlefuse->txpwr_safetyflag == 1)) ||
	      ((rtlefuse->eeprom_version >= 2) &&
	      (rtlefuse->eeprom_regulatory != 0)))
		dont_inc_cck_or_turboscanoff = true;

	if (mac->act_scanning) {
		txagc = 0x3f;
		if (dont_inc_cck_or_turboscanoff)
			txagc = pwrlevel;
	} else {
		txagc = pwrlevel;

		if (rtlpriv->dm.dynamic_txhighpower_lvl ==
		    TX_HIGH_PWR_LEVEL_LEVEL1)
			txagc = 0x10;
		else if (rtlpriv->dm.dynamic_txhighpower_lvl ==
			TX_HIGH_PWR_LEVEL_LEVEL2)
			txagc = 0x0;
	}

	if (txagc > RF6052_MAX_TX_PWR)
		txagc = RF6052_MAX_TX_PWR;

	rtl_set_bbreg(hw, RTXAGC_CCK_MCS32, BTX_AGCRATECCK, txagc);

}
예제 #2
0
파일: rf.c 프로젝트: 303750856/linux-3.1
static void _rtl92s_write_ofdm_powerreg(struct ieee80211_hw *hw,
					u8 index, u32 val)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	struct rtl_phy *rtlphy = &(rtlpriv->phy);
	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
	u16 regoffset[6] = {0xe00, 0xe04, 0xe10, 0xe14, 0xe18, 0xe1c};
	u8 i, rfa_pwr[4];
	u8 rfa_lower_bound = 0, rfa_upper_bound = 0, rf_pwr_diff = 0;
	u32 writeval = val;

	/* If path A and Path B coexist, we must limit Path A tx power.
	 * Protect Path B pwr over or under flow. We need to calculate
	 * upper and lower bound of path A tx power. */
	if (rtlphy->rf_type == RF_2T2R) {
		rf_pwr_diff = rtlefuse->antenna_txpwdiff[0];

		/* Diff=-8~-1 */
		if (rf_pwr_diff >= 8) {
			/* Prevent underflow!! */
			rfa_lower_bound = 0x10 - rf_pwr_diff;
		/* if (rf_pwr_diff >= 0) Diff = 0-7 */
		} else {
			rfa_upper_bound = RF6052_MAX_TX_PWR - rf_pwr_diff;
		}
	}

	for (i = 0; i < 4; i++) {
		rfa_pwr[i] = (u8)((writeval & (0x7f << (i * 8))) >> (i * 8));
		if (rfa_pwr[i]  > RF6052_MAX_TX_PWR)
			rfa_pwr[i]  = RF6052_MAX_TX_PWR;

		/* If path A and Path B coexist, we must limit Path A tx power.
		 * Protect Path B pwr over or under flow. We need to calculate
		 * upper and lower bound of path A tx power. */
		if (rtlphy->rf_type == RF_2T2R) {
			/* Diff=-8~-1 */
			if (rf_pwr_diff >= 8) {
				/* Prevent underflow!! */
				if (rfa_pwr[i] < rfa_lower_bound)
					rfa_pwr[i] = rfa_lower_bound;
			/* Diff = 0-7 */
			} else if (rf_pwr_diff >= 1) {
				/* Prevent overflow */
				if (rfa_pwr[i] > rfa_upper_bound)
					rfa_pwr[i] = rfa_upper_bound;
			}
		}

	}

	writeval = (rfa_pwr[3] << 24) | (rfa_pwr[2] << 16) | (rfa_pwr[1] << 8) |
				rfa_pwr[0];

	rtl_set_bbreg(hw, regoffset[index], 0x7f7f7f7f, writeval);
}
예제 #3
0
static void _rtl_init_mac80211(struct ieee80211_hw *hw)
{
	struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw));
	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
	struct ieee80211_supported_band *sband;

	/* <1> use  mac->bands as mem for hw->wiphy->bands */
	sband = &(rtlmac->bands[IEEE80211_BAND_2GHZ]);

	/*
	 * <2> set hw->wiphy->bands[IEEE80211_BAND_2GHZ]
	 * to default value(1T1R)
	 */
	memcpy(&(rtlmac->bands[IEEE80211_BAND_2GHZ]), &rtl_band_2ghz,
	       sizeof(struct ieee80211_supported_band));

	/* <3> init ht cap base on ant_num */
	_rtl_init_hw_ht_capab(hw, &sband->ht_cap);

	/* <4> set mac->sband to wiphy->sband */
	hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband;

	/* <5> set hw caps */
	hw->flags = IEEE80211_HW_SIGNAL_DBM |
	    IEEE80211_HW_RX_INCLUDES_FCS |
	    IEEE80211_HW_BEACON_FILTER | IEEE80211_HW_AMPDU_AGGREGATION | /*PS*/
	    /*IEEE80211_HW_SUPPORTS_PS | */
	    /*IEEE80211_HW_PS_NULLFUNC_STACK | */
	    /*IEEE80211_HW_SUPPORTS_DYNAMIC_PS | */
	    IEEE80211_HW_REPORTS_TX_ACK_STATUS | 0;

	hw->wiphy->interface_modes =
	    BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);

	hw->wiphy->rts_threshold = 2347;

	hw->queues = AC_MAX;
	hw->extra_tx_headroom = RTL_TX_HEADER_SIZE;

	/* TODO: Correct this value for our hw */
	/* TODO: define these hard code value */
	hw->channel_change_time = 100;
	hw->max_listen_interval = 5;
	hw->max_rate_tries = 4;
	/* hw->max_rates = 1; */

	/* <6> mac address */
	if (is_valid_ether_addr(rtlefuse->dev_addr)) {
		SET_IEEE80211_PERM_ADDR(hw, rtlefuse->dev_addr);
	} else {
		u8 rtlmac[] = { 0x00, 0xe0, 0x4c, 0x81, 0x92, 0x00 };
		get_random_bytes((rtlmac + (ETH_ALEN - 1)), 1);
		SET_IEEE80211_PERM_ADDR(hw, rtlmac);
	}

}
예제 #4
0
파일: rf.c 프로젝트: 303750856/linux-3.1
static void _rtl92s_set_antennadiff(struct ieee80211_hw *hw,
				    u8 *p_final_pwridx)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
	struct rtl_phy *rtlphy = &(rtlpriv->phy);
	char ant_pwr_diff = 0;
	u32	u4reg_val = 0;

	if (rtlphy->rf_type == RF_2T2R) {
		ant_pwr_diff = p_final_pwridx[1] - p_final_pwridx[0];

		/* range is from 7~-8,
		 * index = 0x0~0xf */
		if (ant_pwr_diff > 7)
			ant_pwr_diff = 7;
		if (ant_pwr_diff < -8)
			ant_pwr_diff = -8;

		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
			 ("Antenna Diff from RF-B "
			"to RF-A = %d (0x%x)\n", ant_pwr_diff,
			 ant_pwr_diff & 0xf));

		ant_pwr_diff &= 0xf;
	}

	/* Antenna TX power difference */
	rtlefuse->antenna_txpwdiff[2] = 0;/* RF-D, don't care */
	rtlefuse->antenna_txpwdiff[1] = 0;/* RF-C, don't care */
	rtlefuse->antenna_txpwdiff[0] = (u8)(ant_pwr_diff);	/* RF-B */

	u4reg_val = rtlefuse->antenna_txpwdiff[2] << 8 |
				rtlefuse->antenna_txpwdiff[1] << 4 |
				rtlefuse->antenna_txpwdiff[0];

	rtl_set_bbreg(hw, RFPGA0_TXGAINSTAGE, (BXBTXAGC | BXCTXAGC | BXDTXAGC),
		      u4reg_val);

	RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
		 ("Write BCD-Diff(0x%x) = 0x%x\n",
		 RFPGA0_TXGAINSTAGE, u4reg_val));
}
예제 #5
0
파일: base.c 프로젝트: AiWinters/linux
/* when we use 1 rx ant we send IEEE80211_SMPS_STATIC */
static struct sk_buff *rtl_make_smps_action(struct ieee80211_hw *hw,
		enum ieee80211_smps_mode smps, u8 *da, u8 *bssid)
{
	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
	struct sk_buff *skb;
	struct ieee80211_mgmt *action_frame;

	/* 27 = header + category + action + smps mode */
	skb = dev_alloc_skb(27 + hw->extra_tx_headroom);
	if (!skb)
		return NULL;

	skb_reserve(skb, hw->extra_tx_headroom);
	action_frame = (void *)skb_put(skb, 27);
	memset(action_frame, 0, 27);
	memcpy(action_frame->da, da, ETH_ALEN);
	memcpy(action_frame->sa, rtlefuse->dev_addr, ETH_ALEN);
	memcpy(action_frame->bssid, bssid, ETH_ALEN);
	action_frame->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
						  IEEE80211_STYPE_ACTION);
	action_frame->u.action.category = WLAN_CATEGORY_HT;
	action_frame->u.action.u.ht_smps.action = WLAN_HT_ACTION_SMPS;
	switch (smps) {
	case IEEE80211_SMPS_AUTOMATIC:/* 0 */
	case IEEE80211_SMPS_NUM_MODES:/* 4 */
		WARN_ON(1);
	case IEEE80211_SMPS_OFF:/* 1 */ /*MIMO_PS_NOLIMIT*/
		action_frame->u.action.u.ht_smps.smps_control =
				WLAN_HT_SMPS_CONTROL_DISABLED;/* 0 */
		break;
	case IEEE80211_SMPS_STATIC:/* 2 */ /*MIMO_PS_STATIC*/
		action_frame->u.action.u.ht_smps.smps_control =
				WLAN_HT_SMPS_CONTROL_STATIC;/* 1 */
		break;
	case IEEE80211_SMPS_DYNAMIC:/* 3 */ /*MIMO_PS_DYNAMIC*/
		action_frame->u.action.u.ht_smps.smps_control =
				WLAN_HT_SMPS_CONTROL_DYNAMIC;/* 3 */
		break;
	}

	return skb;
}
예제 #6
0
static void rtl8723e_phy_get_power_base( struct ieee80211_hw *hw,
					u8 *ppowerlevel, u8 channel,
					u32 *ofdmbase, u32 *mcsbase )
{
	struct rtl_priv *rtlpriv = rtl_priv( hw );
	struct rtl_phy *rtlphy = &rtlpriv->phy;
	struct rtl_efuse *rtlefuse = rtl_efuse( rtl_priv( hw ) );
	u32 powerbase0, powerbase1;
	u8 legacy_pwrdiff, ht20_pwrdiff;
	u8 i, powerlevel[2];

	for ( i = 0; i < 2; i++ ) {
		powerlevel[i] = ppowerlevel[i];
		legacy_pwrdiff = rtlefuse->txpwr_legacyhtdiff[i][channel - 1];
		powerbase0 = powerlevel[i] + legacy_pwrdiff;

		powerbase0 = ( powerbase0 << 24 ) | ( powerbase0 << 16 ) |
		    ( powerbase0 << 8 ) | powerbase0;
		*( ofdmbase + i ) = powerbase0;
		RTPRINT( rtlpriv, FPHY, PHY_TXPWR,
			" [OFDM power base index rf(%c) = 0x%x]\n",
			 ( ( i == 0 ) ? 'A' : 'B' ), *( ofdmbase + i ) );
	}

	for ( i = 0; i < 2; i++ ) {
		if ( rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ) {
			ht20_pwrdiff =
				rtlefuse->txpwr_ht20diff[i][channel - 1];
			powerlevel[i] += ht20_pwrdiff;
		}
		powerbase1 = powerlevel[i];
		powerbase1 = ( powerbase1 << 24 ) |
		    ( powerbase1 << 16 ) | ( powerbase1 << 8 ) | powerbase1;

		*( mcsbase + i ) = powerbase1;

		RTPRINT( rtlpriv, FPHY, PHY_TXPWR,
			" [MCS power base index rf(%c) = 0x%x]\n",
			 ( ( i == 0 ) ? 'A' : 'B' ), *( mcsbase + i ) );
	}
}
예제 #7
0
파일: dm.c 프로젝트: andi34/Dhollmen_Kernel
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;
}
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;
}
예제 #9
0
파일: base.c 프로젝트: AiWinters/linux
static void _rtl_init_mac80211(struct ieee80211_hw *hw)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
	struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw));
	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
	struct ieee80211_supported_band *sband;


	if (rtlhal->macphymode == SINGLEMAC_SINGLEPHY && rtlhal->bandset ==
	    BAND_ON_BOTH) {
		/* 1: 2.4 G bands */
		/* <1> use  mac->bands as mem for hw->wiphy->bands */
		sband = &(rtlmac->bands[IEEE80211_BAND_2GHZ]);

		/* <2> set hw->wiphy->bands[IEEE80211_BAND_2GHZ]
		 * to default value(1T1R) */
		memcpy(&(rtlmac->bands[IEEE80211_BAND_2GHZ]), &rtl_band_2ghz,
				sizeof(struct ieee80211_supported_band));

		/* <3> init ht cap base on ant_num */
		_rtl_init_hw_ht_capab(hw, &sband->ht_cap);

		/* <4> set mac->sband to wiphy->sband */
		hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband;

		/* 2: 5 G bands */
		/* <1> use  mac->bands as mem for hw->wiphy->bands */
		sband = &(rtlmac->bands[IEEE80211_BAND_5GHZ]);

		/* <2> set hw->wiphy->bands[IEEE80211_BAND_5GHZ]
		 * to default value(1T1R) */
		memcpy(&(rtlmac->bands[IEEE80211_BAND_5GHZ]), &rtl_band_5ghz,
				sizeof(struct ieee80211_supported_band));

		/* <3> init ht cap base on ant_num */
		_rtl_init_hw_ht_capab(hw, &sband->ht_cap);

		/* <4> set mac->sband to wiphy->sband */
		hw->wiphy->bands[IEEE80211_BAND_5GHZ] = sband;
	} else {
		if (rtlhal->current_bandtype == BAND_ON_2_4G) {
			/* <1> use  mac->bands as mem for hw->wiphy->bands */
			sband = &(rtlmac->bands[IEEE80211_BAND_2GHZ]);

			/* <2> set hw->wiphy->bands[IEEE80211_BAND_2GHZ]
			 * to default value(1T1R) */
			memcpy(&(rtlmac->bands[IEEE80211_BAND_2GHZ]),
				 &rtl_band_2ghz,
				 sizeof(struct ieee80211_supported_band));

			/* <3> init ht cap base on ant_num */
			_rtl_init_hw_ht_capab(hw, &sband->ht_cap);

			/* <4> set mac->sband to wiphy->sband */
			hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband;
		} else if (rtlhal->current_bandtype == BAND_ON_5G) {
			/* <1> use  mac->bands as mem for hw->wiphy->bands */
			sband = &(rtlmac->bands[IEEE80211_BAND_5GHZ]);

			/* <2> set hw->wiphy->bands[IEEE80211_BAND_5GHZ]
			 * to default value(1T1R) */
			memcpy(&(rtlmac->bands[IEEE80211_BAND_5GHZ]),
				 &rtl_band_5ghz,
				 sizeof(struct ieee80211_supported_band));

			/* <3> init ht cap base on ant_num */
			_rtl_init_hw_ht_capab(hw, &sband->ht_cap);

			/* <4> set mac->sband to wiphy->sband */
			hw->wiphy->bands[IEEE80211_BAND_5GHZ] = sband;
		} else {
			RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, "Err BAND %d\n",
				 rtlhal->current_bandtype);
		}
	}
	/* <5> set hw caps */
	hw->flags = IEEE80211_HW_SIGNAL_DBM |
	    IEEE80211_HW_RX_INCLUDES_FCS |
	    IEEE80211_HW_AMPDU_AGGREGATION |
	    IEEE80211_HW_CONNECTION_MONITOR |
	    /* IEEE80211_HW_SUPPORTS_CQM_RSSI | */
	    IEEE80211_HW_REPORTS_TX_ACK_STATUS | 0;

	/* swlps or hwlps has been set in diff chip in init_sw_vars */
	if (rtlpriv->psc.swctrl_lps)
		hw->flags |= IEEE80211_HW_SUPPORTS_PS |
			IEEE80211_HW_PS_NULLFUNC_STACK |
			/* IEEE80211_HW_SUPPORTS_DYNAMIC_PS | */
			0;

	hw->wiphy->interface_modes =
	    BIT(NL80211_IFTYPE_AP) |
	    BIT(NL80211_IFTYPE_STATION) |
	    BIT(NL80211_IFTYPE_ADHOC);

	hw->wiphy->rts_threshold = 2347;

	hw->queues = AC_MAX;
	hw->extra_tx_headroom = RTL_TX_HEADER_SIZE;

	/* TODO: Correct this value for our hw */
	/* TODO: define these hard code value */
	hw->channel_change_time = 100;
	hw->max_listen_interval = 10;
	hw->max_rate_tries = 4;
	/* hw->max_rates = 1; */
	hw->sta_data_size = sizeof(struct rtl_sta_info);

	/* <6> mac address */
	if (is_valid_ether_addr(rtlefuse->dev_addr)) {
		SET_IEEE80211_PERM_ADDR(hw, rtlefuse->dev_addr);
	} else {
		u8 rtlmac1[] = { 0x00, 0xe0, 0x4c, 0x81, 0x92, 0x00 };
		get_random_bytes((rtlmac1 + (ETH_ALEN - 1)), 1);
		SET_IEEE80211_PERM_ADDR(hw, rtlmac1);
	}

}
예제 #10
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;
}
예제 #11
0
static void _rtl8723be_get_txpower_writeval_by_regulatory( 
							struct ieee80211_hw *hw,
							u8 channel, u8 index,
							u32 *powerbase0,
							u32 *powerbase1,
							u32 *p_outwriteval )
{
	struct rtl_priv *rtlpriv = rtl_priv( hw );
	struct rtl_phy *rtlphy = &( rtlpriv->phy );
	struct rtl_efuse *rtlefuse = rtl_efuse( rtl_priv( hw ) );
	u8 i, chnlgroup = 0, pwr_diff_limit[4], pwr_diff = 0, customer_pwr_diff;
	u32 writeval, customer_limit, rf;

	for ( rf = 0; rf < 2; rf++ ) {
		switch ( rtlefuse->eeprom_regulatory ) {
		case 0:
			chnlgroup = 0;

			writeval =
			    rtlphy->mcs_txpwrlevel_origoffset[chnlgroup][index +
								( rf ? 8 : 0 )]
			    + ( ( index < 2 ) ? powerbase0[rf] : powerbase1[rf] );

			RTPRINT( rtlpriv, FPHY, PHY_TXPWR,
				"RTK better performance, writeval(%c) = 0x%x\n",
				( ( rf == 0 ) ? 'A' : 'B' ), writeval );
			break;
		case 1:
			if ( rtlphy->pwrgroup_cnt == 1 ) {
				chnlgroup = 0;
			} else {
				if ( channel < 3 )
					chnlgroup = 0;
				else if ( channel < 6 )
					chnlgroup = 1;
				else if ( channel < 9 )
					chnlgroup = 2;
				else if ( channel < 12 )
					chnlgroup = 3;
				else if ( channel < 14 )
					chnlgroup = 4;
				else if ( channel == 14 )
					chnlgroup = 5;
			}

			writeval =
			    rtlphy->mcs_txpwrlevel_origoffset[chnlgroup]
			    [index + ( rf ? 8 : 0 )] + ( ( index < 2 ) ?
						      powerbase0[rf] :
						      powerbase1[rf] );

			RTPRINT( rtlpriv, FPHY, PHY_TXPWR,
				"Realtek regulatory, 20MHz, writeval(%c) = 0x%x\n",
				( ( rf == 0 ) ? 'A' : 'B' ), writeval );

			break;
		case 2:
			writeval =
			    ( ( index < 2 ) ? powerbase0[rf] : powerbase1[rf] );

			RTPRINT( rtlpriv, FPHY, PHY_TXPWR,
				"Better regulatory, writeval(%c) = 0x%x\n",
				( ( rf == 0 ) ? 'A' : 'B' ), writeval );
			break;
		case 3:
			chnlgroup = 0;

			if ( rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40 ) {
				RTPRINT( rtlpriv, FPHY, PHY_TXPWR,
					"customer's limit, 40MHz rf(%c) = 0x%x\n",
					( ( rf == 0 ) ? 'A' : 'B' ),
					rtlefuse->pwrgroup_ht40
					[rf][channel - 1] );
			} else {
				RTPRINT( rtlpriv, FPHY, PHY_TXPWR,
					"customer's limit, 20MHz rf(%c) = 0x%x\n",
					( ( rf == 0 ) ? 'A' : 'B' ),
					rtlefuse->pwrgroup_ht20
					[rf][channel - 1] );
			}

			if ( index < 2 )
				pwr_diff =
				    rtlefuse->txpwr_legacyhtdiff[rf][channel-1];
			else if ( rtlphy->current_chan_bw ==
				 HT_CHANNEL_WIDTH_20 )
				pwr_diff =
				    rtlefuse->txpwr_ht20diff[rf][channel-1];

			if ( rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40 )
				customer_pwr_diff =
					rtlefuse->pwrgroup_ht40[rf][channel-1];
			else
				customer_pwr_diff =
					rtlefuse->pwrgroup_ht20[rf][channel-1];

			if ( pwr_diff > customer_pwr_diff )
				pwr_diff = 0;
			else
				pwr_diff = customer_pwr_diff - pwr_diff;

			for ( i = 0; i < 4; i++ ) {
				pwr_diff_limit[i] =
				    ( u8 )( ( rtlphy->mcs_txpwrlevel_origoffset
					   [chnlgroup][index + ( rf ? 8 : 0 )] &
					      ( 0x7f << ( i * 8 ) ) ) >> ( i * 8 ) );

					if ( pwr_diff_limit[i] > pwr_diff )
						pwr_diff_limit[i] = pwr_diff;
			}

			customer_limit = ( pwr_diff_limit[3] << 24 ) |
					 ( pwr_diff_limit[2] << 16 ) |
					 ( pwr_diff_limit[1] << 8 ) |
					 ( pwr_diff_limit[0] );

			RTPRINT( rtlpriv, FPHY, PHY_TXPWR,
				"Customer's limit rf(%c) = 0x%x\n",
				 ( ( rf == 0 ) ? 'A' : 'B' ), customer_limit );

			writeval = customer_limit + ( ( index < 2 ) ?
						      powerbase0[rf] :
						      powerbase1[rf] );

			RTPRINT( rtlpriv, FPHY, PHY_TXPWR,
				"Customer, writeval rf(%c)= 0x%x\n",
				 ( ( rf == 0 ) ? 'A' : 'B' ), writeval );
			break;
		default:
			chnlgroup = 0;
			writeval =
			    rtlphy->mcs_txpwrlevel_origoffset[chnlgroup]
			    [index + ( rf ? 8 : 0 )]
			    + ( ( index < 2 ) ? powerbase0[rf] : powerbase1[rf] );

			RTPRINT( rtlpriv, FPHY, PHY_TXPWR,
				"RTK better performance, writeval rf(%c) = 0x%x\n",
				( ( rf == 0 ) ? 'A' : 'B' ), writeval );
			break;
		}

		if ( rtlpriv->dm.dynamic_txhighpower_lvl == TXHIGHPWRLEVEL_BT1 )
			writeval = writeval - 0x06060606;
		else if ( rtlpriv->dm.dynamic_txhighpower_lvl ==
			 TXHIGHPWRLEVEL_BT2 )
			writeval = writeval - 0x0c0c0c0c;
		*( p_outwriteval + rf ) = writeval;
	}
}
예제 #12
0
파일: hw.c 프로젝트: ericdjobs/rtl8192su
/* mix between 8190n and r92su */
static int _rtl92su_macconfig_before_fwdownload(struct ieee80211_hw *hw)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv);
	struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv);
	unsigned int tries = 20;
	u8 tmpu1b;
	u16 tmpu2b;

	rtl_write_byte(rtlpriv, REG_USB_HRPWM, 0x00);

	/* 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;
	}

	rtl92s_set_mac_addr(hw, rtlefuse->dev_addr);

	/* 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;
	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(6));
	udelay(500);
	rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, tmpu1b);
	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);

	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;
}
예제 #13
0
파일: rf.c 프로젝트: 303750856/linux-3.1
static void _rtl92s_get_powerbase(struct ieee80211_hw *hw, u8 *p_pwrlevel,
				  u8 chnl, u32 *ofdmbase, u32 *mcsbase,
				  u8 *p_final_pwridx)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	struct rtl_phy *rtlphy = &(rtlpriv->phy);
	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
	u32 pwrbase0, pwrbase1;
	u8 legacy_pwrdiff = 0, ht20_pwrdiff = 0;
	u8 i, pwrlevel[4];

	for (i = 0; i < 2; i++)
		pwrlevel[i] = p_pwrlevel[i];

	/* We only care about the path A for legacy. */
	if (rtlefuse->eeprom_version < 2) {
		pwrbase0 = pwrlevel[0] + (rtlefuse->legacy_httxpowerdiff & 0xf);
	} else if (rtlefuse->eeprom_version >= 2) {
		legacy_pwrdiff = rtlefuse->txpwr_legacyhtdiff
						[RF90_PATH_A][chnl - 1];

		/* For legacy OFDM, tx pwr always > HT OFDM pwr.
		 * We do not care Path B
		 * legacy OFDM pwr diff. NO BB register
		 * to notify HW. */
		pwrbase0 = pwrlevel[0] + legacy_pwrdiff;
	}

	pwrbase0 = (pwrbase0 << 24) | (pwrbase0 << 16) | (pwrbase0 << 8) |
		    pwrbase0;
	*ofdmbase = pwrbase0;

	/* MCS rates */
	if (rtlefuse->eeprom_version >= 2) {
		/* Check HT20 to HT40 diff	*/
		if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20) {
			for (i = 0; i < 2; i++) {
				/* rf-A, rf-B */
				/* HT 20<->40 pwr diff */
				ht20_pwrdiff = rtlefuse->txpwr_ht20diff
							[i][chnl - 1];

				if (ht20_pwrdiff < 8) /* 0~+7 */
					pwrlevel[i] += ht20_pwrdiff;
				else /* index8-15=-8~-1 */
					pwrlevel[i] -= (16 - ht20_pwrdiff);
			}
		}
	}

	/* use index of rf-A */
	pwrbase1 = pwrlevel[0];
	pwrbase1 = (pwrbase1 << 24) | (pwrbase1 << 16) | (pwrbase1 << 8) |
				pwrbase1;
	*mcsbase = pwrbase1;

	/* The following is for Antenna
	 * diff from Ant-B to Ant-A */
	p_final_pwridx[0] = pwrlevel[0];
	p_final_pwridx[1] = pwrlevel[1];

	switch (rtlefuse->eeprom_regulatory) {
	case 3:
		/* The following is for calculation
		 * of the power diff for Ant-B to Ant-A. */
		if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
			p_final_pwridx[0] += rtlefuse->pwrgroup_ht40
						[RF90_PATH_A][
						chnl - 1];
			p_final_pwridx[1] += rtlefuse->pwrgroup_ht40
						[RF90_PATH_B][
						chnl - 1];
		} else {
			p_final_pwridx[0] += rtlefuse->pwrgroup_ht20
						[RF90_PATH_A][
						chnl - 1];
			p_final_pwridx[1] += rtlefuse->pwrgroup_ht20
						[RF90_PATH_B][
						chnl - 1];
		}
		break;
	default:
		break;
	}

	if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("40MHz finalpwr_idx "
			"(A / B) = 0x%x / 0x%x\n", p_final_pwridx[0],
			p_final_pwridx[1]));
	} else {
		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("20MHz finalpwr_idx "
			"(A / B) = 0x%x / 0x%x\n", p_final_pwridx[0],
			 p_final_pwridx[1]));
	}
}
예제 #14
0
파일: rf.c 프로젝트: paralin/rtl8821au-1
void getTxPowerWriteValByRegulatory8812(
	IN		struct rtl_priv *rtlpriv,
	IN		uint8_t			Channel,
	IN		uint8_t			index,
	IN		u32*		powerBase0,
	IN		u32*		powerBase1,
	OUT		u32*		pOutWriteVal
	)
{
	struct rtl_phy *rtlphy = &(rtlpriv->phy);
	struct rtl_efuse *efuse = rtl_efuse(rtlpriv);
	uint8_t			i, chnlGroup=0, pwr_diff_limit[4], customer_pwr_limit;
	s8			pwr_diff=0;
	uint32_t 			writeVal, customer_limit, rf;
	uint8_t			Regulatory = efuse->eeprom_regulatory;

	//
	// Index 0 & 1= legacy OFDM, 2-5=HT_MCS rate
	//

	for(rf=0; rf<2; rf++)
	{
		switch(Regulatory)
		{
			case 0:	// Realtek better performance
					// increase power diff defined by Realtek for large power
				chnlGroup = 0;
				//RTPRINT(FPHY, PHY_TXPWR, ("MCSTxPowerLevelOriginalOffset[%d][%d] = 0x%x\n",
				//	chnlGroup, index, pHalData->MCSTxPowerLevelOriginalOffset[chnlGroup][index+(rf?8:0)]));
				writeVal = rtlphy->mcs_txpwrlevel_origoffset[chnlGroup][index+(rf?8:0)] +
					((index<2)?powerBase0[rf]:powerBase1[rf]);
				//RTPRINT(FPHY, PHY_TXPWR, ("RTK better performance, writeVal(%c) = 0x%x\n", ((rf==0)?'A':'B'), writeVal));
				break;
			case 1:	// Realtek regulatory
					// increase power diff defined by Realtek for regulatory
				{
					if(rtlphy->pwrgroup_cnt == 1)
						chnlGroup = 0;
					//if(rtlphy->pwrgroup_cnt >= MAX_PG_GROUP)
					{
						if (Channel < 3)			// Chanel 1-2
							chnlGroup = 0;
						else if (Channel < 6)		// Channel 3-5
							chnlGroup = 1;
						else	 if(Channel <9)		// Channel 6-8
							chnlGroup = 2;
						else if(Channel <12)		// Channel 9-11
							chnlGroup = 3;
						else if(Channel <14)		// Channel 12-13
							chnlGroup = 4;
						else if(Channel ==14)		// Channel 14
							chnlGroup = 5;

/*
						if(Channel <= 3)
							chnlGroup = 0;
						else if(Channel >= 4 && Channel <= 9)
							chnlGroup = 1;
						else if(Channel > 9)
							chnlGroup = 2;


						if(pHalData->CurrentChannelBW == CHANNEL_WIDTH_20)
							chnlGroup++;
						else
							chnlGroup+=4;
*/
					}
					//RTPRINT(FPHY, PHY_TXPWR, ("MCSTxPowerLevelOriginalOffset[%d][%d] = 0x%x\n",
					//chnlGroup, index, pHalData->MCSTxPowerLevelOriginalOffset[chnlGroup][index+(rf?8:0)]));
					writeVal = rtlphy->mcs_txpwrlevel_origoffset[chnlGroup][index+(rf?8:0)] +
							((index<2)?powerBase0[rf]:powerBase1[rf]);
					//RTPRINT(FPHY, PHY_TXPWR, ("Realtek regulatory, 20MHz, writeVal(%c) = 0x%x\n", ((rf==0)?'A':'B'), writeVal));
				}
				break;
			case 2:	// Better regulatory
					// don't increase any power diff
				writeVal = ((index<2)?powerBase0[rf]:powerBase1[rf]);
				//RTPRINT(FPHY, PHY_TXPWR, ("Better regulatory, writeVal(%c) = 0x%x\n", ((rf==0)?'A':'B'), writeVal));
				break;
			default:
				chnlGroup = 0;
				writeVal = rtlphy->mcs_txpwrlevel_origoffset[chnlGroup][index+(rf?8:0)] +
						((index<2)?powerBase0[rf]:powerBase1[rf]);
				//RTPRINT(FPHY, PHY_TXPWR, ("RTK better performance, writeVal rf(%c) = 0x%x\n", ((rf==0)?'A':'B'), writeVal));
				break;
		}

// 20100427 Joseph: Driver dynamic Tx power shall not affect Tx power. It shall be determined by power training mechanism.
// Currently, we cannot fully disable driver dynamic tx power mechanism because it is referenced by BT coexist mechanism.
// In the future, two mechanism shall be separated from each other and maintained independantly. Thanks for Lanhsin's reminder.
		//92d do not need this
		if(rtlpriv->dm.dynamic_txhighpower_lvl == TxHighPwrLevel_Level1)
			writeVal = 0x14141414;
		else if(rtlpriv->dm.dynamic_txhighpower_lvl == TxHighPwrLevel_Level2)
			writeVal = 0x00000000;

		// 20100628 Joseph: High power mode for BT-Coexist mechanism.
		// This mechanism is only applied when Driver-Highpower-Mechanism is OFF.
		if(rtlpriv->dm.dynamic_txhighpower_lvl == TxHighPwrLevel_BT1)
		{
			//RTPRINT(FBT, BT_TRACE, ("Tx Power (-6)\n"));
			writeVal = writeVal - 0x06060606;
		}
		else if(rtlpriv->dm.dynamic_txhighpower_lvl == TxHighPwrLevel_BT2)
		{
			//RTPRINT(FBT, BT_TRACE, ("Tx Power (-0)\n"));
			writeVal = writeVal ;
		}
		/*
		if(pMgntInfo->bDisableTXPowerByRate)
		{
		// add for  OID_RT_11N_TX_POWER_BY_RATE ,disable tx powre change by rate
			writeVal = 0x2c2c2c2c;
		}
		*/
		*(pOutWriteVal+rf) = writeVal;
	}
}
예제 #15
0
파일: rf.c 프로젝트: 303750856/linux-3.1
static void _rtl92s_get_txpower_writeval_byregulatory(struct ieee80211_hw *hw,
						      u8 chnl, u8 index,
						      u32 pwrbase0,
						      u32 pwrbase1,
						      u32 *p_outwrite_val)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	struct rtl_phy *rtlphy = &(rtlpriv->phy);
	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
	u8 i, chnlgroup, pwrdiff_limit[4];
	u32 writeval, customer_limit;

	/* Index 0 & 1= legacy OFDM, 2-5=HT_MCS rate */
	switch (rtlefuse->eeprom_regulatory) {
	case 0:
		/* Realtek better performance increase power diff
		 * defined by Realtek for large power */
		chnlgroup = 0;

		writeval = rtlphy->mcs_txpwrlevel_origoffset
				[chnlgroup][index] +
				((index < 2) ? pwrbase0 : pwrbase1);

		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
			 ("RTK better performance, "
			 "writeval = 0x%x\n", writeval));
		break;
	case 1:
		/* Realtek regulatory increase power diff defined
		 * by Realtek for regulatory */
		if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
			writeval = ((index < 2) ? pwrbase0 : pwrbase1);

			RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
				 ("Realtek regulatory, "
				 "40MHz, writeval = 0x%x\n", writeval));
		} else {
			if (rtlphy->pwrgroup_cnt == 1)
				chnlgroup = 0;

			if (rtlphy->pwrgroup_cnt >= 3) {
				if (chnl <= 3)
					chnlgroup = 0;
				else if (chnl >= 4 && chnl <= 8)
					chnlgroup = 1;
				else if (chnl > 8)
					chnlgroup = 2;
				if (rtlphy->pwrgroup_cnt == 4)
					chnlgroup++;
			}

			writeval = rtlphy->mcs_txpwrlevel_origoffset
					[chnlgroup][index]
					+ ((index < 2) ?
					pwrbase0 : pwrbase1);

			RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
				 ("Realtek regulatory, "
				 "20MHz, writeval = 0x%x\n", writeval));
		}
		break;
	case 2:
		/* Better regulatory don't increase any power diff */
		writeval = ((index < 2) ? pwrbase0 : pwrbase1);
		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
			 ("Better regulatory, "
			 "writeval = 0x%x\n", writeval));
		break;
	case 3:
		/* Customer defined power diff. increase power diff
		  defined by customer. */
		chnlgroup = 0;

		if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
			RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
				("customer's limit, 40MHz = 0x%x\n",
				rtlefuse->pwrgroup_ht40
				[RF90_PATH_A][chnl - 1]));
		} else {
			RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
				("customer's limit, 20MHz = 0x%x\n",
				rtlefuse->pwrgroup_ht20
				[RF90_PATH_A][chnl - 1]));
		}

		for (i = 0; i < 4; i++) {
			pwrdiff_limit[i] =
				(u8)((rtlphy->mcs_txpwrlevel_origoffset
				[chnlgroup][index] & (0x7f << (i * 8)))
				>> (i * 8));

			if (rtlphy->current_chan_bw ==
			    HT_CHANNEL_WIDTH_20_40) {
				if (pwrdiff_limit[i] >
				    rtlefuse->pwrgroup_ht40
				    [RF90_PATH_A][chnl - 1]) {
					pwrdiff_limit[i] =
					  rtlefuse->pwrgroup_ht20
					  [RF90_PATH_A][chnl - 1];
				}
			} else {
				if (pwrdiff_limit[i] >
				    rtlefuse->pwrgroup_ht20
				    [RF90_PATH_A][chnl - 1]) {
					pwrdiff_limit[i] =
					    rtlefuse->pwrgroup_ht20
					    [RF90_PATH_A][chnl - 1];
				}
			}
		}

		customer_limit = (pwrdiff_limit[3] << 24) |
				(pwrdiff_limit[2] << 16) |
				(pwrdiff_limit[1] << 8) |
				(pwrdiff_limit[0]);
		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
			 ("Customer's limit = 0x%x\n",
			 customer_limit));

		writeval = customer_limit + ((index < 2) ?
					     pwrbase0 : pwrbase1);
		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
			 ("Customer, writeval = "
			 "0x%x\n", writeval));
		break;
	default:
		chnlgroup = 0;
		writeval = rtlphy->mcs_txpwrlevel_origoffset[chnlgroup][index] +
				((index < 2) ? pwrbase0 : pwrbase1);
		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
			 ("RTK better performance, "
			 "writeval = 0x%x\n", writeval));
		break;
	}

	if (rtlpriv->dm.dynamic_txhighpower_lvl == TX_HIGH_PWR_LEVEL_LEVEL1)
		writeval = 0x10101010;
	else if (rtlpriv->dm.dynamic_txhighpower_lvl ==
		 TX_HIGH_PWR_LEVEL_LEVEL2)
		writeval = 0x0;

	*p_outwrite_val = writeval;

}
예제 #16
0
static int _rtl_phydm_init_com_info(struct rtl_priv *rtlpriv,
				    enum odm_ic_type ic_type,
				    struct rtl_phydm_params *params)
{
	struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv);
	struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
	struct rtl_phy *rtlphy = &rtlpriv->phy;
	struct rtl_mac *mac = rtl_mac(rtlpriv);
	struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv);
	struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv);
	u8 odm_board_type = ODM_BOARD_DEFAULT;
	u32 support_ability;
	int i;

	dm->adapter = (void *)rtlpriv;

	odm_cmn_info_init(dm, ODM_CMNINFO_PLATFORM, ODM_CE);

	odm_cmn_info_init(dm, ODM_CMNINFO_IC_TYPE, ic_type);

	odm_cmn_info_init(dm, ODM_CMNINFO_INTERFACE, ODM_ITRF_PCIE);

	odm_cmn_info_init(dm, ODM_CMNINFO_MP_TEST_CHIP, params->mp_chip);

	odm_cmn_info_init(dm, ODM_CMNINFO_PATCH_ID, rtlhal->oem_id);

	odm_cmn_info_init(dm, ODM_CMNINFO_BWIFI_TEST, 1);

	if (rtlphy->rf_type == RF_1T1R)
		odm_cmn_info_init(dm, ODM_CMNINFO_RF_TYPE, ODM_1T1R);
	else if (rtlphy->rf_type == RF_1T2R)
		odm_cmn_info_init(dm, ODM_CMNINFO_RF_TYPE, ODM_1T2R);
	else if (rtlphy->rf_type == RF_2T2R)
		odm_cmn_info_init(dm, ODM_CMNINFO_RF_TYPE, ODM_2T2R);
	else if (rtlphy->rf_type == RF_2T2R_GREEN)
		odm_cmn_info_init(dm, ODM_CMNINFO_RF_TYPE, ODM_2T2R_GREEN);
	else if (rtlphy->rf_type == RF_2T3R)
		odm_cmn_info_init(dm, ODM_CMNINFO_RF_TYPE, ODM_2T3R);
	else if (rtlphy->rf_type == RF_2T4R)
		odm_cmn_info_init(dm, ODM_CMNINFO_RF_TYPE, ODM_2T4R);
	else if (rtlphy->rf_type == RF_3T3R)
		odm_cmn_info_init(dm, ODM_CMNINFO_RF_TYPE, ODM_3T3R);
	else if (rtlphy->rf_type == RF_3T4R)
		odm_cmn_info_init(dm, ODM_CMNINFO_RF_TYPE, ODM_3T4R);
	else if (rtlphy->rf_type == RF_4T4R)
		odm_cmn_info_init(dm, ODM_CMNINFO_RF_TYPE, ODM_4T4R);
	else
		odm_cmn_info_init(dm, ODM_CMNINFO_RF_TYPE, ODM_XTXR);

	/* 1 ======= BoardType: ODM_CMNINFO_BOARD_TYPE ======= */
	if (rtlhal->external_lna_2g != 0) {
		odm_board_type |= ODM_BOARD_EXT_LNA;
		odm_cmn_info_init(dm, ODM_CMNINFO_EXT_LNA, 1);
	}
	if (rtlhal->external_lna_5g != 0) {
		odm_board_type |= ODM_BOARD_EXT_LNA_5G;
		odm_cmn_info_init(dm, ODM_CMNINFO_5G_EXT_LNA, 1);
	}
	if (rtlhal->external_pa_2g != 0) {
		odm_board_type |= ODM_BOARD_EXT_PA;
		odm_cmn_info_init(dm, ODM_CMNINFO_EXT_PA, 1);
	}
	if (rtlhal->external_pa_5g != 0) {
		odm_board_type |= ODM_BOARD_EXT_PA_5G;
		odm_cmn_info_init(dm, ODM_CMNINFO_5G_EXT_PA, 1);
	}
	if (rtlpriv->cfg->ops->get_btc_status())
		odm_board_type |= ODM_BOARD_BT;

	odm_cmn_info_init(dm, ODM_CMNINFO_BOARD_TYPE, odm_board_type);
	/* 1 ============== End of BoardType ============== */

	odm_cmn_info_init(dm, ODM_CMNINFO_GPA, rtlhal->type_gpa);
	odm_cmn_info_init(dm, ODM_CMNINFO_APA, rtlhal->type_apa);
	odm_cmn_info_init(dm, ODM_CMNINFO_GLNA, rtlhal->type_glna);
	odm_cmn_info_init(dm, ODM_CMNINFO_ALNA, rtlhal->type_alna);

	odm_cmn_info_init(dm, ODM_CMNINFO_RFE_TYPE, rtlhal->rfe_type);

	odm_cmn_info_init(dm, ODM_CMNINFO_EXT_TRSW, 0);

	/*Add by YuChen for kfree init*/
	odm_cmn_info_init(dm, ODM_CMNINFO_REGRFKFREEENABLE, 2);
	odm_cmn_info_init(dm, ODM_CMNINFO_RFKFREEENABLE, 0);

	/*Antenna diversity relative parameters*/
	odm_cmn_info_hook(dm, ODM_CMNINFO_ANT_DIV,
			  &rtlefuse->antenna_div_cfg);
	odm_cmn_info_init(dm, ODM_CMNINFO_RF_ANTENNA_TYPE,
			  rtlefuse->antenna_div_type);
	odm_cmn_info_init(dm, ODM_CMNINFO_BE_FIX_TX_ANT, 0);
	odm_cmn_info_init(dm, ODM_CMNINFO_WITH_EXT_ANTENNA_SWITCH, 0);

	/* (8822B) efuse 0x3D7 & 0x3D8 for TX PA bias */
	odm_cmn_info_init(dm, ODM_CMNINFO_EFUSE0X3D7, params->efuse0x3d7);
	odm_cmn_info_init(dm, ODM_CMNINFO_EFUSE0X3D8, params->efuse0x3d8);

	/*Add by YuChen for adaptivity init*/
	odm_cmn_info_hook(dm, ODM_CMNINFO_ADAPTIVITY,
			  &rtlpriv->phydm.adaptivity_en);
	phydm_adaptivity_info_init(dm, PHYDM_ADAPINFO_CARRIER_SENSE_ENABLE,
				   false);
	phydm_adaptivity_info_init(dm, PHYDM_ADAPINFO_DCBACKOFF, 0);
	phydm_adaptivity_info_init(dm, PHYDM_ADAPINFO_DYNAMICLINKADAPTIVITY,
				   false);
	phydm_adaptivity_info_init(dm, PHYDM_ADAPINFO_TH_L2H_INI, 0);
	phydm_adaptivity_info_init(dm, PHYDM_ADAPINFO_TH_EDCCA_HL_DIFF, 0);

	odm_cmn_info_init(dm, ODM_CMNINFO_IQKFWOFFLOAD, 0);

	/* Pointer reference */
	odm_cmn_info_hook(dm, ODM_CMNINFO_TX_UNI,
			  &rtlpriv->stats.txbytesunicast);
	odm_cmn_info_hook(dm, ODM_CMNINFO_RX_UNI,
			  &rtlpriv->stats.rxbytesunicast);
	odm_cmn_info_hook(dm, ODM_CMNINFO_BAND, &rtlhal->current_bandtype);
	odm_cmn_info_hook(dm, ODM_CMNINFO_FORCED_RATE,
			  &rtlpriv->phydm.forced_data_rate);
	odm_cmn_info_hook(dm, ODM_CMNINFO_FORCED_IGI_LB,
			  &rtlpriv->phydm.forced_igi_lb);

	odm_cmn_info_hook(dm, ODM_CMNINFO_SEC_CHNL_OFFSET,
			  &mac->cur_40_prime_sc);
	odm_cmn_info_hook(dm, ODM_CMNINFO_BW, &rtlphy->current_chan_bw);
	odm_cmn_info_hook(dm, ODM_CMNINFO_CHNL, &rtlphy->current_channel);

	odm_cmn_info_hook(dm, ODM_CMNINFO_SCAN, &mac->act_scanning);
	odm_cmn_info_hook(dm, ODM_CMNINFO_POWER_SAVING,
			  &ppsc->dot11_psmode); /* may add new boolean flag */
	/*Add by Yuchen for phydm beamforming*/
	odm_cmn_info_hook(dm, ODM_CMNINFO_TX_TP,
			  &rtlpriv->stats.txbytesunicast_inperiod_tp);
	odm_cmn_info_hook(dm, ODM_CMNINFO_RX_TP,
			  &rtlpriv->stats.rxbytesunicast_inperiod_tp);
	odm_cmn_info_hook(dm, ODM_CMNINFO_ANT_TEST,
			  &rtlpriv->phydm.antenna_test);
	for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++)
		odm_cmn_info_ptr_array_hook(dm, ODM_CMNINFO_STA_STATUS, i,
					    NULL);

	phydm_init_debug_setting(dm);

	odm_cmn_info_init(dm, ODM_CMNINFO_FAB_VER, params->fab_ver);
	odm_cmn_info_init(dm, ODM_CMNINFO_CUT_VER, params->cut_ver);

	/* after ifup, ability is updated again */
	support_ability = ODM_RF_CALIBRATION | ODM_RF_TX_PWR_TRACK;
	odm_cmn_info_update(dm, ODM_CMNINFO_ABILITY, support_ability);

	return 0;
}
예제 #17
0
void rtl_proc_add_one( struct ieee80211_hw *hw )
{
	struct rtl_priv *rtlpriv = rtl_priv( hw );
	struct rtl_efuse *rtlefuse = rtl_efuse( rtl_priv( hw ) );
	// struct proc_dir_entry *entry; // remove after fixing these TODOs

	snprintf( rtlpriv->dbg.proc_name, 18, "%x-%x-%x-%x-%x-%x",
		rtlefuse->dev_addr[0], rtlefuse->dev_addr[1],
		rtlefuse->dev_addr[2], rtlefuse->dev_addr[3],
		rtlefuse->dev_addr[4], rtlefuse->dev_addr[5] );

        return; // remove after fixing these TODOs
        /* TODO: create_proc_entry is deprecated and has been removed from the kernel.
         * Need to use it's replacement
	rtlpriv->dbg.proc_dir = create_proc_entry( rtlpriv->dbg.proc_name,
		S_IFDIR | S_IRUGO | S_IXUGO, proc_topdir );
	if ( !rtlpriv->dbg.proc_dir ) {
		RT_TRACE( COMP_INIT, DBG_EMERG, ( "Unable to init "
			"/proc/net/%s/%s\n", rtlpriv->cfg->name,
			rtlpriv->dbg.proc_name ) );
		return;
	}

         * TODO: create_proc_read_entry is deprecated and has been removed from the kernel.
         * Need to use it's replacement
	entry = create_proc_read_entry( "mac-0", S_IFREG | S_IRUGO,
				   rtlpriv->dbg.proc_dir, rtl_proc_get_mac_0, hw );
	if ( !entry )
		RT_TRACE( COMP_INIT, DBG_EMERG, ( "Unable to initialize "
		      "/proc/net/%s/%s/mac-0\n",
		      rtlpriv->cfg->name, rtlpriv->dbg.proc_name ) );

	entry = create_proc_read_entry( "mac-1", S_IFREG | S_IRUGO,
				   rtlpriv->dbg.proc_dir, rtl_proc_get_mac_1, hw );
	if ( !entry )
		RT_TRACE( COMP_INIT, COMP_ERR, ( "Unable to initialize "
		      "/proc/net/%s/%s/mac-1\n",
		      rtlpriv->cfg->name, rtlpriv->dbg.proc_name ) );

	entry = create_proc_read_entry( "mac-2", S_IFREG | S_IRUGO,
				   rtlpriv->dbg.proc_dir, rtl_proc_get_mac_2, hw );
	if ( !entry )
		RT_TRACE( COMP_INIT, COMP_ERR, ( "Unable to initialize "
		      "/proc/net/%s/%s/mac-2\n",
		      rtlpriv->cfg->name, rtlpriv->dbg.proc_name ) );

	entry = create_proc_read_entry( "mac-3", S_IFREG | S_IRUGO,
				   rtlpriv->dbg.proc_dir, rtl_proc_get_mac_3, hw );
	if ( !entry )
		RT_TRACE( COMP_INIT, COMP_ERR, ( "Unable to initialize "
		      "/proc/net/%s/%s/mac-3\n",
		      rtlpriv->cfg->name, rtlpriv->dbg.proc_name ) );

	entry = create_proc_read_entry( "mac-4", S_IFREG | S_IRUGO,
				   rtlpriv->dbg.proc_dir, rtl_proc_get_mac_4, hw );
	if ( !entry )
		RT_TRACE( COMP_INIT, COMP_ERR, ( "Unable to initialize "
		      "/proc/net/%s/%s/mac-4\n",
		      rtlpriv->cfg->name, rtlpriv->dbg.proc_name ) );

	entry = create_proc_read_entry( "mac-5", S_IFREG | S_IRUGO,
				   rtlpriv->dbg.proc_dir, rtl_proc_get_mac_5, hw );
	if ( !entry )
		RT_TRACE( COMP_INIT, COMP_ERR, ( "Unable to initialize "
		      "/proc/net/%s/%s/mac-5\n",
		      rtlpriv->cfg->name, rtlpriv->dbg.proc_name ) );

	entry = create_proc_read_entry( "mac-6", S_IFREG | S_IRUGO,
				   rtlpriv->dbg.proc_dir, rtl_proc_get_mac_6, hw );
	if ( !entry )
		RT_TRACE( COMP_INIT, COMP_ERR, ( "Unable to initialize "
		      "/proc/net/%s/%s/mac-6\n",
		      rtlpriv->cfg->name, rtlpriv->dbg.proc_name ) );

	entry = create_proc_read_entry( "mac-7", S_IFREG | S_IRUGO,
				   rtlpriv->dbg.proc_dir, rtl_proc_get_mac_7, hw );
	if ( !entry )
		RT_TRACE( COMP_INIT, COMP_ERR, ( "Unable to initialize "
		      "/proc/net/%s/%s/mac-7\n",
		      rtlpriv->cfg->name, rtlpriv->dbg.proc_name ) );

	entry = create_proc_read_entry( "bb-8", S_IFREG | S_IRUGO,
				   rtlpriv->dbg.proc_dir, rtl_proc_get_bb_8, hw );
	if ( !entry )
		RT_TRACE( COMP_INIT, COMP_ERR, ( "Unable to initialize "
		      "/proc/net/%s/%s/bb-8\n",
		      rtlpriv->cfg->name, rtlpriv->dbg.proc_name ) );

	entry = create_proc_read_entry( "bb-9", S_IFREG | S_IRUGO,
				   rtlpriv->dbg.proc_dir, rtl_proc_get_bb_9, hw );
	if ( !entry )
		RT_TRACE( COMP_INIT, COMP_ERR, ( "Unable to initialize "
		      "/proc/net/%s/%s/bb-9\n",
		      rtlpriv->cfg->name, rtlpriv->dbg.proc_name ) );

	entry = create_proc_read_entry( "bb-a", S_IFREG | S_IRUGO,
				   rtlpriv->dbg.proc_dir, rtl_proc_get_bb_a, hw );
	if ( !entry )
		RT_TRACE( COMP_INIT, COMP_ERR, ( "Unable to initialize "
		      "/proc/net/%s/%s/bb-a\n",
		      rtlpriv->cfg->name, rtlpriv->dbg.proc_name ) );

	entry = create_proc_read_entry( "bb-b", S_IFREG | S_IRUGO,
				   rtlpriv->dbg.proc_dir, rtl_proc_get_bb_b, hw );
	if ( !entry )
		RT_TRACE( COMP_INIT, COMP_ERR, ( "Unable to initialize "
		      "/proc/net/%s/%s/bb-b\n",
		      rtlpriv->cfg->name, rtlpriv->dbg.proc_name ) );

	entry = create_proc_read_entry( "bb-c", S_IFREG | S_IRUGO,
				   rtlpriv->dbg.proc_dir, rtl_proc_get_bb_c, hw );
	if ( !entry )
		RT_TRACE( COMP_INIT, COMP_ERR, ( "Unable to initialize "
		      "/proc/net/%s/%s/bb-c\n",
		      rtlpriv->cfg->name, rtlpriv->dbg.proc_name ) );

	entry = create_proc_read_entry( "bb-d", S_IFREG | S_IRUGO,
				   rtlpriv->dbg.proc_dir, rtl_proc_get_bb_d, hw );
	if ( !entry )
		RT_TRACE( COMP_INIT, COMP_ERR, ( "Unable to initialize "
		      "/proc/net/%s/%s/bb-d\n",
		      rtlpriv->cfg->name, rtlpriv->dbg.proc_name ) );

	entry = create_proc_read_entry( "bb-e", S_IFREG | S_IRUGO,
				   rtlpriv->dbg.proc_dir, rtl_proc_get_bb_e, hw );
	if ( !entry )
		RT_TRACE( COMP_INIT, COMP_ERR, ( "Unable to initialize "
		      "/proc/net/%s/%s/bb-e\n",
		      rtlpriv->cfg->name, rtlpriv->dbg.proc_name ) );

	entry = create_proc_read_entry( "bb-f", S_IFREG | S_IRUGO,
				   rtlpriv->dbg.proc_dir, rtl_proc_get_bb_f, hw );
	if ( !entry )
		RT_TRACE( COMP_INIT, COMP_ERR, ( "Unable to initialize "
		      "/proc/net/%s/%s/bb-f\n",
		      rtlpriv->cfg->name, rtlpriv->dbg.proc_name ) );

	entry = create_proc_read_entry( "rf-a", S_IFREG | S_IRUGO,
				   rtlpriv->dbg.proc_dir, rtl_proc_get_reg_rf_a, hw );
	if ( !entry )
		RT_TRACE( COMP_INIT, COMP_ERR, ( "Unable to initialize "
		      "/proc/net/%s/%s/rf-a\n",
		      rtlpriv->cfg->name, rtlpriv->dbg.proc_name ) );

	entry = create_proc_read_entry( "rf-b", S_IFREG | S_IRUGO,
				   rtlpriv->dbg.proc_dir, rtl_proc_get_reg_rf_b, hw );
	if ( !entry )
		RT_TRACE( COMP_INIT, COMP_ERR, ( "Unable to initialize "
		      "/proc/net/%s/%s/rf-b\n",
		      rtlpriv->cfg->name, rtlpriv->dbg.proc_name ) );

	entry = create_proc_read_entry( "cam-1", S_IFREG | S_IRUGO,
				   rtlpriv->dbg.proc_dir, rtl_proc_get_cam_register_1, hw );
	if ( !entry )
		RT_TRACE( COMP_INIT, COMP_ERR, ( "Unable to initialize "
		      "/proc/net/%s/%s/cam-1\n",
		      rtlpriv->cfg->name, rtlpriv->dbg.proc_name ) );

	entry = create_proc_read_entry( "cam-2", S_IFREG | S_IRUGO,
				   rtlpriv->dbg.proc_dir, rtl_proc_get_cam_register_2, hw );
	if ( !entry )
		RT_TRACE( COMP_INIT, COMP_ERR, ( "Unable to initialize "
		      "/proc/net/%s/%s/cam-2\n",
		      rtlpriv->cfg->name, rtlpriv->dbg.proc_name ) );

	entry = create_proc_read_entry( "cam-3", S_IFREG | S_IRUGO,
				   rtlpriv->dbg.proc_dir, rtl_proc_get_cam_register_3, hw );
	if ( !entry )
		RT_TRACE( COMP_INIT, COMP_ERR, ( "Unable to initialize "
		      "/proc/net/%s/%s/cam-3\n",
		      rtlpriv->cfg->name, rtlpriv->dbg.proc_name ) );
        */
}
예제 #18
0
void rtl_proc_add_one(struct ieee80211_hw *hw)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
	struct proc_dir_entry *entry;

	snprintf(rtlpriv->dbg.proc_name, 18, "%x-%x-%x-%x-%x-%x",
		rtlefuse->dev_addr[0], rtlefuse->dev_addr[1],
		rtlefuse->dev_addr[2], rtlefuse->dev_addr[3],
		rtlefuse->dev_addr[4], rtlefuse->dev_addr[5]);

	rtlpriv->dbg.proc_dir = proc_mkdir(rtlpriv->dbg.proc_name, proc_topdir);
	if (!rtlpriv->dbg.proc_dir) {
		RT_TRACE(COMP_INIT, DBG_EMERG, ("Unable to init "
			"/proc/net/%s/%s\n", rtlpriv->cfg->name,
			rtlpriv->dbg.proc_name));
		return;
	}

	entry = proc_create_data("mac-0", S_IFREG | S_IRUGO,
				  rtlpriv->dbg.proc_dir, &file_ops_mac_0, hw);
	if (!entry)
		RT_TRACE(COMP_INIT, DBG_EMERG,
			 ("Unable to initialize /proc/net/%s/%s/mac-0\n",
			  rtlpriv->cfg->name, rtlpriv->dbg.proc_name));

	entry = proc_create_data("mac-1", S_IFREG | S_IRUGO,
				 rtlpriv->dbg.proc_dir, &file_ops_mac_1, hw);
	if (!entry)
		RT_TRACE(COMP_INIT, COMP_ERR,
			 ("Unable to initialize /proc/net/%s/%s/mac-1\n",
			  rtlpriv->cfg->name, rtlpriv->dbg.proc_name));

	entry = proc_create_data("mac-2", S_IFREG | S_IRUGO,
				 rtlpriv->dbg.proc_dir, &file_ops_mac_2, hw);
	if (!entry)
		RT_TRACE(COMP_INIT, COMP_ERR,
			 ("Unable to initialize /proc/net/%s/%s/mac-2\n",
			  rtlpriv->cfg->name, rtlpriv->dbg.proc_name));

	entry = proc_create_data("mac-3", S_IFREG | S_IRUGO,
				 rtlpriv->dbg.proc_dir, &file_ops_mac_3, hw);
	if (!entry)
		RT_TRACE(COMP_INIT, COMP_ERR,
			 ("Unable to initialize /proc/net/%s/%s/mac-3\n",
			  rtlpriv->cfg->name, rtlpriv->dbg.proc_name));

	entry = proc_create_data("mac-4", S_IFREG | S_IRUGO,
				 rtlpriv->dbg.proc_dir, &file_ops_mac_4, hw);
	if (!entry)
		RT_TRACE(COMP_INIT, COMP_ERR,
			 ("Unable to initialize /proc/net/%s/%s/mac-4\n",
			  rtlpriv->cfg->name, rtlpriv->dbg.proc_name));

	entry = proc_create_data("mac-5", S_IFREG | S_IRUGO,
				 rtlpriv->dbg.proc_dir, &file_ops_mac_5, hw);
	if (!entry)
		RT_TRACE(COMP_INIT, COMP_ERR,
			 ("Unable to initialize /proc/net/%s/%s/mac-5\n",
			  rtlpriv->cfg->name, rtlpriv->dbg.proc_name));

	entry = proc_create_data("mac-6", S_IFREG | S_IRUGO,
				 rtlpriv->dbg.proc_dir, &file_ops_mac_6, hw);
	if (!entry)
		RT_TRACE(COMP_INIT, COMP_ERR,
			 ("Unable to initialize /proc/net/%s/%s/mac-6\n",
			  rtlpriv->cfg->name, rtlpriv->dbg.proc_name));

	entry = proc_create_data("mac-7", S_IFREG | S_IRUGO,
				 rtlpriv->dbg.proc_dir, &file_ops_mac_7, hw);
	if (!entry)
		RT_TRACE(COMP_INIT, COMP_ERR,
			 ("Unable to initialize /proc/net/%s/%s/mac-7\n",
			  rtlpriv->cfg->name, rtlpriv->dbg.proc_name));

	entry = proc_create_data("bb-8", S_IFREG | S_IRUGO,
				 rtlpriv->dbg.proc_dir, &file_ops_bb_8, hw);
	if (!entry)
		RT_TRACE(COMP_INIT, COMP_ERR,
			 ("Unable to initialize /proc/net/%s/%s/bb-8\n",
			  rtlpriv->cfg->name, rtlpriv->dbg.proc_name));

	entry = proc_create_data("bb-9", S_IFREG | S_IRUGO,
				 rtlpriv->dbg.proc_dir, &file_ops_bb_9, hw);
	if (!entry)
		RT_TRACE(COMP_INIT, COMP_ERR,
			 ("Unable to initialize /proc/net/%s/%s/bb-9\n",
			  rtlpriv->cfg->name, rtlpriv->dbg.proc_name));

	entry = proc_create_data("bb-a", S_IFREG | S_IRUGO,
				 rtlpriv->dbg.proc_dir, &file_ops_bb_a, hw);
	if (!entry)
		RT_TRACE(COMP_INIT, COMP_ERR,
			 ("Unable to initialize /proc/net/%s/%s/bb-a\n",
			  rtlpriv->cfg->name, rtlpriv->dbg.proc_name));

	entry = proc_create_data("bb-b", S_IFREG | S_IRUGO,
				 rtlpriv->dbg.proc_dir, &file_ops_bb_b, hw);
	if (!entry)
		RT_TRACE(COMP_INIT, COMP_ERR,
			 ("Unable to initialize /proc/net/%s/%s/bb-b\n",
		      rtlpriv->cfg->name, rtlpriv->dbg.proc_name));

	entry = proc_create_data("bb-c", S_IFREG | S_IRUGO,
				 rtlpriv->dbg.proc_dir, &file_ops_bb_c, hw);
	if (!entry)
		RT_TRACE(COMP_INIT, COMP_ERR,
			 ("Unable to initialize /proc/net/%s/%s/bb-c\n",
			  rtlpriv->cfg->name, rtlpriv->dbg.proc_name));

	entry = proc_create_data("bb-d", S_IFREG | S_IRUGO,
				 rtlpriv->dbg.proc_dir, &file_ops_bb_d, hw);
	if (!entry)
		RT_TRACE(COMP_INIT, COMP_ERR,
			 ("Unable to initialize /proc/net/%s/%s/bb-d\n",
			  rtlpriv->cfg->name, rtlpriv->dbg.proc_name));

	entry = proc_create_data("bb-e", S_IFREG | S_IRUGO,
				 rtlpriv->dbg.proc_dir, &file_ops_bb_e, hw);
	if (!entry)
		RT_TRACE(COMP_INIT, COMP_ERR,
			 ("Unable to initialize /proc/net/%s/%s/bb-e\n",
			  rtlpriv->cfg->name, rtlpriv->dbg.proc_name));

	entry = proc_create_data("bb-f", S_IFREG | S_IRUGO,
				 rtlpriv->dbg.proc_dir, &file_ops_bb_f, hw);
	if (!entry)
		RT_TRACE(COMP_INIT, COMP_ERR,
			 ("Unable to initialize /proc/net/%s/%s/bb-f\n",
			  rtlpriv->cfg->name, rtlpriv->dbg.proc_name));

	entry = proc_create_data("rf-a", S_IFREG | S_IRUGO,
				 rtlpriv->dbg.proc_dir, &file_ops_rf_a, hw);
	if (!entry)
		RT_TRACE(COMP_INIT, COMP_ERR,
			 ("Unable to initialize /proc/net/%s/%s/rf-a\n",
			  rtlpriv->cfg->name, rtlpriv->dbg.proc_name));

	entry = proc_create_data("rf-b", S_IFREG | S_IRUGO,
				 rtlpriv->dbg.proc_dir, &file_ops_rf_b, hw);
	if (!entry)
		RT_TRACE(COMP_INIT, COMP_ERR,
			 ("Unable to initialize /proc/net/%s/%s/rf-b\n",
			  rtlpriv->cfg->name, rtlpriv->dbg.proc_name));

	entry = proc_create_data("cam-1", S_IFREG | S_IRUGO,
				 rtlpriv->dbg.proc_dir, &file_ops_cam_1, hw);
	if (!entry)
		RT_TRACE(COMP_INIT, COMP_ERR,
			 ("Unable to initialize /proc/net/%s/%s/cam-1\n",
			  rtlpriv->cfg->name, rtlpriv->dbg.proc_name));

	entry = proc_create_data("cam-2", S_IFREG | S_IRUGO,
				 rtlpriv->dbg.proc_dir, &file_ops_cam_2, hw);
	if (!entry)
		RT_TRACE(COMP_INIT, COMP_ERR,
			 ("Unable to initialize /proc/net/%s/%s/cam-2\n",
			  rtlpriv->cfg->name, rtlpriv->dbg.proc_name));

	entry = proc_create_data("cam-3", S_IFREG | S_IRUGO,
				 rtlpriv->dbg.proc_dir, &file_ops_cam_3, hw);
	if (!entry)
		RT_TRACE(COMP_INIT, COMP_ERR,
			 ("Unable to initialize /proc/net/%s/%s/cam-3\n",
			  rtlpriv->cfg->name, rtlpriv->dbg.proc_name));
}
예제 #19
0
static void _rtl_init_mac80211(struct ieee80211_hw *hw)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
	struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw));
	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
	struct ieee80211_supported_band *sband;


	if (rtlhal->macphymode == SINGLEMAC_SINGLEPHY && rtlhal->bandset ==
	    BAND_ON_BOTH) {
		
		
		sband = &(rtlmac->bands[IEEE80211_BAND_2GHZ]);

		memcpy(&(rtlmac->bands[IEEE80211_BAND_2GHZ]), &rtl_band_2ghz,
				sizeof(struct ieee80211_supported_band));

		
		_rtl_init_hw_ht_capab(hw, &sband->ht_cap);

		
		hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband;

		
		
		sband = &(rtlmac->bands[IEEE80211_BAND_5GHZ]);

		memcpy(&(rtlmac->bands[IEEE80211_BAND_5GHZ]), &rtl_band_5ghz,
				sizeof(struct ieee80211_supported_band));

		
		_rtl_init_hw_ht_capab(hw, &sband->ht_cap);

		
		hw->wiphy->bands[IEEE80211_BAND_5GHZ] = sband;
	} else {
		if (rtlhal->current_bandtype == BAND_ON_2_4G) {
			
			sband = &(rtlmac->bands[IEEE80211_BAND_2GHZ]);

			memcpy(&(rtlmac->bands[IEEE80211_BAND_2GHZ]),
				 &rtl_band_2ghz,
				 sizeof(struct ieee80211_supported_band));

			
			_rtl_init_hw_ht_capab(hw, &sband->ht_cap);

			
			hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband;
		} else if (rtlhal->current_bandtype == BAND_ON_5G) {
			
			sband = &(rtlmac->bands[IEEE80211_BAND_5GHZ]);

			memcpy(&(rtlmac->bands[IEEE80211_BAND_5GHZ]),
				 &rtl_band_5ghz,
				 sizeof(struct ieee80211_supported_band));

			
			_rtl_init_hw_ht_capab(hw, &sband->ht_cap);

			
			hw->wiphy->bands[IEEE80211_BAND_5GHZ] = sband;
		} else {
			RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, "Err BAND %d\n",
				 rtlhal->current_bandtype);
		}
	}
	
	hw->flags = IEEE80211_HW_SIGNAL_DBM |
	    IEEE80211_HW_RX_INCLUDES_FCS |
	    IEEE80211_HW_AMPDU_AGGREGATION |
	    IEEE80211_HW_CONNECTION_MONITOR |
	    
	    IEEE80211_HW_REPORTS_TX_ACK_STATUS | 0;

	
	if (rtlpriv->psc.swctrl_lps)
		hw->flags |= IEEE80211_HW_SUPPORTS_PS |
			IEEE80211_HW_PS_NULLFUNC_STACK |
			
			0;

	hw->wiphy->interface_modes =
	    BIT(NL80211_IFTYPE_AP) |
	    BIT(NL80211_IFTYPE_STATION) |
	    BIT(NL80211_IFTYPE_ADHOC);

	hw->wiphy->rts_threshold = 2347;

	hw->queues = AC_MAX;
	hw->extra_tx_headroom = RTL_TX_HEADER_SIZE;

	
	
	hw->channel_change_time = 100;
	hw->max_listen_interval = 10;
	hw->max_rate_tries = 4;
	
	hw->sta_data_size = sizeof(struct rtl_sta_info);

	
	if (is_valid_ether_addr(rtlefuse->dev_addr)) {
		SET_IEEE80211_PERM_ADDR(hw, rtlefuse->dev_addr);
	} else {
		u8 rtlmac1[] = { 0x00, 0xe0, 0x4c, 0x81, 0x92, 0x00 };
		get_random_bytes((rtlmac1 + (ETH_ALEN - 1)), 1);
		SET_IEEE80211_PERM_ADDR(hw, rtlmac1);
	}

}
예제 #20
0
파일: hw.c 프로젝트: ericdjobs/rtl8192su
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;
}
예제 #21
0
파일: mac.c 프로젝트: 7799/linux
void rtl92c_set_key(struct ieee80211_hw *hw, u32 key_index,
		     u8 *p_macaddr, bool is_group, u8 enc_algo,
		     bool is_wepkey, bool clear_all)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
	u8 *macaddr = p_macaddr;
	u32 entry_id = 0;
	bool is_pairwise = false;
	static u8 cam_const_addr[4][6] = {
		{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
		{0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
		{0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
		{0x00, 0x00, 0x00, 0x00, 0x00, 0x03}
	};
	static u8 cam_const_broad[] = {
		0xff, 0xff, 0xff, 0xff, 0xff, 0xff
	};

	if (clear_all) {
		u8 idx = 0;
		u8 cam_offset = 0;
		u8 clear_number = 5;

		RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n");
		for (idx = 0; idx < clear_number; idx++) {
			rtl_cam_mark_invalid(hw, cam_offset + idx);
			rtl_cam_empty_entry(hw, cam_offset + idx);
			if (idx < 5) {
				memset(rtlpriv->sec.key_buf[idx], 0,
				       MAX_KEY_LEN);
				rtlpriv->sec.key_len[idx] = 0;
			}
		}
	} else {
		switch (enc_algo) {
		case WEP40_ENCRYPTION:
			enc_algo = CAM_WEP40;
			break;
		case WEP104_ENCRYPTION:
			enc_algo = CAM_WEP104;
			break;
		case TKIP_ENCRYPTION:
			enc_algo = CAM_TKIP;
			break;
		case AESCCMP_ENCRYPTION:
			enc_algo = CAM_AES;
			break;
		default:
			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
				 "illegal switch case\n");
			enc_algo = CAM_TKIP;
			break;
		}
		if (is_wepkey || rtlpriv->sec.use_defaultkey) {
			macaddr = cam_const_addr[key_index];
			entry_id = key_index;
		} else {
			if (is_group) {
				macaddr = cam_const_broad;
				entry_id = key_index;
			} else {
				if (mac->opmode == NL80211_IFTYPE_AP ||
				    mac->opmode == NL80211_IFTYPE_MESH_POINT) {
					entry_id = rtl_cam_get_free_entry(hw,
								 p_macaddr);
					if (entry_id >=  TOTAL_CAM_ENTRY) {
						RT_TRACE(rtlpriv, COMP_SEC,
							 DBG_EMERG,
							 "Can not find free hw security cam entry\n");
						return;
					}
				} else {
					entry_id = CAM_PAIRWISE_KEY_POSITION;
				}

				key_index = PAIRWISE_KEYIDX;
				is_pairwise = true;
			}
		}
		if (rtlpriv->sec.key_len[key_index] == 0) {
			RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
				 "delete one entry\n");
			if (mac->opmode == NL80211_IFTYPE_AP ||
			    mac->opmode == NL80211_IFTYPE_MESH_POINT)
				rtl_cam_del_entry(hw, p_macaddr);
			rtl_cam_delete_one_entry(hw, p_macaddr, entry_id);
		} else {
			RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
				 "The insert KEY length is %d\n",
				 rtlpriv->sec.key_len[PAIRWISE_KEYIDX]);
			RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
				 "The insert KEY is %x %x\n",
				 rtlpriv->sec.key_buf[0][0],
				 rtlpriv->sec.key_buf[0][1]);
			RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
				 "add one entry\n");
			if (is_pairwise) {
				RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_LOUD,
					      "Pairwise Key content",
					      rtlpriv->sec.pairwise_key,
					      rtlpriv->sec.
					      key_len[PAIRWISE_KEYIDX]);
				RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
					 "set Pairwise key\n");

				rtl_cam_add_one_entry(hw, macaddr, key_index,
						entry_id, enc_algo,
						CAM_CONFIG_NO_USEDK,
						rtlpriv->sec.
						key_buf[key_index]);
			} else {
				RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
					 "set group key\n");
				if (mac->opmode == NL80211_IFTYPE_ADHOC) {
					rtl_cam_add_one_entry(hw,
						rtlefuse->dev_addr,
						PAIRWISE_KEYIDX,
						CAM_PAIRWISE_KEY_POSITION,
						enc_algo,
						CAM_CONFIG_NO_USEDK,
						rtlpriv->sec.key_buf
						[entry_id]);
				}
				rtl_cam_add_one_entry(hw, macaddr, key_index,
						entry_id, enc_algo,
						CAM_CONFIG_NO_USEDK,
						rtlpriv->sec.key_buf[entry_id]);
			}
		}
	}
}
예제 #22
0
void rtl8723be_phy_rf6052_set_cck_txpower( struct ieee80211_hw *hw,
					  u8 *ppowerlevel )
{
	struct rtl_priv *rtlpriv = rtl_priv( hw );
	struct rtl_phy *rtlphy = &( rtlpriv->phy );
	struct rtl_mac *mac = rtl_mac( rtl_priv( hw ) );
	struct rtl_efuse *rtlefuse = rtl_efuse( rtl_priv( hw ) );
	u32 tx_agc[2] = {0, 0}, tmpval;
	bool turbo_scanoff = false;
	u8 idx1, idx2;
	u8 *ptr;
	u8 direction;
	u32 pwrtrac_value;

	if ( rtlefuse->eeprom_regulatory != 0 )
		turbo_scanoff = true;

	if ( mac->act_scanning ) {
		tx_agc[RF90_PATH_A] = 0x3f3f3f3f;
		tx_agc[RF90_PATH_B] = 0x3f3f3f3f;

		if ( turbo_scanoff ) {
			for ( idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++ ) {
				tx_agc[idx1] = ppowerlevel[idx1] |
					       ( ppowerlevel[idx1] << 8 ) |
					       ( ppowerlevel[idx1] << 16 ) |
					       ( ppowerlevel[idx1] << 24 );
			}
		}
	} else {
		for ( idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++ ) {
			tx_agc[idx1] = ppowerlevel[idx1] |
				       ( ppowerlevel[idx1] << 8 ) |
				       ( ppowerlevel[idx1] << 16 ) |
				       ( ppowerlevel[idx1] << 24 );
		}

		if ( rtlefuse->eeprom_regulatory == 0 ) {
			tmpval =
			    ( rtlphy->mcs_txpwrlevel_origoffset[0][6] ) +
			    ( rtlphy->mcs_txpwrlevel_origoffset[0][7] << 8 );
			tx_agc[RF90_PATH_A] += tmpval;

			tmpval = ( rtlphy->mcs_txpwrlevel_origoffset[0][14] ) +
				 ( rtlphy->mcs_txpwrlevel_origoffset[0][15] <<
				  24 );
			tx_agc[RF90_PATH_B] += tmpval;
		}
	}

	for ( idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++ ) {
		ptr = ( u8 * )( &( tx_agc[idx1] ) );
		for ( idx2 = 0; idx2 < 4; idx2++ ) {
			if ( *ptr > RF6052_MAX_TX_PWR )
				*ptr = RF6052_MAX_TX_PWR;
			ptr++;
		}
	}
	rtl8723be_dm_txpower_track_adjust( hw, 1, &direction, &pwrtrac_value );
	if ( direction == 1 ) {
		tx_agc[0] += pwrtrac_value;
		tx_agc[1] += pwrtrac_value;
	} else if ( direction == 2 ) {
		tx_agc[0] -= pwrtrac_value;
		tx_agc[1] -= pwrtrac_value;
	}
	tmpval = tx_agc[RF90_PATH_A] & 0xff;
	rtl_set_bbreg( hw, RTXAGC_A_CCK1_MCS32, MASKBYTE1, tmpval );

	RTPRINT( rtlpriv, FPHY, PHY_TXPWR,
		"CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n", tmpval,
		 RTXAGC_A_CCK1_MCS32 );

	tmpval = tx_agc[RF90_PATH_A] >> 8;

	/*tmpval = tmpval & 0xff00ffff;*/

	rtl_set_bbreg( hw, RTXAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval );

	RTPRINT( rtlpriv, FPHY, PHY_TXPWR,
		"CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n", tmpval,
		 RTXAGC_B_CCK11_A_CCK2_11 );

	tmpval = tx_agc[RF90_PATH_B] >> 24;
	rtl_set_bbreg( hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE0, tmpval );

	RTPRINT( rtlpriv, FPHY, PHY_TXPWR,
		"CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", tmpval,
		 RTXAGC_B_CCK11_A_CCK2_11 );

	tmpval = tx_agc[RF90_PATH_B] & 0x00ffffff;
	rtl_set_bbreg( hw, RTXAGC_B_CCK1_55_MCS32, 0xffffff00, tmpval );

	RTPRINT( rtlpriv, FPHY, PHY_TXPWR,
		"CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n", tmpval,
		 RTXAGC_B_CCK1_55_MCS32 );
}
예제 #23
0
static bool rtl_phydm_query_phy_status(struct rtl_priv *rtlpriv, u8 *phystrpt,
				       struct ieee80211_hdr *hdr,
				       struct rtl_stats *pstatus)
{
	/* NOTE: phystrpt may be NULL, and need to fill default value */

	struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv);
	struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv);
	struct rtl_mac *mac = rtl_mac(rtlpriv);
	struct dm_per_pkt_info pktinfo; /* input of pydm */
	struct dm_phy_status_info phy_info; /* output of phydm */
	__le16 fc = hdr->frame_control;

	/* fill driver pstatus */
	ether_addr_copy(pstatus->psaddr, ieee80211_get_SA(hdr));

	/* fill pktinfo */
	memset(&pktinfo, 0, sizeof(pktinfo));

	pktinfo.data_rate = pstatus->rate;

	if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_STATION) {
		pktinfo.station_id = 0;
	} else {
		/* TODO: use rtl_find_sta() to find ID */
		pktinfo.station_id = 0xFF;
	}

	pktinfo.is_packet_match_bssid =
		(!ieee80211_is_ctl(fc) &&
		 (ether_addr_equal(mac->bssid,
				   ieee80211_has_tods(fc) ?
					   hdr->addr1 :
					   ieee80211_has_fromds(fc) ?
					   hdr->addr2 :
					   hdr->addr3)) &&
		 (!pstatus->hwerror) && (!pstatus->crc) && (!pstatus->icv));
	pktinfo.is_packet_to_self =
		pktinfo.is_packet_match_bssid &&
		(ether_addr_equal(hdr->addr1, rtlefuse->dev_addr));
	pktinfo.is_to_self = (!pstatus->icv) && (!pstatus->crc) &&
			     (ether_addr_equal(hdr->addr1, rtlefuse->dev_addr));
	pktinfo.is_packet_beacon = (ieee80211_is_beacon(fc) ? true : false);

	/* query phy status */
	if (phystrpt)
		odm_phy_status_query(dm, &phy_info, phystrpt, &pktinfo);
	else
		memset(&phy_info, 0, sizeof(phy_info));

	/* copy phy_info from phydm to driver */
	pstatus->rx_pwdb_all = phy_info.rx_pwdb_all;
	pstatus->bt_rx_rssi_percentage = phy_info.bt_rx_rssi_percentage;
	pstatus->recvsignalpower = phy_info.recv_signal_power;
	pstatus->signalquality = phy_info.signal_quality;
	pstatus->rx_mimo_signalquality[0] = phy_info.rx_mimo_signal_quality[0];
	pstatus->rx_mimo_signalquality[1] = phy_info.rx_mimo_signal_quality[1];
	pstatus->rx_packet_bw =
		phy_info.band_width; /* HT_CHANNEL_WIDTH_20 <- ODM_BW20M */

	/* fill driver pstatus */
	pstatus->packet_matchbssid = pktinfo.is_packet_match_bssid;
	pstatus->packet_toself = pktinfo.is_packet_to_self;
	pstatus->packet_beacon = pktinfo.is_packet_beacon;

	return true;
}
예제 #24
0
파일: rf.c 프로젝트: paralin/rtl8821au-1
void rtl8821au_phy_rf6052_set_cck_txpower(struct rtl_priv *rtlpriv, uint8_t *pPowerlevel)
{
	struct rtl_phy *rtlphy = &(rtlpriv->phy);
	struct rtl_efuse *efuse = rtl_efuse(rtlpriv);
	struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
	struct mlme_ext_priv 	*pmlmeext = &rtlpriv->mlmeextpriv;
	uint32_t		TxAGC[2] = {0, 0},
				tmpval = 0;
	BOOLEAN	TurboScanOff = _FALSE;
	uint8_t	idx1, idx2;
	uint8_t *ptr;

	/* FOR CE ,must disable turbo scan */
	TurboScanOff = _TRUE;

	if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) {
		TxAGC[RF90_PATH_A] = 0x3f3f3f3f;
		TxAGC[RF90_PATH_B] = 0x3f3f3f3f;

		TurboScanOff = _TRUE;	/* disable turbo scan */

		if (TurboScanOff) {
			for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
				TxAGC[idx1] =
					pPowerlevel[idx1] | (pPowerlevel[idx1]<<8) |
					(pPowerlevel[idx1]<<16) | (pPowerlevel[idx1]<<24);
				/* 2010/10/18 MH For external PA module. We need to limit power index to be less than 0x20. */
				if (TxAGC[idx1] > 0x20 && rtlhal->external_pa_5g)
					TxAGC[idx1] = 0x20;
			}
		}
	} else {
/*
 * 20100427 Joseph: Driver dynamic Tx power shall not affect Tx power. It shall be determined by power training mechanism.
 * Currently, we cannot fully disable driver dynamic tx power mechanism because it is referenced by BT coexist mechanism.
 * In the future, two mechanism shall be separated from each other and maintained independantly. Thanks for Lanhsin's reminder.
 */
		if (rtlpriv->dm.dynamic_txhighpower_lvl == TxHighPwrLevel_Level1) {
			TxAGC[RF90_PATH_A] = 0x10101010;
			TxAGC[RF90_PATH_B] = 0x10101010;
		} else if (rtlpriv->dm.dynamic_txhighpower_lvl == TxHighPwrLevel_Level2) {
			TxAGC[RF90_PATH_A] = 0x00000000;
			TxAGC[RF90_PATH_B] = 0x00000000;
		} else {
			for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
				TxAGC[idx1] =
					pPowerlevel[idx1] | (pPowerlevel[idx1]<<8) |
					(pPowerlevel[idx1]<<16) | (pPowerlevel[idx1]<<24);
			}

			if (efuse->eeprom_regulatory == 0) {
				tmpval = (rtlphy->mcs_txpwrlevel_origoffset[0][6]) +
						(rtlphy->mcs_txpwrlevel_origoffset[0][7]<<8);
				TxAGC[RF90_PATH_A] += tmpval;

				tmpval = (rtlphy->mcs_txpwrlevel_origoffset[0][14]) +
						(rtlphy->mcs_txpwrlevel_origoffset[0][15]<<24);
				TxAGC[RF90_PATH_B] += tmpval;
			}
		}
	}

	for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
		ptr = (uint8_t *)(&(TxAGC[idx1]));
		for (idx2 = 0; idx2 < 4; idx2++) {
			if (*ptr > RF6052_MAX_TX_PWR)
				*ptr = RF6052_MAX_TX_PWR;
			ptr++;
		}
	}

	/* rf-A cck tx power */
	tmpval = TxAGC[RF90_PATH_A]&0xff;
	rtl_set_bbreg(rtlpriv, RTXAGC_A_CCK11_CCK1, MASKBYTE1, tmpval);
	/* RT_DISP(FPHY, PHY_TXPWR, ("CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n", tmpval, rTxAGC_A_CCK1_Mcs32)); */
	tmpval = TxAGC[RF90_PATH_A]>>8;
	rtl_set_bbreg(rtlpriv, RTXAGC_A_CCK11_CCK1, 0xffffff00, tmpval);
	/* RT_DISP(FPHY, PHY_TXPWR, ("CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n", tmpval, rTxAGC_B_CCK11_A_CCK2_11)); */

	/* rf-B cck tx power */
	tmpval = TxAGC[RF90_PATH_B]>>24;
	rtl_set_bbreg(rtlpriv, RTXAGC_B_CCK11_CCK1, MASKBYTE0, tmpval);
	/* RT_DISP(FPHY, PHY_TXPWR, ("CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", tmpval, rTxAGC_B_CCK11_A_CCK2_11)); */
	tmpval = TxAGC[RF90_PATH_B]&0x00ffffff;
	rtl_set_bbreg(rtlpriv, RTXAGC_B_CCK11_CCK1, 0xffffff00, tmpval);
	/* RT_DISP(FPHY, PHY_TXPWR, ("CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n", tmpval, rTxAGC_B_CCK1_55_Mcs32)); */

}	/* PHY_RF6052SetCckTxPower */