iwlwifi: mvm: don't send an A-MSDU that is larger than the TXF
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Wed, 11 Nov 2015 09:37:02 +0000 (11:37 +0200)
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Sat, 27 Feb 2016 20:00:03 +0000 (22:00 +0200)
The A-MSDU must be smaller than the Transmit FIFO in the
device. Since the size of the TXF can change depending
on the device / firmware compilation mode, take the size
of the FIFO dynamically from the what the firmware tells us.

Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
drivers/net/wireless/intel/iwlwifi/mvm/tx.c

index a73ae01f3a48c337895883e6df274ccf67c56abb..dd616c1d59b7d59094a40c6a8e58a2320f90c693 100644 (file)
@@ -449,7 +449,7 @@ static int iwl_mvm_tx_tso(struct iwl_mvm *mvm, struct sk_buff *skb,
        u16 ip_base_id = ipv4 ? ntohs(ip_hdr(skb)->id) : 0;
        u16 amsdu_add, snap_ip_tcp, pad, i = 0;
        unsigned int dbg_max_amsdu_len;
-       u8 *qc, tid;
+       u8 *qc, tid, txf;
 
        snap_ip_tcp = 8 + skb_transport_header(skb) - skb_network_header(skb) +
                tcp_hdrlen(skb);
@@ -480,6 +480,19 @@ static int iwl_mvm_tx_tso(struct iwl_mvm *mvm, struct sk_buff *skb,
 
        max_amsdu_len = sta->max_amsdu_len;
        dbg_max_amsdu_len = ACCESS_ONCE(mvm->max_amsdu_len);
+
+       /* the Tx FIFO to which this A-MSDU will be routed */
+       txf = iwl_mvm_ac_to_tx_fifo[tid_to_mac80211_ac[tid]];
+
+       /*
+        * Don't send an AMSDU that will be longer than the TXF.
+        * Add a security margin of 256 for the TX command + headers.
+        * We also want to have the start of the next packet inside the
+        * fifo to be able to send bursts.
+        */
+       max_amsdu_len = min_t(unsigned int, max_amsdu_len,
+                             mvm->shared_mem_cfg.txfifo_size[txf] - 256);
+
        if (dbg_max_amsdu_len)
                max_amsdu_len = min_t(unsigned int, max_amsdu_len,
                                      dbg_max_amsdu_len);