static void netdev_stats_update(struct be_adapter *adapter) { struct be_hw_stats *hw_stats = hw_stats_from_cmd(adapter->stats.cmd.va); struct be_rxf_stats *rxf_stats = &hw_stats->rxf; struct be_port_rxf_stats *port_stats = &rxf_stats->port[adapter->port_num]; struct net_device_stats *dev_stats = &adapter->stats.net_stats; dev_stats->rx_packets = port_stats->rx_total_frames; dev_stats->tx_packets = port_stats->tx_unicastframes + port_stats->tx_multicastframes + port_stats->tx_broadcastframes; dev_stats->rx_bytes = (u64) port_stats->rx_bytes_msd << 32 | (u64) port_stats->rx_bytes_lsd; dev_stats->tx_bytes = (u64) port_stats->tx_bytes_msd << 32 | (u64) port_stats->tx_bytes_lsd; /* bad pkts received */ dev_stats->rx_errors = port_stats->rx_crc_errors + port_stats->rx_alignment_symbol_errors + port_stats->rx_in_range_errors + port_stats->rx_out_range_errors + port_stats->rx_frame_too_long; /* packet transmit problems */ dev_stats->tx_errors = 0; /* no space in linux buffers */ dev_stats->rx_dropped = 0; /* no space available in linux */ dev_stats->tx_dropped = 0; dev_stats->multicast = port_stats->tx_multicastframes; dev_stats->collisions = 0; /* detailed rx errors */ dev_stats->rx_length_errors = port_stats->rx_in_range_errors + port_stats->rx_out_range_errors + port_stats->rx_frame_too_long; /* receive ring buffer overflow */ dev_stats->rx_over_errors = 0; dev_stats->rx_crc_errors = port_stats->rx_crc_errors; /* frame alignment errors */ dev_stats->rx_frame_errors = port_stats->rx_alignment_symbol_errors; /* receiver fifo overrun */ /* drops_no_pbuf is no per i/f, it's per BE card */ dev_stats->rx_fifo_errors = port_stats->rx_fifo_overflow + port_stats->rx_input_fifo_overflow + rxf_stats->rx_drops_no_pbuf; /* receiver missed packetd */ dev_stats->rx_missed_errors = 0; /* detailed tx_errors */ dev_stats->tx_aborted_errors = 0; dev_stats->tx_carrier_errors = 0; dev_stats->tx_fifo_errors = 0; dev_stats->tx_heartbeat_errors = 0; dev_stats->tx_window_errors = 0; }
static void be_get_ethtool_stats(struct net_device *netdev, struct ethtool_stats *stats, uint64_t *data) { struct be_adapter *adapter = netdev_priv(netdev); struct be_drvr_stats *drvr_stats = &adapter->stats.drvr_stats; struct be_hw_stats *hw_stats = hw_stats_from_cmd(adapter->stats.cmd.va); struct be_rxf_stats *rxf_stats = &hw_stats->rxf; struct be_port_rxf_stats *port_stats = &rxf_stats->port[adapter->port_num]; struct net_device_stats *net_stats = &adapter->stats.net_stats; struct be_erx_stats *erx_stats = &hw_stats->erx; void *p = NULL; int i; for (i = 0; i < ETHTOOL_STATS_NUM; i++) { switch (et_stats[i].type) { case NETSTAT: p = net_stats; break; case DRVSTAT: p = drvr_stats; break; case PORTSTAT: p = port_stats; break; case MISCSTAT: p = rxf_stats; break; case ERXSTAT: /* Currently only one ERX stat is provided */ p = (u32 *)erx_stats + adapter->rx_obj.q.id; break; } p = (u8 *)p + et_stats[i].offset; data[i] = (et_stats[i].size == sizeof(u64)) ? *(u64 *)p: *(u32 *)p; } return; }