Merge tag 'mac80211-next-for-net-next-2019-10-11' of git://git.kernel.org/pub/scm...
authorDavid S. Miller <davem@davemloft.net>
Sun, 13 Oct 2019 18:29:07 +0000 (11:29 -0700)
committerDavid S. Miller <davem@davemloft.net>
Sun, 13 Oct 2019 18:29:07 +0000 (11:29 -0700)
Johannes Berg says:

====================
A few more small things, nothing really stands out:
 * minstrel improvements from Felix
 * a TX aggregation simplification
 * some additional capabilities for hwsim
 * minor cleanups & docs updates
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
30 files changed:
drivers/net/wireless/ath/ath9k/htc_drv_main.c
drivers/net/wireless/ath/ath9k/main.c
drivers/net/wireless/ath/carl9170/main.c
drivers/net/wireless/ath/wcn36xx/main.c
drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c
drivers/net/wireless/intel/iwlegacy/4965-mac.c
drivers/net/wireless/intel/iwlwifi/dvm/tx.c
drivers/net/wireless/intel/iwlwifi/mvm/sta.c
drivers/net/wireless/mac80211_hwsim.c
drivers/net/wireless/marvell/mwl8k.c
drivers/net/wireless/mediatek/mt76/mt7603/main.c
drivers/net/wireless/mediatek/mt76/mt7615/main.c
drivers/net/wireless/mediatek/mt76/mt76x02_util.c
drivers/net/wireless/mediatek/mt7601u/main.c
drivers/net/wireless/ralink/rt2x00/rt2800lib.c
drivers/net/wireless/realtek/rtlwifi/base.c
drivers/net/wireless/realtek/rtw88/mac80211.c
drivers/net/wireless/rsi/rsi_91x_mac80211.c
include/net/mac80211.h
include/uapi/linux/nl80211.h
net/mac80211/agg-tx.c
net/mac80211/ibss.c
net/mac80211/rc80211_minstrel.c
net/mac80211/rc80211_minstrel.h
net/mac80211/rc80211_minstrel_debugfs.c
net/mac80211/rc80211_minstrel_ht.c
net/mac80211/rc80211_minstrel_ht.h
net/mac80211/rc80211_minstrel_ht_debugfs.c
net/mac80211/tx.c
net/wireless/nl80211.c

index a82ad739ab80653efd17b2eae0929fb4c224432f..791f6633667ce516d10074b71d251fbd6862a18d 100644 (file)
@@ -1674,7 +1674,7 @@ static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw,
        case IEEE80211_AMPDU_TX_START:
                ret = ath9k_htc_tx_aggr_oper(priv, vif, sta, action, tid);
                if (!ret)
-                       ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
+                       ret = IEEE80211_AMPDU_TX_START_IMMEDIATE;
                break;
        case IEEE80211_AMPDU_TX_STOP_CONT:
        case IEEE80211_AMPDU_TX_STOP_FLUSH:
index 34121fbf32e37a9a3931b81fa384fe3e8e67408a..0548aa3702e3b4df782605200ab37855c6adb926 100644 (file)
@@ -1921,7 +1921,7 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw,
                ath9k_ps_wakeup(sc);
                ret = ath_tx_aggr_start(sc, sta, tid, ssn);
                if (!ret)
-                       ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
+                       ret = IEEE80211_AMPDU_TX_START_IMMEDIATE;
                ath9k_ps_restore(sc);
                break;
        case IEEE80211_AMPDU_TX_STOP_FLUSH:
index 40a8054f8aa680178997e412ffa772086b791d1b..5914926a5c5b8add0e387dff9dea1b39559f24e8 100644 (file)
@@ -1449,8 +1449,7 @@ static int carl9170_op_ampdu_action(struct ieee80211_hw *hw,
                rcu_assign_pointer(sta_info->agg[tid], tid_info);
                spin_unlock_bh(&ar->tx_ampdu_list_lock);
 
-               ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
-               break;
+               return IEEE80211_AMPDU_TX_START_IMMEDIATE;
 
        case IEEE80211_AMPDU_TX_STOP_CONT:
        case IEEE80211_AMPDU_TX_STOP_FLUSH:
index 79998a3ddb7afaf4df76449e5567e59aaf69863f..a276dae30887128eddf529f25eb74f33ea771cc1 100644 (file)
@@ -1084,6 +1084,7 @@ static int wcn36xx_ampdu_action(struct ieee80211_hw *hw,
        enum ieee80211_ampdu_mlme_action action = params->action;
        u16 tid = params->tid;
        u16 *ssn = &params->ssn;
+       int ret = 0;
 
        wcn36xx_dbg(WCN36XX_DBG_MAC, "mac ampdu action action %d tid %d\n",
                    action, tid);
@@ -1106,7 +1107,7 @@ static int wcn36xx_ampdu_action(struct ieee80211_hw *hw,
                sta_priv->ampdu_state[tid] = WCN36XX_AMPDU_START;
                spin_unlock_bh(&sta_priv->ampdu_lock);
 
-               ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
+               ret = IEEE80211_AMPDU_TX_START_IMMEDIATE;
                break;
        case IEEE80211_AMPDU_TX_OPERATIONAL:
                spin_lock_bh(&sta_priv->ampdu_lock);
@@ -1131,7 +1132,7 @@ static int wcn36xx_ampdu_action(struct ieee80211_hw *hw,
 
        mutex_unlock(&wcn->conf_mutex);
 
-       return 0;
+       return ret;
 }
 
 static const struct ieee80211_ops wcn36xx_ops = {
index 6188275b17e5aee8df963ee5c848a4d5d4921687..8e8b685cfe09b5161d3a2f7b1d03d8ee842472df 100644 (file)
@@ -850,8 +850,7 @@ brcms_ops_ampdu_action(struct ieee80211_hw *hw,
                                     "START: tid %d is not agg\'able\n", tid);
                        return -EINVAL;
                }
-               ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
-               break;
+               return IEEE80211_AMPDU_TX_START_IMMEDIATE;
 
        case IEEE80211_AMPDU_TX_STOP_CONT:
        case IEEE80211_AMPDU_TX_STOP_FLUSH:
index ffb705b18fb13bd3a44753087358e72ded6aea75..51fdd7ce30aff66e5a5cbbc99254be5bd1e474c4 100644 (file)
@@ -2265,7 +2265,7 @@ il4965_tx_agg_start(struct il_priv *il, struct ieee80211_vif *vif,
        if (tid_data->tfds_in_queue == 0) {
                D_HT("HW queue is empty\n");
                tid_data->agg.state = IL_AGG_ON;
-               ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
+               ret = IEEE80211_AMPDU_TX_START_IMMEDIATE;
        } else {
                D_HT("HW queue is NOT empty: %d packets in HW queue\n",
                     tid_data->tfds_in_queue);
index 3029e3f6de63b5e8feeab7ef0505c18c2ffd17e8..cd73fc5cfcbb21c537cde3e05e7025f6387edcc4 100644 (file)
@@ -621,7 +621,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
                IWL_DEBUG_TX_QUEUES(priv, "Can proceed: ssn = next_recl = %d\n",
                                    tid_data->agg.ssn);
                tid_data->agg.state = IWL_AGG_STARTING;
-               ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
+               ret = IEEE80211_AMPDU_TX_START_IMMEDIATE;
        } else {
                IWL_DEBUG_TX_QUEUES(priv, "Can't proceed: ssn %d, "
                                    "next_reclaimed = %d\n",
index 0bedba4c61f2ae898c7ddbb612d041e9c9fdd7dc..1d6bc62b104cd3721d387eb325c554eb87be0ecf 100644 (file)
@@ -2818,13 +2818,12 @@ int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
 
        if (normalized_ssn == tid_data->next_reclaimed) {
                tid_data->state = IWL_AGG_STARTING;
-               ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
+               ret = IEEE80211_AMPDU_TX_START_IMMEDIATE;
        } else {
                tid_data->state = IWL_EMPTYING_HW_QUEUE_ADDBA;
+               ret = 0;
        }
 
-       ret = 0;
-
 out:
        spin_unlock_bh(&mvmsta->lock);
 
index 45c73a6f09a128a8ef069906b1e02aaf144ffaea..3888ad0f797b83f2edcd47f905d65adc26ac6f44 100644 (file)
@@ -148,23 +148,25 @@ static const char *hwsim_alpha2s[] = {
 };
 
 static const struct ieee80211_regdomain hwsim_world_regdom_custom_01 = {
-       .n_reg_rules = 4,
+       .n_reg_rules = 5,
        .alpha2 =  "99",
        .reg_rules = {
                REG_RULE(2412-10, 2462+10, 40, 0, 20, 0),
                REG_RULE(2484-10, 2484+10, 40, 0, 20, 0),
                REG_RULE(5150-10, 5240+10, 40, 0, 30, 0),
                REG_RULE(5745-10, 5825+10, 40, 0, 30, 0),
+               REG_RULE(5855-10, 5925+10, 40, 0, 33, 0),
        }
 };
 
 static const struct ieee80211_regdomain hwsim_world_regdom_custom_02 = {
-       .n_reg_rules = 2,
+       .n_reg_rules = 3,
        .alpha2 =  "99",
        .reg_rules = {
                REG_RULE(2412-10, 2462+10, 40, 0, 20, 0),
                REG_RULE(5725-10, 5850+10, 40, 0, 30,
                         NL80211_RRF_NO_IR),
+               REG_RULE(5855-10, 5925+10, 40, 0, 33, 0),
        }
 };
 
@@ -354,6 +356,24 @@ static const struct ieee80211_channel hwsim_channels_5ghz[] = {
        CHAN5G(5805), /* Channel 161 */
        CHAN5G(5825), /* Channel 165 */
        CHAN5G(5845), /* Channel 169 */
+
+       CHAN5G(5855), /* Channel 171 */
+       CHAN5G(5860), /* Channel 172 */
+       CHAN5G(5865), /* Channel 173 */
+       CHAN5G(5870), /* Channel 174 */
+
+       CHAN5G(5875), /* Channel 175 */
+       CHAN5G(5880), /* Channel 176 */
+       CHAN5G(5885), /* Channel 177 */
+       CHAN5G(5890), /* Channel 178 */
+       CHAN5G(5895), /* Channel 179 */
+       CHAN5G(5900), /* Channel 180 */
+       CHAN5G(5905), /* Channel 181 */
+
+       CHAN5G(5910), /* Channel 182 */
+       CHAN5G(5915), /* Channel 183 */
+       CHAN5G(5920), /* Channel 184 */
+       CHAN5G(5925), /* Channel 185 */
 };
 
 static const struct ieee80211_rate hwsim_rates[] = {
@@ -1550,7 +1570,8 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac,
 
        if (vif->type != NL80211_IFTYPE_AP &&
            vif->type != NL80211_IFTYPE_MESH_POINT &&
-           vif->type != NL80211_IFTYPE_ADHOC)
+           vif->type != NL80211_IFTYPE_ADHOC &&
+           vif->type != NL80211_IFTYPE_OCB)
                return;
 
        skb = ieee80211_beacon_get(hw, vif);
@@ -1604,6 +1625,8 @@ mac80211_hwsim_beacon(struct hrtimer *timer)
 }
 
 static const char * const hwsim_chanwidths[] = {
+       [NL80211_CHAN_WIDTH_5] = "ht5",
+       [NL80211_CHAN_WIDTH_10] = "ht10",
        [NL80211_CHAN_WIDTH_20_NOHT] = "noht",
        [NL80211_CHAN_WIDTH_20] = "ht20",
        [NL80211_CHAN_WIDTH_40] = "ht40",
@@ -1979,8 +2002,7 @@ static int mac80211_hwsim_ampdu_action(struct ieee80211_hw *hw,
 
        switch (action) {
        case IEEE80211_AMPDU_TX_START:
-               ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
-               break;
+               return IEEE80211_AMPDU_TX_START_IMMEDIATE;
        case IEEE80211_AMPDU_TX_STOP_CONT:
        case IEEE80211_AMPDU_TX_STOP_FLUSH:
        case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
@@ -2723,7 +2745,8 @@ static void mac80211_hwsim_he_capab(struct ieee80211_supported_band *sband)
         BIT(NL80211_IFTYPE_P2P_CLIENT) | \
         BIT(NL80211_IFTYPE_P2P_GO) | \
         BIT(NL80211_IFTYPE_ADHOC) | \
-        BIT(NL80211_IFTYPE_MESH_POINT))
+        BIT(NL80211_IFTYPE_MESH_POINT) | \
+        BIT(NL80211_IFTYPE_OCB))
 
 static int mac80211_hwsim_new_radio(struct genl_info *info,
                                    struct hwsim_new_radio_params *param)
@@ -2847,6 +2870,8 @@ static int mac80211_hwsim_new_radio(struct genl_info *info,
        } else {
                data->if_combination.num_different_channels = 1;
                data->if_combination.radar_detect_widths =
+                                       BIT(NL80211_CHAN_WIDTH_5) |
+                                       BIT(NL80211_CHAN_WIDTH_10) |
                                        BIT(NL80211_CHAN_WIDTH_20_NOHT) |
                                        BIT(NL80211_CHAN_WIDTH_20) |
                                        BIT(NL80211_CHAN_WIDTH_40) |
index c4db6417748f346518619c65720c443968a3544e..d55f229abeea66a1cd4cc9c4938f00170f1d59bf 100644 (file)
@@ -5520,7 +5520,7 @@ mwl8k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                        rc = -EBUSY;
                        break;
                }
-               ieee80211_start_tx_ba_cb_irqsafe(vif, addr, tid);
+               rc = IEEE80211_AMPDU_TX_START_IMMEDIATE;
                break;
        case IEEE80211_AMPDU_TX_STOP_CONT:
        case IEEE80211_AMPDU_TX_STOP_FLUSH:
index 25d5b1608bc91d7e2cdc49e8d191826e1007d6db..4b3217b43a04fe289cce6abc023c53e75e253f76 100644 (file)
@@ -582,8 +582,7 @@ mt7603_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                break;
        case IEEE80211_AMPDU_TX_START:
                mtxq->agg_ssn = IEEE80211_SN_TO_SEQ(ssn);
-               ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
-               break;
+               return IEEE80211_AMPDU_TX_START_IMMEDIATE;
        case IEEE80211_AMPDU_TX_STOP_CONT:
                mtxq->aggr = false;
                mt7603_mac_tx_ba_reset(dev, msta->wcid.idx, tid, -1);
index 87c748715b5d70091ae38ad66d0bf318941e9bcf..b6d78212306a3d0e499692425c2738c1116c6ddc 100644 (file)
@@ -477,8 +477,7 @@ mt7615_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                break;
        case IEEE80211_AMPDU_TX_START:
                mtxq->agg_ssn = IEEE80211_SN_TO_SEQ(ssn);
-               ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
-               break;
+               return IEEE80211_AMPDU_TX_START_IMMEDIATE;
        case IEEE80211_AMPDU_TX_STOP_CONT:
                mtxq->aggr = false;
                mt7615_mcu_set_tx_ba(dev, params, 0);
index aec73a0295e86eb800f38d9d47285b4a47faac13..414b22399d9366911b2f41ae62dee517e1d4f7a3 100644 (file)
@@ -393,8 +393,7 @@ int mt76x02_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                break;
        case IEEE80211_AMPDU_TX_START:
                mtxq->agg_ssn = IEEE80211_SN_TO_SEQ(ssn);
-               ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
-               break;
+               return IEEE80211_AMPDU_TX_START_IMMEDIATE;
        case IEEE80211_AMPDU_TX_STOP_CONT:
                mtxq->aggr = false;
                ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
index 72e608cc53afcb6b2ecc1b5732674a6840fad8af..671d8897ae76c2b4c0c018c46d7de96ad24a49a0 100644 (file)
@@ -372,8 +372,7 @@ mt76_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                break;
        case IEEE80211_AMPDU_TX_START:
                msta->agg_ssn[tid] = ssn << 4;
-               ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
-               break;
+               return IEEE80211_AMPDU_TX_START_IMMEDIATE;
        case IEEE80211_AMPDU_TX_STOP_CONT:
                ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
                break;
index f1cdcd61c54a5eeec18fc349e63a5cd832cb17fa..25466454b73e94cb802ee6a59058c14d539f38e1 100644 (file)
@@ -10476,7 +10476,7 @@ int rt2800_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
         * when the hw reorders frames due to aggregation.
         */
        if (sta_priv->wcid > WCID_END)
-               return 1;
+               return -ENOSPC;
 
        switch (action) {
        case IEEE80211_AMPDU_RX_START:
@@ -10489,7 +10489,7 @@ int rt2800_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                 */
                break;
        case IEEE80211_AMPDU_TX_START:
-               ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
+               ret = IEEE80211_AMPDU_TX_START_IMMEDIATE;
                break;
        case IEEE80211_AMPDU_TX_STOP_CONT:
        case IEEE80211_AMPDU_TX_STOP_FLUSH:
index ac746c322554b393676f79f214b9fccdfddb3fda..c75192c4447f91ff2d91fe8042a8d2a2bd521487 100644 (file)
@@ -1776,8 +1776,7 @@ int rtl_tx_agg_start(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 
        tid_data->agg.agg_state = RTL_AGG_START;
 
-       ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
-       return 0;
+       return IEEE80211_AMPDU_TX_START_IMMEDIATE;
 }
 
 int rtl_tx_agg_stop(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
index e5e3605bb6931c1c6f0d87a1434ce78eedc9f36a..a203b4705b9449cf670a5bee86fce487df276b8c 100644 (file)
@@ -437,8 +437,7 @@ static int rtw_ops_ampdu_action(struct ieee80211_hw *hw,
 
        switch (params->action) {
        case IEEE80211_AMPDU_TX_START:
-               ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
-               break;
+               return IEEE80211_AMPDU_TX_START_IMMEDIATE;
        case IEEE80211_AMPDU_TX_STOP_CONT:
        case IEEE80211_AMPDU_TX_STOP_FLUSH:
        case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
index ce5e92d82efc8038dc02bd777a7805add811860a..440088293afff4a381c71e1f4759e100d6129e64 100644 (file)
@@ -1140,8 +1140,7 @@ static int rsi_mac80211_ampdu_action(struct ieee80211_hw *hw,
                else if ((vif->type == NL80211_IFTYPE_AP) ||
                         (vif->type == NL80211_IFTYPE_P2P_GO))
                        rsta->seq_start[tid] = seq_no;
-               ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
-               status = 0;
+               status = IEEE80211_AMPDU_TX_START_IMMEDIATE;
                break;
 
        case IEEE80211_AMPDU_TX_STOP_CONT:
index 523c6a09e1c8c722a725b03f2ca0d09ff638afca..d69081c38788ac2474d389b6203323b58794e898 100644 (file)
@@ -3095,7 +3095,9 @@ enum ieee80211_filter_flags {
  *
  * @IEEE80211_AMPDU_RX_START: start RX aggregation
  * @IEEE80211_AMPDU_RX_STOP: stop RX aggregation
- * @IEEE80211_AMPDU_TX_START: start TX aggregation
+ * @IEEE80211_AMPDU_TX_START: start TX aggregation, the driver must either
+ *     call ieee80211_start_tx_ba_cb_irqsafe() or return the special
+ *     status %IEEE80211_AMPDU_TX_START_IMMEDIATE.
  * @IEEE80211_AMPDU_TX_OPERATIONAL: TX aggregation has become operational
  * @IEEE80211_AMPDU_TX_STOP_CONT: stop TX aggregation but continue transmitting
  *     queued packets, now unaggregated. After all packets are transmitted the
@@ -3119,6 +3121,8 @@ enum ieee80211_ampdu_mlme_action {
        IEEE80211_AMPDU_TX_OPERATIONAL,
 };
 
+#define IEEE80211_AMPDU_TX_START_IMMEDIATE 1
+
 /**
  * struct ieee80211_ampdu_params - AMPDU action parameters
  *
@@ -3896,7 +3900,10 @@ struct ieee80211_ops {
         *
         * Even ``189`` would be wrong since 1 could be lost again.
         *
-        * Returns a negative error code on failure.
+        * Returns a negative error code on failure. The driver may return
+        * %IEEE80211_AMPDU_TX_START_IMMEDIATE for %IEEE80211_AMPDU_TX_START
+        * if the session can start immediately.
+        *
         * The callback can sleep.
         */
        int (*ampdu_action)(struct ieee80211_hw *hw,
index beee59c831a735042a94521b40eb41840363e35b..64135ab3a7acb0abced8c0706c5b6623509b4655 100644 (file)
  *     set of BSSID,frequency parameters is used (i.e., either the enforcing
  *     %NL80211_ATTR_MAC,%NL80211_ATTR_WIPHY_FREQ or the less strict
  *     %NL80211_ATTR_MAC_HINT and %NL80211_ATTR_WIPHY_FREQ_HINT).
+ *     Driver shall not modify the IEs specified through %NL80211_ATTR_IE if
+ *     %NL80211_ATTR_MAC is included. However, if %NL80211_ATTR_MAC_HINT is
+ *     included, these IEs through %NL80211_ATTR_IE are specified by the user
+ *     space based on the best possible BSS selected. Thus, if the driver ends
+ *     up selecting a different BSS, it can modify these IEs accordingly (e.g.
+ *     userspace asks the driver to perform PMKSA caching with BSS1 and the
+ *     driver ends up selecting BSS2 with different PMKSA cache entry; RSNIE
+ *     has to get updated with the apt PMKID).
  *     %NL80211_ATTR_PREV_BSSID can be used to request a reassociation within
  *     the ESS in case the device is already associated and an association with
  *     a different BSS is desired.
index b11883d268759a4f2eb138b7c3aa2027fc833b21..33da6f738c999270ebdfd1364cf30f57b8797166 100644 (file)
@@ -485,7 +485,14 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid)
 
        params.ssn = sta->tid_seq[tid] >> 4;
        ret = drv_ampdu_action(local, sdata, &params);
-       if (ret) {
+       if (ret == IEEE80211_AMPDU_TX_START_IMMEDIATE) {
+               /*
+                * We didn't send the request yet, so don't need to check
+                * here if we already got a response, just mark as driver
+                * ready immediately.
+                */
+               set_bit(HT_AGG_STATE_DRV_READY, &tid_tx->state);
+       } else if (ret) {
                ht_dbg(sdata,
                       "BA request denied - HW unavailable for %pM tid %d\n",
                       sta->sta.addr, tid);
index 0a6ff01c68a9659b71bb0823ccc089a0cc4964cb..d40744903fa90f596435d7e9fdb4d46ec39683b3 100644 (file)
@@ -538,7 +538,6 @@ int ieee80211_ibss_finish_csa(struct ieee80211_sub_if_data *sdata)
 {
        struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
        struct cfg80211_bss *cbss;
-       int err, changed = 0;
 
        sdata_assert_lock(sdata);
 
@@ -560,13 +559,7 @@ int ieee80211_ibss_finish_csa(struct ieee80211_sub_if_data *sdata)
        ifibss->chandef = sdata->csa_chandef;
 
        /* generate the beacon */
-       err = ieee80211_ibss_csa_beacon(sdata, NULL);
-       if (err < 0)
-               return err;
-
-       changed |= err;
-
-       return changed;
+       return ieee80211_ibss_csa_beacon(sdata, NULL);
 }
 
 void ieee80211_ibss_stop(struct ieee80211_sub_if_data *sdata)
index ee86c3333999a187af599c305d7ec86544148619..86bc469a28bc5f7f6e1d2d084712801cadebacb3 100644 (file)
@@ -70,7 +70,7 @@ rix_to_ndx(struct minstrel_sta_info *mi, int rix)
 }
 
 /* return current EMWA throughput */
-int minstrel_get_tp_avg(struct minstrel_rate *mr, int prob_ewma)
+int minstrel_get_tp_avg(struct minstrel_rate *mr, int prob_avg)
 {
        int usecs;
 
@@ -79,13 +79,13 @@ int minstrel_get_tp_avg(struct minstrel_rate *mr, int prob_ewma)
                usecs = 1000000;
 
        /* reset thr. below 10% success */
-       if (mr->stats.prob_ewma < MINSTREL_FRAC(10, 100))
+       if (mr->stats.prob_avg < MINSTREL_FRAC(10, 100))
                return 0;
 
-       if (prob_ewma > MINSTREL_FRAC(90, 100))
+       if (prob_avg > MINSTREL_FRAC(90, 100))
                return MINSTREL_TRUNC(100000 * (MINSTREL_FRAC(90, 100) / usecs));
        else
-               return MINSTREL_TRUNC(100000 * (prob_ewma / usecs));
+               return MINSTREL_TRUNC(100000 * (prob_avg / usecs));
 }
 
 /* find & sort topmost throughput rates */
@@ -98,8 +98,8 @@ minstrel_sort_best_tp_rates(struct minstrel_sta_info *mi, int i, u8 *tp_list)
 
        for (j = MAX_THR_RATES; j > 0; --j) {
                tmp_mrs = &mi->r[tp_list[j - 1]].stats;
-               if (minstrel_get_tp_avg(&mi->r[i], cur_mrs->prob_ewma) <=
-                   minstrel_get_tp_avg(&mi->r[tp_list[j - 1]], tmp_mrs->prob_ewma))
+               if (minstrel_get_tp_avg(&mi->r[i], cur_mrs->prob_avg) <=
+                   minstrel_get_tp_avg(&mi->r[tp_list[j - 1]], tmp_mrs->prob_avg))
                        break;
        }
 
@@ -157,20 +157,24 @@ minstrel_update_rates(struct minstrel_priv *mp, struct minstrel_sta_info *mi)
 * Recalculate statistics and counters of a given rate
 */
 void
-minstrel_calc_rate_stats(struct minstrel_rate_stats *mrs)
+minstrel_calc_rate_stats(struct minstrel_priv *mp,
+                        struct minstrel_rate_stats *mrs)
 {
        unsigned int cur_prob;
 
        if (unlikely(mrs->attempts > 0)) {
                mrs->sample_skipped = 0;
                cur_prob = MINSTREL_FRAC(mrs->success, mrs->attempts);
-               if (unlikely(!mrs->att_hist)) {
-                       mrs->prob_ewma = cur_prob;
+               if (mp->new_avg) {
+                       minstrel_filter_avg_add(&mrs->prob_avg,
+                                               &mrs->prob_avg_1, cur_prob);
+               } else if (unlikely(!mrs->att_hist)) {
+                       mrs->prob_avg = cur_prob;
                } else {
                        /*update exponential weighted moving avarage */
-                       mrs->prob_ewma = minstrel_ewma(mrs->prob_ewma,
-                                                      cur_prob,
-                                                      EWMA_LEVEL);
+                       mrs->prob_avg = minstrel_ewma(mrs->prob_avg,
+                                                     cur_prob,
+                                                     EWMA_LEVEL);
                }
                mrs->att_hist += mrs->attempts;
                mrs->succ_hist += mrs->success;
@@ -200,12 +204,12 @@ minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi)
                struct minstrel_rate_stats *tmp_mrs = &mi->r[tmp_prob_rate].stats;
 
                /* Update statistics of success probability per rate */
-               minstrel_calc_rate_stats(mrs);
+               minstrel_calc_rate_stats(mp, mrs);
 
                /* Sample less often below the 10% chance of success.
                 * Sample less often above the 95% chance of success. */
-               if (mrs->prob_ewma > MINSTREL_FRAC(95, 100) ||
-                   mrs->prob_ewma < MINSTREL_FRAC(10, 100)) {
+               if (mrs->prob_avg > MINSTREL_FRAC(95, 100) ||
+                   mrs->prob_avg < MINSTREL_FRAC(10, 100)) {
                        mr->adjusted_retry_count = mrs->retry_count >> 1;
                        if (mr->adjusted_retry_count > 2)
                                mr->adjusted_retry_count = 2;
@@ -225,14 +229,14 @@ minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi)
                 * choose the maximum throughput rate as max_prob_rate
                 * (2) if all success probabilities < 95%, the rate with
                 * highest success probability is chosen as max_prob_rate */
-               if (mrs->prob_ewma >= MINSTREL_FRAC(95, 100)) {
-                       tmp_cur_tp = minstrel_get_tp_avg(mr, mrs->prob_ewma);
+               if (mrs->prob_avg >= MINSTREL_FRAC(95, 100)) {
+                       tmp_cur_tp = minstrel_get_tp_avg(mr, mrs->prob_avg);
                        tmp_prob_tp = minstrel_get_tp_avg(&mi->r[tmp_prob_rate],
-                                                         tmp_mrs->prob_ewma);
+                                                         tmp_mrs->prob_avg);
                        if (tmp_cur_tp >= tmp_prob_tp)
                                tmp_prob_rate = i;
                } else {
-                       if (mrs->prob_ewma >= tmp_mrs->prob_ewma)
+                       if (mrs->prob_avg >= tmp_mrs->prob_avg)
                                tmp_prob_rate = i;
                }
        }
@@ -290,7 +294,7 @@ minstrel_tx_status(void *priv, struct ieee80211_supported_band *sband,
                mi->sample_deferred--;
 
        if (time_after(jiffies, mi->last_stats_update +
-                               (mp->update_interval * HZ) / 1000))
+                               mp->update_interval / (mp->new_avg ? 2 : 1)))
                minstrel_update_stats(mp, mi);
 }
 
@@ -422,7 +426,7 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta,
         * has a probability of >95%, we shouldn't be attempting
         * to use it, as this only wastes precious airtime */
        if (!mrr_capable &&
-          (mi->r[ndx].stats.prob_ewma > MINSTREL_FRAC(95, 100)))
+          (mi->r[ndx].stats.prob_avg > MINSTREL_FRAC(95, 100)))
                return;
 
        mi->prev_sample = true;
@@ -573,7 +577,7 @@ static u32 minstrel_get_expected_throughput(void *priv_sta)
         * computing cur_tp
         */
        tmp_mrs = &mi->r[idx].stats;
-       tmp_cur_tp = minstrel_get_tp_avg(&mi->r[idx], tmp_mrs->prob_ewma) * 10;
+       tmp_cur_tp = minstrel_get_tp_avg(&mi->r[idx], tmp_mrs->prob_avg) * 10;
        tmp_cur_tp = tmp_cur_tp * 1200 * 8 / 1024;
 
        return tmp_cur_tp;
index 51d8b2c846e77ddbc568cac2d1311da4ca55a44e..dbb43bcd3c45a205165df331620d8e003fbcc8a7 100644 (file)
 /* number of highest throughput rates to consider*/
 #define MAX_THR_RATES 4
 
+/*
+ * Coefficients for moving average with noise filter (period=16),
+ * scaled by 10 bits
+ *
+ * a1 = exp(-pi * sqrt(2) / period)
+ * coeff2 = 2 * a1 * cos(sqrt(2) * 2 * pi / period)
+ * coeff3 = -sqr(a1)
+ * coeff1 = 1 - coeff2 - coeff3
+ */
+#define MINSTREL_AVG_COEFF1            (MINSTREL_FRAC(1, 1) - \
+                                        MINSTREL_AVG_COEFF2 - \
+                                        MINSTREL_AVG_COEFF3)
+#define MINSTREL_AVG_COEFF2            0x00001499
+#define MINSTREL_AVG_COEFF3            -0x0000092e
+
 /*
  * Perform EWMA (Exponentially Weighted Moving Average) calculation
  */
@@ -32,6 +47,37 @@ minstrel_ewma(int old, int new, int weight)
        return old + incr;
 }
 
+static inline int minstrel_filter_avg_add(u16 *prev_1, u16 *prev_2, s32 in)
+{
+       s32 out_1 = *prev_1;
+       s32 out_2 = *prev_2;
+       s32 val;
+
+       if (!in)
+               in += 1;
+
+       if (!out_1) {
+               val = out_1 = in;
+               goto out;
+       }
+
+       val = MINSTREL_AVG_COEFF1 * in;
+       val += MINSTREL_AVG_COEFF2 * out_1;
+       val += MINSTREL_AVG_COEFF3 * out_2;
+       val >>= MINSTREL_SCALE;
+
+       if (val > 1 << MINSTREL_SCALE)
+               val = 1 << MINSTREL_SCALE;
+       if (val < 0)
+               val = 1;
+
+out:
+       *prev_2 = out_1;
+       *prev_1 = val;
+
+       return val;
+}
+
 struct minstrel_rate_stats {
        /* current / last sampling period attempts/success counters */
        u16 attempts, last_attempts;
@@ -40,8 +86,9 @@ struct minstrel_rate_stats {
        /* total attempts/success counters */
        u32 att_hist, succ_hist;
 
-       /* prob_ewma - exponential weighted moving average of prob */
-       u16 prob_ewma;
+       /* prob_avg - moving average of prob */
+       u16 prob_avg;
+       u16 prob_avg_1;
 
        /* maximum retry counts */
        u8 retry_count;
@@ -95,6 +142,7 @@ struct minstrel_sta_info {
 struct minstrel_priv {
        struct ieee80211_hw *hw;
        bool has_mrr;
+       bool new_avg;
        u32 sample_switch;
        unsigned int cw_min;
        unsigned int cw_max;
@@ -126,8 +174,9 @@ extern const struct rate_control_ops mac80211_minstrel;
 void minstrel_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir);
 
 /* Recalculate success probabilities and counters for a given rate using EWMA */
-void minstrel_calc_rate_stats(struct minstrel_rate_stats *mrs);
-int minstrel_get_tp_avg(struct minstrel_rate *mr, int prob_ewma);
+void minstrel_calc_rate_stats(struct minstrel_priv *mp,
+                             struct minstrel_rate_stats *mrs);
+int minstrel_get_tp_avg(struct minstrel_rate *mr, int prob_avg);
 
 /* debugfs */
 int minstrel_stats_open(struct inode *inode, struct file *file);
index c8afd85b51a0580389b4a9a2293166db3e80da32..9b8e0daeb7bb578282bf51a868befd808d766e02 100644 (file)
@@ -90,8 +90,8 @@ minstrel_stats_open(struct inode *inode, struct file *file)
                p += sprintf(p, "%6u ", mr->perfect_tx_time);
 
                tp_max = minstrel_get_tp_avg(mr, MINSTREL_FRAC(100,100));
-               tp_avg = minstrel_get_tp_avg(mr, mrs->prob_ewma);
-               eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000);
+               tp_avg = minstrel_get_tp_avg(mr, mrs->prob_avg);
+               eprob = MINSTREL_TRUNC(mrs->prob_avg * 1000);
 
                p += sprintf(p, "%4u.%1u    %4u.%1u     %3u.%1u"
                                "     %3u   %3u %-3u   "
@@ -147,8 +147,8 @@ minstrel_stats_csv_open(struct inode *inode, struct file *file)
                p += sprintf(p, "%u,",mr->perfect_tx_time);
 
                tp_max = minstrel_get_tp_avg(mr, MINSTREL_FRAC(100,100));
-               tp_avg = minstrel_get_tp_avg(mr, mrs->prob_ewma);
-               eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000);
+               tp_avg = minstrel_get_tp_avg(mr, mrs->prob_avg);
+               eprob = MINSTREL_TRUNC(mrs->prob_avg * 1000);
 
                p += sprintf(p, "%u.%u,%u.%u,%u.%u,%u,%u,%u,"
                                "%llu,%llu,%d,%d\n",
index 0ef2633349b5d7809127e1ad79f9108b57ac1481..694a31978a0443dacbdfdd91ce9dd48d46974afe 100644 (file)
@@ -346,12 +346,12 @@ minstrel_ht_avg_ampdu_len(struct minstrel_ht_sta *mi)
  */
 int
 minstrel_ht_get_tp_avg(struct minstrel_ht_sta *mi, int group, int rate,
-                      int prob_ewma)
+                      int prob_avg)
 {
        unsigned int nsecs = 0;
 
        /* do not account throughput if sucess prob is below 10% */
-       if (prob_ewma < MINSTREL_FRAC(10, 100))
+       if (prob_avg < MINSTREL_FRAC(10, 100))
                return 0;
 
        if (group != MINSTREL_CCK_GROUP)
@@ -365,11 +365,11 @@ minstrel_ht_get_tp_avg(struct minstrel_ht_sta *mi, int group, int rate,
         * account for collision related packet error rate fluctuation
         * (prob is scaled - see MINSTREL_FRAC above)
         */
-       if (prob_ewma > MINSTREL_FRAC(90, 100))
+       if (prob_avg > MINSTREL_FRAC(90, 100))
                return MINSTREL_TRUNC(100000 * ((MINSTREL_FRAC(90, 100) * 1000)
                                                                      / nsecs));
        else
-               return MINSTREL_TRUNC(100000 * ((prob_ewma * 1000) / nsecs));
+               return MINSTREL_TRUNC(100000 * ((prob_avg * 1000) / nsecs));
 }
 
 /*
@@ -389,13 +389,13 @@ minstrel_ht_sort_best_tp_rates(struct minstrel_ht_sta *mi, u16 index,
 
        cur_group = index / MCS_GROUP_RATES;
        cur_idx = index  % MCS_GROUP_RATES;
-       cur_prob = mi->groups[cur_group].rates[cur_idx].prob_ewma;
+       cur_prob = mi->groups[cur_group].rates[cur_idx].prob_avg;
        cur_tp_avg = minstrel_ht_get_tp_avg(mi, cur_group, cur_idx, cur_prob);
 
        do {
                tmp_group = tp_list[j - 1] / MCS_GROUP_RATES;
                tmp_idx = tp_list[j - 1] % MCS_GROUP_RATES;
-               tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_ewma;
+               tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_avg;
                tmp_tp_avg = minstrel_ht_get_tp_avg(mi, tmp_group, tmp_idx,
                                                    tmp_prob);
                if (cur_tp_avg < tmp_tp_avg ||
@@ -432,7 +432,7 @@ minstrel_ht_set_best_prob_rate(struct minstrel_ht_sta *mi, u16 index)
 
        tmp_group = mi->max_prob_rate / MCS_GROUP_RATES;
        tmp_idx = mi->max_prob_rate % MCS_GROUP_RATES;
-       tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_ewma;
+       tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_avg;
        tmp_tp_avg = minstrel_ht_get_tp_avg(mi, tmp_group, tmp_idx, tmp_prob);
 
        /* if max_tp_rate[0] is from MCS_GROUP max_prob_rate get selected from
@@ -444,11 +444,11 @@ minstrel_ht_set_best_prob_rate(struct minstrel_ht_sta *mi, u16 index)
 
        max_gpr_group = mg->max_group_prob_rate / MCS_GROUP_RATES;
        max_gpr_idx = mg->max_group_prob_rate % MCS_GROUP_RATES;
-       max_gpr_prob = mi->groups[max_gpr_group].rates[max_gpr_idx].prob_ewma;
+       max_gpr_prob = mi->groups[max_gpr_group].rates[max_gpr_idx].prob_avg;
 
-       if (mrs->prob_ewma > MINSTREL_FRAC(75, 100)) {
+       if (mrs->prob_avg > MINSTREL_FRAC(75, 100)) {
                cur_tp_avg = minstrel_ht_get_tp_avg(mi, cur_group, cur_idx,
-                                                   mrs->prob_ewma);
+                                                   mrs->prob_avg);
                if (cur_tp_avg > tmp_tp_avg)
                        mi->max_prob_rate = index;
 
@@ -458,9 +458,9 @@ minstrel_ht_set_best_prob_rate(struct minstrel_ht_sta *mi, u16 index)
                if (cur_tp_avg > max_gpr_tp_avg)
                        mg->max_group_prob_rate = index;
        } else {
-               if (mrs->prob_ewma > tmp_prob)
+               if (mrs->prob_avg > tmp_prob)
                        mi->max_prob_rate = index;
-               if (mrs->prob_ewma > max_gpr_prob)
+               if (mrs->prob_avg > max_gpr_prob)
                        mg->max_group_prob_rate = index;
        }
 }
@@ -482,12 +482,12 @@ minstrel_ht_assign_best_tp_rates(struct minstrel_ht_sta *mi,
 
        tmp_group = tmp_cck_tp_rate[0] / MCS_GROUP_RATES;
        tmp_idx = tmp_cck_tp_rate[0] % MCS_GROUP_RATES;
-       tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_ewma;
+       tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_avg;
        tmp_cck_tp = minstrel_ht_get_tp_avg(mi, tmp_group, tmp_idx, tmp_prob);
 
        tmp_group = tmp_mcs_tp_rate[0] / MCS_GROUP_RATES;
        tmp_idx = tmp_mcs_tp_rate[0] % MCS_GROUP_RATES;
-       tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_ewma;
+       tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_avg;
        tmp_mcs_tp = minstrel_ht_get_tp_avg(mi, tmp_group, tmp_idx, tmp_prob);
 
        if (tmp_cck_tp_rate && tmp_cck_tp > tmp_mcs_tp) {
@@ -518,7 +518,7 @@ minstrel_ht_prob_rate_reduce_streams(struct minstrel_ht_sta *mi)
                        continue;
 
                tmp_idx = mg->max_group_prob_rate % MCS_GROUP_RATES;
-               tmp_prob = mi->groups[group].rates[tmp_idx].prob_ewma;
+               tmp_prob = mi->groups[group].rates[tmp_idx].prob_avg;
 
                if (tmp_tp < minstrel_ht_get_tp_avg(mi, group, tmp_idx, tmp_prob) &&
                   (minstrel_mcs_groups[group].streams < tmp_max_streams)) {
@@ -623,7 +623,7 @@ minstrel_ht_rate_sample_switch(struct minstrel_priv *mp,
         * If that fails, look again for a rate that is at least as fast
         */
        mrs = minstrel_get_ratestats(mi, mi->max_tp_rate[0]);
-       faster_rate = mrs->prob_ewma > MINSTREL_FRAC(75, 100);
+       faster_rate = mrs->prob_avg > MINSTREL_FRAC(75, 100);
        minstrel_ht_find_probe_rates(mi, rates, &n_rates, faster_rate);
        if (!n_rates && faster_rate)
                minstrel_ht_find_probe_rates(mi, rates, &n_rates, false);
@@ -737,8 +737,8 @@ minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
 
                        mrs = &mg->rates[i];
                        mrs->retry_updated = false;
-                       minstrel_calc_rate_stats(mrs);
-                       cur_prob = mrs->prob_ewma;
+                       minstrel_calc_rate_stats(mp, mrs);
+                       cur_prob = mrs->prob_avg;
 
                        if (minstrel_ht_get_tp_avg(mi, group, i, cur_prob) == 0)
                                continue;
@@ -773,6 +773,8 @@ minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
 
        /* try to sample all available rates during each interval */
        mi->sample_count *= 8;
+       if (mp->new_avg)
+               mi->sample_count /= 2;
 
        if (sample)
                minstrel_ht_rate_sample_switch(mp, mi);
@@ -889,6 +891,7 @@ minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband,
        struct ieee80211_tx_rate *ar = info->status.rates;
        struct minstrel_rate_stats *rate, *rate2, *rate_sample = NULL;
        struct minstrel_priv *mp = priv;
+       u32 update_interval = mp->update_interval / 2;
        bool last, update = false;
        bool sample_status = false;
        int i;
@@ -943,6 +946,10 @@ minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband,
 
        switch (mi->sample_mode) {
        case MINSTREL_SAMPLE_IDLE:
+               if (mp->new_avg &&
+                   (mp->hw->max_rates > 1 ||
+                    mi->total_packets_cur < SAMPLE_SWITCH_THR))
+                       update_interval /= 2;
                break;
 
        case MINSTREL_SAMPLE_ACTIVE:
@@ -970,23 +977,20 @@ minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband,
                 */
                rate = minstrel_get_ratestats(mi, mi->max_tp_rate[0]);
                if (rate->attempts > 30 &&
-                   MINSTREL_FRAC(rate->success, rate->attempts) <
-                   MINSTREL_FRAC(20, 100)) {
+                   rate->success < rate->attempts / 4) {
                        minstrel_downgrade_rate(mi, &mi->max_tp_rate[0], true);
                        update = true;
                }
 
                rate2 = minstrel_get_ratestats(mi, mi->max_tp_rate[1]);
                if (rate2->attempts > 30 &&
-                   MINSTREL_FRAC(rate2->success, rate2->attempts) <
-                   MINSTREL_FRAC(20, 100)) {
+                   rate2->success < rate2->attempts / 4) {
                        minstrel_downgrade_rate(mi, &mi->max_tp_rate[1], false);
                        update = true;
                }
        }
 
-       if (time_after(jiffies, mi->last_stats_update +
-                               (mp->update_interval / 2 * HZ) / 1000)) {
+       if (time_after(jiffies, mi->last_stats_update + update_interval)) {
                update = true;
                minstrel_ht_update_stats(mp, mi, true);
        }
@@ -1008,7 +1012,7 @@ minstrel_calc_retransmit(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
        unsigned int overhead = 0, overhead_rtscts = 0;
 
        mrs = minstrel_get_ratestats(mi, index);
-       if (mrs->prob_ewma < MINSTREL_FRAC(1, 10)) {
+       if (mrs->prob_avg < MINSTREL_FRAC(1, 10)) {
                mrs->retry_count = 1;
                mrs->retry_count_rtscts = 1;
                return;
@@ -1065,7 +1069,7 @@ minstrel_ht_set_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
        if (!mrs->retry_updated)
                minstrel_calc_retransmit(mp, mi, index);
 
-       if (mrs->prob_ewma < MINSTREL_FRAC(20, 100) || !mrs->retry_count) {
+       if (mrs->prob_avg < MINSTREL_FRAC(20, 100) || !mrs->retry_count) {
                ratetbl->rate[offset].count = 2;
                ratetbl->rate[offset].count_rts = 2;
                ratetbl->rate[offset].count_cts = 2;
@@ -1099,11 +1103,11 @@ minstrel_ht_set_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
 }
 
 static inline int
-minstrel_ht_get_prob_ewma(struct minstrel_ht_sta *mi, int rate)
+minstrel_ht_get_prob_avg(struct minstrel_ht_sta *mi, int rate)
 {
        int group = rate / MCS_GROUP_RATES;
        rate %= MCS_GROUP_RATES;
-       return mi->groups[group].rates[rate].prob_ewma;
+       return mi->groups[group].rates[rate].prob_avg;
 }
 
 static int
@@ -1115,7 +1119,7 @@ minstrel_ht_get_max_amsdu_len(struct minstrel_ht_sta *mi)
        unsigned int duration;
 
        /* Disable A-MSDU if max_prob_rate is bad */
-       if (mi->groups[group].rates[rate].prob_ewma < MINSTREL_FRAC(50, 100))
+       if (mi->groups[group].rates[rate].prob_avg < MINSTREL_FRAC(50, 100))
                return 1;
 
        duration = g->duration[rate];
@@ -1138,7 +1142,7 @@ minstrel_ht_get_max_amsdu_len(struct minstrel_ht_sta *mi)
         * data packet size
         */
        if (duration > MCS_DURATION(1, 0, 260) ||
-           (minstrel_ht_get_prob_ewma(mi, mi->max_tp_rate[0]) <
+           (minstrel_ht_get_prob_avg(mi, mi->max_tp_rate[0]) <
             MINSTREL_FRAC(75, 100)))
                return 3200;
 
@@ -1243,7 +1247,7 @@ minstrel_get_sample_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
         * rate, to avoid wasting airtime.
         */
        sample_dur = minstrel_get_duration(sample_idx);
-       if (mrs->prob_ewma > MINSTREL_FRAC(95, 100) ||
+       if (mrs->prob_avg > MINSTREL_FRAC(95, 100) ||
            minstrel_get_duration(mi->max_prob_rate) * 3 < sample_dur)
                return -1;
 
@@ -1666,7 +1670,8 @@ minstrel_ht_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
                mp->has_mrr = true;
 
        mp->hw = hw;
-       mp->update_interval = 100;
+       mp->update_interval = HZ / 10;
+       mp->new_avg = true;
 
 #ifdef CONFIG_MAC80211_DEBUGFS
        mp->fixed_rate_idx = (u32) -1;
@@ -1674,6 +1679,8 @@ minstrel_ht_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
                           &mp->fixed_rate_idx);
        debugfs_create_u32("sample_switch", S_IRUGO | S_IWUSR, debugfsdir,
                           &mp->sample_switch);
+       debugfs_create_bool("new_avg", S_IRUGO | S_IWUSR, debugfsdir,
+                          &mp->new_avg);
 #endif
 
        minstrel_ht_init_cck_rates(mp);
@@ -1698,7 +1705,7 @@ static u32 minstrel_ht_get_expected_throughput(void *priv_sta)
 
        i = mi->max_tp_rate[0] / MCS_GROUP_RATES;
        j = mi->max_tp_rate[0] % MCS_GROUP_RATES;
-       prob = mi->groups[i].rates[j].prob_ewma;
+       prob = mi->groups[i].rates[j].prob_avg;
 
        /* convert tp_avg from pkt per second in kbps */
        tp_avg = minstrel_ht_get_tp_avg(mi, i, j, prob) * 10;
index f938701e7ab7d6348d243e4e809942f067df76b5..53ea3c29debfdff7986ec6263c3ef1faf37db47c 100644 (file)
@@ -119,6 +119,6 @@ struct minstrel_ht_sta_priv {
 
 void minstrel_ht_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir);
 int minstrel_ht_get_tp_avg(struct minstrel_ht_sta *mi, int group, int rate,
-                          int prob_ewma);
+                          int prob_avg);
 
 #endif
index 5a6e9f3edc041c66cf6b377b58bdf06f74dcc619..bebb71917742a73f35f2d7f2dff72f342200e32a 100644 (file)
@@ -98,8 +98,8 @@ minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p)
                p += sprintf(p, "%6u  ", tx_time);
 
                tp_max = minstrel_ht_get_tp_avg(mi, i, j, MINSTREL_FRAC(100, 100));
-               tp_avg = minstrel_ht_get_tp_avg(mi, i, j, mrs->prob_ewma);
-               eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000);
+               tp_avg = minstrel_ht_get_tp_avg(mi, i, j, mrs->prob_avg);
+               eprob = MINSTREL_TRUNC(mrs->prob_avg * 1000);
 
                p += sprintf(p, "%4u.%1u    %4u.%1u     %3u.%1u"
                                "     %3u   %3u %-3u   "
@@ -243,8 +243,8 @@ minstrel_ht_stats_csv_dump(struct minstrel_ht_sta *mi, int i, char *p)
                p += sprintf(p, "%u,", tx_time);
 
                tp_max = minstrel_ht_get_tp_avg(mi, i, j, MINSTREL_FRAC(100, 100));
-               tp_avg = minstrel_ht_get_tp_avg(mi, i, j, mrs->prob_ewma);
-               eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000);
+               tp_avg = minstrel_ht_get_tp_avg(mi, i, j, mrs->prob_avg);
+               eprob = MINSTREL_TRUNC(mrs->prob_avg * 1000);
 
                p += sprintf(p, "%u.%u,%u.%u,%u.%u,%u,%u,"
                                "%u,%llu,%llu,",
index 1fa422782905873cfac8fc4964cfecd012308346..938c10f7955bcb4516d493df6e783518c8fb3ba6 100644 (file)
@@ -1617,7 +1617,7 @@ static bool ieee80211_queue_skb(struct ieee80211_local *local,
 
 static bool ieee80211_tx_frags(struct ieee80211_local *local,
                               struct ieee80211_vif *vif,
-                              struct ieee80211_sta *sta,
+                              struct sta_info *sta,
                               struct sk_buff_head *skbs,
                               bool txpending)
 {
@@ -1679,7 +1679,7 @@ static bool ieee80211_tx_frags(struct ieee80211_local *local,
                spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
 
                info->control.vif = vif;
-               control.sta = sta;
+               control.sta = sta ? &sta->sta : NULL;
 
                __skb_unlink(skb, skbs);
                drv_tx(local, &control, skb);
@@ -1698,7 +1698,6 @@ static bool __ieee80211_tx(struct ieee80211_local *local,
        struct ieee80211_tx_info *info;
        struct ieee80211_sub_if_data *sdata;
        struct ieee80211_vif *vif;
-       struct ieee80211_sta *pubsta;
        struct sk_buff *skb;
        bool result = true;
        __le16 fc;
@@ -1713,11 +1712,6 @@ static bool __ieee80211_tx(struct ieee80211_local *local,
        if (sta && !sta->uploaded)
                sta = NULL;
 
-       if (sta)
-               pubsta = &sta->sta;
-       else
-               pubsta = NULL;
-
        switch (sdata->vif.type) {
        case NL80211_IFTYPE_MONITOR:
                if (sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE) {
@@ -1744,8 +1738,7 @@ static bool __ieee80211_tx(struct ieee80211_local *local,
                break;
        }
 
-       result = ieee80211_tx_frags(local, vif, pubsta, skbs,
-                                   txpending);
+       result = ieee80211_tx_frags(local, vif, sta, skbs, txpending);
 
        ieee80211_tpt_led_trig_tx(local, fc, led_len);
 
@@ -3529,7 +3522,7 @@ static bool ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata,
                                     struct ieee80211_sub_if_data, u.ap);
 
        __skb_queue_tail(&tx.skbs, skb);
-       ieee80211_tx_frags(local, &sdata->vif, &sta->sta, &tx.skbs, false);
+       ieee80211_tx_frags(local, &sdata->vif, sta, &tx.skbs, false);
        return true;
 }
 
index 141cdb171665e6b371c7d03818b46d17810ef912..7a7b63550eb648c8137c9ba766624d8c10ace3a0 100644 (file)
@@ -8265,10 +8265,8 @@ static int nl80211_start_sched_scan(struct sk_buff *skb,
        /* leave request id zero for legacy request
         * or if driver does not support multi-scheduled scan
         */
-       if (want_multi && rdev->wiphy.max_sched_scan_reqs > 1) {
-               while (!sched_scan_req->reqid)
-                       sched_scan_req->reqid = cfg80211_assign_cookie(rdev);
-       }
+       if (want_multi && rdev->wiphy.max_sched_scan_reqs > 1)
+               sched_scan_req->reqid = cfg80211_assign_cookie(rdev);
 
        err = rdev_sched_scan_start(rdev, dev, sched_scan_req);
        if (err)