lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Wed, 18 Dec 2013 22:34:41 -0800
From:	Jeff Kirsher <jeffrey.t.kirsher@...el.com>
To:	davem@...emloft.net
Cc:	Shannon Nelson <shannon.nelson@...el.com>, netdev@...r.kernel.org,
	gospo@...hat.com, sassmann@...hat.com,
	Jesse Brandeburg <jesse.brandeburg@...el.com>,
	Jeff Kirsher <jeffrey.t.kirsher@...el.com>
Subject: [net-next 05/15] i40e: add set settings and pauseparam

From: Shannon Nelson <shannon.nelson@...el.com>

This implements the set_settings and set_pauseparam ethtool
functionality.

Change-Id: I4634ee2c8bce00204edac7df9f0af4fb7bf33b75
Signed-off-by: Shannon Nelson <shannon.nelson@...el.com>
Signed-off-by: Jesse Brandeburg <jesse.brandeburg@...el.com>
Tested-by: Kavindya Deegala <kavindya.s.deegala@...el.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@...el.com>
---
 drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 97 ++++++++++++++++++++++++++
 1 file changed, 97 insertions(+)

diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
index 255a138..a12dd01 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
@@ -261,6 +261,61 @@ static int i40e_get_settings(struct net_device *netdev,
 }
 
 /**
+ * i40e_set_settings - Set Speed and Duplex
+ * @netdev: network interface device structure
+ * @ecmd: ethtool command
+ *
+ * Set speed/duplex per media_types advertised/forced
+ **/
+static int i40e_set_settings(struct net_device *netdev,
+			     struct ethtool_cmd *ecmd)
+{
+	struct i40e_netdev_priv *np = netdev_priv(netdev);
+	struct i40e_pf *pf = np->vsi->back;
+	struct i40e_vsi *vsi = np->vsi;
+	struct i40e_hw *hw = &pf->hw;
+	u32 old_link, advertised;
+	int err = 0;
+
+	if (vsi != pf->vsi[pf->lan_vsi])
+		return -EOPNOTSUPP;
+
+	while (test_and_set_bit(__I40E_CONFIG_BUSY, &vsi->state))
+		usleep_range(1000, 2000);
+
+	if ((hw->phy.media_type == I40E_MEDIA_TYPE_BASET) ||
+	    (hw->phy.media_type == I40E_MEDIA_TYPE_FIBER)) {
+		if (ecmd->autoneg == AUTONEG_DISABLE)
+			goto clear_reset;
+		if (ecmd->advertising & ~ecmd->supported)
+			goto clear_reset;
+		old_link = hw->phy.autoneg_advertised;
+		advertised = 0;
+
+		if (ecmd->advertising & (ADVERTISED_40000baseCR4_Full |
+					 ADVERTISED_40000baseKR4_Full |
+					 ADVERTISED_40000baseSR4_Full |
+					 ADVERTISED_40000baseLR4_Full))
+			advertised |= I40E_LINK_SPEED_40GB;
+		if (ecmd->advertising & (ADVERTISED_10000baseKX4_Full |
+					 ADVERTISED_10000baseKR_Full |
+					 ADVERTISED_10000baseT_Full))
+			advertised |= I40E_LINK_SPEED_10GB;
+		if (ecmd->advertising & ADVERTISED_1000baseT_Full)
+			advertised |= I40E_LINK_SPEED_1GB;
+		if (old_link == advertised) {
+			err = 0;
+			goto clear_reset;
+		}
+		hw->phy.get_link_info = true;
+	}
+clear_reset:
+	clear_bit(__I40E_CONFIG_BUSY, &vsi->state);
+
+	return err;
+}
+
+/**
  * i40e_get_pauseparam -  Get Flow Control status
  * Return tx/rx-pause status
  **/
@@ -286,6 +341,46 @@ static void i40e_get_pauseparam(struct net_device *netdev,
 	}
 }
 
+/**
+ * i40e_set_pauseparam - Set Flow Control parameter
+ * @netdev: network interface device structure
+ * @pause: return tx/rx flow control status
+ **/
+static int i40e_set_pauseparam(struct net_device *netdev,
+			       struct ethtool_pauseparam *pause)
+{
+	struct i40e_netdev_priv *np = netdev_priv(netdev);
+	struct i40e_pf *pf = np->vsi->back;
+	struct i40e_vsi *vsi = np->vsi;
+	struct i40e_hw *hw = &pf->hw;
+	struct i40e_fc_info fc;
+
+	if (vsi != pf->vsi[pf->lan_vsi])
+		return -EOPNOTSUPP;
+
+	fc = hw->fc;
+	pf->fc_autoneg_status = pause->autoneg;
+
+	if ((pause->rx_pause && pause->tx_pause) || pause->autoneg)
+		fc.requested_mode = I40E_FC_FULL;
+	else if (pause->rx_pause && !pause->tx_pause)
+		fc.requested_mode = I40E_FC_RX_PAUSE;
+	else if (!pause->rx_pause && pause->tx_pause)
+		fc.requested_mode = I40E_FC_TX_PAUSE;
+	else if (!pause->rx_pause && !pause->tx_pause)
+		fc.requested_mode = I40E_FC_NONE;
+	else
+		 return -EINVAL;
+
+	fc.current_mode = fc.requested_mode;
+
+	/* if the status changed, then we will use updated autoneg*/
+	if (memcmp(&fc, &hw->fc, sizeof(struct i40e_fc_info)))
+		hw->fc = fc;
+
+	return 0;
+}
+
 static u32 i40e_get_msglevel(struct net_device *netdev)
 {
 	struct i40e_netdev_priv *np = netdev_priv(netdev);
@@ -1599,6 +1694,7 @@ static int i40e_set_channels(struct net_device *dev,
 
 static const struct ethtool_ops i40e_ethtool_ops = {
 	.get_settings		= i40e_get_settings,
+	.set_settings		= i40e_set_settings,
 	.get_drvinfo		= i40e_get_drvinfo,
 	.get_regs_len		= i40e_get_regs_len,
 	.get_regs		= i40e_get_regs,
@@ -1611,6 +1707,7 @@ static const struct ethtool_ops i40e_ethtool_ops = {
 	.get_ringparam		= i40e_get_ringparam,
 	.set_ringparam		= i40e_set_ringparam,
 	.get_pauseparam		= i40e_get_pauseparam,
+	.set_pauseparam		= i40e_set_pauseparam,
 	.get_msglevel		= i40e_get_msglevel,
 	.set_msglevel		= i40e_set_msglevel,
 	.get_rxnfc		= i40e_get_rxnfc,
-- 
1.8.3.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ