Пример #1
0
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;
}
Пример #2
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;
}
Пример #3
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;
}
Пример #4
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;
}
Пример #5
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;
}
Пример #6
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));
}
Пример #7
0
/**
 * 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;
}
Пример #8
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;
}
Пример #10
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;
}
Пример #11
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;
}
Пример #12
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;
}
Пример #13
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;
}
Пример #15
0
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;
}
Пример #16
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(&current_link, 0, sizeof(current_link));
	edev->ops->common->get_link(edev->cdev, &current_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;
}
Пример #17
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;
}
Пример #18
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;
}
Пример #19
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));
}
Пример #20
0
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;
}
Пример #21
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);
}
Пример #23
0
/* 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;
}
Пример #24
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;
}
Пример #25
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);
}
Пример #26
0
/**
 * 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;
}
Пример #28
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;
}
Пример #30
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;
}