From: Dmitry Kravkov Date: Sun, 2 Dec 2012 04:05:48 +0000 (+0000) Subject: bnx2x: Filter packets on FCoE rings X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=c96bdc0c9e86ac243c5eff41c0c1418cbbc3057c;p=linux-beck.git bnx2x: Filter packets on FCoE rings 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 Signed-off-by: Yuval Mintz Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index e95174d451a5..5e07aa5e1aea 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -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; } diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c index e05f981398be..c7270c082ad6 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c @@ -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"} }; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c index 348ed02d3c69..89ec0667140a 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c @@ -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); } } diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h index 24b8e505b60c..b4d7b26c7fe7 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h @@ -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 {