mac80211: add a HW flag for supporting HW TX fragmentation
authorSara Sharon <sara.sharon@intel.com>
Tue, 18 Oct 2016 20:12:11 +0000 (23:12 +0300)
committerJohannes Berg <johannes.berg@intel.com>
Wed, 19 Oct 2016 10:12:44 +0000 (12:12 +0200)
Currently mac80211 determines whether HW does fragmentation
by checking whether the set_frag_threshold callback is set
or not.
However, some drivers may want to set the HW fragmentation
capability depending on HW generation.
Allow this by checking a HW flag instead of checking the
callback.

Signed-off-by: Sara Sharon <sara.sharon@intel.com>
[added the flag to ath10k and wlcore]
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
drivers/net/wireless/ath/ath10k/mac.c
drivers/net/wireless/ti/wlcore/main.c
include/net/mac80211.h
net/mac80211/debugfs.c
net/mac80211/main.c
net/mac80211/tx.c
net/mac80211/wpa.c

index 76297d69f1ed4303ec6595f3ad59ef29ee3137b6..e322b6df0ebcec2a49dbcd843c6dec82c166b24e 100644 (file)
@@ -7881,6 +7881,7 @@ int ath10k_mac_register(struct ath10k *ar)
        ieee80211_hw_set(ar->hw, WANT_MONITOR_VIF);
        ieee80211_hw_set(ar->hw, CHANCTX_STA_CSA);
        ieee80211_hw_set(ar->hw, QUEUE_CONTROL);
+       ieee80211_hw_set(ar->hw, SUPPORTS_TX_FRAG);
 
        if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
                ieee80211_hw_set(ar->hw, SW_CRYPTO_CONTROL);
index 471521a0db7b6634e0f2c36ef8a168116c336f4f..9f39c6cf98fb74fefd27ea16a3775fdb5adf110e 100644 (file)
@@ -6086,6 +6086,7 @@ static int wl1271_init_ieee80211(struct wl1271 *wl)
        ieee80211_hw_set(wl->hw, SUPPORTS_DYNAMIC_PS);
        ieee80211_hw_set(wl->hw, SIGNAL_DBM);
        ieee80211_hw_set(wl->hw, SUPPORTS_PS);
+       ieee80211_hw_set(wl->hw, SUPPORTS_TX_FRAG);
 
        wl->hw->wiphy->cipher_suites = cipher_suites;
        wl->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
index f3dbadafe16e1c7c06562ccb64d97e0251b964e2..a1a27021f45279859534bfe4721bb6c85a7635f8 100644 (file)
@@ -2025,6 +2025,10 @@ struct ieee80211_txq {
  *     drivers, mac80211 packet loss mechanism will not be triggered and driver
  *     is completely depending on firmware event for station kickout.
  *
+ * @IEEE80211_HW_SUPPORTS_TX_FRAG: Hardware does fragmentation by itself.
+ *     The stack will not do fragmentation.
+ *     The callback for @set_frag_threshold should be set as well.
+ *
  * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays
  */
 enum ieee80211_hw_flags {
@@ -2066,6 +2070,7 @@ enum ieee80211_hw_flags {
        IEEE80211_HW_TX_AMSDU,
        IEEE80211_HW_TX_FRAG_LIST,
        IEEE80211_HW_REPORTS_LOW_ACK,
+       IEEE80211_HW_SUPPORTS_TX_FRAG,
 
        /* keep last, obviously */
        NUM_IEEE80211_HW_FLAGS
@@ -3093,8 +3098,9 @@ enum ieee80211_reconfig_type {
  *     The callback must be atomic.
  *
  * @set_frag_threshold: Configuration of fragmentation threshold. Assign this
- *     if the device does fragmentation by itself; if this callback is
- *     implemented then the stack will not do fragmentation.
+ *     if the device does fragmentation by itself. Note that to prevent the
+ *     stack from doing fragmentation IEEE80211_HW_SUPPORTS_TX_FRAG
+ *     should be set as well.
  *     The callback can sleep.
  *
  * @set_rts_threshold: Configuration of RTS threshold (if device needs it)
index f56e2f487d096aef3f7e1c083688548f92ed7110..e02ba42ca827501fdefc155d0ad71f2d4ffc2f36 100644 (file)
@@ -210,6 +210,7 @@ static const char *hw_flag_names[] = {
        FLAG(TX_AMSDU),
        FLAG(TX_FRAG_LIST),
        FLAG(REPORTS_LOW_ACK),
+       FLAG(SUPPORTS_TX_FRAG),
 #undef FLAG
 };
 
index 1075ac24c8c5f433690749970d9e27393351caa9..0d9163c16dda3391b3dc118a5588dade3a877c5b 100644 (file)
@@ -821,6 +821,10 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
             !local->ops->tdls_recv_channel_switch))
                return -EOPNOTSUPP;
 
+       if (WARN_ON(ieee80211_hw_check(hw, SUPPORTS_TX_FRAG) &&
+                   !local->ops->set_frag_threshold))
+               return -EINVAL;
+
        if (WARN_ON(local->hw.wiphy->interface_modes &
                        BIT(NL80211_IFTYPE_NAN) &&
                    (!local->ops->start_nan || !local->ops->stop_nan)))
index 772e36909fa34fa0715a895b165bdedc4493e120..62ccaf6f585d02198b997411dc622fc433b8a242 100644 (file)
@@ -934,7 +934,7 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx)
        if (info->flags & IEEE80211_TX_CTL_DONTFRAG)
                return TX_CONTINUE;
 
-       if (tx->local->ops->set_frag_threshold)
+       if (ieee80211_hw_check(&tx->local->hw, SUPPORTS_TX_FRAG))
                return TX_CONTINUE;
 
        /*
@@ -2800,7 +2800,7 @@ void ieee80211_check_fast_xmit(struct sta_info *sta)
 
        /* fast-xmit doesn't handle fragmentation at all */
        if (local->hw.wiphy->frag_threshold != (u32)-1 &&
-           !local->ops->set_frag_threshold)
+           !ieee80211_hw_check(&local->hw, SUPPORTS_TX_FRAG))
                goto out;
 
        rcu_read_lock();
index b48c1e13e28170edd0202a6bb21c6e2fdb488f47..c24934544f9cd2e972c0fbc54deb84199ee67371 100644 (file)
@@ -57,7 +57,7 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx)
 
        if (info->control.hw_key &&
            (info->flags & IEEE80211_TX_CTL_DONTFRAG ||
-            tx->local->ops->set_frag_threshold) &&
+            ieee80211_hw_check(&tx->local->hw, SUPPORTS_TX_FRAG)) &&
            !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC)) {
                /* hwaccel - with no need for SW-generated MMIC */
                return TX_CONTINUE;