be2net: fix net-snmp error because of wrong packet stats

Wrong packet statistics for multicast Rx was causing net-snmp error messages
every 15 seconds. Instead of picking the multicast stats from hardware,
now maintain it in the driver itself.

Signed-off-by: Ajit Khaparde <ajitk@serverengines.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Ajit Khaparde 2010-09-03 06:17:10 +00:00 committed by David S. Miller
parent 0b5d404e34
commit 1ef78abec6
4 changed files with 18 additions and 6 deletions

View File

@ -181,6 +181,7 @@ struct be_drvr_stats {
u64 be_rx_bytes_prev; u64 be_rx_bytes_prev;
u64 be_rx_pkts; u64 be_rx_pkts;
u32 be_rx_rate; u32 be_rx_rate;
u32 be_rx_mcast_pkt;
/* number of non ether type II frames dropped where /* number of non ether type II frames dropped where
* frame len > length field of Mac Hdr */ * frame len > length field of Mac Hdr */
u32 be_802_3_dropped_frames; u32 be_802_3_dropped_frames;

View File

@ -60,6 +60,7 @@ static const struct be_ethtool_stat et_stats[] = {
{DRVSTAT_INFO(be_rx_events)}, {DRVSTAT_INFO(be_rx_events)},
{DRVSTAT_INFO(be_tx_compl)}, {DRVSTAT_INFO(be_tx_compl)},
{DRVSTAT_INFO(be_rx_compl)}, {DRVSTAT_INFO(be_rx_compl)},
{DRVSTAT_INFO(be_rx_mcast_pkt)},
{DRVSTAT_INFO(be_ethrx_post_fail)}, {DRVSTAT_INFO(be_ethrx_post_fail)},
{DRVSTAT_INFO(be_802_3_dropped_frames)}, {DRVSTAT_INFO(be_802_3_dropped_frames)},
{DRVSTAT_INFO(be_802_3_malformed_frames)}, {DRVSTAT_INFO(be_802_3_malformed_frames)},

View File

@ -167,8 +167,11 @@
#define FLASH_FCoE_BIOS_START_g3 (13631488) #define FLASH_FCoE_BIOS_START_g3 (13631488)
#define FLASH_REDBOOT_START_g3 (262144) #define FLASH_REDBOOT_START_g3 (262144)
/************* Rx Packet Type Encoding **************/
#define BE_UNICAST_PACKET 0
#define BE_MULTICAST_PACKET 1
#define BE_BROADCAST_PACKET 2
#define BE_RSVD_PACKET 3
/* /*
* BE descriptors: host memory data structures whose formats * BE descriptors: host memory data structures whose formats

View File

@ -247,6 +247,7 @@ void netdev_stats_update(struct be_adapter *adapter)
dev_stats->tx_packets = drvr_stats(adapter)->be_tx_pkts; dev_stats->tx_packets = drvr_stats(adapter)->be_tx_pkts;
dev_stats->rx_bytes = drvr_stats(adapter)->be_rx_bytes; dev_stats->rx_bytes = drvr_stats(adapter)->be_rx_bytes;
dev_stats->tx_bytes = drvr_stats(adapter)->be_tx_bytes; dev_stats->tx_bytes = drvr_stats(adapter)->be_tx_bytes;
dev_stats->multicast = drvr_stats(adapter)->be_rx_mcast_pkt;
/* bad pkts received */ /* bad pkts received */
dev_stats->rx_errors = port_stats->rx_crc_errors + dev_stats->rx_errors = port_stats->rx_crc_errors +
@ -294,7 +295,6 @@ void netdev_stats_update(struct be_adapter *adapter)
/* no space available in linux */ /* no space available in linux */
dev_stats->tx_dropped = 0; dev_stats->tx_dropped = 0;
dev_stats->multicast = port_stats->rx_multicast_frames;
dev_stats->collisions = 0; dev_stats->collisions = 0;
/* detailed tx_errors */ /* detailed tx_errors */
@ -848,7 +848,7 @@ static void be_rx_rate_update(struct be_adapter *adapter)
} }
static void be_rx_stats_update(struct be_adapter *adapter, static void be_rx_stats_update(struct be_adapter *adapter,
u32 pktsize, u16 numfrags) u32 pktsize, u16 numfrags, u8 pkt_type)
{ {
struct be_drvr_stats *stats = drvr_stats(adapter); struct be_drvr_stats *stats = drvr_stats(adapter);
@ -856,6 +856,9 @@ static void be_rx_stats_update(struct be_adapter *adapter,
stats->be_rx_frags += numfrags; stats->be_rx_frags += numfrags;
stats->be_rx_bytes += pktsize; stats->be_rx_bytes += pktsize;
stats->be_rx_pkts++; stats->be_rx_pkts++;
if (pkt_type == BE_MULTICAST_PACKET)
stats->be_rx_mcast_pkt++;
} }
static inline bool do_pkt_csum(struct be_eth_rx_compl *rxcp, bool cso) static inline bool do_pkt_csum(struct be_eth_rx_compl *rxcp, bool cso)
@ -925,9 +928,11 @@ static void skb_fill_rx_data(struct be_adapter *adapter,
u16 rxq_idx, i, j; u16 rxq_idx, i, j;
u32 pktsize, hdr_len, curr_frag_len, size; u32 pktsize, hdr_len, curr_frag_len, size;
u8 *start; u8 *start;
u8 pkt_type;
rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp); rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp);
pktsize = AMAP_GET_BITS(struct amap_eth_rx_compl, pktsize, rxcp); pktsize = AMAP_GET_BITS(struct amap_eth_rx_compl, pktsize, rxcp);
pkt_type = AMAP_GET_BITS(struct amap_eth_rx_compl, cast_enc, rxcp);
page_info = get_rx_page_info(adapter, rxq_idx); page_info = get_rx_page_info(adapter, rxq_idx);
@ -993,7 +998,7 @@ static void skb_fill_rx_data(struct be_adapter *adapter,
BUG_ON(j > MAX_SKB_FRAGS); BUG_ON(j > MAX_SKB_FRAGS);
done: done:
be_rx_stats_update(adapter, pktsize, num_rcvd); be_rx_stats_update(adapter, pktsize, num_rcvd, pkt_type);
} }
/* Process the RX completion indicated by rxcp when GRO is disabled */ /* Process the RX completion indicated by rxcp when GRO is disabled */
@ -1060,6 +1065,7 @@ static void be_rx_compl_process_gro(struct be_adapter *adapter,
u32 num_rcvd, pkt_size, remaining, vlanf, curr_frag_len; u32 num_rcvd, pkt_size, remaining, vlanf, curr_frag_len;
u16 i, rxq_idx = 0, vid, j; u16 i, rxq_idx = 0, vid, j;
u8 vtm; u8 vtm;
u8 pkt_type;
num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp); num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp);
/* Is it a flush compl that has no data */ /* Is it a flush compl that has no data */
@ -1070,6 +1076,7 @@ static void be_rx_compl_process_gro(struct be_adapter *adapter,
vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl, vtp, rxcp); vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl, vtp, rxcp);
rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp); rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp);
vtm = AMAP_GET_BITS(struct amap_eth_rx_compl, vtm, rxcp); vtm = AMAP_GET_BITS(struct amap_eth_rx_compl, vtm, rxcp);
pkt_type = AMAP_GET_BITS(struct amap_eth_rx_compl, cast_enc, rxcp);
/* vlanf could be wrongly set in some cards. /* vlanf could be wrongly set in some cards.
* ignore if vtm is not set */ * ignore if vtm is not set */
@ -1125,7 +1132,7 @@ static void be_rx_compl_process_gro(struct be_adapter *adapter,
vlan_gro_frags(&eq_obj->napi, adapter->vlan_grp, vid); vlan_gro_frags(&eq_obj->napi, adapter->vlan_grp, vid);
} }
be_rx_stats_update(adapter, pkt_size, num_rcvd); be_rx_stats_update(adapter, pkt_size, num_rcvd, pkt_type);
} }
static struct be_eth_rx_compl *be_rx_compl_get(struct be_adapter *adapter) static struct be_eth_rx_compl *be_rx_compl_get(struct be_adapter *adapter)