From 20c1d28e106c0b526ae015fcac8e1e254bff091c Mon Sep 17 00:00:00 2001 From: Vasundhara Volam Date: Thu, 26 Apr 2018 17:44:36 -0400 Subject: bnxt_en: Display function level rx/tx_discard_pkts via ethtool Add counters to display sum of rx/tx_discard_pkts of all rings as function level statistics via ethtool. Signed-off-by: Vasundhara Volam Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 33 +++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c') diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c index 8ba14ae00e8ff..0ea8466d531b7 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c @@ -140,6 +140,19 @@ reset_coalesce: #define BNXT_RX_STATS_EXT_ENTRY(counter) \ { BNXT_RX_STATS_EXT_OFFSET(counter), __stringify(counter) } +enum { + RX_TOTAL_DISCARDS, + TX_TOTAL_DISCARDS, +}; + +static struct { + u64 counter; + char string[ETH_GSTRING_LEN]; +} bnxt_sw_func_stats[] = { + {0, "rx_total_discard_pkts"}, + {0, "tx_total_discard_pkts"}, +}; + static const struct { long offset; char string[ETH_GSTRING_LEN]; @@ -237,6 +250,7 @@ static const struct { BNXT_RX_STATS_EXT_ENTRY(resume_roce_pause_events), }; +#define BNXT_NUM_SW_FUNC_STATS ARRAY_SIZE(bnxt_sw_func_stats) #define BNXT_NUM_PORT_STATS ARRAY_SIZE(bnxt_port_stats_arr) #define BNXT_NUM_PORT_STATS_EXT ARRAY_SIZE(bnxt_port_stats_ext_arr) @@ -244,6 +258,8 @@ static int bnxt_get_num_stats(struct bnxt *bp) { int num_stats = BNXT_NUM_STATS * bp->cp_nr_rings; + num_stats += BNXT_NUM_SW_FUNC_STATS; + if (bp->flags & BNXT_FLAG_PORT_STATS) num_stats += BNXT_NUM_PORT_STATS; @@ -279,6 +295,9 @@ static void bnxt_get_ethtool_stats(struct net_device *dev, if (!bp->bnapi) return; + for (i = 0; i < BNXT_NUM_SW_FUNC_STATS; i++) + bnxt_sw_func_stats[i].counter = 0; + for (i = 0; i < bp->cp_nr_rings; i++) { struct bnxt_napi *bnapi = bp->bnapi[i]; struct bnxt_cp_ring_info *cpr = &bnapi->cp_ring; @@ -288,7 +307,16 @@ static void bnxt_get_ethtool_stats(struct net_device *dev, for (k = 0; k < stat_fields; j++, k++) buf[j] = le64_to_cpu(hw_stats[k]); buf[j++] = cpr->rx_l4_csum_errors; + + bnxt_sw_func_stats[RX_TOTAL_DISCARDS].counter += + le64_to_cpu(cpr->hw_stats->rx_discard_pkts); + bnxt_sw_func_stats[TX_TOTAL_DISCARDS].counter += + le64_to_cpu(cpr->hw_stats->tx_discard_pkts); } + + for (i = 0; i < BNXT_NUM_SW_FUNC_STATS; i++, j++) + buf[j] = bnxt_sw_func_stats[i].counter; + if (bp->flags & BNXT_FLAG_PORT_STATS) { __le64 *port_stats = (__le64 *)bp->hw_rx_port_stats; @@ -359,6 +387,11 @@ static void bnxt_get_strings(struct net_device *dev, u32 stringset, u8 *buf) sprintf(buf, "[%d]: rx_l4_csum_errors", i); buf += ETH_GSTRING_LEN; } + for (i = 0; i < BNXT_NUM_SW_FUNC_STATS; i++) { + strcpy(buf, bnxt_sw_func_stats[i].string); + buf += ETH_GSTRING_LEN; + } + if (bp->flags & BNXT_FLAG_PORT_STATS) { for (i = 0; i < BNXT_NUM_PORT_STATS; i++) { strcpy(buf, bnxt_port_stats_arr[i].string); -- cgit v1.2.3 From 4cebbaca12514986039b2ac7d30e36ecd2222f64 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Thu, 26 Apr 2018 17:44:37 -0400 Subject: bnxt_en: Do not allow VF to read EEPROM. Firmware does not allow the operation and would return failure, causing a warning in dmesg. So check for VF and disallow it in the driver. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c') diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c index 0ea8466d531b7..a699ca5493ef3 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c @@ -1818,6 +1818,11 @@ static int nvm_get_dir_info(struct net_device *dev, u32 *entries, u32 *length) static int bnxt_get_eeprom_len(struct net_device *dev) { + struct bnxt *bp = netdev_priv(dev); + + if (BNXT_VF(bp)) + return 0; + /* The -1 return value allows the entire 32-bit range of offsets to be * passed via the ethtool command-line utility. */ -- cgit v1.2.3 From d8c09f19accb89fc08b246339abb005455e4c846 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Thu, 26 Apr 2018 17:44:41 -0400 Subject: bnxt_en: Reserve rings in bnxt_set_channels() if device is down. The current code does not reserve rings during ethtool -L when the device is down. The rings will be reserved when the device is later opened. Change it to reserve rings during ethtool -L when the device is down. This provides a better guarantee that the device open will be successful when the rings are reserved ahead of time. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c') diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c index a699ca5493ef3..ad98b78f5aa13 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c @@ -584,6 +584,8 @@ static int bnxt_set_channels(struct net_device *dev, * to renable */ } + } else { + rc = bnxt_reserve_rings(bp); } return rc; -- cgit v1.2.3 From 7328a23c063a9ecf56314fb9631889c1820bd0ce Mon Sep 17 00:00:00 2001 From: Vasundhara Volam Date: Tue, 8 May 2018 03:18:40 -0400 Subject: bnxt_en: Read phy eeprom A2h address only when optical diagnostics is supported. For SFP+ modules, 0xA2 page is available only when Diagnostic Monitoring Type [Address A0h, Byte 92] is implemented. Extend bnxt_get_module_info(), to read optical diagnostics support at offset 92(0x5c) and set eeprom_len length to ETH_MODULE_SFF_8436_LEN (to exclude A2 page), if dianostics is not supported. Also in bnxt_get_module_info(), module id is read from offset 0x5e which is not correct. It was working by accident, as offset was not effective without setting enables flag in the firmware request. SFP module id is present at location 0. Fix this by removing the offset and read it from location 0. Signed-off-by: Vasundhara Volam Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnxt/bnxt.h | 3 +-- drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 20 ++++++++------------ 2 files changed, 9 insertions(+), 14 deletions(-) (limited to 'drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c') diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h index a9c210e708681..9b14eb610b9f6 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h @@ -1414,8 +1414,7 @@ struct bnxt { #define I2C_DEV_ADDR_A0 0xa0 #define I2C_DEV_ADDR_A2 0xa2 -#define SFP_EEPROM_SFF_8472_COMP_ADDR 0x5e -#define SFP_EEPROM_SFF_8472_COMP_SIZE 1 +#define SFF_DIAG_SUPPORT_OFFSET 0x5c #define SFF_MODULE_ID_SFP 0x3 #define SFF_MODULE_ID_QSFP 0xc #define SFF_MODULE_ID_QSFP_PLUS 0xd diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c index ad98b78f5aa13..7270c8b0cef38 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c @@ -2184,9 +2184,8 @@ static int bnxt_read_sfp_module_eeprom_info(struct bnxt *bp, u16 i2c_addr, static int bnxt_get_module_info(struct net_device *dev, struct ethtool_modinfo *modinfo) { + u8 data[SFF_DIAG_SUPPORT_OFFSET + 1]; struct bnxt *bp = netdev_priv(dev); - struct hwrm_port_phy_i2c_read_input req = {0}; - struct hwrm_port_phy_i2c_read_output *output = bp->hwrm_cmd_resp_addr; int rc; /* No point in going further if phy status indicates @@ -2201,21 +2200,19 @@ static int bnxt_get_module_info(struct net_device *dev, if (bp->hwrm_spec_code < 0x10202) return -EOPNOTSUPP; - bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_PORT_PHY_I2C_READ, -1, -1); - req.i2c_slave_addr = I2C_DEV_ADDR_A0; - req.page_number = 0; - req.page_offset = cpu_to_le16(SFP_EEPROM_SFF_8472_COMP_ADDR); - req.data_length = SFP_EEPROM_SFF_8472_COMP_SIZE; - req.port_id = cpu_to_le16(bp->pf.port_id); - mutex_lock(&bp->hwrm_cmd_lock); - rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); + rc = bnxt_read_sfp_module_eeprom_info(bp, I2C_DEV_ADDR_A0, 0, 0, + SFF_DIAG_SUPPORT_OFFSET + 1, + data); if (!rc) { - u32 module_id = le32_to_cpu(output->data[0]); + u8 module_id = data[0]; + u8 diag_supported = data[SFF_DIAG_SUPPORT_OFFSET]; switch (module_id) { case SFF_MODULE_ID_SFP: modinfo->type = ETH_MODULE_SFF_8472; modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN; + if (!diag_supported) + modinfo->eeprom_len = ETH_MODULE_SFF_8436_LEN; break; case SFF_MODULE_ID_QSFP: case SFF_MODULE_ID_QSFP_PLUS: @@ -2231,7 +2228,6 @@ static int bnxt_get_module_info(struct net_device *dev, break; } } - mutex_unlock(&bp->hwrm_cmd_lock); return rc; } -- cgit v1.2.3