summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/realtek/rtlwifi/base.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/realtek/rtlwifi/base.c')
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/base.c164
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);