static int lio_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) { struct lio *lio = GET_LIO(netdev); struct octeon_device *oct = lio->oct_dev; struct oct_link_info *linfo; linfo = &lio->linfo; if (linfo->link.s.if_mode == INTERFACE_MODE_XAUI || linfo->link.s.if_mode == INTERFACE_MODE_RXAUI || linfo->link.s.if_mode == INTERFACE_MODE_XFI) { ecmd->port = PORT_FIBRE; ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE | SUPPORTED_Pause); ecmd->advertising = (ADVERTISED_10000baseT_Full | ADVERTISED_Pause); ecmd->transceiver = XCVR_EXTERNAL; ecmd->autoneg = AUTONEG_DISABLE; } else { dev_err(&oct->pci_dev->dev, "Unknown link interface reported %d\n", linfo->link.s.if_mode); } if (linfo->link.s.link_up) { ethtool_cmd_speed_set(ecmd, linfo->link.s.speed); ecmd->duplex = linfo->link.s.duplex; } else { ethtool_cmd_speed_set(ecmd, SPEED_UNKNOWN); ecmd->duplex = DUPLEX_UNKNOWN; } return 0; }
static int ixgbevf_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) { struct ixgbevf_adapter *adapter = netdev_priv(netdev); struct ixgbe_hw *hw = &adapter->hw; u32 link_speed = 0; bool link_up; ecmd->supported = SUPPORTED_10000baseT_Full; ecmd->autoneg = AUTONEG_DISABLE; ecmd->transceiver = XCVR_DUMMY1; ecmd->port = -1; hw->mac.ops.check_link(hw, &link_speed, &link_up, false); if (link_up) { ethtool_cmd_speed_set( ecmd, (link_speed == IXGBE_LINK_SPEED_10GB_FULL) ? SPEED_10000 : SPEED_1000); ecmd->duplex = DUPLEX_FULL; } else { ethtool_cmd_speed_set(ecmd, -1); ecmd->duplex = -1; } return 0; }
static int nicvf_get_settings(struct net_device *netdev, struct ethtool_cmd *cmd) { struct nicvf *nic = netdev_priv(netdev); cmd->supported = 0; cmd->transceiver = XCVR_EXTERNAL; if (!nic->link_up) { cmd->duplex = DUPLEX_UNKNOWN; ethtool_cmd_speed_set(cmd, SPEED_UNKNOWN); return 0; } if (nic->speed <= 1000) { cmd->port = PORT_MII; cmd->autoneg = AUTONEG_ENABLE; } else { cmd->port = PORT_FIBRE; cmd->autoneg = AUTONEG_DISABLE; } cmd->duplex = nic->duplex; ethtool_cmd_speed_set(cmd, nic->speed); return 0; }
static int ql_get_settings(struct net_device *ndev, struct ethtool_cmd *ecmd) { struct ql_adapter *qdev = netdev_priv(ndev); ecmd->supported = SUPPORTED_10000baseT_Full; ecmd->advertising = ADVERTISED_10000baseT_Full; ecmd->autoneg = AUTONEG_ENABLE; ecmd->transceiver = XCVR_EXTERNAL; if ((qdev->link_status & STS_LINK_TYPE_MASK) == STS_LINK_TYPE_10GBASET) { ecmd->supported |= (SUPPORTED_TP | SUPPORTED_Autoneg); ecmd->advertising |= (ADVERTISED_TP | ADVERTISED_Autoneg); ecmd->port = PORT_TP; } else { ecmd->supported |= SUPPORTED_FIBRE; ecmd->advertising |= ADVERTISED_FIBRE; ecmd->port = PORT_FIBRE; } ethtool_cmd_speed_set(ecmd, SPEED_10000); ecmd->duplex = DUPLEX_FULL; return 0; }
static int efx_ethtool_get_settings(struct net_device *net_dev, struct ethtool_cmd *ecmd) #endif { struct efx_nic *efx = netdev_priv(net_dev); struct efx_link_state *link_state = &efx->link_state; #if defined(EFX_USE_KCOMPAT) && defined(EFX_NEED_BONDING_HACKS) if (in_interrupt()) { memset(ecmd, 0, sizeof(*ecmd)); ecmd->speed = link_state->speed; ecmd->duplex = link_state->fd ? DUPLEX_FULL : DUPLEX_HALF; return 0; } #endif mutex_lock(&efx->mac_lock); efx->phy_op->get_settings(efx, ecmd); mutex_unlock(&efx->mac_lock); /* Both MACs support pause frames (bidirectional and respond-only) */ ecmd->supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause; if (LOOPBACK_INTERNAL(efx)) { ethtool_cmd_speed_set(ecmd, link_state->speed); ecmd->duplex = link_state->fd ? DUPLEX_FULL : DUPLEX_HALF; } return 0; }
static void efx_mcdi_phy_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) { struct efx_mcdi_phy_data *phy_cfg = efx->phy_data; MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_LINK_OUT_LEN); int rc; ecmd->supported = mcdi_to_ethtool_cap(phy_cfg->media, phy_cfg->supported_cap); ecmd->advertising = efx->link_advertising; ethtool_cmd_speed_set(ecmd, efx->link_state.speed); ecmd->duplex = efx->link_state.fd; ecmd->port = mcdi_to_ethtool_media(phy_cfg->media); ecmd->phy_address = phy_cfg->port; ecmd->transceiver = XCVR_INTERNAL; ecmd->autoneg = !!(efx->link_advertising & ADVERTISED_Autoneg); ecmd->mdio_support = (efx->mdio.mode_support & (MDIO_SUPPORTS_C45 | MDIO_SUPPORTS_C22)); BUILD_BUG_ON(MC_CMD_GET_LINK_IN_LEN != 0); rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0, outbuf, sizeof(outbuf), NULL); if (rc) return; ecmd->lp_advertising = mcdi_to_ethtool_cap(phy_cfg->media, MCDI_DWORD(outbuf, GET_LINK_OUT_LP_CAP)); }
/** * vxge_ethtool_gset - Return link specific information. * @dev: device pointer. * @info: pointer to the structure with parameters given by ethtool * to return link information. * * Returns link specific information like speed, duplex etc.. to ethtool. * Return value : * return 0 on success. */ static int vxge_ethtool_gset(struct net_device *dev, struct ethtool_cmd *info) { info->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE); info->advertising = (ADVERTISED_10000baseT_Full | ADVERTISED_FIBRE); info->port = PORT_FIBRE; info->transceiver = XCVR_EXTERNAL; if (netif_carrier_ok(dev)) { ethtool_cmd_speed_set(info, SPEED_10000); info->duplex = DUPLEX_FULL; } else { ethtool_cmd_speed_set(info, -1); info->duplex = -1; } info->autoneg = AUTONEG_DISABLE; return 0; }
static int netvsc_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) { struct net_device_context *ndc = netdev_priv(dev); ethtool_cmd_speed_set(cmd, ndc->speed); cmd->duplex = ndc->duplex; cmd->port = PORT_OTHER; return 0; }
static int ehea_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) { struct ehea_port *port = netdev_priv(dev); u32 speed; int ret; ret = ehea_sense_port_attr(port); if (ret) return ret; if (netif_carrier_ok(dev)) { switch (port->port_speed) { case EHEA_SPEED_10M: speed = SPEED_10; break; case EHEA_SPEED_100M: speed = SPEED_100; break; case EHEA_SPEED_1G: speed = SPEED_1000; break; case EHEA_SPEED_10G: speed = SPEED_10000; break; default: speed = -1; break; /* BUG */ } cmd->duplex = port->full_duplex == 1 ? DUPLEX_FULL : DUPLEX_HALF; } else { speed = ~0; cmd->duplex = -1; } ethtool_cmd_speed_set(cmd, speed); if (cmd->speed == SPEED_10000) { cmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE); cmd->advertising = (ADVERTISED_10000baseT_Full | ADVERTISED_FIBRE); cmd->port = PORT_FIBRE; } else { cmd->supported = (SUPPORTED_1000baseT_Full | SUPPORTED_100baseT_Full | SUPPORTED_100baseT_Half | SUPPORTED_10baseT_Full | SUPPORTED_10baseT_Half | SUPPORTED_Autoneg | SUPPORTED_TP); cmd->advertising = (ADVERTISED_1000baseT_Full | ADVERTISED_Autoneg | ADVERTISED_TP); cmd->port = PORT_TP; } cmd->autoneg = port->autoneg == 1 ? AUTONEG_ENABLE : AUTONEG_DISABLE; return 0; }
static int vmxnet3_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) { struct vmxnet3_adapter *adapter = netdev_priv(netdev); ecmd->supported = SUPPORTED_10000baseT_Full | SUPPORTED_1000baseT_Full | SUPPORTED_TP; ecmd->advertising = ADVERTISED_TP; ecmd->port = PORT_TP; ecmd->transceiver = XCVR_INTERNAL; if (adapter->link_speed) { ethtool_cmd_speed_set(ecmd, adapter->link_speed); ecmd->duplex = DUPLEX_FULL; } else { ethtool_cmd_speed_set(ecmd, -1); ecmd->duplex = -1; } return 0; }
static int ixgb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) { struct ixgb_adapter *adapter = netdev_priv(netdev); ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE); ecmd->advertising = (ADVERTISED_10000baseT_Full | ADVERTISED_FIBRE); ecmd->port = PORT_FIBRE; ecmd->transceiver = XCVR_EXTERNAL; if (netif_carrier_ok(adapter->netdev)) { ethtool_cmd_speed_set(ecmd, SPEED_10000); ecmd->duplex = DUPLEX_FULL; } else { ethtool_cmd_speed_set(ecmd, SPEED_UNKNOWN); ecmd->duplex = DUPLEX_UNKNOWN; } ecmd->autoneg = AUTONEG_DISABLE; return 0; }
static int get_settings(struct net_device *dev, struct ethtool_cmd *cmd) { const struct port_info *p = netdev_priv(dev); if (p->port_type == FW_PORT_TYPE_BT_SGMII || p->port_type == FW_PORT_TYPE_BT_XFI || p->port_type == FW_PORT_TYPE_BT_XAUI) { cmd->port = PORT_TP; } else if (p->port_type == FW_PORT_TYPE_FIBER_XFI || p->port_type == FW_PORT_TYPE_FIBER_XAUI) { cmd->port = PORT_FIBRE; } else if (p->port_type == FW_PORT_TYPE_SFP || p->port_type == FW_PORT_TYPE_QSFP_10G || p->port_type == FW_PORT_TYPE_QSA || p->port_type == FW_PORT_TYPE_QSFP) { if (p->mod_type == FW_PORT_MOD_TYPE_LR || p->mod_type == FW_PORT_MOD_TYPE_SR || p->mod_type == FW_PORT_MOD_TYPE_ER || p->mod_type == FW_PORT_MOD_TYPE_LRM) cmd->port = PORT_FIBRE; else if (p->mod_type == FW_PORT_MOD_TYPE_TWINAX_PASSIVE || p->mod_type == FW_PORT_MOD_TYPE_TWINAX_ACTIVE) cmd->port = PORT_DA; else cmd->port = PORT_OTHER; } else { cmd->port = PORT_OTHER; } if (p->mdio_addr >= 0) { cmd->phy_address = p->mdio_addr; cmd->transceiver = XCVR_EXTERNAL; cmd->mdio_support = p->port_type == FW_PORT_TYPE_BT_SGMII ? MDIO_SUPPORTS_C22 : MDIO_SUPPORTS_C45; } else { cmd->phy_address = 0; /* not really, but no better option */ cmd->transceiver = XCVR_INTERNAL; cmd->mdio_support = 0; } cmd->supported = from_fw_linkcaps(p->port_type, p->link_cfg.supported); cmd->advertising = from_fw_linkcaps(p->port_type, p->link_cfg.advertising); ethtool_cmd_speed_set(cmd, netif_carrier_ok(dev) ? p->link_cfg.speed : 0); cmd->duplex = DUPLEX_FULL; cmd->autoneg = p->link_cfg.autoneg; cmd->maxtxpkt = 0; cmd->maxrxpkt = 0; return 0; }
static int atl1e_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) { struct atl1e_adapter *adapter = netdev_priv(netdev); struct atl1e_hw *hw = &adapter->hw; ecmd->supported = (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | SUPPORTED_Autoneg | SUPPORTED_TP); if (hw->nic_type == athr_l1e) ecmd->supported |= SUPPORTED_1000baseT_Full; ecmd->advertising = ADVERTISED_TP; ecmd->advertising |= ADVERTISED_Autoneg; ecmd->advertising |= hw->autoneg_advertised; ecmd->port = PORT_TP; ecmd->phy_address = 0; ecmd->transceiver = XCVR_INTERNAL; if (adapter->link_speed != SPEED_0) { ethtool_cmd_speed_set(ecmd, adapter->link_speed); if (adapter->link_duplex == FULL_DUPLEX) ecmd->duplex = DUPLEX_FULL; else ecmd->duplex = DUPLEX_HALF; } else { ethtool_cmd_speed_set(ecmd, -1); ecmd->duplex = -1; } ecmd->autoneg = AUTONEG_ENABLE; return 0; }
static int pch_gbe_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) { struct pch_gbe_adapter *adapter = netdev_priv(netdev); int ret; ret = mii_ethtool_gset(&adapter->mii, ecmd); ecmd->supported &= ~(SUPPORTED_TP | SUPPORTED_1000baseT_Half); ecmd->advertising &= ~(ADVERTISED_TP | ADVERTISED_1000baseT_Half); if (!netif_carrier_ok(adapter->netdev)) ethtool_cmd_speed_set(ecmd, -1); return ret; }
static int veth_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) { cmd->supported = 0; cmd->advertising = 0; ethtool_cmd_speed_set(cmd, SPEED_10000); cmd->duplex = DUPLEX_FULL; cmd->port = PORT_TP; cmd->phy_address = 0; cmd->transceiver = XCVR_INTERNAL; cmd->autoneg = AUTONEG_DISABLE; cmd->maxtxpkt = 0; cmd->maxrxpkt = 0; return 0; }
static int qede_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) { struct qede_dev *edev = netdev_priv(dev); struct qed_link_output current_link; memset(¤t_link, 0, sizeof(current_link)); edev->ops->common->get_link(edev->cdev, ¤t_link); cmd->supported = current_link.supported_caps; cmd->advertising = current_link.advertised_caps; if ((edev->state == QEDE_STATE_OPEN) && (current_link.link_up)) { ethtool_cmd_speed_set(cmd, current_link.speed); cmd->duplex = current_link.duplex; } else { cmd->duplex = DUPLEX_UNKNOWN; ethtool_cmd_speed_set(cmd, SPEED_UNKNOWN); } cmd->port = current_link.port; cmd->autoneg = (current_link.autoneg) ? AUTONEG_ENABLE : AUTONEG_DISABLE; cmd->lp_advertising = current_link.lp_caps; return 0; }
static int igbvf_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) { struct igbvf_adapter *adapter = netdev_priv(netdev); struct e1000_hw *hw = &adapter->hw; u32 status; ecmd->supported = SUPPORTED_1000baseT_Full; ecmd->advertising = ADVERTISED_1000baseT_Full; ecmd->port = -1; ecmd->transceiver = XCVR_DUMMY1; status = er32(STATUS); if (status & E1000_STATUS_LU) { if (status & E1000_STATUS_SPEED_1000) ethtool_cmd_speed_set(ecmd, SPEED_1000); else if (status & E1000_STATUS_SPEED_100) ethtool_cmd_speed_set(ecmd, SPEED_100); else ethtool_cmd_speed_set(ecmd, SPEED_10); if (status & E1000_STATUS_FD) ecmd->duplex = DUPLEX_FULL; else ecmd->duplex = DUPLEX_HALF; } else { ethtool_cmd_speed_set(ecmd, -1); ecmd->duplex = -1; } ecmd->autoneg = AUTONEG_DISABLE; return 0; }
static int bnad_get_settings(struct net_device *netdev, struct ethtool_cmd *cmd) { cmd->supported = SUPPORTED_10000baseT_Full; cmd->advertising = ADVERTISED_10000baseT_Full; cmd->autoneg = AUTONEG_DISABLE; cmd->supported |= SUPPORTED_FIBRE; cmd->advertising |= ADVERTISED_FIBRE; cmd->port = PORT_FIBRE; cmd->phy_address = 0; if (netif_carrier_ok(netdev)) { ethtool_cmd_speed_set(cmd, SPEED_10000); cmd->duplex = DUPLEX_FULL; } else { ethtool_cmd_speed_set(cmd, -1); cmd->duplex = -1; } cmd->transceiver = XCVR_EXTERNAL; cmd->maxtxpkt = 0; cmd->maxrxpkt = 0; return 0; }
static bool netvsc_validate_ethtool_ss_cmd(const struct ethtool_cmd *cmd) { struct ethtool_cmd diff1 = *cmd; struct ethtool_cmd diff2 = {}; ethtool_cmd_speed_set(&diff1, 0); diff1.duplex = 0; /* advertising and cmd are usually set */ diff1.advertising = 0; diff1.cmd = 0; /* We set port to PORT_OTHER */ diff2.port = PORT_OTHER; return !memcmp(&diff1, &diff2, sizeof(diff1)); }
static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) { cmd->supported = (SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg | SUPPORTED_FIBRE); cmd->advertising = (ADVERTISED_1000baseT_Full | ADVERTISED_Autoneg | ADVERTISED_FIBRE); ethtool_cmd_speed_set(cmd, SPEED_1000); cmd->duplex = DUPLEX_FULL; cmd->port = PORT_FIBRE; cmd->phy_address = 0; cmd->transceiver = XCVR_INTERNAL; cmd->autoneg = AUTONEG_ENABLE; cmd->maxtxpkt = 0; cmd->maxrxpkt = 1; return 0; }
static int spider_net_ethtool_get_settings(struct net_device *netdev, struct ethtool_cmd *cmd) { struct spider_net_card *card; card = netdev_priv(netdev); cmd->supported = (SUPPORTED_1000baseT_Full | SUPPORTED_FIBRE); cmd->advertising = (ADVERTISED_1000baseT_Full | ADVERTISED_FIBRE); cmd->port = PORT_FIBRE; ethtool_cmd_speed_set(cmd, card->phy.speed); cmd->duplex = DUPLEX_FULL; return 0; }
static void tenxpress_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) { u32 adv = 0, lpa = 0; int reg; reg = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL); if (reg & MDIO_AN_10GBT_CTRL_ADV10G) adv |= ADVERTISED_10000baseT_Full; reg = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_AN_10GBT_STAT); if (reg & MDIO_AN_10GBT_STAT_LP10G) lpa |= ADVERTISED_10000baseT_Full; mdio45_ethtool_gset_npage(&efx->mdio, ecmd, adv, lpa); if (LOOPBACK_EXTERNAL(efx)) ethtool_cmd_speed_set(ecmd, SPEED_10000); }
/* ethtool_ops::get_settings */ static int vboxNetAdpEthGetSettings(struct net_device *pNetDev, struct ethtool_cmd *cmd) { cmd->supported = 0; cmd->advertising = 0; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) ethtool_cmd_speed_set(cmd, SPEED_10); #else cmd->speed = SPEED_10; #endif cmd->duplex = DUPLEX_FULL; cmd->port = PORT_TP; cmd->phy_address = 0; cmd->transceiver = XCVR_INTERNAL; cmd->autoneg = AUTONEG_DISABLE; cmd->maxtxpkt = 0; cmd->maxrxpkt = 0; return 0; }
/* This must be called with rtnl_lock held. */ static int efx_ethtool_get_settings(struct net_device *net_dev, struct ethtool_cmd *ecmd) { struct efx_nic *efx = netdev_priv(net_dev); struct efx_link_state *link_state = &efx->link_state; mutex_lock(&efx->mac_lock); efx->phy_op->get_settings(efx, ecmd); mutex_unlock(&efx->mac_lock); /* Both MACs support pause frames (bidirectional and respond-only) */ ecmd->supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause; if (LOOPBACK_INTERNAL(efx)) { ethtool_cmd_speed_set(ecmd, link_state->speed); ecmd->duplex = link_state->fd ? DUPLEX_FULL : DUPLEX_HALF; } return 0; }
static void tenxpress_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) { u32 adv = 0, lpa = 0; int reg; reg = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL); if (reg & MDIO_AN_10GBT_CTRL_ADV10G) adv |= ADVERTISED_10000baseT_Full; reg = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_AN_10GBT_STAT); if (reg & MDIO_AN_10GBT_STAT_LP10G) lpa |= ADVERTISED_10000baseT_Full; mdio45_ethtool_gset_npage(&efx->mdio, ecmd, adv, lpa); /* In loopback, the PHY automatically brings up the correct interface, * but doesn't advertise the correct speed. So override it */ if (LOOPBACK_EXTERNAL(efx)) ethtool_cmd_speed_set(ecmd, SPEED_10000); }
/** * mii_ethtool_gset - get settings that are specified in @ecmd * @mii: MII interface * @ecmd: requested ethtool_cmd * * The @ecmd parameter is expected to have been cleared before calling * mii_ethtool_gset(). * * Returns 0 for success, negative on error. */ int mii_ethtool_gset(struct mii_if_info *mii, struct ethtool_cmd *ecmd) { struct net_device *dev = mii->dev; u16 bmcr, bmsr, ctrl1000 = 0, stat1000 = 0; u32 nego; ecmd->supported = (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII); if (mii->supports_gmii) ecmd->supported |= SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full; /* only supports twisted-pair */ ecmd->port = PORT_MII; /* only supports internal transceiver */ ecmd->transceiver = XCVR_INTERNAL; /* this isn't fully supported at higher layers */ ecmd->phy_address = mii->phy_id; ecmd->mdio_support = MDIO_SUPPORTS_C22; ecmd->advertising = ADVERTISED_TP | ADVERTISED_MII; bmcr = mii->mdio_read(dev, mii->phy_id, MII_BMCR); bmsr = mii->mdio_read(dev, mii->phy_id, MII_BMSR); if (mii->supports_gmii) { ctrl1000 = mii->mdio_read(dev, mii->phy_id, MII_CTRL1000); stat1000 = mii->mdio_read(dev, mii->phy_id, MII_STAT1000); } if (bmcr & BMCR_ANENABLE) { ecmd->advertising |= ADVERTISED_Autoneg; ecmd->autoneg = AUTONEG_ENABLE; ecmd->advertising |= mii_get_an(mii, MII_ADVERTISE); if (ctrl1000 & ADVERTISE_1000HALF) ecmd->advertising |= ADVERTISED_1000baseT_Half; if (ctrl1000 & ADVERTISE_1000FULL) ecmd->advertising |= ADVERTISED_1000baseT_Full; if (bmsr & BMSR_ANEGCOMPLETE) { ecmd->lp_advertising = mii_get_an(mii, MII_LPA); if (stat1000 & LPA_1000HALF) ecmd->lp_advertising |= ADVERTISED_1000baseT_Half; if (stat1000 & LPA_1000FULL) ecmd->lp_advertising |= ADVERTISED_1000baseT_Full; } else { ecmd->lp_advertising = 0; } nego = ecmd->advertising & ecmd->lp_advertising; if (nego & (ADVERTISED_1000baseT_Full | ADVERTISED_1000baseT_Half)) { ethtool_cmd_speed_set(ecmd, SPEED_1000); ecmd->duplex = !!(nego & ADVERTISED_1000baseT_Full); } else if (nego & (ADVERTISED_100baseT_Full | ADVERTISED_100baseT_Half)) { ethtool_cmd_speed_set(ecmd, SPEED_100); ecmd->duplex = !!(nego & ADVERTISED_100baseT_Full); } else { ethtool_cmd_speed_set(ecmd, SPEED_10); ecmd->duplex = !!(nego & ADVERTISED_10baseT_Full); } } else { ecmd->autoneg = AUTONEG_DISABLE; ethtool_cmd_speed_set(ecmd, ((bmcr & BMCR_SPEED1000 && (bmcr & BMCR_SPEED100) == 0) ? SPEED_1000 : ((bmcr & BMCR_SPEED100) ? SPEED_100 : SPEED_10))); ecmd->duplex = (bmcr & BMCR_FULLDPLX) ? DUPLEX_FULL : DUPLEX_HALF; } mii->full_duplex = ecmd->duplex; /* ignore maxtxpkt, maxrxpkt for now */ return 0; }
int qlcnic_82xx_get_settings(struct qlcnic_adapter *adapter, struct ethtool_cmd *ecmd) { struct qlcnic_hardware_context *ahw = adapter->ahw; u32 speed, reg; int check_sfp_module = 0; u16 pcifn = ahw->pci_func; /* read which mode */ if (adapter->ahw->port_type == QLCNIC_GBE) { ecmd->supported = (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full); ecmd->advertising = (ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full | ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full); ethtool_cmd_speed_set(ecmd, adapter->ahw->link_speed); ecmd->duplex = adapter->ahw->link_duplex; ecmd->autoneg = adapter->ahw->link_autoneg; } else if (adapter->ahw->port_type == QLCNIC_XGBE) { u32 val = 0; val = QLCRD32(adapter, QLCNIC_PORT_MODE_ADDR); if (val == QLCNIC_PORT_MODE_802_3_AP) { ecmd->supported = SUPPORTED_1000baseT_Full; ecmd->advertising = ADVERTISED_1000baseT_Full; } else { ecmd->supported = SUPPORTED_10000baseT_Full; ecmd->advertising = ADVERTISED_10000baseT_Full; } if (netif_running(adapter->netdev) && ahw->has_link_events) { reg = QLCRD32(adapter, P3P_LINK_SPEED_REG(pcifn)); speed = P3P_LINK_SPEED_VAL(pcifn, reg); ahw->link_speed = speed * P3P_LINK_SPEED_MHZ; ethtool_cmd_speed_set(ecmd, ahw->link_speed); ecmd->autoneg = ahw->link_autoneg; ecmd->duplex = ahw->link_duplex; goto skip; } ethtool_cmd_speed_set(ecmd, SPEED_UNKNOWN); ecmd->duplex = DUPLEX_UNKNOWN; ecmd->autoneg = AUTONEG_DISABLE; } else return -EIO; skip: ecmd->phy_address = adapter->ahw->physical_port; ecmd->transceiver = XCVR_EXTERNAL; switch (adapter->ahw->board_type) { case QLCNIC_BRDTYPE_P3P_REF_QG: case QLCNIC_BRDTYPE_P3P_4_GB: case QLCNIC_BRDTYPE_P3P_4_GB_MM: ecmd->supported |= SUPPORTED_Autoneg; ecmd->advertising |= ADVERTISED_Autoneg; case QLCNIC_BRDTYPE_P3P_10G_CX4: case QLCNIC_BRDTYPE_P3P_10G_CX4_LP: case QLCNIC_BRDTYPE_P3P_10000_BASE_T: ecmd->supported |= SUPPORTED_TP; ecmd->advertising |= ADVERTISED_TP; ecmd->port = PORT_TP; ecmd->autoneg = adapter->ahw->link_autoneg; break; case QLCNIC_BRDTYPE_P3P_IMEZ: case QLCNIC_BRDTYPE_P3P_XG_LOM: case QLCNIC_BRDTYPE_P3P_HMEZ: ecmd->supported |= SUPPORTED_MII; ecmd->advertising |= ADVERTISED_MII; ecmd->port = PORT_MII; ecmd->autoneg = AUTONEG_DISABLE; break; case QLCNIC_BRDTYPE_P3P_10G_SFP_PLUS: case QLCNIC_BRDTYPE_P3P_10G_SFP_CT: case QLCNIC_BRDTYPE_P3P_10G_SFP_QT: ecmd->advertising |= ADVERTISED_TP; ecmd->supported |= SUPPORTED_TP; check_sfp_module = netif_running(adapter->netdev) && ahw->has_link_events; case QLCNIC_BRDTYPE_P3P_10G_XFP: ecmd->supported |= SUPPORTED_FIBRE; ecmd->advertising |= ADVERTISED_FIBRE; ecmd->port = PORT_FIBRE; ecmd->autoneg = AUTONEG_DISABLE; break; case QLCNIC_BRDTYPE_P3P_10G_TP: if (adapter->ahw->port_type == QLCNIC_XGBE) { ecmd->autoneg = AUTONEG_DISABLE; ecmd->supported |= (SUPPORTED_FIBRE | SUPPORTED_TP); ecmd->advertising |= (ADVERTISED_FIBRE | ADVERTISED_TP); ecmd->port = PORT_FIBRE; check_sfp_module = netif_running(adapter->netdev) && ahw->has_link_events; } else { ecmd->autoneg = AUTONEG_ENABLE; ecmd->supported |= (SUPPORTED_TP | SUPPORTED_Autoneg); ecmd->advertising |= (ADVERTISED_TP | ADVERTISED_Autoneg); ecmd->port = PORT_TP; } break; default: dev_err(&adapter->pdev->dev, "Unsupported board model %d\n", adapter->ahw->board_type); return -EIO; } if (check_sfp_module) { switch (adapter->ahw->module_type) { case LINKEVENT_MODULE_OPTICAL_UNKNOWN: case LINKEVENT_MODULE_OPTICAL_SRLR: case LINKEVENT_MODULE_OPTICAL_LRM: case LINKEVENT_MODULE_OPTICAL_SFP_1G: ecmd->port = PORT_FIBRE; break; case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLE: case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLELEN: case LINKEVENT_MODULE_TWINAX: ecmd->port = PORT_TP; break; default: ecmd->port = PORT_OTHER; } } return 0; }
static int bnxt_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) { struct bnxt *bp = netdev_priv(dev); struct bnxt_link_info *link_info = &bp->link_info; u16 ethtool_speed; cmd->supported = bnxt_fw_to_ethtool_support_spds(link_info); if (link_info->auto_link_speeds) cmd->supported |= SUPPORTED_Autoneg; if (BNXT_AUTO_MODE(link_info->auto_mode)) { cmd->advertising = bnxt_fw_to_ethtool_advertised_spds(link_info); cmd->advertising |= ADVERTISED_Autoneg; cmd->autoneg = AUTONEG_ENABLE; } else { cmd->autoneg = AUTONEG_DISABLE; cmd->advertising = 0; } if (link_info->auto_pause_setting & BNXT_LINK_PAUSE_BOTH) { if ((link_info->auto_pause_setting & BNXT_LINK_PAUSE_BOTH) == BNXT_LINK_PAUSE_BOTH) { cmd->advertising |= ADVERTISED_Pause; cmd->supported |= SUPPORTED_Pause; } else { cmd->advertising |= ADVERTISED_Asym_Pause; cmd->supported |= SUPPORTED_Asym_Pause; if (link_info->auto_pause_setting & BNXT_LINK_PAUSE_RX) cmd->advertising |= ADVERTISED_Pause; } } else if (link_info->force_pause_setting & BNXT_LINK_PAUSE_BOTH) { if ((link_info->force_pause_setting & BNXT_LINK_PAUSE_BOTH) == BNXT_LINK_PAUSE_BOTH) { cmd->supported |= SUPPORTED_Pause; } else { cmd->supported |= SUPPORTED_Asym_Pause; if (link_info->force_pause_setting & BNXT_LINK_PAUSE_RX) cmd->supported |= SUPPORTED_Pause; } } cmd->port = PORT_NONE; if (link_info->media_type == PORT_PHY_QCFG_RESP_MEDIA_TYPE_TP) { cmd->port = PORT_TP; cmd->supported |= SUPPORTED_TP; cmd->advertising |= ADVERTISED_TP; } else { cmd->supported |= SUPPORTED_FIBRE; cmd->advertising |= ADVERTISED_FIBRE; if (link_info->media_type == PORT_PHY_QCFG_RESP_MEDIA_TYPE_DAC) cmd->port = PORT_DA; else if (link_info->media_type == PORT_PHY_QCFG_RESP_MEDIA_TYPE_FIBRE) cmd->port = PORT_FIBRE; } if (link_info->phy_link_status == BNXT_LINK_LINK) { if (link_info->duplex & BNXT_LINK_DUPLEX_FULL) cmd->duplex = DUPLEX_FULL; } else { cmd->duplex = DUPLEX_UNKNOWN; } ethtool_speed = bnxt_fw_to_ethtool_speed(link_info->link_speed); ethtool_cmd_speed_set(cmd, ethtool_speed); if (link_info->transceiver == PORT_PHY_QCFG_RESP_TRANSCEIVER_TYPE_XCVR_INTERNAL) cmd->transceiver = XCVR_INTERNAL; else cmd->transceiver = XCVR_EXTERNAL; cmd->phy_address = link_info->phy_addr; return 0; }
/** * @brief Get Settings * @param[in] pointer to struct net_device. * @param[in] pointer to struct ethtool_cmd. */ static int32_t nss_gmac_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) { struct nss_gmac_dev *gmacdev = NULL; struct phy_device *phydev = NULL; uint16_t phyreg; gmacdev = (struct nss_gmac_dev *)netdev_priv(netdev); BUG_ON(gmacdev == NULL); /* * If the speed/duplex for this GMAC is forced and we are not * polling for link state changes, return the values as specified by * platform. This will be true for GMACs connected to switch, and * interfaces that do not use a PHY. */ if (!test_bit(__NSS_GMAC_LINKPOLL, &gmacdev->flags)) { if (gmacdev->forced_speed != SPEED_UNKNOWN) { ethtool_cmd_speed_set(ecmd, gmacdev->forced_speed); ecmd->duplex = gmacdev->forced_duplex; ecmd->mdio_support = 0; ecmd->lp_advertising = 0; return 0; } else { /* Non-link polled interfaced must have a forced * speed/duplex */ return -EIO; } } phydev = gmacdev->phydev; /* update PHY status */ if (phydev->is_c45 == true) { ecmd->mdio_support = ETH_MDIO_SUPPORTS_C45; } else { if (genphy_read_status(phydev) != 0) { return -EIO; } ecmd->mdio_support = ETH_MDIO_SUPPORTS_C22; } /* Populate capabilities advertised by self */ ecmd->advertising = phydev->advertising; ecmd->autoneg = phydev->autoneg; if (gmacdev->link_state == LINKDOWN) { ethtool_cmd_speed_set(ecmd, SPEED_UNKNOWN); ecmd->duplex = DUPLEX_UNKNOWN; } else { ethtool_cmd_speed_set(ecmd, phydev->speed); ecmd->duplex = phydev->duplex; } ecmd->port = PORT_TP; ecmd->phy_address = gmacdev->phy_base; ecmd->transceiver = XCVR_EXTERNAL; /* Populate supported capabilities */ ecmd->supported = phydev->supported; if (phydev->is_c45 == true) return 0; /* Populate capabilities advertised by link partner */ phyreg = nss_gmac_mii_rd_reg(gmacdev, gmacdev->phy_base, MII_LPA); if (phyreg & LPA_10HALF) ecmd->lp_advertising |= ADVERTISED_10baseT_Half; if (phyreg & LPA_10FULL) ecmd->lp_advertising |= ADVERTISED_10baseT_Full; if (phyreg & LPA_100HALF) ecmd->lp_advertising |= ADVERTISED_100baseT_Half; if (phyreg & LPA_100FULL) ecmd->lp_advertising |= ADVERTISED_100baseT_Full; if (phyreg & LPA_PAUSE_CAP) ecmd->lp_advertising |= ADVERTISED_Pause; if (phyreg & LPA_PAUSE_ASYM) ecmd->lp_advertising |= ADVERTISED_Asym_Pause; phyreg = nss_gmac_mii_rd_reg(gmacdev, gmacdev->phy_base, MII_STAT1000); if (phyreg & LPA_1000HALF) ecmd->lp_advertising |= ADVERTISED_1000baseT_Half; if (phyreg & LPA_1000FULL) ecmd->lp_advertising |= ADVERTISED_1000baseT_Full; return 0; }
bool update_device_status( ether_device *device ) { assert( device != NULL ); assert( strlen( device->name ) > 0 ); int fd = socket( PF_INET, SOCK_DGRAM, 0 ); if ( fd < 0 ) { char error_string[ ERROR_STRING_SIZE ]; error( "Failed to open a socket ( ret = %d, errno = %s [%d] ).", fd, safe_strerror_r( errno, error_string, sizeof( error_string ) ), errno ); return false; } struct ifreq ifr; memset( &ifr, 0, sizeof( ifr ) ); strncpy( ifr.ifr_name, device->name, IFNAMSIZ ); ifr.ifr_name[ IFNAMSIZ - 1 ] = '\0'; struct ethtool_value ev; memset( &ev, 0, sizeof( struct ethtool_value ) ); ev.cmd = ETHTOOL_GLINK; ifr.ifr_data = ( char * ) &ev; int ret = ioctl( fd, SIOCETHTOOL, &ifr ); if ( ret == -1 ) { char error_string[ ERROR_STRING_SIZE ]; error( "Failed to retrieve link status of %s ( ret = %d, error = %s [%d] ).", device->name, ret, safe_strerror_r( errno, error_string, sizeof( error_string ) ), errno ); warn( "Assuming link is up ( device = %s ).", device->name ); device->status.up = true; } else { if ( ev.data > 0 ) { device->status.up = true; } else { device->status.up = false; } } struct ethtool_cmd ec; memset( &ec, 0, sizeof( struct ethtool_cmd ) ); if ( device->status.can_retrieve_link_status ) { ec.cmd = ETHTOOL_GSET; ifr.ifr_data = ( char * ) &ec; ret = ioctl( fd, SIOCETHTOOL, &ifr ); if ( ret == -1 ) { char error_string[ ERROR_STRING_SIZE ]; warn( "Failed to retrieve statuses of %s ( ret = %d, error = %s [%d] ).", device->name, ret, safe_strerror_r( errno, error_string, sizeof( error_string ) ), errno ); warn( "Assuming 100Mbps/Full Duplex/Twisted Pair link ( device = %s ).", device->name ); device->status.can_retrieve_link_status = false; } } if ( !device->status.can_retrieve_link_status ) { ethtool_cmd_speed_set( &ec, SPEED_100 ); ec.duplex = DUPLEX_FULL; ec.port = PORT_TP; ec.advertising = ADVERTISED_100baseT_Full | ADVERTISED_TP; ec.supported = SUPPORTED_100baseT_Full | SUPPORTED_TP; } struct ethtool_pauseparam ep; memset( &ep, 0, sizeof( struct ethtool_pauseparam ) ); if ( device->status.can_retrieve_pause ) { ep.cmd = ETHTOOL_GPAUSEPARAM; ifr.ifr_data = ( char * ) &ep; ret = ioctl( fd, SIOCETHTOOL, &ifr ); if ( ret == -1 ) { char error_string[ ERROR_STRING_SIZE ]; warn( "Failed to retrieve pause parameters of %s ( ret = %d, error = %s [%d] ).", device->name, ret, safe_strerror_r( errno, error_string, sizeof( error_string ) ), errno ); warn( "Assuming pause is disabled ( device = %s ).", device->name ); device->status.can_retrieve_pause = false; } } close( fd ); device->status.curr = make_current_ofp_port_features( ethtool_cmd_speed( &ec ), ec.duplex, ec.port, ec.autoneg, ep.rx_pause, ep.tx_pause ); device->status.advertised = make_supported_ofp_port_features( ec.advertising ); device->status.supported = make_supported_ofp_port_features( ec.supported ); device->status.peer = device->status.curr; // FIMXE: how to know the correct value? device->status.curr_speed = 0; // Since we set curr flags, this field might be meaningless. device->status.max_speed = 0; // Since we set supported flags, this field might be meaningless. return true; }