From patchwork Thu May 16 09:52:56 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Berg X-Patchwork-Id: 10946241 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A4E4314DB for ; Thu, 16 May 2019 09:53:11 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 920902838F for ; Thu, 16 May 2019 09:53:11 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 862FD284E9; Thu, 16 May 2019 09:53:11 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8F67A2838F for ; Thu, 16 May 2019 09:53:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727160AbfEPJxJ (ORCPT ); Thu, 16 May 2019 05:53:09 -0400 Received: from s3.sipsolutions.net ([144.76.43.62]:39762 "EHLO sipsolutions.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727147AbfEPJxI (ORCPT ); Thu, 16 May 2019 05:53:08 -0400 Received: by sipsolutions.net with esmtpsa (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1hRD4S-0007MT-MC; Thu, 16 May 2019 11:53:04 +0200 From: Johannes Berg To: linux-wireless@vger.kernel.org Cc: Johannes Berg Subject: [PATCH 1/2] mac80211: call rate_control_send_low() internally Date: Thu, 16 May 2019 11:52:56 +0200 Message-Id: <20190516095257.11503-1-johannes@sipsolutions.net> X-Mailer: git-send-email 2.17.2 Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Johannes Berg There's no rate control algorithm that *doesn't* want to call it internally, and calling it internally will let us modify its behaviour in the future. Signed-off-by: Johannes Berg --- .../driver-api/80211/mac80211-advanced.rst | 3 --- drivers/net/wireless/intel/iwlegacy/3945-rs.c | 3 --- drivers/net/wireless/intel/iwlegacy/4965-rs.c | 4 ---- drivers/net/wireless/intel/iwlwifi/dvm/rs.c | 4 ---- drivers/net/wireless/intel/iwlwifi/mvm/rs.c | 4 ---- drivers/net/wireless/realtek/rtlwifi/rc.c | 3 --- include/net/mac80211.h | 23 ------------------- net/mac80211/rate.c | 13 ++++++----- net/mac80211/rc80211_minstrel.c | 4 ---- net/mac80211/rc80211_minstrel_ht.c | 3 --- 10 files changed, 7 insertions(+), 57 deletions(-) diff --git a/Documentation/driver-api/80211/mac80211-advanced.rst b/Documentation/driver-api/80211/mac80211-advanced.rst index 70a89b2163c2..9f1c5bb7ac35 100644 --- a/Documentation/driver-api/80211/mac80211-advanced.rst +++ b/Documentation/driver-api/80211/mac80211-advanced.rst @@ -226,9 +226,6 @@ TBD .. kernel-doc:: include/net/mac80211.h :functions: ieee80211_tx_rate_control -.. kernel-doc:: include/net/mac80211.h - :functions: rate_control_send_low - TBD This part of the book describes mac80211 internals. diff --git a/drivers/net/wireless/intel/iwlegacy/3945-rs.c b/drivers/net/wireless/intel/iwlegacy/3945-rs.c index a697edd46e7f..922f09f7ea3e 100644 --- a/drivers/net/wireless/intel/iwlegacy/3945-rs.c +++ b/drivers/net/wireless/intel/iwlegacy/3945-rs.c @@ -646,9 +646,6 @@ il3945_rs_get_rate(void *il_r, struct ieee80211_sta *sta, void *il_sta, il_sta = NULL; } - if (rate_control_send_low(sta, il_sta, txrc)) - return; - rate_mask = sta->supp_rates[sband->band]; /* get user max rate if set */ diff --git a/drivers/net/wireless/intel/iwlegacy/4965-rs.c b/drivers/net/wireless/intel/iwlegacy/4965-rs.c index 54ff83829afb..946f352fd9a4 100644 --- a/drivers/net/wireless/intel/iwlegacy/4965-rs.c +++ b/drivers/net/wireless/intel/iwlegacy/4965-rs.c @@ -2224,10 +2224,6 @@ il4965_rs_get_rate(void *il_r, struct ieee80211_sta *sta, void *il_sta, il_sta = NULL; } - /* Send management frames and NO_ACK data using lowest rate. */ - if (rate_control_send_low(sta, il_sta, txrc)) - return; - if (!lq_sta) return; diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/rs.c b/drivers/net/wireless/intel/iwlwifi/dvm/rs.c index ef4b9de256f7..838e76a5db68 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/rs.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/rs.c @@ -2731,10 +2731,6 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta, priv_sta = NULL; } - /* Send management frames and NO_ACK data using lowest rate. */ - if (rate_control_send_low(sta, priv_sta, txrc)) - return; - rate_idx = lq_sta->last_txrate_idx; if (lq_sta->last_rate_n_flags & RATE_MCS_HT_MSK) { diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c index c182821ab22b..9107b1698b0f 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c @@ -2960,10 +2960,6 @@ static void rs_drv_get_rate(void *mvm_r, struct ieee80211_sta *sta, mvm_sta = NULL; } - /* Send management frames and NO_ACK data using lowest rate. */ - if (rate_control_send_low(sta, mvm_sta, txrc)) - return; - if (!mvm_sta) return; diff --git a/drivers/net/wireless/realtek/rtlwifi/rc.c b/drivers/net/wireless/realtek/rtlwifi/rc.c index cf8e42a01015..0c7d74902d33 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rc.c +++ b/drivers/net/wireless/realtek/rtlwifi/rc.c @@ -173,9 +173,6 @@ static void rtl_get_rate(void *ppriv, struct ieee80211_sta *sta, u8 try_per_rate, i, rix; bool not_data = !ieee80211_is_data(fc); - if (rate_control_send_low(sta, priv_sta, txrc)) - return; - rix = _rtl_rc_get_highest_rix(rtlpriv, sta, skb, not_data); try_per_rate = 1; _rtl_rc_rate_set_series(rtlpriv, sta, &rates[0], txrc, diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 72080d9d617e..9dc98d6d1b4d 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -5951,29 +5951,6 @@ static inline int rate_supported(struct ieee80211_sta *sta, return (sta == NULL || sta->supp_rates[band] & BIT(index)); } -/** - * rate_control_send_low - helper for drivers for management/no-ack frames - * - * Rate control algorithms that agree to use the lowest rate to - * send management frames and NO_ACK data with the respective hw - * retries should use this in the beginning of their mac80211 get_rate - * callback. If true is returned the rate control can simply return. - * If false is returned we guarantee that sta and sta and priv_sta is - * not null. - * - * Rate control algorithms wishing to do more intelligent selection of - * rate for multicast/broadcast frames may choose to not use this. - * - * @sta: &struct ieee80211_sta pointer to the target destination. Note - * that this may be null. - * @priv_sta: private rate control structure. This may be null. - * @txrc: rate control information we sholud populate for mac80211. - */ -bool rate_control_send_low(struct ieee80211_sta *sta, - void *priv_sta, - struct ieee80211_tx_rate_control *txrc); - - static inline s8 rate_lowest_index(struct ieee80211_supported_band *sband, struct ieee80211_sta *sta) diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c index 76f303fda3ed..09f89d004a70 100644 --- a/net/mac80211/rate.c +++ b/net/mac80211/rate.c @@ -369,9 +369,8 @@ static void __rate_control_send_low(struct ieee80211_hw *hw, } -bool rate_control_send_low(struct ieee80211_sta *pubsta, - void *priv_sta, - struct ieee80211_tx_rate_control *txrc) +static bool rate_control_send_low(struct ieee80211_sta *pubsta, + struct ieee80211_tx_rate_control *txrc) { struct ieee80211_tx_info *info = IEEE80211_SKB_CB(txrc->skb); struct ieee80211_supported_band *sband = txrc->sband; @@ -379,7 +378,7 @@ bool rate_control_send_low(struct ieee80211_sta *pubsta, int mcast_rate; bool use_basicrate = false; - if (!pubsta || !priv_sta || rc_no_data_or_no_ack_use_min(txrc)) { + if (!pubsta || rc_no_data_or_no_ack_use_min(txrc)) { __rate_control_send_low(txrc->hw, sband, pubsta, info, txrc->rate_idx_mask); @@ -405,7 +404,6 @@ bool rate_control_send_low(struct ieee80211_sta *pubsta, } return false; } -EXPORT_SYMBOL(rate_control_send_low); static bool rate_idx_match_legacy_mask(s8 *rate_idx, int n_bitrates, u32 mask) { @@ -902,12 +900,15 @@ void rate_control_get_rate(struct ieee80211_sub_if_data *sdata, if (ieee80211_hw_check(&sdata->local->hw, HAS_RATE_CONTROL)) return; + if (rate_control_send_low(ista, txrc)) + return; + if (ista) { spin_lock_bh(&sta->rate_ctrl_lock); ref->ops->get_rate(ref->priv, ista, priv_sta, txrc); spin_unlock_bh(&sta->rate_ctrl_lock); } else { - ref->ops->get_rate(ref->priv, NULL, NULL, txrc); + rate_control_send_low(NULL, txrc); } if (ieee80211_hw_check(&sdata->local->hw, SUPPORTS_RC_TABLE)) diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c index a34e9c2ca626..ee86c3333999 100644 --- a/net/mac80211/rc80211_minstrel.c +++ b/net/mac80211/rc80211_minstrel.c @@ -340,10 +340,6 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta, int delta; int sampling_ratio; - /* management/no-ack frames do not use rate control */ - if (rate_control_send_low(sta, priv_sta, txrc)) - return; - /* check multi-rate-retry capabilities & adjust lookaround_rate */ mrr_capable = mp->has_mrr && !txrc->rts && diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index 8b168724c5e7..da18c6fb6c1d 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c @@ -1098,9 +1098,6 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, struct minstrel_priv *mp = priv; int sample_idx; - if (rate_control_send_low(sta, priv_sta, txrc)) - return; - if (!msp->is_ht) return mac80211_minstrel.get_rate(priv, sta, &msp->legacy, txrc); From patchwork Thu May 16 09:52:57 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Berg X-Patchwork-Id: 10946239 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 779791395 for ; Thu, 16 May 2019 09:53:11 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 679302844E for ; Thu, 16 May 2019 09:53:11 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 5C5B42855C; Thu, 16 May 2019 09:53:11 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B9F382844E for ; Thu, 16 May 2019 09:53:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727157AbfEPJxJ (ORCPT ); Thu, 16 May 2019 05:53:09 -0400 Received: from s3.sipsolutions.net ([144.76.43.62]:39766 "EHLO sipsolutions.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726336AbfEPJxI (ORCPT ); Thu, 16 May 2019 05:53:08 -0400 Received: by sipsolutions.net with esmtpsa (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1hRD4T-0007MT-38; Thu, 16 May 2019 11:53:05 +0200 From: Johannes Berg To: linux-wireless@vger.kernel.org Cc: Johannes Berg Subject: [PATCH 2/2] mac80211: use STA info in rate_control_send_low() Date: Thu, 16 May 2019 11:52:57 +0200 Message-Id: <20190516095257.11503-2-johannes@sipsolutions.net> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190516095257.11503-1-johannes@sipsolutions.net> References: <20190516095257.11503-1-johannes@sipsolutions.net> Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Johannes Berg Even if we have a station, we currently call rate_control_send_low() with the NULL station unless further rate control (driver, minstrel) has been initialized. Change this so we can use more information about the station to use a better rate. For example, when we associate with an AP, we will now use the lowest rate it advertised as supported (that we can) rather than the lowest mandatory rate. This aligns our behaviour with most other 802.11 implementations. To make this possible, we need to also ensure that we have non-zero rates at all times, so in case we really have *nothing* pre-fill the supp_rates bitmap with the very lowest mandatory bitmap (11b and 11a on 2.4 and 5 GHz respectively). Additionally, hostapd appears to be giving us an empty supported rates bitmap (it can and should do better, since the STA must have supported for at least the basic rates in the BSS), so ignore any such bitmaps that would actually zero out the supp_rates, and in that case just keep the pre-filled mandatory rates. Signed-off-by: Johannes Berg Reported-by: kernel test robot --- net/mac80211/cfg.c | 2 +- net/mac80211/mlme.c | 7 ++++++- net/mac80211/rate.c | 12 ++++++------ net/mac80211/sta_info.c | 31 +++++++++++++++++++++++++++++++ 4 files changed, 44 insertions(+), 8 deletions(-) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 52e6a091b7e4..58c97e6dadb0 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1466,7 +1466,7 @@ static int sta_apply_parameters(struct ieee80211_local *local, return ret; } - if (params->supported_rates) { + if (params->supported_rates && params->supported_rates_len) { ieee80211_parse_bitrates(&sdata->vif.bss_conf.chandef, sband, params->supported_rates, params->supported_rates_len, diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index b7a9fe3d5fcb..bc2fdadf69bc 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -4941,7 +4941,12 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, basic_rates = BIT(min_rate_index); } - new_sta->sta.supp_rates[cbss->channel->band] = rates; + if (rates) + new_sta->sta.supp_rates[cbss->channel->band] = rates; + else + sdata_info(sdata, + "No rates found, keeping mandatory only\n"); + sdata->vif.bss_conf.basic_rates = basic_rates; /* cf. IEEE 802.11 9.2.12 */ diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c index 09f89d004a70..bc3cedc653f0 100644 --- a/net/mac80211/rate.c +++ b/net/mac80211/rate.c @@ -886,11 +886,6 @@ void rate_control_get_rate(struct ieee80211_sub_if_data *sdata, struct ieee80211_tx_info *info = IEEE80211_SKB_CB(txrc->skb); int i; - if (sta && test_sta_flag(sta, WLAN_STA_RATE_CONTROL)) { - ista = &sta->sta; - priv_sta = sta->rate_ctrl_priv; - } - for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { info->control.rates[i].idx = -1; info->control.rates[i].flags = 0; @@ -900,9 +895,14 @@ void rate_control_get_rate(struct ieee80211_sub_if_data *sdata, if (ieee80211_hw_check(&sdata->local->hw, HAS_RATE_CONTROL)) return; - if (rate_control_send_low(ista, txrc)) + if (rate_control_send_low(sta ? &sta->sta : NULL, txrc)) return; + if (sta && test_sta_flag(sta, WLAN_STA_RATE_CONTROL)) { + ista = &sta->sta; + priv_sta = sta->rate_ctrl_priv; + } + if (ista) { spin_lock_bh(&sta->rate_ctrl_lock); ref->ops->get_rate(ref->priv, ista, priv_sta, txrc); diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index a4932ee3595c..4b4774e07151 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -404,6 +404,37 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, for (i = 0; i < IEEE80211_NUM_TIDS; i++) sta->last_seq_ctrl[i] = cpu_to_le16(USHRT_MAX); + for (i = 0; i < NUM_NL80211_BANDS; i++) { + u32 mandatory = 0; + int r; + + if (!hw->wiphy->bands[i]) + continue; + + switch (i) { + case NL80211_BAND_2GHZ: + mandatory = IEEE80211_RATE_MANDATORY_B; + break; + case NL80211_BAND_5GHZ: + mandatory = IEEE80211_RATE_MANDATORY_G; + break; + case NL80211_BAND_60GHZ: + WARN_ON(1); + mandatory = 0; + break; + } + + for (r = 0; r < hw->wiphy->bands[i]->n_bitrates; r++) { + struct ieee80211_rate *rate; + + rate = &hw->wiphy->bands[i]->bitrates[r]; + + if (!(rate->flags & mandatory)) + continue; + sta->sta.supp_rates[i] |= BIT(r); + } + } + sta->sta.smps_mode = IEEE80211_SMPS_OFF; if (sdata->vif.type == NL80211_IFTYPE_AP || sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {