sfc: Tighten the check for RX merged completion events
authorBen Hutchings <bhutchings@solarflare.com>
Tue, 24 Sep 2013 22:21:57 +0000 (23:21 +0100)
committerBen Hutchings <bhutchings@solarflare.com>
Thu, 12 Dec 2013 22:06:49 +0000 (22:06 +0000)
The addition of RX event merging support means we don't reliably
detect dropped RX events now.  Currently we will only detect them if
the previous event for the RX queue had the CONT bit set.

Only accept RX completion events as merged if the
GET_CAPABILITIES_OUT_RX_BATCHING bit is set in datapath_caps (which it
won't be for the low-latency datapath) and the CONT bit is not set on
the event.

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
drivers/net/ethernet/sfc/ef10.c

index 5d46d155b6423470084e606b8d082ac80db5a9b0..2f77359607d2c03803d82ae9e6cb2e17d551883b 100644 (file)
@@ -1766,6 +1766,8 @@ static int efx_ef10_handle_rx_event(struct efx_channel *channel,
                   ((1 << ESF_DZ_RX_DSC_PTR_LBITS_WIDTH) - 1));
 
        if (n_descs != rx_queue->scatter_n + 1) {
+               struct efx_ef10_nic_data *nic_data = efx->nic_data;
+
                /* detect rx abort */
                if (unlikely(n_descs == rx_queue->scatter_n)) {
                        WARN_ON(rx_bytes != 0);
@@ -1773,10 +1775,13 @@ static int efx_ef10_handle_rx_event(struct efx_channel *channel,
                        return 0;
                }
 
-               if (unlikely(rx_queue->scatter_n != 0)) {
-                       /* Scattered packet completions cannot be
-                        * merged, so something has gone wrong.
-                        */
+               /* Check that RX completion merging is valid, i.e.
+                * the current firmware supports it and this is a
+                * non-scattered packet.
+                */
+               if (!(nic_data->datapath_caps &
+                     (1 << MC_CMD_GET_CAPABILITIES_OUT_RX_BATCHING_LBN)) ||
+                   rx_queue->scatter_n != 0 || rx_cont) {
                        efx_ef10_handle_rx_bad_lbits(
                                rx_queue, next_ptr_lbits,
                                (rx_queue->removed_count +