]> err.no Git - linux-2.6/commitdiff
bnx2x: Rx work check
authorEilon Greenstein <eilong@broadcom.com>
Mon, 25 Aug 2008 22:19:17 +0000 (15:19 -0700)
committerDavid S. Miller <davem@davemloft.net>
Mon, 25 Aug 2008 22:19:17 +0000 (15:19 -0700)
The has Rx work check was wrong: when the FW was at the end of the page,
the driver was already at the beginning of the next page. Since the
check only validated that both driver and FW are pointing to the same
place, it concluded that there is still work to be done. This caused
some serious issues including long latency results on ping-pong test and
lockups while unloading the driver in that condition.

Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/bnx2x.h
drivers/net/bnx2x_main.c

index b468f904c7f88591cd952c983c44693412d7b239..a14dba1afcc56210508ce0b03805f37aea0035f7 100644 (file)
@@ -271,7 +271,7 @@ struct bnx2x_fastpath {
                         (fp->tx_pkt_prod != fp->tx_pkt_cons))
 
 #define BNX2X_HAS_RX_WORK(fp) \
-                       (fp->rx_comp_cons != le16_to_cpu(*fp->rx_cons_sb))
+                       (fp->rx_comp_cons != rx_cons_sb)
 
 #define BNX2X_HAS_WORK(fp)     (BNX2X_HAS_RX_WORK(fp) || BNX2X_HAS_TX_WORK(fp))
 
index 971576b4368751846f95d85064cccf2c6d5255eb..272f5d112bb3800f26c1788145fe05af159caeb2 100644 (file)
@@ -9250,6 +9250,7 @@ static int bnx2x_poll(struct napi_struct *napi, int budget)
                                                 napi);
        struct bnx2x *bp = fp->bp;
        int work_done = 0;
+       u16 rx_cons_sb;
 
 #ifdef BNX2X_STOP_ON_ERROR
        if (unlikely(bp->panic))
@@ -9265,10 +9266,16 @@ static int bnx2x_poll(struct napi_struct *napi, int budget)
        if (BNX2X_HAS_TX_WORK(fp))
                bnx2x_tx_int(fp, budget);
 
+       rx_cons_sb = le16_to_cpu(*fp->rx_cons_sb);
+       if ((rx_cons_sb & MAX_RCQ_DESC_CNT) == MAX_RCQ_DESC_CNT)
+               rx_cons_sb++;
        if (BNX2X_HAS_RX_WORK(fp))
                work_done = bnx2x_rx_int(fp, budget);
 
        rmb(); /* BNX2X_HAS_WORK() reads the status block */
+       rx_cons_sb = le16_to_cpu(*fp->rx_cons_sb);
+       if ((rx_cons_sb & MAX_RCQ_DESC_CNT) == MAX_RCQ_DESC_CNT)
+               rx_cons_sb++;
 
        /* must not complete if we consumed full budget */
        if ((work_done < budget) && !BNX2X_HAS_WORK(fp)) {