From dfb5b894f87cb78168e04283e8d15626dc3e6d5a Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Fri, 26 Feb 2016 04:00:01 -0500 Subject: bnxt_en: Store irq coalescing timer values in micro seconds. Don't convert these to internal hardware tick values before storing them. This avoids the confusion of ethtool -c returning slightly different values than the ones set using ethtool -C when we convert hardware tick values back to micro seconds. Add better comments for the hardware settings. Also, rename the current set of coalescing fields with rx_ prefix. The next patch will add support of tx coalescing values. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) (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 3238817dfd5f..d18a97727394 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c @@ -41,12 +41,11 @@ static int bnxt_get_coalesce(struct net_device *dev, memset(coal, 0, sizeof(*coal)); - coal->rx_coalesce_usecs = - max_t(u16, BNXT_COAL_TIMER_TO_USEC(bp->coal_ticks), 1); - coal->rx_max_coalesced_frames = bp->coal_bufs / 2; - coal->rx_coalesce_usecs_irq = - max_t(u16, BNXT_COAL_TIMER_TO_USEC(bp->coal_ticks_irq), 1); - coal->rx_max_coalesced_frames_irq = bp->coal_bufs_irq / 2; + coal->rx_coalesce_usecs = bp->rx_coal_ticks; + /* 2 completion records per rx packet */ + coal->rx_max_coalesced_frames = bp->rx_coal_bufs / 2; + coal->rx_coalesce_usecs_irq = bp->rx_coal_ticks_irq; + coal->rx_max_coalesced_frames_irq = bp->rx_coal_bufs_irq / 2; return 0; } @@ -57,11 +56,11 @@ static int bnxt_set_coalesce(struct net_device *dev, struct bnxt *bp = netdev_priv(dev); int rc = 0; - bp->coal_ticks = BNXT_USEC_TO_COAL_TIMER(coal->rx_coalesce_usecs); - bp->coal_bufs = coal->rx_max_coalesced_frames * 2; - bp->coal_ticks_irq = - BNXT_USEC_TO_COAL_TIMER(coal->rx_coalesce_usecs_irq); - bp->coal_bufs_irq = coal->rx_max_coalesced_frames_irq * 2; + bp->rx_coal_ticks = coal->rx_coalesce_usecs; + /* 2 completion records per rx packet */ + bp->rx_coal_bufs = coal->rx_max_coalesced_frames * 2; + bp->rx_coal_ticks_irq = coal->rx_coalesce_usecs_irq; + bp->rx_coal_bufs_irq = coal->rx_max_coalesced_frames_irq * 2; if (netif_running(dev)) rc = bnxt_hwrm_set_coal(bp); -- cgit v1.2.3 From dfc9c94a83909f4be80e5d0c67e79793830aa312 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Fri, 26 Feb 2016 04:00:03 -0500 Subject: bnxt_en: Add coalescing support for tx rings. When tx and rx rings don't share the same completion ring, tx coalescing parameters can be set differently from the rx coalescing parameters. Otherwise, use rx coalescing parameters on shared completion rings. Adjust rx coalescing default values to lower interrupt rate. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 10 ++++++++++ 1 file changed, 10 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 d18a97727394..a2d25499a73c 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c @@ -47,6 +47,11 @@ static int bnxt_get_coalesce(struct net_device *dev, coal->rx_coalesce_usecs_irq = bp->rx_coal_ticks_irq; coal->rx_max_coalesced_frames_irq = bp->rx_coal_bufs_irq / 2; + coal->tx_coalesce_usecs = bp->tx_coal_ticks; + coal->tx_max_coalesced_frames = bp->tx_coal_bufs; + coal->tx_coalesce_usecs_irq = bp->tx_coal_ticks_irq; + coal->tx_max_coalesced_frames_irq = bp->tx_coal_bufs_irq; + return 0; } @@ -62,6 +67,11 @@ static int bnxt_set_coalesce(struct net_device *dev, bp->rx_coal_ticks_irq = coal->rx_coalesce_usecs_irq; bp->rx_coal_bufs_irq = coal->rx_max_coalesced_frames_irq * 2; + bp->tx_coal_ticks = coal->tx_coalesce_usecs; + bp->tx_coal_bufs = coal->tx_max_coalesced_frames; + bp->tx_coal_ticks_irq = coal->tx_coalesce_usecs_irq; + bp->tx_coal_bufs_irq = coal->tx_max_coalesced_frames_irq; + if (netif_running(dev)) rc = bnxt_hwrm_set_coal(bp); -- cgit v1.2.3 From 3ebf6f0a09a284adef62111c7cfca29f56d6cce7 Mon Sep 17 00:00:00 2001 From: Rob Swindell Date: Fri, 26 Feb 2016 04:00:06 -0500 Subject: bnxt_en: Add installed-package firmware version reporting via Ethtool GDRVINFO For everything to fit, we remove the PHY microcode version and replace it with the firmware package version in the fw_version string. Signed-off-by: Rob Swindell Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 95 ++++++++++++++++++++++- 1 file changed, 94 insertions(+), 1 deletion(-) (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 a2d25499a73c..bfda92ef1778 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c @@ -7,6 +7,7 @@ * the Free Software Foundation. */ +#include #include #include #include @@ -20,6 +21,8 @@ #include "bnxt_fw_hdr.h" /* Firmware hdr constant and structure defs */ #define FLASH_NVRAM_TIMEOUT ((HWRM_CMD_TIMEOUT) * 100) +static char *bnxt_get_pkgver(struct net_device *dev, char *buf, size_t buflen); + static u32 bnxt_get_msglevel(struct net_device *dev) { struct bnxt *bp = netdev_priv(dev); @@ -469,10 +472,20 @@ static void bnxt_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { struct bnxt *bp = netdev_priv(dev); + char *pkglog; + char *pkgver = NULL; + pkglog = kmalloc(BNX_PKG_LOG_MAX_LENGTH, GFP_KERNEL); + if (pkglog) + pkgver = bnxt_get_pkgver(dev, pkglog, BNX_PKG_LOG_MAX_LENGTH); strlcpy(info->driver, DRV_MODULE_NAME, sizeof(info->driver)); strlcpy(info->version, DRV_MODULE_VERSION, sizeof(info->version)); - strlcpy(info->fw_version, bp->fw_ver_str, sizeof(info->fw_version)); + if (pkgver && *pkgver != 0 && isdigit(*pkgver)) + snprintf(info->fw_version, sizeof(info->fw_version) - 1, + "%s pkg %s", bp->fw_ver_str, pkgver); + else + strlcpy(info->fw_version, bp->fw_ver_str, + sizeof(info->fw_version)); strlcpy(info->bus_info, pci_name(bp->pdev), sizeof(info->bus_info)); info->n_stats = BNXT_NUM_STATS * bp->cp_nr_rings; info->testinfo_len = BNXT_NUM_TESTS(bp); @@ -480,6 +493,7 @@ static void bnxt_get_drvinfo(struct net_device *dev, info->eedump_len = 0; /* TODO CHIMP FW: reg dump details */ info->regdump_len = 0; + kfree(pkglog); } static u32 bnxt_fw_to_ethtool_support_spds(struct bnxt_link_info *link_info) @@ -1111,6 +1125,85 @@ static int bnxt_get_nvram_item(struct net_device *dev, u32 index, u32 offset, return rc; } +static int bnxt_find_nvram_item(struct net_device *dev, u16 type, u16 ordinal, + u16 ext, u16 *index, u32 *item_length, + u32 *data_length) +{ + struct bnxt *bp = netdev_priv(dev); + int rc; + struct hwrm_nvm_find_dir_entry_input req = {0}; + struct hwrm_nvm_find_dir_entry_output *output = bp->hwrm_cmd_resp_addr; + + bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_NVM_FIND_DIR_ENTRY, -1, -1); + req.enables = 0; + req.dir_idx = 0; + req.dir_type = cpu_to_le16(type); + req.dir_ordinal = cpu_to_le16(ordinal); + req.dir_ext = cpu_to_le16(ext); + req.opt_ordinal = NVM_FIND_DIR_ENTRY_REQ_OPT_ORDINAL_EQ; + rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); + if (rc == 0) { + if (index) + *index = le16_to_cpu(output->dir_idx); + if (item_length) + *item_length = le32_to_cpu(output->dir_item_length); + if (data_length) + *data_length = le32_to_cpu(output->dir_data_length); + } + return rc; +} + +static char *bnxt_parse_pkglog(int desired_field, u8 *data, size_t datalen) +{ + char *retval = NULL; + char *p; + char *value; + int field = 0; + + if (datalen < 1) + return NULL; + /* null-terminate the log data (removing last '\n'): */ + data[datalen - 1] = 0; + for (p = data; *p != 0; p++) { + field = 0; + retval = NULL; + while (*p != 0 && *p != '\n') { + value = p; + while (*p != 0 && *p != '\t' && *p != '\n') + p++; + if (field == desired_field) + retval = value; + if (*p != '\t') + break; + *p = 0; + field++; + p++; + } + if (*p == 0) + break; + *p = 0; + } + return retval; +} + +static char *bnxt_get_pkgver(struct net_device *dev, char *buf, size_t buflen) +{ + u16 index = 0; + u32 datalen; + + if (bnxt_find_nvram_item(dev, BNX_DIR_TYPE_PKG_LOG, + BNX_DIR_ORDINAL_FIRST, BNX_DIR_EXT_NONE, + &index, NULL, &datalen) != 0) + return NULL; + + memset(buf, 0, buflen); + if (bnxt_get_nvram_item(dev, index, 0, datalen, buf) != 0) + return NULL; + + return bnxt_parse_pkglog(BNX_PKG_LOG_FIELD_IDX_PKG_VERSION, buf, + datalen); +} + static int bnxt_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 *data) -- cgit v1.2.3 From 90e209213096110bce06ef580e1c73702fe4a288 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Fri, 26 Feb 2016 04:00:08 -0500 Subject: bnxt_en: Add hwrm_send_message_silent(). This is used to send NVM_FIND_DIR_ENTRY messages which can return error if the entry is not found. This is normal and the error message will cause unnecessary alarm, so silence it. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (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 bfda92ef1778..84ea26d6f3ff 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c @@ -1141,7 +1141,7 @@ static int bnxt_find_nvram_item(struct net_device *dev, u16 type, u16 ordinal, req.dir_ordinal = cpu_to_le16(ordinal); req.dir_ext = cpu_to_le16(ext); req.opt_ordinal = NVM_FIND_DIR_ENTRY_REQ_OPT_ORDINAL_EQ; - rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); + rc = hwrm_send_message_silent(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); if (rc == 0) { if (index) *index = le16_to_cpu(output->dir_idx); -- cgit v1.2.3 From 27c4d578600c401c119c012a90920805fab05cc9 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Mon, 7 Mar 2016 15:38:41 -0500 Subject: bnxt_en: Refactor bnxt_fw_to_ethtool_advertised_spds(). Include the conversion of pause bits and add one extra call layer so that the same refactored function can be reused to get the link partner advertisement bits. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 33 ++++++++++++++--------- 1 file changed, 20 insertions(+), 13 deletions(-) (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 84ea26d6f3ff..a6ee26a6b6bb 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c @@ -515,9 +515,8 @@ static u32 bnxt_fw_to_ethtool_support_spds(struct bnxt_link_info *link_info) return speed_mask; } -static u32 bnxt_fw_to_ethtool_advertised_spds(struct bnxt_link_info *link_info) +static u32 _bnxt_fw_to_ethtool_adv_spds(u16 fw_speeds, u8 fw_pause) { - u16 fw_speeds = link_info->auto_link_speeds; u32 speed_mask = 0; /* TODO: support 25GB, 40GB, 50GB with different cable type */ @@ -532,9 +531,28 @@ static u32 bnxt_fw_to_ethtool_advertised_spds(struct bnxt_link_info *link_info) speed_mask |= ADVERTISED_10000baseT_Full; if (fw_speeds & BNXT_LINK_SPEED_MSK_40GB) speed_mask |= ADVERTISED_40000baseCR4_Full; + + if ((fw_pause & BNXT_LINK_PAUSE_BOTH) == BNXT_LINK_PAUSE_BOTH) + speed_mask |= ADVERTISED_Pause; + else if (fw_pause & BNXT_LINK_PAUSE_TX) + speed_mask |= ADVERTISED_Asym_Pause; + else if (fw_pause & BNXT_LINK_PAUSE_RX) + speed_mask |= ADVERTISED_Pause | ADVERTISED_Asym_Pause; + return speed_mask; } +static u32 bnxt_fw_to_ethtool_advertised_spds(struct bnxt_link_info *link_info) +{ + u16 fw_speeds = link_info->auto_link_speeds; + u8 fw_pause = 0; + + if (link_info->autoneg & BNXT_AUTONEG_FLOW_CTRL) + fw_pause = link_info->auto_pause_setting; + + return _bnxt_fw_to_ethtool_adv_spds(fw_speeds, fw_pause); +} + u32 bnxt_fw_to_ethtool_speed(u16 fw_link_speed) { switch (fw_link_speed) { @@ -580,17 +598,6 @@ static int bnxt_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) cmd->autoneg = AUTONEG_DISABLE; cmd->advertising = 0; } - if (link_info->autoneg & BNXT_AUTONEG_FLOW_CTRL) { - if ((link_info->auto_pause_setting & BNXT_LINK_PAUSE_BOTH) == - BNXT_LINK_PAUSE_BOTH) { - cmd->advertising |= ADVERTISED_Pause; - } else { - cmd->advertising |= ADVERTISED_Asym_Pause; - if (link_info->auto_pause_setting & - BNXT_LINK_PAUSE_RX) - cmd->advertising |= ADVERTISED_Pause; - } - } cmd->port = PORT_NONE; if (link_info->media_type == PORT_PHY_QCFG_RESP_MEDIA_TYPE_TP) { -- cgit v1.2.3 From 3277360eb29c6e482391975717d983060ecbd28d Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Mon, 7 Mar 2016 15:38:42 -0500 Subject: bnxt_en: Add reporting of link partner advertisement. And report actual pause settings to ETHTOOL_GPAUSEPARAM to let ethtool resolve the actual pause settings. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (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 a6ee26a6b6bb..591c290f6588 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c @@ -553,6 +553,17 @@ static u32 bnxt_fw_to_ethtool_advertised_spds(struct bnxt_link_info *link_info) return _bnxt_fw_to_ethtool_adv_spds(fw_speeds, fw_pause); } +static u32 bnxt_fw_to_ethtool_lp_adv(struct bnxt_link_info *link_info) +{ + u16 fw_speeds = link_info->lp_auto_link_speeds; + u8 fw_pause = 0; + + if (link_info->autoneg & BNXT_AUTONEG_FLOW_CTRL) + fw_pause = link_info->lp_pause; + + return _bnxt_fw_to_ethtool_adv_spds(fw_speeds, fw_pause); +} + u32 bnxt_fw_to_ethtool_speed(u16 fw_link_speed) { switch (fw_link_speed) { @@ -594,6 +605,9 @@ static int bnxt_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) bnxt_fw_to_ethtool_advertised_spds(link_info); cmd->advertising |= ADVERTISED_Autoneg; cmd->autoneg = AUTONEG_ENABLE; + if (link_info->phy_link_status == BNXT_LINK_LINK) + cmd->lp_advertising = + bnxt_fw_to_ethtool_lp_adv(link_info); } else { cmd->autoneg = AUTONEG_DISABLE; cmd->advertising = 0; @@ -757,8 +771,10 @@ static void bnxt_get_pauseparam(struct net_device *dev, if (BNXT_VF(bp)) return; epause->autoneg = !!(link_info->autoneg & BNXT_AUTONEG_FLOW_CTRL); - epause->rx_pause = ((link_info->pause & BNXT_LINK_PAUSE_RX) != 0); - epause->tx_pause = ((link_info->pause & BNXT_LINK_PAUSE_TX) != 0); + epause->rx_pause = + ((link_info->auto_pause_setting & BNXT_LINK_PAUSE_RX) != 0); + epause->tx_pause = + ((link_info->auto_pause_setting & BNXT_LINK_PAUSE_TX) != 0); } static int bnxt_set_pauseparam(struct net_device *dev, -- cgit v1.2.3 From 4b32cacca28fe8b29bf266feff19b6fc2180402e Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Mon, 7 Mar 2016 15:38:43 -0500 Subject: bnxt_en: Use common function to get ethtool supported flags. The supported bits and advertising bits in ethtool have the same definitions. The same is true for the firmware bits. So use the common function to handle the conversion for both supported and advertising bits. v2: Don't use parentheses on function return. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 29 +++++++---------------- 1 file changed, 9 insertions(+), 20 deletions(-) (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 591c290f6588..ac9d6e5bc585 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c @@ -496,25 +496,6 @@ static void bnxt_get_drvinfo(struct net_device *dev, kfree(pkglog); } -static u32 bnxt_fw_to_ethtool_support_spds(struct bnxt_link_info *link_info) -{ - u16 fw_speeds = link_info->support_speeds; - u32 speed_mask = 0; - - if (fw_speeds & BNXT_LINK_SPEED_MSK_100MB) - speed_mask |= SUPPORTED_100baseT_Full; - if (fw_speeds & BNXT_LINK_SPEED_MSK_1GB) - speed_mask |= SUPPORTED_1000baseT_Full; - if (fw_speeds & BNXT_LINK_SPEED_MSK_2_5GB) - speed_mask |= SUPPORTED_2500baseX_Full; - if (fw_speeds & BNXT_LINK_SPEED_MSK_10GB) - speed_mask |= SUPPORTED_10000baseT_Full; - if (fw_speeds & BNXT_LINK_SPEED_MSK_40GB) - speed_mask |= SUPPORTED_40000baseCR4_Full; - - return speed_mask; -} - static u32 _bnxt_fw_to_ethtool_adv_spds(u16 fw_speeds, u8 fw_pause) { u32 speed_mask = 0; @@ -564,6 +545,15 @@ static u32 bnxt_fw_to_ethtool_lp_adv(struct bnxt_link_info *link_info) return _bnxt_fw_to_ethtool_adv_spds(fw_speeds, fw_pause); } +static u32 bnxt_fw_to_ethtool_support_spds(struct bnxt_link_info *link_info) +{ + u16 fw_speeds = link_info->support_speeds; + u32 supported; + + supported = _bnxt_fw_to_ethtool_adv_spds(fw_speeds, 0); + return supported | SUPPORTED_Pause | SUPPORTED_Asym_Pause; +} + u32 bnxt_fw_to_ethtool_speed(u16 fw_link_speed) { switch (fw_link_speed) { @@ -595,7 +585,6 @@ static int bnxt_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) u16 ethtool_speed; cmd->supported = bnxt_fw_to_ethtool_support_spds(link_info); - cmd->supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause; if (link_info->auto_link_speeds) cmd->supported |= SUPPORTED_Autoneg; -- cgit v1.2.3 From f1a082a6f79fd5f06b27ef05a5ba7ec8d6e83b4c Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Mon, 7 Mar 2016 15:38:44 -0500 Subject: bnxt_en: Extend autoneg to all speeds. Allow all autoneg speeds aupported by firmware to be advertised. If the advertising parameter is 0, then all supported speeds will be advertised. Remove BNXT_ALL_COPPER_ETHTOOL_SPEED which is no longer used as all supported speeds can be advertised. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) (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 ac9d6e5bc585..c0998025cb11 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c @@ -696,16 +696,10 @@ static int bnxt_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) return rc; if (cmd->autoneg == AUTONEG_ENABLE) { - if (link_info->media_type != PORT_PHY_QCFG_RESP_MEDIA_TYPE_TP) { - netdev_err(dev, "Media type doesn't support autoneg\n"); - rc = -EINVAL; - goto set_setting_exit; - } - if (cmd->advertising & ~(BNXT_ALL_COPPER_ETHTOOL_SPEED | - ADVERTISED_Autoneg | - ADVERTISED_TP | - ADVERTISED_Pause | - ADVERTISED_Asym_Pause)) { + u32 supported_spds = bnxt_fw_to_ethtool_support_spds(link_info); + + if (cmd->advertising & ~(supported_spds | ADVERTISED_Autoneg | + ADVERTISED_TP | ADVERTISED_FIBRE)) { netdev_err(dev, "Unsupported advertising mask (adv: 0x%x)\n", cmd->advertising); rc = -EINVAL; -- cgit v1.2.3 From 8ddc9aaa725a9337fc7bbe95fe1d1499769fb9b2 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Mon, 7 Mar 2016 15:38:47 -0500 Subject: bnxt_en: Include hardware port statistics in ethtool -S. Include the more useful port statistics in ethtool -S for the PF device. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 105 +++++++++++++++++++++- 1 file changed, 103 insertions(+), 2 deletions(-) (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 c0998025cb11..9ada1662b651 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c @@ -8,6 +8,7 @@ */ #include +#include #include #include #include @@ -83,13 +84,99 @@ static int bnxt_set_coalesce(struct net_device *dev, #define BNXT_NUM_STATS 21 +#define BNXT_RX_STATS_OFFSET(counter) \ + (offsetof(struct rx_port_stats, counter) / 8) + +#define BNXT_RX_STATS_ENTRY(counter) \ + { BNXT_RX_STATS_OFFSET(counter), __stringify(counter) } + +#define BNXT_TX_STATS_OFFSET(counter) \ + ((offsetof(struct tx_port_stats, counter) + \ + sizeof(struct rx_port_stats) + 512) / 8) + +#define BNXT_TX_STATS_ENTRY(counter) \ + { BNXT_TX_STATS_OFFSET(counter), __stringify(counter) } + +static const struct { + long offset; + char string[ETH_GSTRING_LEN]; +} bnxt_port_stats_arr[] = { + BNXT_RX_STATS_ENTRY(rx_64b_frames), + BNXT_RX_STATS_ENTRY(rx_65b_127b_frames), + BNXT_RX_STATS_ENTRY(rx_128b_255b_frames), + BNXT_RX_STATS_ENTRY(rx_256b_511b_frames), + BNXT_RX_STATS_ENTRY(rx_512b_1023b_frames), + BNXT_RX_STATS_ENTRY(rx_1024b_1518_frames), + BNXT_RX_STATS_ENTRY(rx_good_vlan_frames), + BNXT_RX_STATS_ENTRY(rx_1519b_2047b_frames), + BNXT_RX_STATS_ENTRY(rx_2048b_4095b_frames), + BNXT_RX_STATS_ENTRY(rx_4096b_9216b_frames), + BNXT_RX_STATS_ENTRY(rx_9217b_16383b_frames), + BNXT_RX_STATS_ENTRY(rx_total_frames), + BNXT_RX_STATS_ENTRY(rx_ucast_frames), + BNXT_RX_STATS_ENTRY(rx_mcast_frames), + BNXT_RX_STATS_ENTRY(rx_bcast_frames), + BNXT_RX_STATS_ENTRY(rx_fcs_err_frames), + BNXT_RX_STATS_ENTRY(rx_ctrl_frames), + BNXT_RX_STATS_ENTRY(rx_pause_frames), + BNXT_RX_STATS_ENTRY(rx_pfc_frames), + BNXT_RX_STATS_ENTRY(rx_align_err_frames), + BNXT_RX_STATS_ENTRY(rx_ovrsz_frames), + BNXT_RX_STATS_ENTRY(rx_jbr_frames), + BNXT_RX_STATS_ENTRY(rx_mtu_err_frames), + BNXT_RX_STATS_ENTRY(rx_tagged_frames), + BNXT_RX_STATS_ENTRY(rx_double_tagged_frames), + BNXT_RX_STATS_ENTRY(rx_good_frames), + BNXT_RX_STATS_ENTRY(rx_undrsz_frames), + BNXT_RX_STATS_ENTRY(rx_eee_lpi_events), + BNXT_RX_STATS_ENTRY(rx_eee_lpi_duration), + BNXT_RX_STATS_ENTRY(rx_bytes), + BNXT_RX_STATS_ENTRY(rx_runt_bytes), + BNXT_RX_STATS_ENTRY(rx_runt_frames), + + BNXT_TX_STATS_ENTRY(tx_64b_frames), + BNXT_TX_STATS_ENTRY(tx_65b_127b_frames), + BNXT_TX_STATS_ENTRY(tx_128b_255b_frames), + BNXT_TX_STATS_ENTRY(tx_256b_511b_frames), + BNXT_TX_STATS_ENTRY(tx_512b_1023b_frames), + BNXT_TX_STATS_ENTRY(tx_1024b_1518_frames), + BNXT_TX_STATS_ENTRY(tx_good_vlan_frames), + BNXT_TX_STATS_ENTRY(tx_1519b_2047_frames), + BNXT_TX_STATS_ENTRY(tx_2048b_4095b_frames), + BNXT_TX_STATS_ENTRY(tx_4096b_9216b_frames), + BNXT_TX_STATS_ENTRY(tx_9217b_16383b_frames), + BNXT_TX_STATS_ENTRY(tx_good_frames), + BNXT_TX_STATS_ENTRY(tx_total_frames), + BNXT_TX_STATS_ENTRY(tx_ucast_frames), + BNXT_TX_STATS_ENTRY(tx_mcast_frames), + BNXT_TX_STATS_ENTRY(tx_bcast_frames), + BNXT_TX_STATS_ENTRY(tx_pause_frames), + BNXT_TX_STATS_ENTRY(tx_pfc_frames), + BNXT_TX_STATS_ENTRY(tx_jabber_frames), + BNXT_TX_STATS_ENTRY(tx_fcs_err_frames), + BNXT_TX_STATS_ENTRY(tx_err), + BNXT_TX_STATS_ENTRY(tx_fifo_underruns), + BNXT_TX_STATS_ENTRY(tx_eee_lpi_events), + BNXT_TX_STATS_ENTRY(tx_eee_lpi_duration), + BNXT_TX_STATS_ENTRY(tx_total_collisions), + BNXT_TX_STATS_ENTRY(tx_bytes), +}; + +#define BNXT_NUM_PORT_STATS ARRAY_SIZE(bnxt_port_stats_arr) + static int bnxt_get_sset_count(struct net_device *dev, int sset) { struct bnxt *bp = netdev_priv(dev); switch (sset) { - case ETH_SS_STATS: - return BNXT_NUM_STATS * bp->cp_nr_rings; + case ETH_SS_STATS: { + int num_stats = BNXT_NUM_STATS * bp->cp_nr_rings; + + if (bp->flags & BNXT_FLAG_PORT_STATS) + num_stats += BNXT_NUM_PORT_STATS; + + return num_stats; + } default: return -EOPNOTSUPP; } @@ -118,6 +205,14 @@ static void bnxt_get_ethtool_stats(struct net_device *dev, buf[j] = le64_to_cpu(hw_stats[k]); buf[j++] = cpr->rx_l4_csum_errors; } + if (bp->flags & BNXT_FLAG_PORT_STATS) { + __le64 *port_stats = (__le64 *)bp->hw_rx_port_stats; + + for (i = 0; i < BNXT_NUM_PORT_STATS; i++, j++) { + buf[j] = le64_to_cpu(*(port_stats + + bnxt_port_stats_arr[i].offset)); + } + } } static void bnxt_get_strings(struct net_device *dev, u32 stringset, u8 *buf) @@ -172,6 +267,12 @@ 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; } + if (bp->flags & BNXT_FLAG_PORT_STATS) { + for (i = 0; i < BNXT_NUM_PORT_STATS; i++) { + strcpy(buf, bnxt_port_stats_arr[i].string); + buf += ETH_GSTRING_LEN; + } + } break; default: netdev_err(bp->dev, "bnxt_get_strings invalid request %x\n", -- cgit v1.2.3