]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 18 May 2017 08:19:21 +0000 (10:19 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 18 May 2017 08:19:21 +0000 (10:19 +0200)
added patches:
mac80211-pass-block-ack-session-timeout-to-to-driver.patch
mac80211-pass-rx-aggregation-window-size-to-driver.patch
mac80211-rx-ba-support-for-sta-max_rx_aggregation_subframes.patch
wlcore-add-rx_ba_win_size_change_event-event.patch
wlcore-pass-win_size-taken-from-ieee80211_sta-to-fw.patch

queue-4.4/mac80211-pass-block-ack-session-timeout-to-to-driver.patch [new file with mode: 0644]
queue-4.4/mac80211-pass-rx-aggregation-window-size-to-driver.patch [new file with mode: 0644]
queue-4.4/mac80211-rx-ba-support-for-sta-max_rx_aggregation_subframes.patch [new file with mode: 0644]
queue-4.4/series
queue-4.4/wlcore-add-rx_ba_win_size_change_event-event.patch [new file with mode: 0644]
queue-4.4/wlcore-pass-win_size-taken-from-ieee80211_sta-to-fw.patch [new file with mode: 0644]

diff --git a/queue-4.4/mac80211-pass-block-ack-session-timeout-to-to-driver.patch b/queue-4.4/mac80211-pass-block-ack-session-timeout-to-to-driver.patch
new file mode 100644 (file)
index 0000000..c615cd9
--- /dev/null
@@ -0,0 +1,843 @@
+From 50ea05efaf3bed7dd34bcc2635a8b3f53bd0ccc1 Mon Sep 17 00:00:00 2001
+From: Sara Sharon <sarasharon1@gmail.com>
+Date: Wed, 30 Dec 2015 16:06:04 +0200
+Subject: mac80211: pass block ack session timeout to to driver
+
+From: Sara Sharon <sarasharon1@gmail.com>
+
+commit 50ea05efaf3bed7dd34bcc2635a8b3f53bd0ccc1 upstream.
+
+Currently mac80211 does not inform the driver of the session
+block ack timeout when starting a rx aggregation session.
+Drivers that manage the reorder buffer need to know this
+parameter.
+Seeing that there are now too many arguments for the
+drv_ampdu_action() function, wrap them inside a structure.
+
+Signed-off-by: Sara Sharon <sara.sharon@intel.com>
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/wireless/ath/ath10k/mac.c                 |    7 +-
+ drivers/net/wireless/ath/ath9k/htc_drv_main.c         |    7 +-
+ drivers/net/wireless/ath/ath9k/main.c                 |    8 +-
+ drivers/net/wireless/ath/carl9170/main.c              |    8 +-
+ drivers/net/wireless/ath/wcn36xx/main.c               |    8 +-
+ drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c |    8 +-
+ drivers/net/wireless/cw1200/sta.c                     |    4 -
+ drivers/net/wireless/cw1200/sta.h                     |    4 -
+ drivers/net/wireless/iwlegacy/4965-mac.c              |    8 +-
+ drivers/net/wireless/iwlegacy/4965.h                  |    4 -
+ drivers/net/wireless/iwlwifi/dvm/mac80211.c           |    9 ++-
+ drivers/net/wireless/iwlwifi/mvm/mac80211.c           |    9 ++-
+ drivers/net/wireless/mac80211_hwsim.c                 |    8 +-
+ drivers/net/wireless/mediatek/mt7601u/main.c          |    8 +-
+ drivers/net/wireless/mwl8k.c                          |   10 ++-
+ drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.c      |    6 +-
+ drivers/net/wireless/realtek/rtlwifi/core.c           |    8 +-
+ drivers/net/wireless/rsi/rsi_91x_mac80211.c           |   19 ++----
+ drivers/net/wireless/rt2x00/rt2800lib.c               |    7 +-
+ drivers/net/wireless/rt2x00/rt2800lib.h               |    4 -
+ drivers/net/wireless/ti/wlcore/main.c                 |    8 +-
+ include/net/mac80211.h                                |   44 ++++++++++----
+ net/mac80211/agg-rx.c                                 |   25 +++++++-
+ net/mac80211/agg-tx.c                                 |   53 +++++++++++-------
+ net/mac80211/driver-ops.c                             |   10 +--
+ net/mac80211/driver-ops.h                             |    4 -
+ net/mac80211/trace.h                                  |   43 +++++++-------
+ 27 files changed, 202 insertions(+), 139 deletions(-)
+
+--- a/drivers/net/wireless/ath/ath10k/mac.c
++++ b/drivers/net/wireless/ath/ath10k/mac.c
+@@ -6351,12 +6351,13 @@ static u64 ath10k_get_tsf(struct ieee802
+ static int ath10k_ampdu_action(struct ieee80211_hw *hw,
+                              struct ieee80211_vif *vif,
+-                             enum ieee80211_ampdu_mlme_action action,
+-                             struct ieee80211_sta *sta, u16 tid, u16 *ssn,
+-                             u8 buf_size, bool amsdu)
++                             struct ieee80211_ampdu_params *params)
+ {
+       struct ath10k *ar = hw->priv;
+       struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
++      struct ieee80211_sta *sta = params->sta;
++      enum ieee80211_ampdu_mlme_action action = params->action;
++      u16 tid = params->tid;
+       ath10k_dbg(ar, ATH10K_DBG_MAC, "mac ampdu vdev_id %i sta %pM tid %hu action %d\n",
+                  arvif->vdev_id, sta->addr, tid, action);
+--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
++++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+@@ -1657,13 +1657,14 @@ static void ath9k_htc_reset_tsf(struct i
+ static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw,
+                                 struct ieee80211_vif *vif,
+-                                enum ieee80211_ampdu_mlme_action action,
+-                                struct ieee80211_sta *sta,
+-                                u16 tid, u16 *ssn, u8 buf_size, bool amsdu)
++                                struct ieee80211_ampdu_params *params)
+ {
+       struct ath9k_htc_priv *priv = hw->priv;
+       struct ath9k_htc_sta *ista;
+       int ret = 0;
++      struct ieee80211_sta *sta = params->sta;
++      enum ieee80211_ampdu_mlme_action action = params->action;
++      u16 tid = params->tid;
+       mutex_lock(&priv->mutex);
+       ath9k_htc_ps_wakeup(priv);
+--- a/drivers/net/wireless/ath/ath9k/main.c
++++ b/drivers/net/wireless/ath/ath9k/main.c
+@@ -1855,14 +1855,16 @@ static void ath9k_reset_tsf(struct ieee8
+ static int ath9k_ampdu_action(struct ieee80211_hw *hw,
+                             struct ieee80211_vif *vif,
+-                            enum ieee80211_ampdu_mlme_action action,
+-                            struct ieee80211_sta *sta,
+-                            u16 tid, u16 *ssn, u8 buf_size, bool amsdu)
++                            struct ieee80211_ampdu_params *params)
+ {
+       struct ath_softc *sc = hw->priv;
+       struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+       bool flush = false;
+       int ret = 0;
++      struct ieee80211_sta *sta = params->sta;
++      enum ieee80211_ampdu_mlme_action action = params->action;
++      u16 tid = params->tid;
++      u16 *ssn = &params->ssn;
+       mutex_lock(&sc->mutex);
+--- a/drivers/net/wireless/ath/carl9170/main.c
++++ b/drivers/net/wireless/ath/carl9170/main.c
+@@ -1413,10 +1413,12 @@ static void carl9170_ampdu_work(struct w
+ static int carl9170_op_ampdu_action(struct ieee80211_hw *hw,
+                                   struct ieee80211_vif *vif,
+-                                  enum ieee80211_ampdu_mlme_action action,
+-                                  struct ieee80211_sta *sta,
+-                                  u16 tid, u16 *ssn, u8 buf_size, bool amsdu)
++                                  struct ieee80211_ampdu_params *params)
+ {
++      struct ieee80211_sta *sta = params->sta;
++      enum ieee80211_ampdu_mlme_action action = params->action;
++      u16 tid = params->tid;
++      u16 *ssn = &params->ssn;
+       struct ar9170 *ar = hw->priv;
+       struct carl9170_sta_info *sta_info = (void *) sta->drv_priv;
+       struct carl9170_sta_tid *tid_info;
+--- a/drivers/net/wireless/ath/wcn36xx/main.c
++++ b/drivers/net/wireless/ath/wcn36xx/main.c
+@@ -857,12 +857,14 @@ static int wcn36xx_resume(struct ieee802
+ static int wcn36xx_ampdu_action(struct ieee80211_hw *hw,
+                   struct ieee80211_vif *vif,
+-                  enum ieee80211_ampdu_mlme_action action,
+-                  struct ieee80211_sta *sta, u16 tid, u16 *ssn,
+-                  u8 buf_size, bool amsdu)
++                  struct ieee80211_ampdu_params *params)
+ {
+       struct wcn36xx *wcn = hw->priv;
+       struct wcn36xx_sta *sta_priv = NULL;
++      struct ieee80211_sta *sta = params->sta;
++      enum ieee80211_ampdu_mlme_action action = params->action;
++      u16 tid = params->tid;
++      u16 *ssn = &params->ssn;
+       wcn36xx_dbg(WCN36XX_DBG_MAC, "mac ampdu action action %d tid %d\n",
+                   action, tid);
+--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
++++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+@@ -818,13 +818,15 @@ brcms_ops_sta_add(struct ieee80211_hw *h
+ static int
+ brcms_ops_ampdu_action(struct ieee80211_hw *hw,
+                   struct ieee80211_vif *vif,
+-                  enum ieee80211_ampdu_mlme_action action,
+-                  struct ieee80211_sta *sta, u16 tid, u16 *ssn,
+-                  u8 buf_size, bool amsdu)
++                  struct ieee80211_ampdu_params *params)
+ {
+       struct brcms_info *wl = hw->priv;
+       struct scb *scb = &wl->wlc->pri_scb;
+       int status;
++      struct ieee80211_sta *sta = params->sta;
++      enum ieee80211_ampdu_mlme_action action = params->action;
++      u16 tid = params->tid;
++      u8 buf_size = params->buf_size;
+       if (WARN_ON(scb->magic != SCB_MAGIC))
+               return -EIDRM;
+--- a/drivers/net/wireless/cw1200/sta.c
++++ b/drivers/net/wireless/cw1200/sta.c
+@@ -2135,9 +2135,7 @@ void cw1200_mcast_timeout(unsigned long
+ int cw1200_ampdu_action(struct ieee80211_hw *hw,
+                       struct ieee80211_vif *vif,
+-                      enum ieee80211_ampdu_mlme_action action,
+-                      struct ieee80211_sta *sta, u16 tid, u16 *ssn,
+-                      u8 buf_size, bool amsdu)
++                      struct ieee80211_ampdu_params *params)
+ {
+       /* Aggregation is implemented fully in firmware,
+        * including block ack negotiation. Do not allow
+--- a/drivers/net/wireless/cw1200/sta.h
++++ b/drivers/net/wireless/cw1200/sta.h
+@@ -109,9 +109,7 @@ void cw1200_bss_info_changed(struct ieee
+                            u32 changed);
+ int cw1200_ampdu_action(struct ieee80211_hw *hw,
+                       struct ieee80211_vif *vif,
+-                      enum ieee80211_ampdu_mlme_action action,
+-                      struct ieee80211_sta *sta, u16 tid, u16 *ssn,
+-                      u8 buf_size, bool amsdu);
++                      struct ieee80211_ampdu_params *params);
+ void cw1200_suspend_resume(struct cw1200_common *priv,
+                         struct wsm_suspend_resume *arg);
+--- a/drivers/net/wireless/iwlegacy/4965-mac.c
++++ b/drivers/net/wireless/iwlegacy/4965-mac.c
+@@ -5982,12 +5982,14 @@ il4965_mac_set_key(struct ieee80211_hw *
+ int
+ il4965_mac_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+-                      enum ieee80211_ampdu_mlme_action action,
+-                      struct ieee80211_sta *sta, u16 tid, u16 * ssn,
+-                      u8 buf_size, bool amsdu)
++                      struct ieee80211_ampdu_params *params)
+ {
+       struct il_priv *il = hw->priv;
+       int ret = -EINVAL;
++      struct ieee80211_sta *sta = params->sta;
++      enum ieee80211_ampdu_mlme_action action = params->action;
++      u16 tid = params->tid;
++      u16 *ssn = &params->ssn;
+       D_HT("A-MPDU action on addr %pM tid %d\n", sta->addr, tid);
+--- a/drivers/net/wireless/iwlegacy/4965.h
++++ b/drivers/net/wireless/iwlegacy/4965.h
+@@ -182,9 +182,7 @@ void il4965_mac_update_tkip_key(struct i
+                               struct ieee80211_sta *sta, u32 iv32,
+                               u16 *phase1key);
+ int il4965_mac_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+-                          enum ieee80211_ampdu_mlme_action action,
+-                          struct ieee80211_sta *sta, u16 tid, u16 * ssn,
+-                          u8 buf_size, bool amsdu);
++                          struct ieee80211_ampdu_params *params);
+ int il4965_mac_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+                      struct ieee80211_sta *sta);
+ void
+--- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c
++++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
+@@ -729,12 +729,15 @@ static inline bool iwl_enable_tx_ampdu(c
+ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
+                                  struct ieee80211_vif *vif,
+-                                 enum ieee80211_ampdu_mlme_action action,
+-                                 struct ieee80211_sta *sta, u16 tid, u16 *ssn,
+-                                 u8 buf_size, bool amsdu)
++                                 struct ieee80211_ampdu_params *params)
+ {
+       struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
+       int ret = -EINVAL;
++      struct ieee80211_sta *sta = params->sta;
++      enum ieee80211_ampdu_mlme_action action = params->action;
++      u16 tid = params->tid;
++      u16 *ssn = &params->ssn;
++      u8 buf_size = params->buf_size;
+       struct iwl_station_priv *sta_priv = (void *) sta->drv_priv;
+       IWL_DEBUG_HT(priv, "A-MPDU action on addr %pM tid %d\n",
+--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
++++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+@@ -826,13 +826,16 @@ iwl_mvm_ampdu_check_trigger(struct iwl_m
+ static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw,
+                                   struct ieee80211_vif *vif,
+-                                  enum ieee80211_ampdu_mlme_action action,
+-                                  struct ieee80211_sta *sta, u16 tid,
+-                                  u16 *ssn, u8 buf_size, bool amsdu)
++                                  struct ieee80211_ampdu_params *params)
+ {
+       struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
+       int ret;
+       bool tx_agg_ref = false;
++      struct ieee80211_sta *sta = params->sta;
++      enum ieee80211_ampdu_mlme_action action = params->action;
++      u16 tid = params->tid;
++      u16 *ssn = &params->ssn;
++      u8 buf_size = params->buf_size;
+       IWL_DEBUG_HT(mvm, "A-MPDU action on addr %pM tid %d: action %d\n",
+                    sta->addr, tid, action);
+--- a/drivers/net/wireless/mac80211_hwsim.c
++++ b/drivers/net/wireless/mac80211_hwsim.c
+@@ -1817,10 +1817,12 @@ static int mac80211_hwsim_testmode_cmd(s
+ static int mac80211_hwsim_ampdu_action(struct ieee80211_hw *hw,
+                                      struct ieee80211_vif *vif,
+-                                     enum ieee80211_ampdu_mlme_action action,
+-                                     struct ieee80211_sta *sta, u16 tid, u16 *ssn,
+-                                     u8 buf_size, bool amsdu)
++                                     struct ieee80211_ampdu_params *params)
+ {
++      struct ieee80211_sta *sta = params->sta;
++      enum ieee80211_ampdu_mlme_action action = params->action;
++      u16 tid = params->tid;
++
+       switch (action) {
+       case IEEE80211_AMPDU_TX_START:
+               ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
+--- a/drivers/net/wireless/mediatek/mt7601u/main.c
++++ b/drivers/net/wireless/mediatek/mt7601u/main.c
+@@ -334,11 +334,13 @@ static int mt7601u_set_rts_threshold(str
+ static int
+ mt76_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+-                enum ieee80211_ampdu_mlme_action action,
+-                struct ieee80211_sta *sta, u16 tid, u16 *ssn, u8 buf_size,
+-                bool amsdu)
++                struct ieee80211_ampdu_params *params)
+ {
+       struct mt7601u_dev *dev = hw->priv;
++      struct ieee80211_sta *sta = params->sta;
++      enum ieee80211_ampdu_mlme_action action = params->action;
++      u16 tid = params->tid;
++      u16 *ssn = &params->ssn;
+       struct mt76_sta *msta = (struct mt76_sta *) sta->drv_priv;
+       WARN_ON(msta->wcid.idx > GROUP_WCID(0));
+--- a/drivers/net/wireless/mwl8k.c
++++ b/drivers/net/wireless/mwl8k.c
+@@ -5421,11 +5421,13 @@ static int mwl8k_get_survey(struct ieee8
+ static int
+ mwl8k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+-                 enum ieee80211_ampdu_mlme_action action,
+-                 struct ieee80211_sta *sta, u16 tid, u16 *ssn,
+-                 u8 buf_size, bool amsdu)
++                 struct ieee80211_ampdu_params *params)
+ {
+-
++      struct ieee80211_sta *sta = params->sta;
++      enum ieee80211_ampdu_mlme_action action = params->action;
++      u16 tid = params->tid;
++      u16 *ssn = &params->ssn;
++      u8 buf_size = params->buf_size;
+       int i, rc = 0;
+       struct mwl8k_priv *priv = hw->priv;
+       struct mwl8k_ampdu_stream *stream;
+--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.c
++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.c
+@@ -5375,13 +5375,13 @@ static int rtl8xxxu_set_key(struct ieee8
+ static int
+ rtl8xxxu_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+-                    enum ieee80211_ampdu_mlme_action action,
+-                    struct ieee80211_sta *sta, u16 tid, u16 *ssn, u8 buf_size,
+-                    bool amsdu)
++                    struct ieee80211_ampdu_params *params)
+ {
+       struct rtl8xxxu_priv *priv = hw->priv;
+       struct device *dev = &priv->udev->dev;
+       u8 ampdu_factor, ampdu_density;
++      struct ieee80211_sta *sta = params->sta;
++      enum ieee80211_ampdu_mlme_action action = params->action;
+       switch (action) {
+       case IEEE80211_AMPDU_TX_START:
+--- a/drivers/net/wireless/realtek/rtlwifi/core.c
++++ b/drivers/net/wireless/realtek/rtlwifi/core.c
+@@ -1369,11 +1369,13 @@ static void rtl_op_sta_notify(struct iee
+ static int rtl_op_ampdu_action(struct ieee80211_hw *hw,
+                              struct ieee80211_vif *vif,
+-                             enum ieee80211_ampdu_mlme_action action,
+-                             struct ieee80211_sta *sta, u16 tid, u16 *ssn,
+-                             u8 buf_size, bool amsdu)
++                             struct ieee80211_ampdu_params *params)
+ {
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
++      struct ieee80211_sta *sta = params->sta;
++      enum ieee80211_ampdu_mlme_action action = params->action;
++      u16 tid = params->tid;
++      u16 *ssn = &params->ssn;
+       switch (action) {
+       case IEEE80211_AMPDU_TX_START:
+--- a/drivers/net/wireless/rsi/rsi_91x_mac80211.c
++++ b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
+@@ -659,29 +659,24 @@ static int rsi_mac80211_set_key(struct i
+  *                             informs the f/w regarding this.
+  * @hw: Pointer to the ieee80211_hw structure.
+  * @vif: Pointer to the ieee80211_vif structure.
+- * @action: ieee80211_ampdu_mlme_action enum.
+- * @sta: Pointer to the ieee80211_sta structure.
+- * @tid: Traffic identifier.
+- * @ssn: Pointer to ssn value.
+- * @buf_size: Buffer size (for kernel version > 2.6.38).
+- * @amsdu: is AMSDU in AMPDU allowed
++ * @params: Pointer to A-MPDU action parameters
+  *
+  * Return: status: 0 on success, negative error code on failure.
+  */
+ static int rsi_mac80211_ampdu_action(struct ieee80211_hw *hw,
+                                    struct ieee80211_vif *vif,
+-                                   enum ieee80211_ampdu_mlme_action action,
+-                                   struct ieee80211_sta *sta,
+-                                   unsigned short tid,
+-                                   unsigned short *ssn,
+-                                   unsigned char buf_size,
+-                                   bool amsdu)
++                                   struct ieee80211_ampdu_params *params)
+ {
+       int status = -EOPNOTSUPP;
+       struct rsi_hw *adapter = hw->priv;
+       struct rsi_common *common = adapter->priv;
+       u16 seq_no = 0;
+       u8 ii = 0;
++      struct ieee80211_sta *sta = params->sta;
++      enum ieee80211_ampdu_mlme_action action = params->action;
++      u16 tid = params->tid;
++      u16 *ssn = &params->ssn;
++      u8 buf_size = params->buf_size;
+       for (ii = 0; ii < RSI_MAX_VIFS; ii++) {
+               if (vif == adapter->vifs[ii])
+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+@@ -7935,10 +7935,11 @@ u64 rt2800_get_tsf(struct ieee80211_hw *
+ EXPORT_SYMBOL_GPL(rt2800_get_tsf);
+ int rt2800_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+-                      enum ieee80211_ampdu_mlme_action action,
+-                      struct ieee80211_sta *sta, u16 tid, u16 *ssn,
+-                      u8 buf_size, bool amsdu)
++                      struct ieee80211_ampdu_params *params)
+ {
++      struct ieee80211_sta *sta = params->sta;
++      enum ieee80211_ampdu_mlme_action action = params->action;
++      u16 tid = params->tid;
+       struct rt2x00_sta *sta_priv = (struct rt2x00_sta *)sta->drv_priv;
+       int ret = 0;
+--- a/drivers/net/wireless/rt2x00/rt2800lib.h
++++ b/drivers/net/wireless/rt2x00/rt2800lib.h
+@@ -218,9 +218,7 @@ int rt2800_conf_tx(struct ieee80211_hw *
+                  const struct ieee80211_tx_queue_params *params);
+ u64 rt2800_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
+ int rt2800_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+-                      enum ieee80211_ampdu_mlme_action action,
+-                      struct ieee80211_sta *sta, u16 tid, u16 *ssn,
+-                      u8 buf_size, bool amsdu);
++                      struct ieee80211_ampdu_params *params);
+ int rt2800_get_survey(struct ieee80211_hw *hw, int idx,
+                     struct survey_info *survey);
+ void rt2800_disable_wpdma(struct rt2x00_dev *rt2x00dev);
+--- a/drivers/net/wireless/ti/wlcore/main.c
++++ b/drivers/net/wireless/ti/wlcore/main.c
+@@ -5261,14 +5261,16 @@ out:
+ static int wl1271_op_ampdu_action(struct ieee80211_hw *hw,
+                                 struct ieee80211_vif *vif,
+-                                enum ieee80211_ampdu_mlme_action action,
+-                                struct ieee80211_sta *sta, u16 tid, u16 *ssn,
+-                                u8 buf_size, bool amsdu)
++                                struct ieee80211_ampdu_params *params)
+ {
+       struct wl1271 *wl = hw->priv;
+       struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
+       int ret;
+       u8 hlid, *ba_bitmap;
++      struct ieee80211_sta *sta = params->sta;
++      enum ieee80211_ampdu_mlme_action action = params->action;
++      u16 tid = params->tid;
++      u16 *ssn = &params->ssn;
+       wl1271_debug(DEBUG_MAC80211, "mac80211 ampdu action %d tid %d", action,
+                    tid);
+--- a/include/net/mac80211.h
++++ b/include/net/mac80211.h
+@@ -2674,6 +2674,33 @@ enum ieee80211_ampdu_mlme_action {
+ };
+ /**
++ * struct ieee80211_ampdu_params - AMPDU action parameters
++ *
++ * @action: the ampdu action, value from %ieee80211_ampdu_mlme_action.
++ * @sta: peer of this AMPDU session
++ * @tid: tid of the BA session
++ * @ssn: start sequence number of the session. TX/RX_STOP can pass 0. When
++ *    action is set to %IEEE80211_AMPDU_RX_START the driver passes back the
++ *    actual ssn value used to start the session and writes the value here.
++ * @buf_size: reorder buffer size  (number of subframes). Valid only when the
++ *    action is set to %IEEE80211_AMPDU_RX_START or
++ *    %IEEE80211_AMPDU_TX_OPERATIONAL
++ * @amsdu: indicates the peer's ability to receive A-MSDU within A-MPDU.
++ *    valid when the action is set to %IEEE80211_AMPDU_TX_OPERATIONAL
++ * @timeout: BA session timeout. Valid only when the action is set to
++ *    %IEEE80211_AMPDU_RX_START
++ */
++struct ieee80211_ampdu_params {
++      enum ieee80211_ampdu_mlme_action action;
++      struct ieee80211_sta *sta;
++      u16 tid;
++      u16 ssn;
++      u8 buf_size;
++      bool amsdu;
++      u16 timeout;
++};
++
++/**
+  * enum ieee80211_frame_release_type - frame release reason
+  * @IEEE80211_FRAME_RELEASE_PSPOLL: frame released for PS-Poll
+  * @IEEE80211_FRAME_RELEASE_UAPSD: frame(s) released due to
+@@ -3017,15 +3044,9 @@ enum ieee80211_reconfig_type {
+  * @ampdu_action: Perform a certain A-MPDU action
+  *    The RA/TID combination determines the destination and TID we want
+  *    the ampdu action to be performed for. The action is defined through
+- *    ieee80211_ampdu_mlme_action. Starting sequence number (@ssn)
+- *    is the first frame we expect to perform the action on. Notice
+- *    that TX/RX_STOP can pass NULL for this parameter.
+- *    The @buf_size parameter is valid only when the action is set to
+- *    %IEEE80211_AMPDU_RX_START or %IEEE80211_AMPDU_TX_OPERATIONAL and
+- *    indicates the reorder buffer size (number of subframes) for this
+- *    session.
++ *    ieee80211_ampdu_mlme_action.
+  *    When the action is set to %IEEE80211_AMPDU_TX_OPERATIONAL the driver
+- *    may neither send aggregates containing more subframes than this
++ *    may neither send aggregates containing more subframes than @buf_size
+  *    nor send aggregates in a way that lost frames would exceed the
+  *    buffer size. If just limiting the aggregate size, this would be
+  *    possible with a buf_size of 8:
+@@ -3036,9 +3057,6 @@ enum ieee80211_reconfig_type {
+  *    buffer size of 8. Correct ways to retransmit #1 would be:
+  *     - TX:       1 or 18 or 81
+  *    Even "189" would be wrong since 1 could be lost again.
+- *    The @amsdu parameter is valid when the action is set to
+- *    %IEEE80211_AMPDU_TX_OPERATIONAL and indicates the peer's ability
+- *    to receive A-MSDU within A-MPDU.
+  *
+  *    Returns a negative error code on failure.
+  *    The callback can sleep.
+@@ -3380,9 +3398,7 @@ struct ieee80211_ops {
+       int (*tx_last_beacon)(struct ieee80211_hw *hw);
+       int (*ampdu_action)(struct ieee80211_hw *hw,
+                           struct ieee80211_vif *vif,
+-                          enum ieee80211_ampdu_mlme_action action,
+-                          struct ieee80211_sta *sta, u16 tid, u16 *ssn,
+-                          u8 buf_size, bool amsdu);
++                          struct ieee80211_ampdu_params *params);
+       int (*get_survey)(struct ieee80211_hw *hw, int idx,
+               struct survey_info *survey);
+       void (*rfkill_poll)(struct ieee80211_hw *hw);
+--- a/net/mac80211/agg-rx.c
++++ b/net/mac80211/agg-rx.c
+@@ -7,6 +7,7 @@
+  * Copyright 2006-2007        Jiri Benc <jbenc@suse.cz>
+  * Copyright 2007, Michael Wu <flamingice@sourmilk.net>
+  * Copyright 2007-2010, Intel Corporation
++ * Copyright(c) 2015 Intel Deutschland GmbH
+  *
+  * This program is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License version 2 as
+@@ -61,6 +62,14 @@ void ___ieee80211_stop_rx_ba_session(str
+ {
+       struct ieee80211_local *local = sta->local;
+       struct tid_ampdu_rx *tid_rx;
++      struct ieee80211_ampdu_params params = {
++              .sta = &sta->sta,
++              .action = IEEE80211_AMPDU_RX_STOP,
++              .tid = tid,
++              .amsdu = false,
++              .timeout = 0,
++              .ssn = 0,
++      };
+       lockdep_assert_held(&sta->ampdu_mlme.mtx);
+@@ -78,8 +87,7 @@ void ___ieee80211_stop_rx_ba_session(str
+              initiator == WLAN_BACK_RECIPIENT ? "recipient" : "inititator",
+              (int)reason);
+-      if (drv_ampdu_action(local, sta->sdata, IEEE80211_AMPDU_RX_STOP,
+-                           &sta->sta, tid, NULL, 0, false))
++      if (drv_ampdu_action(local, sta->sdata, &params))
+               sdata_info(sta->sdata,
+                          "HW problem - can not stop rx aggregation for %pM tid %d\n",
+                          sta->sta.addr, tid);
+@@ -237,6 +245,15 @@ void __ieee80211_start_rx_ba_session(str
+ {
+       struct ieee80211_local *local = sta->sdata->local;
+       struct tid_ampdu_rx *tid_agg_rx;
++      struct ieee80211_ampdu_params params = {
++              .sta = &sta->sta,
++              .action = IEEE80211_AMPDU_RX_START,
++              .tid = tid,
++              .amsdu = false,
++              .timeout = timeout,
++              .ssn = start_seq_num,
++      };
++
+       int i, ret = -EOPNOTSUPP;
+       u16 status = WLAN_STATUS_REQUEST_DECLINED;
+@@ -275,6 +292,7 @@ void __ieee80211_start_rx_ba_session(str
+       /* make sure the size doesn't exceed the maximum supported by the hw */
+       if (buf_size > local->hw.max_rx_aggregation_subframes)
+               buf_size = local->hw.max_rx_aggregation_subframes;
++      params.buf_size = buf_size;
+       /* examine state machine */
+       mutex_lock(&sta->ampdu_mlme.mtx);
+@@ -322,8 +340,7 @@ void __ieee80211_start_rx_ba_session(str
+       for (i = 0; i < buf_size; i++)
+               __skb_queue_head_init(&tid_agg_rx->reorder_buf[i]);
+-      ret = drv_ampdu_action(local, sta->sdata, IEEE80211_AMPDU_RX_START,
+-                             &sta->sta, tid, &start_seq_num, buf_size, false);
++      ret = drv_ampdu_action(local, sta->sdata, &params);
+       ht_dbg(sta->sdata, "Rx A-MPDU request on %pM tid %d result %d\n",
+              sta->sta.addr, tid, ret);
+       if (ret) {
+--- a/net/mac80211/agg-tx.c
++++ b/net/mac80211/agg-tx.c
+@@ -7,6 +7,7 @@
+  * Copyright 2006-2007        Jiri Benc <jbenc@suse.cz>
+  * Copyright 2007, Michael Wu <flamingice@sourmilk.net>
+  * Copyright 2007-2010, Intel Corporation
++ * Copyright(c) 2015 Intel Deutschland GmbH
+  *
+  * This program is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License version 2 as
+@@ -295,7 +296,14 @@ int ___ieee80211_stop_tx_ba_session(stru
+ {
+       struct ieee80211_local *local = sta->local;
+       struct tid_ampdu_tx *tid_tx;
+-      enum ieee80211_ampdu_mlme_action action;
++      struct ieee80211_ampdu_params params = {
++              .sta = &sta->sta,
++              .tid = tid,
++              .buf_size = 0,
++              .amsdu = false,
++              .timeout = 0,
++              .ssn = 0,
++      };
+       int ret;
+       lockdep_assert_held(&sta->ampdu_mlme.mtx);
+@@ -304,10 +312,10 @@ int ___ieee80211_stop_tx_ba_session(stru
+       case AGG_STOP_DECLINED:
+       case AGG_STOP_LOCAL_REQUEST:
+       case AGG_STOP_PEER_REQUEST:
+-              action = IEEE80211_AMPDU_TX_STOP_CONT;
++              params.action = IEEE80211_AMPDU_TX_STOP_CONT;
+               break;
+       case AGG_STOP_DESTROY_STA:
+-              action = IEEE80211_AMPDU_TX_STOP_FLUSH;
++              params.action = IEEE80211_AMPDU_TX_STOP_FLUSH;
+               break;
+       default:
+               WARN_ON_ONCE(1);
+@@ -330,9 +338,8 @@ int ___ieee80211_stop_tx_ba_session(stru
+               spin_unlock_bh(&sta->lock);
+               if (reason != AGG_STOP_DESTROY_STA)
+                       return -EALREADY;
+-              ret = drv_ampdu_action(local, sta->sdata,
+-                                     IEEE80211_AMPDU_TX_STOP_FLUSH_CONT,
+-                                     &sta->sta, tid, NULL, 0, false);
++              params.action = IEEE80211_AMPDU_TX_STOP_FLUSH_CONT;
++              ret = drv_ampdu_action(local, sta->sdata, &params);
+               WARN_ON_ONCE(ret);
+               return 0;
+       }
+@@ -381,8 +388,7 @@ int ___ieee80211_stop_tx_ba_session(stru
+                                       WLAN_BACK_INITIATOR;
+       tid_tx->tx_stop = reason == AGG_STOP_LOCAL_REQUEST;
+-      ret = drv_ampdu_action(local, sta->sdata, action,
+-                             &sta->sta, tid, NULL, 0, false);
++      ret = drv_ampdu_action(local, sta->sdata, &params);
+       /* HW shall not deny going back to legacy */
+       if (WARN_ON(ret)) {
+@@ -445,7 +451,14 @@ void ieee80211_tx_ba_session_handle_star
+       struct tid_ampdu_tx *tid_tx;
+       struct ieee80211_local *local = sta->local;
+       struct ieee80211_sub_if_data *sdata = sta->sdata;
+-      u16 start_seq_num;
++      struct ieee80211_ampdu_params params = {
++              .sta = &sta->sta,
++              .action = IEEE80211_AMPDU_TX_START,
++              .tid = tid,
++              .buf_size = 0,
++              .amsdu = false,
++              .timeout = 0,
++      };
+       int ret;
+       tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
+@@ -467,10 +480,8 @@ void ieee80211_tx_ba_session_handle_star
+        */
+       synchronize_net();
+-      start_seq_num = sta->tid_seq[tid] >> 4;
+-
+-      ret = drv_ampdu_action(local, sdata, IEEE80211_AMPDU_TX_START,
+-                             &sta->sta, tid, &start_seq_num, 0, false);
++      params.ssn = sta->tid_seq[tid] >> 4;
++      ret = drv_ampdu_action(local, sdata, &params);
+       if (ret) {
+               ht_dbg(sdata,
+                      "BA request denied - HW unavailable for %pM tid %d\n",
+@@ -499,7 +510,7 @@ void ieee80211_tx_ba_session_handle_star
+       /* send AddBA request */
+       ieee80211_send_addba_request(sdata, sta->sta.addr, tid,
+-                                   tid_tx->dialog_token, start_seq_num,
++                                   tid_tx->dialog_token, params.ssn,
+                                    IEEE80211_MAX_AMPDU_BUF,
+                                    tid_tx->timeout);
+ }
+@@ -684,18 +695,24 @@ static void ieee80211_agg_tx_operational
+                                        struct sta_info *sta, u16 tid)
+ {
+       struct tid_ampdu_tx *tid_tx;
++      struct ieee80211_ampdu_params params = {
++              .sta = &sta->sta,
++              .action = IEEE80211_AMPDU_TX_OPERATIONAL,
++              .tid = tid,
++              .timeout = 0,
++              .ssn = 0,
++      };
+       lockdep_assert_held(&sta->ampdu_mlme.mtx);
+       tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
++      params.buf_size = tid_tx->buf_size;
++      params.amsdu = tid_tx->amsdu;
+       ht_dbg(sta->sdata, "Aggregation is on for %pM tid %d\n",
+              sta->sta.addr, tid);
+-      drv_ampdu_action(local, sta->sdata,
+-                       IEEE80211_AMPDU_TX_OPERATIONAL,
+-                       &sta->sta, tid, NULL, tid_tx->buf_size,
+-                       tid_tx->amsdu);
++      drv_ampdu_action(local, sta->sdata, &params);
+       /*
+        * synchronize with TX path, while splicing the TX path
+--- a/net/mac80211/driver-ops.c
++++ b/net/mac80211/driver-ops.c
+@@ -284,9 +284,7 @@ int drv_switch_vif_chanctx(struct ieee80
+ int drv_ampdu_action(struct ieee80211_local *local,
+                    struct ieee80211_sub_if_data *sdata,
+-                   enum ieee80211_ampdu_mlme_action action,
+-                   struct ieee80211_sta *sta, u16 tid,
+-                   u16 *ssn, u8 buf_size, bool amsdu)
++                   struct ieee80211_ampdu_params *params)
+ {
+       int ret = -EOPNOTSUPP;
+@@ -296,12 +294,10 @@ int drv_ampdu_action(struct ieee80211_lo
+       if (!check_sdata_in_driver(sdata))
+               return -EIO;
+-      trace_drv_ampdu_action(local, sdata, action, sta, tid,
+-                             ssn, buf_size, amsdu);
++      trace_drv_ampdu_action(local, sdata, params);
+       if (local->ops->ampdu_action)
+-              ret = local->ops->ampdu_action(&local->hw, &sdata->vif, action,
+-                                             sta, tid, ssn, buf_size, amsdu);
++              ret = local->ops->ampdu_action(&local->hw, &sdata->vif, params);
+       trace_drv_return_int(local, ret);
+--- a/net/mac80211/driver-ops.h
++++ b/net/mac80211/driver-ops.h
+@@ -585,9 +585,7 @@ static inline int drv_tx_last_beacon(str
+ int drv_ampdu_action(struct ieee80211_local *local,
+                    struct ieee80211_sub_if_data *sdata,
+-                   enum ieee80211_ampdu_mlme_action action,
+-                   struct ieee80211_sta *sta, u16 tid,
+-                   u16 *ssn, u8 buf_size, bool amsdu);
++                   struct ieee80211_ampdu_params *params);
+ static inline int drv_get_survey(struct ieee80211_local *local, int idx,
+                               struct survey_info *survey)
+--- a/net/mac80211/trace.h
++++ b/net/mac80211/trace.h
+@@ -80,7 +80,23 @@
+ #define KEY_PR_FMT    " cipher:0x%x, flags=%#x, keyidx=%d, hw_key_idx=%d"
+ #define KEY_PR_ARG    __entry->cipher, __entry->flags, __entry->keyidx, __entry->hw_key_idx
+-
++#define AMPDU_ACTION_ENTRY    __field(enum ieee80211_ampdu_mlme_action,               \
++                                      ieee80211_ampdu_mlme_action)                    \
++                              STA_ENTRY                                               \
++                              __field(u16, tid)                                       \
++                              __field(u16, ssn)                                       \
++                              __field(u8, buf_size)                                   \
++                              __field(bool, amsdu)                                    \
++                              __field(u16, timeout)
++#define AMPDU_ACTION_ASSIGN   STA_NAMED_ASSIGN(params->sta);                          \
++                              __entry->tid = params->tid;                             \
++                              __entry->ssn = params->ssn;                             \
++                              __entry->buf_size = params->buf_size;                   \
++                              __entry->amsdu = params->amsdu;                         \
++                              __entry->timeout = params->timeout;
++#define AMPDU_ACTION_PR_FMT   STA_PR_FMT " tid %d, ssn %d, buf_size %u, amsdu %d, timeout %d"
++#define AMPDU_ACTION_PR_ARG   STA_PR_ARG, __entry->tid, __entry->ssn,                 \
++                              __entry->buf_size, __entry->amsdu, __entry->timeout
+ /*
+  * Tracing for driver callbacks.
+@@ -970,38 +986,25 @@ DEFINE_EVENT(local_only_evt, drv_tx_last
+ TRACE_EVENT(drv_ampdu_action,
+       TP_PROTO(struct ieee80211_local *local,
+                struct ieee80211_sub_if_data *sdata,
+-               enum ieee80211_ampdu_mlme_action action,
+-               struct ieee80211_sta *sta, u16 tid,
+-               u16 *ssn, u8 buf_size, bool amsdu),
++               struct ieee80211_ampdu_params *params),
+-      TP_ARGS(local, sdata, action, sta, tid, ssn, buf_size, amsdu),
++      TP_ARGS(local, sdata, params),
+       TP_STRUCT__entry(
+               LOCAL_ENTRY
+-              STA_ENTRY
+-              __field(u32, action)
+-              __field(u16, tid)
+-              __field(u16, ssn)
+-              __field(u8, buf_size)
+-              __field(bool, amsdu)
+               VIF_ENTRY
++              AMPDU_ACTION_ENTRY
+       ),
+       TP_fast_assign(
+               LOCAL_ASSIGN;
+               VIF_ASSIGN;
+-              STA_ASSIGN;
+-              __entry->action = action;
+-              __entry->tid = tid;
+-              __entry->ssn = ssn ? *ssn : 0;
+-              __entry->buf_size = buf_size;
+-              __entry->amsdu = amsdu;
++              AMPDU_ACTION_ASSIGN;
+       ),
+       TP_printk(
+-              LOCAL_PR_FMT VIF_PR_FMT STA_PR_FMT " action:%d tid:%d buf:%d amsdu:%d",
+-              LOCAL_PR_ARG, VIF_PR_ARG, STA_PR_ARG, __entry->action,
+-              __entry->tid, __entry->buf_size, __entry->amsdu
++              LOCAL_PR_FMT VIF_PR_FMT AMPDU_ACTION_PR_FMT,
++              LOCAL_PR_ARG, VIF_PR_ARG, AMPDU_ACTION_PR_ARG
+       )
+ );
diff --git a/queue-4.4/mac80211-pass-rx-aggregation-window-size-to-driver.patch b/queue-4.4/mac80211-pass-rx-aggregation-window-size-to-driver.patch
new file mode 100644 (file)
index 0000000..407959f
--- /dev/null
@@ -0,0 +1,53 @@
+From fad471860c097844432c7cf5d3ae6a0a059c2bdc Mon Sep 17 00:00:00 2001
+From: Sara Sharon <sara.sharon@intel.com>
+Date: Tue, 8 Dec 2015 16:04:34 +0200
+Subject: mac80211: pass RX aggregation window size to driver
+
+From: Sara Sharon <sara.sharon@intel.com>
+
+commit fad471860c097844432c7cf5d3ae6a0a059c2bdc upstream.
+
+Currently mac80211 does not inform the driver of the window
+size when starting an RX aggregation session.
+To enable managing the reorder buffer in the driver or hardware
+the window size is needed.
+
+Signed-off-by: Sara Sharon <sara.sharon@intel.com>
+Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/net/mac80211.h |    8 +++++---
+ net/mac80211/agg-rx.c  |    2 +-
+ 2 files changed, 6 insertions(+), 4 deletions(-)
+
+--- a/include/net/mac80211.h
++++ b/include/net/mac80211.h
+@@ -3020,9 +3020,11 @@ enum ieee80211_reconfig_type {
+  *    ieee80211_ampdu_mlme_action. Starting sequence number (@ssn)
+  *    is the first frame we expect to perform the action on. Notice
+  *    that TX/RX_STOP can pass NULL for this parameter.
+- *    The @buf_size parameter is only valid when the action is set to
+- *    %IEEE80211_AMPDU_TX_OPERATIONAL and indicates the peer's reorder
+- *    buffer size (number of subframes) for this session -- the driver
++ *    The @buf_size parameter is valid only when the action is set to
++ *    %IEEE80211_AMPDU_RX_START or %IEEE80211_AMPDU_TX_OPERATIONAL and
++ *    indicates the reorder buffer size (number of subframes) for this
++ *    session.
++ *    When the action is set to %IEEE80211_AMPDU_TX_OPERATIONAL the driver
+  *    may neither send aggregates containing more subframes than this
+  *    nor send aggregates in a way that lost frames would exceed the
+  *    buffer size. If just limiting the aggregate size, this would be
+--- a/net/mac80211/agg-rx.c
++++ b/net/mac80211/agg-rx.c
+@@ -323,7 +323,7 @@ void __ieee80211_start_rx_ba_session(str
+               __skb_queue_head_init(&tid_agg_rx->reorder_buf[i]);
+       ret = drv_ampdu_action(local, sta->sdata, IEEE80211_AMPDU_RX_START,
+-                             &sta->sta, tid, &start_seq_num, 0, false);
++                             &sta->sta, tid, &start_seq_num, buf_size, false);
+       ht_dbg(sta->sdata, "Rx A-MPDU request on %pM tid %d result %d\n",
+              sta->sta.addr, tid, ret);
+       if (ret) {
diff --git a/queue-4.4/mac80211-rx-ba-support-for-sta-max_rx_aggregation_subframes.patch b/queue-4.4/mac80211-rx-ba-support-for-sta-max_rx_aggregation_subframes.patch
new file mode 100644 (file)
index 0000000..ff8f4fc
--- /dev/null
@@ -0,0 +1,88 @@
+From 480dd46b9d6812e5fb7172c305ee0f1154c26eed Mon Sep 17 00:00:00 2001
+From: Maxim Altshul <maxim.altshul@ti.com>
+Date: Mon, 22 Aug 2016 17:14:04 +0300
+Subject: mac80211: RX BA support for sta max_rx_aggregation_subframes
+
+From: Maxim Altshul <maxim.altshul@ti.com>
+
+commit 480dd46b9d6812e5fb7172c305ee0f1154c26eed upstream.
+
+The ability to change the max_rx_aggregation frames is useful
+in cases of IOP.
+
+There exist some devices (latest mobile phones and some AP's)
+that tend to not respect a BA sessions maximum size (in Kbps).
+These devices won't respect the AMPDU size that was negotiated during
+association (even though they do respect the maximal number of packets).
+
+This violation is characterized by a valid number of packets in
+a single AMPDU. Even so, the total size will exceed the size negotiated
+during association.
+
+Eventually, this will cause some undefined behavior, which in turn
+causes the hw to drop packets, causing the throughput to plummet.
+
+This patch will make the subframe limitation to be held by each station,
+instead of being held only by hw.
+
+Signed-off-by: Maxim Altshul <maxim.altshul@ti.com>
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/net/mac80211.h  |    4 ++++
+ net/mac80211/agg-rx.c   |    7 +++++--
+ net/mac80211/sta_info.c |    3 +++
+ 3 files changed, 12 insertions(+), 2 deletions(-)
+
+--- a/include/net/mac80211.h
++++ b/include/net/mac80211.h
+@@ -1662,6 +1662,9 @@ struct ieee80211_sta_rates {
+  * @supp_rates: Bitmap of supported rates (per band)
+  * @ht_cap: HT capabilities of this STA; restricted to our own capabilities
+  * @vht_cap: VHT capabilities of this STA; restricted to our own capabilities
++ * @max_rx_aggregation_subframes: maximal amount of frames in a single AMPDU
++ *    that this station is allowed to transmit to us.
++ *    Can be modified by driver.
+  * @wme: indicates whether the STA supports QoS/WME (if local devices does,
+  *    otherwise always false)
+  * @drv_priv: data area for driver use, will always be aligned to
+@@ -1688,6 +1691,7 @@ struct ieee80211_sta {
+       u16 aid;
+       struct ieee80211_sta_ht_cap ht_cap;
+       struct ieee80211_sta_vht_cap vht_cap;
++      u8 max_rx_aggregation_subframes;
+       bool wme;
+       u8 uapsd_queues;
+       u8 max_sp;
+--- a/net/mac80211/agg-rx.c
++++ b/net/mac80211/agg-rx.c
+@@ -290,10 +290,13 @@ void __ieee80211_start_rx_ba_session(str
+               buf_size = IEEE80211_MAX_AMPDU_BUF;
+       /* make sure the size doesn't exceed the maximum supported by the hw */
+-      if (buf_size > local->hw.max_rx_aggregation_subframes)
+-              buf_size = local->hw.max_rx_aggregation_subframes;
++      if (buf_size > sta->sta.max_rx_aggregation_subframes)
++              buf_size = sta->sta.max_rx_aggregation_subframes;
+       params.buf_size = buf_size;
++      ht_dbg(sta->sdata, "AddBA Req buf_size=%d for %pM\n",
++             buf_size, sta->sta.addr);
++
+       /* examine state machine */
+       mutex_lock(&sta->ampdu_mlme.mtx);
+--- a/net/mac80211/sta_info.c
++++ b/net/mac80211/sta_info.c
+@@ -329,6 +329,9 @@ struct sta_info *sta_info_alloc(struct i
+       memcpy(sta->addr, addr, ETH_ALEN);
+       memcpy(sta->sta.addr, addr, ETH_ALEN);
++      sta->sta.max_rx_aggregation_subframes =
++              local->hw.max_rx_aggregation_subframes;
++
+       sta->local = local;
+       sta->sdata = sdata;
+       sta->rx_stats.last_rx = jiffies;
index d68b3a3c98ce4f1bc50a0e10e9e4725744407ae1..a5751201daeea6332f9a37a7731ce9b2b3e1ec34 100644 (file)
@@ -48,3 +48,8 @@ tty-pty-fix-ldisc-flush-after-userspace-become-aware-of-the-data-already.patch
 bluetooth-fix-user-channel-for-32bit-userspace-on-64bit-kernel.patch
 bluetooth-hci_bcm-add-missing-tty-device-sanity-check.patch
 bluetooth-hci_intel-add-missing-tty-device-sanity-check.patch
+mac80211-pass-rx-aggregation-window-size-to-driver.patch
+mac80211-pass-block-ack-session-timeout-to-to-driver.patch
+mac80211-rx-ba-support-for-sta-max_rx_aggregation_subframes.patch
+wlcore-pass-win_size-taken-from-ieee80211_sta-to-fw.patch
+wlcore-add-rx_ba_win_size_change_event-event.patch
diff --git a/queue-4.4/wlcore-add-rx_ba_win_size_change_event-event.patch b/queue-4.4/wlcore-add-rx_ba_win_size_change_event-event.patch
new file mode 100644 (file)
index 0000000..519145a
--- /dev/null
@@ -0,0 +1,88 @@
+From e7ee74b56f23ba447d3124f2eccc32033cca501d Mon Sep 17 00:00:00 2001
+From: Maxim Altshul <maxim.altshul@ti.com>
+Date: Sun, 21 Aug 2016 14:24:25 +0300
+Subject: wlcore: Add RX_BA_WIN_SIZE_CHANGE_EVENT event
+
+From: Maxim Altshul <maxim.altshul@ti.com>
+
+commit e7ee74b56f23ba447d3124f2eccc32033cca501d upstream.
+
+This event is used by the Firmware to limit the RX BA win size
+for a specific link.
+
+The event handler updates the new size in the mac's sta->sta struct.
+
+BA sessions opened for that link will use the new restricted
+win_size. This limitation remains until a new update is received or
+until the link is closed.
+
+Signed-off-by: Maxim Altshul <maxim.altshul@ti.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+[AmitP: Minor refactoring for linux-4.4.y]
+Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/ti/wl18xx/event.c |   28 ++++++++++++++++++++++++++++
+ drivers/net/wireless/ti/wl18xx/event.h |    1 +
+ drivers/net/wireless/ti/wl18xx/main.c  |    3 ++-
+ 3 files changed, 31 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/ti/wl18xx/event.c
++++ b/drivers/net/wireless/ti/wl18xx/event.c
+@@ -206,5 +206,33 @@ int wl18xx_process_mailbox_events(struct
+                                                mbox->sc_pwd_len,
+                                                mbox->sc_pwd);
++      if (vector & RX_BA_WIN_SIZE_CHANGE_EVENT_ID) {
++              struct wl12xx_vif *wlvif;
++              struct ieee80211_vif *vif;
++              struct ieee80211_sta *sta;
++              u8 link_id = mbox->rx_ba_link_id;
++              u8 win_size = mbox->rx_ba_win_size;
++              const u8 *addr;
++
++              wlvif = wl->links[link_id].wlvif;
++              vif = wl12xx_wlvif_to_vif(wlvif);
++
++              /* Update RX aggregation window size and call
++               * MAC routine to stop active RX aggregations for this link
++               */
++              if (wlvif->bss_type != BSS_TYPE_AP_BSS)
++                      addr = vif->bss_conf.bssid;
++              else
++                      addr = wl->links[link_id].addr;
++
++              sta = ieee80211_find_sta(vif, addr);
++              if (sta) {
++                      sta->max_rx_aggregation_subframes = win_size;
++                      ieee80211_stop_rx_ba_session(vif,
++                                              wl->links[link_id].ba_bitmap,
++                                              addr);
++              }
++      }
++
+       return 0;
+ }
+--- a/drivers/net/wireless/ti/wl18xx/event.h
++++ b/drivers/net/wireless/ti/wl18xx/event.h
+@@ -38,6 +38,7 @@ enum {
+       REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID      = BIT(18),
+       DFS_CHANNELS_CONFIG_COMPLETE_EVENT       = BIT(19),
+       PERIODIC_SCAN_REPORT_EVENT_ID            = BIT(20),
++      RX_BA_WIN_SIZE_CHANGE_EVENT_ID           = BIT(21),
+       SMART_CONFIG_SYNC_EVENT_ID               = BIT(22),
+       SMART_CONFIG_DECODE_EVENT_ID             = BIT(23),
+       TIME_SYNC_EVENT_ID                       = BIT(24),
+--- a/drivers/net/wireless/ti/wl18xx/main.c
++++ b/drivers/net/wireless/ti/wl18xx/main.c
+@@ -1029,7 +1029,8 @@ static int wl18xx_boot(struct wl1271 *wl
+               DFS_CHANNELS_CONFIG_COMPLETE_EVENT |
+               SMART_CONFIG_SYNC_EVENT_ID |
+               SMART_CONFIG_DECODE_EVENT_ID |
+-              TIME_SYNC_EVENT_ID;
++              TIME_SYNC_EVENT_ID |
++              RX_BA_WIN_SIZE_CHANGE_EVENT_ID;
+       wl->ap_event_mask = MAX_TX_FAILURE_EVENT_ID;
diff --git a/queue-4.4/wlcore-pass-win_size-taken-from-ieee80211_sta-to-fw.patch b/queue-4.4/wlcore-pass-win_size-taken-from-ieee80211_sta-to-fw.patch
new file mode 100644 (file)
index 0000000..165293a
--- /dev/null
@@ -0,0 +1,83 @@
+From 42c7372a111630dab200c2f959424f5ec3bf79a4 Mon Sep 17 00:00:00 2001
+From: Maxim Altshul <maxim.altshul@ti.com>
+Date: Sun, 21 Aug 2016 14:24:24 +0300
+Subject: wlcore: Pass win_size taken from ieee80211_sta to FW
+
+From: Maxim Altshul <maxim.altshul@ti.com>
+
+commit 42c7372a111630dab200c2f959424f5ec3bf79a4 upstream.
+
+When starting a new BA session, we must pass the win_size to the FW.
+
+To do this we take max_rx_aggregation_subframes (BA RX win size)
+which is stored in ieee80211_sta structure (e.g per link and not per HW)
+
+We will use the value stored per link when passing the win_size to
+firmware through the ACX_BA_SESSION_RX_SETUP command.
+
+Signed-off-by: Maxim Altshul <maxim.altshul@ti.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/ti/wlcore/acx.c  |    5 +++--
+ drivers/net/wireless/ti/wlcore/acx.h  |    3 ++-
+ drivers/net/wireless/ti/wlcore/main.c |    6 ++++--
+ 3 files changed, 9 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/wireless/ti/wlcore/acx.c
++++ b/drivers/net/wireless/ti/wlcore/acx.c
+@@ -1419,7 +1419,8 @@ out:
+ /* setup BA session receiver setting in the FW. */
+ int wl12xx_acx_set_ba_receiver_session(struct wl1271 *wl, u8 tid_index,
+-                                     u16 ssn, bool enable, u8 peer_hlid)
++                                     u16 ssn, bool enable, u8 peer_hlid,
++                                     u8 win_size)
+ {
+       struct wl1271_acx_ba_receiver_setup *acx;
+       int ret;
+@@ -1435,7 +1436,7 @@ int wl12xx_acx_set_ba_receiver_session(s
+       acx->hlid = peer_hlid;
+       acx->tid = tid_index;
+       acx->enable = enable;
+-      acx->win_size = wl->conf.ht.rx_ba_win_size;
++      acx->win_size = win_size;
+       acx->ssn = ssn;
+       ret = wlcore_cmd_configure_failsafe(wl, ACX_BA_SESSION_RX_SETUP, acx,
+--- a/drivers/net/wireless/ti/wlcore/acx.h
++++ b/drivers/net/wireless/ti/wlcore/acx.h
+@@ -1112,7 +1112,8 @@ int wl1271_acx_set_ht_information(struct
+ int wl12xx_acx_set_ba_initiator_policy(struct wl1271 *wl,
+                                      struct wl12xx_vif *wlvif);
+ int wl12xx_acx_set_ba_receiver_session(struct wl1271 *wl, u8 tid_index,
+-                                     u16 ssn, bool enable, u8 peer_hlid);
++                                     u16 ssn, bool enable, u8 peer_hlid,
++                                     u8 win_size);
+ int wl12xx_acx_tsf_info(struct wl1271 *wl, struct wl12xx_vif *wlvif,
+                       u64 *mactime);
+ int wl1271_acx_ps_rx_streaming(struct wl1271 *wl, struct wl12xx_vif *wlvif,
+--- a/drivers/net/wireless/ti/wlcore/main.c
++++ b/drivers/net/wireless/ti/wlcore/main.c
+@@ -5328,7 +5328,9 @@ static int wl1271_op_ampdu_action(struct
+               }
+               ret = wl12xx_acx_set_ba_receiver_session(wl, tid, *ssn, true,
+-                                                       hlid);
++                              hlid,
++                              params->buf_size);
++
+               if (!ret) {
+                       *ba_bitmap |= BIT(tid);
+                       wl->ba_rx_session_count++;
+@@ -5349,7 +5351,7 @@ static int wl1271_op_ampdu_action(struct
+               }
+               ret = wl12xx_acx_set_ba_receiver_session(wl, tid, 0, false,
+-                                                       hlid);
++                                                       hlid, 0);
+               if (!ret) {
+                       *ba_bitmap &= ~BIT(tid);
+                       wl->ba_rx_session_count--;