iwlwifi: mvm: don't WARN when a legit race happens in A-MPDU
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Thu, 27 Jul 2017 12:34:12 +0000 (15:34 +0300)
committerLuca Coelho <luciano.coelho@intel.com>
Wed, 9 Aug 2017 05:53:50 +0000 (08:53 +0300)
When we start an Rx A-MPDU session, we first get the AddBA
request, then we send an ADD_STA command to the firmware
that will reply with a BAID which is a hardware resource
that tracks the BA session.
This BAID will appear on each and every frame that we get
from the firwmare until the A-MPDU session is torn down.
In the Rx path, we look at this BAID to manage the
reordering buffer.

This flow is inherently racy since the hardware will start
to put the BAID in the frames it receives even if the
firmware hasn't sent the response to the ADD_STA command.
This basically means that the driver can get frames with
a valid BAID that it doesn't know yet.
When that happens, the driver used to WARN.
Fix this by simply not WARN in this case. When the driver
will know abou the BAID, it will initialise the relevant
states and the next frame with a valid BAID will refresh
them.

Fixes: b915c10174fb ("iwlwifi: mvm: add reorder buffer per queue")
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c

index f3e608196369a3885804b42331f442a16623e388..71c8b800ffa99874bd4120e59e2aa7f51212d2da 100644 (file)
@@ -636,9 +636,9 @@ static bool iwl_mvm_reorder(struct iwl_mvm *mvm,
 
        baid_data = rcu_dereference(mvm->baid_map[baid]);
        if (!baid_data) {
-               WARN(!(reorder & IWL_RX_MPDU_REORDER_BA_OLD_SN),
-                    "Received baid %d, but no data exists for this BAID\n",
-                    baid);
+               IWL_DEBUG_RX(mvm,
+                            "Got valid BAID but no baid allocated, bypass the re-ordering buffer. Baid %d reorder 0x%x\n",
+                             baid, reorder);
                return false;
        }
 
@@ -759,7 +759,9 @@ static void iwl_mvm_agg_rx_received(struct iwl_mvm *mvm,
 
        data = rcu_dereference(mvm->baid_map[baid]);
        if (!data) {
-               WARN_ON(!(reorder_data & IWL_RX_MPDU_REORDER_BA_OLD_SN));
+               IWL_DEBUG_RX(mvm,
+                            "Got valid BAID but no baid allocated, bypass the re-ordering buffer. Baid %d reorder 0x%x\n",
+                             baid, reorder_data);
                goto out;
        }