diff options
Diffstat (limited to 'drivers/net/wireless/realtek/rtlwifi/base.c')
-rw-r--r-- | drivers/net/wireless/realtek/rtlwifi/base.c | 132 |
1 files changed, 105 insertions, 27 deletions
diff --git a/drivers/net/wireless/realtek/rtlwifi/base.c b/drivers/net/wireless/realtek/rtlwifi/base.c index ea18aa7afecb..cad2272ae21b 100644 --- a/drivers/net/wireless/realtek/rtlwifi/base.c +++ b/drivers/net/wireless/realtek/rtlwifi/base.c @@ -249,8 +249,6 @@ static void _rtl_init_hw_vht_capab(struct ieee80211_hw *hw, vht_cap->vht_supported = true; vht_cap->cap = - IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895 | - IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991 | IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 | IEEE80211_VHT_CAP_SHORT_GI_80 | IEEE80211_VHT_CAP_TXSTBC | @@ -283,8 +281,6 @@ static void _rtl_init_hw_vht_capab(struct ieee80211_hw *hw, vht_cap->vht_supported = true; vht_cap->cap = - IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895 | - IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991 | IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 | IEEE80211_VHT_CAP_SHORT_GI_80 | IEEE80211_VHT_CAP_TXSTBC | @@ -461,10 +457,10 @@ static void _rtl_init_deferred_work(struct ieee80211_hw *hw) struct rtl_priv *rtlpriv = rtl_priv(hw); /* <1> timer */ - setup_timer(&rtlpriv->works.watchdog_timer, - rtl_watch_dog_timer_callback, (unsigned long)hw); - setup_timer(&rtlpriv->works.dualmac_easyconcurrent_retrytimer, - rtl_easy_concurrent_retrytimer_callback, (unsigned long)hw); + timer_setup(&rtlpriv->works.watchdog_timer, + rtl_watch_dog_timer_callback, 0); + timer_setup(&rtlpriv->works.dualmac_easyconcurrent_retrytimer, + rtl_easy_concurrent_retrytimer_callback, 0); /* <2> work queue */ rtlpriv->works.hw = hw; rtlpriv->works.rtl_wq = alloc_workqueue("%s", 0, 0, rtlpriv->cfg->name); @@ -835,7 +831,7 @@ static u8 _rtl_get_vht_highest_n_rate(struct ieee80211_hw *hw, else if ((tx_mcs_map & 0x000c) >> 2 == IEEE80211_VHT_MCS_SUPPORT_0_8) hw_rate = - rtlpriv->cfg->maps[RTL_RC_VHT_RATE_2SS_MCS9]; + rtlpriv->cfg->maps[RTL_RC_VHT_RATE_2SS_MCS8]; else hw_rate = rtlpriv->cfg->maps[RTL_RC_VHT_RATE_2SS_MCS9]; @@ -847,7 +843,7 @@ static u8 _rtl_get_vht_highest_n_rate(struct ieee80211_hw *hw, else if ((tx_mcs_map & 0x0003) == IEEE80211_VHT_MCS_SUPPORT_0_8) hw_rate = - rtlpriv->cfg->maps[RTL_RC_VHT_RATE_1SS_MCS9]; + rtlpriv->cfg->maps[RTL_RC_VHT_RATE_1SS_MCS8]; else hw_rate = rtlpriv->cfg->maps[RTL_RC_VHT_RATE_1SS_MCS9]; @@ -1103,6 +1099,42 @@ int rtlwifi_rate_mapping(struct ieee80211_hw *hw, bool isht, bool isvht, } EXPORT_SYMBOL(rtlwifi_rate_mapping); +static u8 _rtl_get_tx_hw_rate(struct ieee80211_hw *hw, + struct ieee80211_tx_info *info) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct ieee80211_tx_rate *r = &info->status.rates[0]; + struct ieee80211_rate *txrate; + u8 hw_value = 0x0; + + if (r->flags & IEEE80211_TX_RC_MCS) { + /* HT MCS0-15 */ + hw_value = rtlpriv->cfg->maps[RTL_RC_HT_RATEMCS15] - 15 + + r->idx; + } else if (r->flags & IEEE80211_TX_RC_VHT_MCS) { + /* VHT MCS0-9, NSS */ + if (ieee80211_rate_get_vht_nss(r) == 2) + hw_value = rtlpriv->cfg->maps[RTL_RC_VHT_RATE_2SS_MCS9]; + else + hw_value = rtlpriv->cfg->maps[RTL_RC_VHT_RATE_1SS_MCS9]; + + hw_value = hw_value - 9 + ieee80211_rate_get_vht_mcs(r); + } else { + /* legacy */ + txrate = ieee80211_get_tx_rate(hw, info); + + if (txrate) + hw_value = txrate->hw_value; + } + + /* check 5G band */ + if (rtlpriv->rtlhal.current_bandtype == BAND_ON_5G && + hw_value < rtlpriv->cfg->maps[RTL_RC_OFDM_RATE6M]) + hw_value = rtlpriv->cfg->maps[RTL_RC_OFDM_RATE6M]; + + return hw_value; +} + void rtl_get_tcb_desc(struct ieee80211_hw *hw, struct ieee80211_tx_info *info, struct ieee80211_sta *sta, @@ -1111,12 +1143,10 @@ void rtl_get_tcb_desc(struct ieee80211_hw *hw, 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 ieee80211_rate *txrate; + __le16 fc = rtl_get_fc(skb); - txrate = ieee80211_get_tx_rate(hw, info); - if (txrate) - tcb_desc->hw_rate = txrate->hw_value; + tcb_desc->hw_rate = _rtl_get_tx_hw_rate(hw, info); if (rtl_is_tx_report_skb(hw, skb)) tcb_desc->use_spe_rpt = 1; @@ -1527,6 +1557,42 @@ void rtl_wait_tx_report_acked(struct ieee80211_hw *hw, u32 wait_ms) "Wait 1ms (%d/%d) to disable key.\n", i, wait_ms); } } + +u32 rtl_get_hal_edca_param(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + enum wireless_mode wirelessmode, + struct ieee80211_tx_queue_params *param) +{ + u32 reg = 0; + u8 sifstime = 10; + u8 slottime = 20; + + /* AIFS = AIFSN * slot time + SIFS */ + switch (wirelessmode) { + case WIRELESS_MODE_A: + case WIRELESS_MODE_N_24G: + case WIRELESS_MODE_N_5G: + case WIRELESS_MODE_AC_5G: + case WIRELESS_MODE_AC_24G: + sifstime = 16; + slottime = 9; + break; + case WIRELESS_MODE_G: + slottime = (vif->bss_conf.use_short_slot ? 9 : 20); + break; + default: + break; + } + + reg |= (param->txop & 0x7FF) << 16; + reg |= (fls(param->cw_max) & 0xF) << 12; + reg |= (fls(param->cw_min) & 0xF) << 8; + reg |= (param->aifs & 0x0F) * slottime + sifstime; + + return reg; +} +EXPORT_SYMBOL_GPL(rtl_get_hal_edca_param); + /********************************************************* * * functions called by core.c @@ -1552,9 +1618,8 @@ int rtl_tx_agg_start(struct ieee80211_hw *hw, struct ieee80211_vif *vif, RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "on ra = %pM tid = %d seq:%d\n", sta->addr, tid, - tid_data->seq_number); + *ssn); - *ssn = tid_data->seq_number; tid_data->agg.agg_state = RTL_AGG_START; ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); @@ -1565,7 +1630,6 @@ int rtl_tx_agg_stop(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta, u16 tid) { struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_tid_data *tid_data; struct rtl_sta_info *sta_entry = NULL; if (sta == NULL) @@ -1578,7 +1642,6 @@ int rtl_tx_agg_stop(struct ieee80211_hw *hw, struct ieee80211_vif *vif, return -EINVAL; sta_entry = (struct rtl_sta_info *)sta->drv_priv; - tid_data = &sta_entry->tids[tid]; sta_entry->tids[tid].agg.agg_state = RTL_AGG_STOP; ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); @@ -1613,8 +1676,7 @@ int rtl_rx_agg_start(struct ieee80211_hw *hw, tid_data = &sta_entry->tids[tid]; RT_TRACE(rtlpriv, COMP_RECV, DBG_DMESG, - "on ra = %pM tid = %d seq:%d\n", sta->addr, tid, - tid_data->seq_number); + "on ra = %pM tid = %d\n", sta->addr, tid); tid_data->agg.rx_agg_state = RTL_RX_AGG_START; return 0; @@ -1932,6 +1994,22 @@ label_lps_done: rtlpriv->link_info.tx_busy_traffic = tx_busy_traffic; rtlpriv->link_info.higher_busyrxtraffic = higher_busyrxtraffic; + rtlpriv->stats.txbytesunicast_inperiod = + rtlpriv->stats.txbytesunicast - + rtlpriv->stats.txbytesunicast_last; + rtlpriv->stats.rxbytesunicast_inperiod = + rtlpriv->stats.rxbytesunicast - + rtlpriv->stats.rxbytesunicast_last; + rtlpriv->stats.txbytesunicast_last = rtlpriv->stats.txbytesunicast; + rtlpriv->stats.rxbytesunicast_last = rtlpriv->stats.rxbytesunicast; + + rtlpriv->stats.txbytesunicast_inperiod_tp = + (u32)(rtlpriv->stats.txbytesunicast_inperiod * 8 / 2 / + 1024 / 1024); + rtlpriv->stats.rxbytesunicast_inperiod_tp = + (u32)(rtlpriv->stats.rxbytesunicast_inperiod * 8 / 2 / + 1024 / 1024); + /* <3> DM */ if (!rtlpriv->cfg->mod_params->disable_watchdog) rtlpriv->cfg->ops->dm_watchdog(hw); @@ -1975,10 +2053,9 @@ label_lps_done: rtl_scan_list_expire(hw); } -void rtl_watch_dog_timer_callback(unsigned long data) +void rtl_watch_dog_timer_callback(struct timer_list *t) { - struct ieee80211_hw *hw = (struct ieee80211_hw *)data; - struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_priv *rtlpriv = from_timer(rtlpriv, t, works.watchdog_timer); queue_delayed_work(rtlpriv->works.rtl_wq, &rtlpriv->works.watchdog_wq, 0); @@ -2084,10 +2161,11 @@ void rtl_c2hcmd_wq_callback(void *data) rtl_c2hcmd_launcher(hw, 1); } -void rtl_easy_concurrent_retrytimer_callback(unsigned long data) +void rtl_easy_concurrent_retrytimer_callback(struct timer_list *t) { - struct ieee80211_hw *hw = (struct ieee80211_hw *)data; - struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_priv *rtlpriv = + from_timer(rtlpriv, t, works.dualmac_easyconcurrent_retrytimer); + struct ieee80211_hw *hw = rtlpriv->hw; struct rtl_priv *buddy_priv = rtlpriv->buddy_priv; if (buddy_priv == NULL) @@ -2204,7 +2282,7 @@ int rtl_send_smps_action(struct ieee80211_hw *hw, struct rtl_sta_info *sta_entry = (struct rtl_sta_info *) sta->drv_priv; sta_entry->mimo_ps = smps; - /* rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0); */ + /* rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0, true); */ info->control.rates[0].idx = 0; info->band = hw->conf.chandef.chan->band; |