bnx2x: Filter packets on FCoE rings
authorDmitry Kravkov <dmitry@broadcom.com>
Sun, 2 Dec 2012 04:05:48 +0000 (04:05 +0000)
committerDavid S. Miller <davem@davemloft.net>
Mon, 3 Dec 2012 01:22:59 +0000 (20:22 -0500)
Whenever bnx2x fails to transmit a packet due to a full Tx ring, if the
ring size is zero (indicating an FCoE ring) driver filters the packet out
and gracefully continues.
Driver also gathers statistics on such filtered packets.

Signed-off-by: Dmitry Kravkov <dmitry@broadcom.com>
Signed-off-by: Yuval Mintz <yuvalmin@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h

index e95174d..5e07aa5 100644 (file)
@@ -3127,11 +3127,16 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
                        BDS_PER_TX_PKT +
                        NEXT_CNT_PER_TX_PKT(MAX_BDS_PER_TX_PKT))) {
                /* Handle special storage cases separately */
-               if (txdata->tx_ring_size != 0) {
-                       BNX2X_ERR("BUG! Tx ring full when queue awake!\n");
+               if (txdata->tx_ring_size == 0) {
+                       struct bnx2x_eth_q_stats *q_stats =
+                               bnx2x_fp_qstats(bp, txdata->parent_fp);
+                       q_stats->driver_filtered_tx_pkt++;
+                       dev_kfree_skb(skb);
+                       return NETDEV_TX_OK;
+               }
                        bnx2x_fp_qstats(bp, txdata->parent_fp)->driver_xoff++;
                        netif_tx_stop_queue(txq);
-               }
+               BNX2X_ERR("BUG! Tx ring full when queue awake!\n");
 
                return NETDEV_TX_BUSY;
        }
index e05f981..c7270c0 100644 (file)
@@ -62,7 +62,9 @@ static const struct {
                                                8, "[%s]: tpa_aggregations" },
        { Q_STATS_OFFSET32(total_tpa_aggregated_frames_hi),
                                        8, "[%s]: tpa_aggregated_frames"},
-       { Q_STATS_OFFSET32(total_tpa_bytes_hi), 8, "[%s]: tpa_bytes"}
+       { Q_STATS_OFFSET32(total_tpa_bytes_hi), 8, "[%s]: tpa_bytes"},
+       { Q_STATS_OFFSET32(driver_filtered_tx_pkt),
+                                       4, "[%s]: driver_filtered_tx_pkt" }
 };
 
 #define BNX2X_NUM_Q_STATS ARRAY_SIZE(bnx2x_q_stats_arr)
@@ -177,6 +179,8 @@ static const struct {
                        4, STATS_FLAGS_FUNC, "recoverable_errors" },
        { STATS_OFFSET32(unrecoverable_error),
                        4, STATS_FLAGS_FUNC, "unrecoverable_errors" },
+       { STATS_OFFSET32(driver_filtered_tx_pkt),
+                       4, STATS_FLAGS_FUNC, "driver_filtered_tx_pkt" },
        { STATS_OFFSET32(eee_tx_lpi),
                        4, STATS_FLAGS_PORT, "Tx LPI entry count"}
 };
index 348ed02..89ec066 100644 (file)
@@ -1149,6 +1149,7 @@ static void bnx2x_drv_stats_update(struct bnx2x *bp)
                UPDATE_ESTAT_QSTAT(rx_err_discard_pkt);
                UPDATE_ESTAT_QSTAT(rx_skb_alloc_failed);
                UPDATE_ESTAT_QSTAT(hw_csum_err);
+               UPDATE_ESTAT_QSTAT(driver_filtered_tx_pkt);
        }
 }
 
index 24b8e50..b4d7b26 100644 (file)
@@ -203,6 +203,7 @@ struct bnx2x_eth_stats {
        /* Recovery */
        u32 recoverable_error;
        u32 unrecoverable_error;
+       u32 driver_filtered_tx_pkt;
        /* src: Clear-on-Read register; Will not survive PMF Migration */
        u32 eee_tx_lpi;
 };
@@ -264,6 +265,7 @@ struct bnx2x_eth_q_stats {
        u32 total_tpa_aggregated_frames_lo;
        u32 total_tpa_bytes_hi;
        u32 total_tpa_bytes_lo;
+       u32 driver_filtered_tx_pkt;
 };
 
 struct bnx2x_eth_stats_old {
@@ -315,6 +317,7 @@ struct bnx2x_eth_q_stats_old {
        u32 rx_err_discard_pkt_old;
        u32 rx_skb_alloc_failed_old;
        u32 hw_csum_err_old;
+       u32 driver_filtered_tx_pkt_old;
 };
 
 struct bnx2x_net_stats_old {