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