static void bnxt_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause) { struct bnxt *bp = netdev_priv(dev); struct bnxt_link_info *link_info = &bp->link_info; 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); }
void bnxt_dev_xstats_reset_op(struct rte_eth_dev *eth_dev) { struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private; if (bp->flags & BNXT_FLAG_PORT_STATS && !BNXT_NPAR_PF(bp)) bnxt_hwrm_port_clr_stats(bp); if (BNXT_VF(bp)) RTE_LOG(ERR, PMD, "Operation not supported on a VF device\n"); if (BNXT_NPAR_PF(bp)) RTE_LOG(ERR, PMD, "Operation not supported on a MF device\n"); if (!(bp->flags & BNXT_FLAG_PORT_STATS)) RTE_LOG(ERR, PMD, "Operation not supported\n"); }
static int bnxt_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause) { int rc = 0; struct bnxt *bp = netdev_priv(dev); struct bnxt_link_info *link_info = &bp->link_info; if (BNXT_VF(bp)) return rc; if (epause->autoneg) { if (!(link_info->autoneg & BNXT_AUTONEG_SPEED)) return -EINVAL; link_info->autoneg |= BNXT_AUTONEG_FLOW_CTRL; link_info->req_flow_ctrl |= BNXT_LINK_PAUSE_BOTH; } else { /* when transition from auto pause to force pause, * force a link change */ if (link_info->autoneg & BNXT_AUTONEG_FLOW_CTRL) link_info->force_link_chng = true; link_info->autoneg &= ~BNXT_AUTONEG_FLOW_CTRL; link_info->req_flow_ctrl &= ~BNXT_LINK_PAUSE_BOTH; } if (epause->rx_pause) link_info->req_flow_ctrl |= BNXT_LINK_PAUSE_RX; else link_info->req_flow_ctrl &= ~BNXT_LINK_PAUSE_RX; if (epause->tx_pause) link_info->req_flow_ctrl |= BNXT_LINK_PAUSE_TX; else link_info->req_flow_ctrl &= ~BNXT_LINK_PAUSE_TX; if (netif_running(dev)) rc = bnxt_hwrm_set_pause(bp); return rc; }
static int bnxt_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) { int rc = 0; struct bnxt *bp = netdev_priv(dev); struct bnxt_link_info *link_info = &bp->link_info; u32 speed, fw_advertising = 0; bool set_pause = false; if (BNXT_VF(bp)) 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)) { netdev_err(dev, "Unsupported advertising mask (adv: 0x%x)\n", cmd->advertising); rc = -EINVAL; goto set_setting_exit; } fw_advertising = bnxt_get_fw_auto_link_speeds(cmd->advertising); if (fw_advertising & ~link_info->support_speeds) { netdev_err(dev, "Advertising parameters are not supported! (adv: 0x%x)\n", cmd->advertising); rc = -EINVAL; goto set_setting_exit; } link_info->autoneg |= BNXT_AUTONEG_SPEED; if (!fw_advertising) link_info->advertising = link_info->support_speeds; else link_info->advertising = fw_advertising; /* any change to autoneg will cause link change, therefore the * driver should put back the original pause setting in autoneg */ set_pause = true; } else { /* TODO: currently don't support half duplex */ if (cmd->duplex == DUPLEX_HALF) { netdev_err(dev, "HALF DUPLEX is not supported!\n"); rc = -EINVAL; goto set_setting_exit; } /* If received a request for an unknown duplex, assume full*/ if (cmd->duplex == DUPLEX_UNKNOWN) cmd->duplex = DUPLEX_FULL; speed = ethtool_cmd_speed(cmd); link_info->req_link_speed = bnxt_get_fw_speed(dev, speed); link_info->req_duplex = BNXT_LINK_DUPLEX_FULL; link_info->autoneg &= ~BNXT_AUTONEG_SPEED; link_info->advertising = 0; } if (netif_running(dev)) rc = bnxt_hwrm_set_link_setting(bp, set_pause); set_setting_exit: return rc; }