diff options
Diffstat (limited to 'drivers/net/wireless/realtek/rtlwifi/base.c')
-rw-r--r-- | drivers/net/wireless/realtek/rtlwifi/base.c | 164 |
1 files changed, 137 insertions, 27 deletions
diff --git a/drivers/net/wireless/realtek/rtlwifi/base.c b/drivers/net/wireless/realtek/rtlwifi/base.c index cad2272ae21b..d6c03bd5cc65 100644 --- a/drivers/net/wireless/realtek/rtlwifi/base.c +++ b/drivers/net/wireless/realtek/rtlwifi/base.c @@ -244,7 +244,8 @@ static void _rtl_init_hw_vht_capab(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_hal *rtlhal = rtl_hal(rtlpriv); - if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) { + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE || + rtlhal->hw_type == HARDWARE_TYPE_RTL8822BE) { u16 mcs_map; vht_cap->vht_supported = true; @@ -395,6 +396,7 @@ static void _rtl_init_mac80211(struct ieee80211_hw *hw) ieee80211_hw_set(hw, CONNECTION_MONITOR); ieee80211_hw_set(hw, MFP_CAPABLE); ieee80211_hw_set(hw, REPORTS_TX_ACK_STATUS); + ieee80211_hw_set(hw, SUPPORTS_AMSDU_IN_AMPDU); /* swlps or hwlps has been set in diff chip in init_sw_vars */ if (rtlpriv->psc.swctrl_lps) { @@ -551,7 +553,8 @@ int rtl_init_core(struct ieee80211_hw *hw) /* <4> locks */ mutex_init(&rtlpriv->locks.conf_mutex); - spin_lock_init(&rtlpriv->locks.ips_lock); + mutex_init(&rtlpriv->locks.ips_mutex); + mutex_init(&rtlpriv->locks.lps_mutex); spin_lock_init(&rtlpriv->locks.irq_th_lock); spin_lock_init(&rtlpriv->locks.h2c_lock); spin_lock_init(&rtlpriv->locks.rf_ps_lock); @@ -561,9 +564,7 @@ int rtl_init_core(struct ieee80211_hw *hw) spin_lock_init(&rtlpriv->locks.c2hcmd_lock); spin_lock_init(&rtlpriv->locks.scan_list_lock); spin_lock_init(&rtlpriv->locks.cck_and_rw_pagea_lock); - spin_lock_init(&rtlpriv->locks.check_sendpkt_lock); spin_lock_init(&rtlpriv->locks.fw_ps_lock); - spin_lock_init(&rtlpriv->locks.lps_lock); spin_lock_init(&rtlpriv->locks.iqk_lock); /* <5> init list */ INIT_LIST_HEAD(&rtlpriv->entry_list); @@ -697,14 +698,94 @@ static void _rtl_query_protection_mode(struct ieee80211_hw *hw, } } +u8 rtl_mrate_idx_to_arfr_id(struct ieee80211_hw *hw, u8 rate_index, + enum wireless_mode wirelessmode) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 ret = 0; + + switch (rate_index) { + case RATR_INX_WIRELESS_NGB: + if (rtlphy->rf_type == RF_1T1R) + ret = RATEID_IDX_BGN_40M_1SS; + else + ret = RATEID_IDX_BGN_40M_2SS; + ; break; + case RATR_INX_WIRELESS_N: + case RATR_INX_WIRELESS_NG: + if (rtlphy->rf_type == RF_1T1R) + ret = RATEID_IDX_GN_N1SS; + else + ret = RATEID_IDX_GN_N2SS; + ; break; + case RATR_INX_WIRELESS_NB: + if (rtlphy->rf_type == RF_1T1R) + ret = RATEID_IDX_BGN_20M_1SS_BN; + else + ret = RATEID_IDX_BGN_20M_2SS_BN; + ; break; + case RATR_INX_WIRELESS_GB: + ret = RATEID_IDX_BG; + break; + case RATR_INX_WIRELESS_G: + ret = RATEID_IDX_G; + break; + case RATR_INX_WIRELESS_B: + ret = RATEID_IDX_B; + break; + case RATR_INX_WIRELESS_MC: + if (wirelessmode == WIRELESS_MODE_B || + wirelessmode == WIRELESS_MODE_G || + wirelessmode == WIRELESS_MODE_N_24G || + wirelessmode == WIRELESS_MODE_AC_24G) + ret = RATEID_IDX_BG; + else + ret = RATEID_IDX_G; + break; + case RATR_INX_WIRELESS_AC_5N: + if (rtlphy->rf_type == RF_1T1R) + ret = RATEID_IDX_VHT_1SS; + else + ret = RATEID_IDX_VHT_2SS; + break; + case RATR_INX_WIRELESS_AC_24N: + if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80) { + if (rtlphy->rf_type == RF_1T1R) + ret = RATEID_IDX_VHT_1SS; + else + ret = RATEID_IDX_VHT_2SS; + } else { + if (rtlphy->rf_type == RF_1T1R) + ret = RATEID_IDX_MIX1; + else + ret = RATEID_IDX_MIX2; + } + break; + default: + ret = RATEID_IDX_BGN_40M_2SS; + break; + } + return ret; +} +EXPORT_SYMBOL(rtl_mrate_idx_to_arfr_id); + static void _rtl_txrate_selectmode(struct ieee80211_hw *hw, struct ieee80211_sta *sta, struct rtl_tcb_desc *tcb_desc) { +#define SET_RATE_ID(rate_id) \ + ({typeof(rate_id) _id = rate_id; \ + ((rtlpriv->cfg->spec_ver & RTL_SPEC_NEW_RATEID) ? \ + rtl_mrate_idx_to_arfr_id(hw, _id, \ + (sta_entry ? sta_entry->wireless_mode : \ + WIRELESS_MODE_G)) : \ + _id); }) + struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); struct rtl_sta_info *sta_entry = NULL; - u8 ratr_index = 7; + u8 ratr_index = SET_RATE_ID(RATR_INX_WIRELESS_MC); if (sta) { sta_entry = (struct rtl_sta_info *) sta->drv_priv; @@ -719,7 +800,8 @@ static void _rtl_txrate_selectmode(struct ieee80211_hw *hw, tcb_desc->hw_rate = rtlpriv->cfg->maps[RTL_RC_CCK_RATE2M]; tcb_desc->use_driver_rate = 1; - tcb_desc->ratr_index = RATR_INX_WIRELESS_MC; + tcb_desc->ratr_index = + SET_RATE_ID(RATR_INX_WIRELESS_MC); } else { tcb_desc->ratr_index = ratr_index; } @@ -735,22 +817,30 @@ static void _rtl_txrate_selectmode(struct ieee80211_hw *hw, mac->opmode == NL80211_IFTYPE_MESH_POINT) { tcb_desc->mac_id = 0; - if (mac->mode == WIRELESS_MODE_AC_5G) + if (sta && + (rtlpriv->cfg->spec_ver & RTL_SPEC_NEW_RATEID)) + ; /* use sta_entry->ratr_index */ + else if (mac->mode == WIRELESS_MODE_AC_5G) tcb_desc->ratr_index = - RATR_INX_WIRELESS_AC_5N; + SET_RATE_ID(RATR_INX_WIRELESS_AC_5N); else if (mac->mode == WIRELESS_MODE_AC_24G) tcb_desc->ratr_index = - RATR_INX_WIRELESS_AC_24N; + SET_RATE_ID(RATR_INX_WIRELESS_AC_24N); else if (mac->mode == WIRELESS_MODE_N_24G) - tcb_desc->ratr_index = RATR_INX_WIRELESS_NGB; + tcb_desc->ratr_index = + SET_RATE_ID(RATR_INX_WIRELESS_NGB); else if (mac->mode == WIRELESS_MODE_N_5G) - tcb_desc->ratr_index = RATR_INX_WIRELESS_NG; + tcb_desc->ratr_index = + SET_RATE_ID(RATR_INX_WIRELESS_NG); else if (mac->mode & WIRELESS_MODE_G) - tcb_desc->ratr_index = RATR_INX_WIRELESS_GB; + tcb_desc->ratr_index = + SET_RATE_ID(RATR_INX_WIRELESS_GB); else if (mac->mode & WIRELESS_MODE_B) - tcb_desc->ratr_index = RATR_INX_WIRELESS_B; + tcb_desc->ratr_index = + SET_RATE_ID(RATR_INX_WIRELESS_B); else if (mac->mode & WIRELESS_MODE_A) - tcb_desc->ratr_index = RATR_INX_WIRELESS_G; + tcb_desc->ratr_index = + SET_RATE_ID(RATR_INX_WIRELESS_G); } else if (mac->opmode == NL80211_IFTYPE_AP || mac->opmode == NL80211_IFTYPE_ADHOC) { @@ -764,6 +854,7 @@ static void _rtl_txrate_selectmode(struct ieee80211_hw *hw, } } } +#undef SET_RATE_ID } static void _rtl_query_bandwidth_mode(struct ieee80211_hw *hw, @@ -859,8 +950,8 @@ static u8 _rtl_get_highest_n_rate(struct ieee80211_hw *hw, struct rtl_phy *rtlphy = &rtlpriv->phy; u8 hw_rate; - if ((get_rf_type(rtlphy) == RF_2T2R) && - (sta->ht_cap.mcs.rx_mask[1] != 0)) + if (get_rf_type(rtlphy) == RF_2T2R && + sta->ht_cap.mcs.rx_mask[1] != 0) hw_rate = rtlpriv->cfg->maps[RTL_RC_HT_RATEMCS15]; else hw_rate = rtlpriv->cfg->maps[RTL_RC_HT_RATEMCS7]; @@ -1140,9 +1231,19 @@ void rtl_get_tcb_desc(struct ieee80211_hw *hw, struct ieee80211_sta *sta, struct sk_buff *skb, struct rtl_tcb_desc *tcb_desc) { +#define SET_RATE_ID(rate_id) \ + ({typeof(rate_id) _id = rate_id; \ + ((rtlpriv->cfg->spec_ver & RTL_SPEC_NEW_RATEID) ? \ + rtl_mrate_idx_to_arfr_id(hw, _id, \ + (sta_entry ? sta_entry->wireless_mode : \ + WIRELESS_MODE_G)) : \ + _id); }) + struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw)); struct ieee80211_hdr *hdr = rtl_get_hdr(skb); + struct rtl_sta_info *sta_entry = + (sta ? (struct rtl_sta_info *)sta->drv_priv : NULL); __le16 fc = rtl_get_fc(skb); @@ -1165,7 +1266,8 @@ void rtl_get_tcb_desc(struct ieee80211_hw *hw, if (info->control.rates[0].idx == 0 || ieee80211_is_nullfunc(fc)) { tcb_desc->use_driver_rate = true; - tcb_desc->ratr_index = RATR_INX_WIRELESS_MC; + tcb_desc->ratr_index = + SET_RATE_ID(RATR_INX_WIRELESS_MC); tcb_desc->disable_ratefallback = 1; } else { @@ -1180,7 +1282,7 @@ void rtl_get_tcb_desc(struct ieee80211_hw *hw, tcb_desc->hw_rate = _rtl_get_vht_highest_n_rate(hw, sta); } else { - if (sta && (sta->ht_cap.ht_supported)) { + if (sta && sta->ht_cap.ht_supported) { tcb_desc->hw_rate = _rtl_get_highest_n_rate(hw, sta); } else { @@ -1207,11 +1309,12 @@ void rtl_get_tcb_desc(struct ieee80211_hw *hw, _rtl_query_protection_mode(hw, tcb_desc, info); } else { tcb_desc->use_driver_rate = true; - tcb_desc->ratr_index = RATR_INX_WIRELESS_MC; + tcb_desc->ratr_index = SET_RATE_ID(RATR_INX_WIRELESS_MC); tcb_desc->disable_ratefallback = 1; tcb_desc->mac_id = 0; tcb_desc->packet_bw = false; } +#undef SET_RATE_ID } EXPORT_SYMBOL(rtl_get_tcb_desc); @@ -1229,7 +1332,6 @@ bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb) } if (ieee80211_is_auth(fc)) { RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "MAC80211_LINKING\n"); - rtl_ips_nic_on(hw); mac->link_state = MAC80211_LINKING; /* Dul mac */ @@ -1321,6 +1423,10 @@ bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) le16_to_cpu(mgmt->u.action.u.addba_req.capab); tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2; + if (tid >= MAX_TID_COUNT) { + rcu_read_unlock(); + return true; + } tid_data = &sta_entry->tids[tid]; if (tid_data->agg.rx_agg_state == RTL_RX_AGG_START) @@ -1726,7 +1832,7 @@ int rtl_tx_agg_oper(struct ieee80211_hw *hw, void rtl_rx_ampdu_apply(struct rtl_priv *rtlpriv) { struct rtl_btc_ops *btc_ops = rtlpriv->btcoexist.btc_ops; - u8 reject_agg, ctrl_agg_size = 0, agg_size; + u8 reject_agg = 0, ctrl_agg_size = 0, agg_size = 0; if (rtlpriv->cfg->ops->get_btc_status()) btc_ops->btc_get_ampdu_cfg(rtlpriv, &reject_agg, @@ -1972,9 +2078,9 @@ void rtl_watchdog_wq_callback(void *data) rtlpriv->btcoexist.btc_ops->btc_is_bt_ctrl_lps(rtlpriv)) goto label_lps_done; - if (((rtlpriv->link_info.num_rx_inperiod + - rtlpriv->link_info.num_tx_inperiod) > 8) || - (rtlpriv->link_info.num_rx_inperiod > 2)) + if (rtlpriv->link_info.num_rx_inperiod + + rtlpriv->link_info.num_tx_inperiod > 8 || + rtlpriv->link_info.num_rx_inperiod > 2) rtl_lps_leave(hw); else rtl_lps_enter(hw); @@ -2225,9 +2331,7 @@ static struct sk_buff *rtl_make_smps_action(struct ieee80211_hw *hw, case IEEE80211_SMPS_AUTOMATIC:/* 0 */ case IEEE80211_SMPS_NUM_MODES:/* 4 */ WARN_ON(1); - /* Here will get a 'MISSING_BREAK' in Coverity Test, just ignore it. - * According to Kernel Code, here is right. - */ + /* fall through */ case IEEE80211_SMPS_OFF:/* 1 */ /*MIMO_PS_NOLIMIT*/ action_frame->u.action.u.ht_smps.smps_control = WLAN_HT_SMPS_CONTROL_DISABLED;/* 0 */ @@ -2528,6 +2632,9 @@ static int __init rtl_core_module_init(void) if (rtl_rate_control_register()) pr_err("rtl: Unable to register rtl_rc, use default RC !!\n"); + /* add debugfs */ + rtl_debugfs_add_topdir(); + /* init some global vars */ INIT_LIST_HEAD(&rtl_global_var.glb_priv_list); spin_lock_init(&rtl_global_var.glb_list_lock); @@ -2539,6 +2646,9 @@ static void __exit rtl_core_module_exit(void) { /*RC*/ rtl_rate_control_unregister(); + + /* remove debugfs */ + rtl_debugfs_remove_topdir(); } module_init(rtl_core_module_init); |