Exemple #1
0
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);
}
Exemple #2
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");
}
Exemple #3
0
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;
}