All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 net-next 0/3] net: atlantic: phy tunables from mac driver
@ 2020-10-02 13:39 Igor Russkikh
  2020-10-02 13:39 ` [PATCH v2 net-next 1/3] ethtool: allow netdev driver to define phy tunables Igor Russkikh
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Igor Russkikh @ 2020-10-02 13:39 UTC (permalink / raw)
  To: netdev; +Cc: David S . Miller, Jakub Kicinski, Andrew Lunn, Igor Russkikh

This series implements phy tunables settings via MAC driver callbacks.

AQC 10G devices use integrated MAC+PHY solution, where PHY is fully controlled
by MAC firmware. Therefore, it is not possible to implement separate phy driver
for these.

We use ethtool ops callbacks to implement downshift and EDPC tunables.

v2: comments from Andrew

Igor Russkikh (3):
  ethtool: allow netdev driver to define phy tunables
  net: atlantic: implement phy downshift feature
  net: atlantic: implement media detect feature via phy tunables

 .../ethernet/aquantia/atlantic/aq_ethtool.c   | 53 +++++++++++++++++++
 .../net/ethernet/aquantia/atlantic/aq_hw.h    |  6 +++
 .../net/ethernet/aquantia/atlantic/aq_nic.c   | 49 +++++++++++++++++
 .../net/ethernet/aquantia/atlantic/aq_nic.h   |  4 ++
 .../atlantic/hw_atl/hw_atl_utils_fw2x.c       | 37 +++++++++++++
 .../atlantic/hw_atl2/hw_atl2_utils_fw.c       | 13 +++++
 include/linux/ethtool.h                       |  4 ++
 net/ethtool/ioctl.c                           | 37 ++++++++-----
 8 files changed, 190 insertions(+), 13 deletions(-)

-- 
2.17.1


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v2 net-next 1/3] ethtool: allow netdev driver to define phy tunables
  2020-10-02 13:39 [PATCH v2 net-next 0/3] net: atlantic: phy tunables from mac driver Igor Russkikh
@ 2020-10-02 13:39 ` Igor Russkikh
  2020-10-02 14:25   ` Andrew Lunn
  2020-10-02 13:39 ` [PATCH v2 net-next 2/3] net: atlantic: implement phy downshift feature Igor Russkikh
  2020-10-02 13:39 ` [PATCH v2 net-next 3/3] net: atlantic: implement media detect feature via phy tunables Igor Russkikh
  2 siblings, 1 reply; 8+ messages in thread
From: Igor Russkikh @ 2020-10-02 13:39 UTC (permalink / raw)
  To: netdev; +Cc: David S . Miller, Jakub Kicinski, Andrew Lunn, Igor Russkikh

Define get/set phy tunable callbacks in ethtool ops.
This will allow MAC drivers with integrated PHY still to implement
these tunables.

Signed-off-by: Igor Russkikh <irusskikh@marvell.com>
---
 include/linux/ethtool.h |  4 ++++
 net/ethtool/ioctl.c     | 37 ++++++++++++++++++++++++-------------
 2 files changed, 28 insertions(+), 13 deletions(-)

diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index 060b20f0b20f..6408b446051f 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -505,6 +505,10 @@ struct ethtool_ops {
 				      struct ethtool_fecparam *);
 	void	(*get_ethtool_phy_stats)(struct net_device *,
 					 struct ethtool_stats *, u64 *);
+	int	(*get_phy_tunable)(struct net_device *,
+				   const struct ethtool_tunable *, void *);
+	int	(*set_phy_tunable)(struct net_device *,
+				   const struct ethtool_tunable *, const void *);
 };
 
 int ethtool_check_ops(const struct ethtool_ops *ops);
diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c
index 328d15cd4006..ec2cd7aab5ad 100644
--- a/net/ethtool/ioctl.c
+++ b/net/ethtool/ioctl.c
@@ -2459,14 +2459,15 @@ static int ethtool_phy_tunable_valid(const struct ethtool_tunable *tuna)
 
 static int get_phy_tunable(struct net_device *dev, void __user *useraddr)
 {
-	int ret;
-	struct ethtool_tunable tuna;
 	struct phy_device *phydev = dev->phydev;
+	struct ethtool_tunable tuna;
+	bool phy_drv_tunable;
 	void *data;
+	int ret;
 
-	if (!(phydev && phydev->drv && phydev->drv->get_tunable))
+	phy_drv_tunable = phydev && phydev->drv && phydev->drv->get_tunable;
+	if (!phy_drv_tunable && !dev->ethtool_ops->get_phy_tunable)
 		return -EOPNOTSUPP;
-
 	if (copy_from_user(&tuna, useraddr, sizeof(tuna)))
 		return -EFAULT;
 	ret = ethtool_phy_tunable_valid(&tuna);
@@ -2475,9 +2476,13 @@ static int get_phy_tunable(struct net_device *dev, void __user *useraddr)
 	data = kmalloc(tuna.len, GFP_USER);
 	if (!data)
 		return -ENOMEM;
-	mutex_lock(&phydev->lock);
-	ret = phydev->drv->get_tunable(phydev, &tuna, data);
-	mutex_unlock(&phydev->lock);
+	if (phy_drv_tunable) {
+		mutex_lock(&phydev->lock);
+		ret = phydev->drv->get_tunable(phydev, &tuna, data);
+		mutex_unlock(&phydev->lock);
+	} else {
+		ret = dev->ethtool_ops->get_phy_tunable(dev, &tuna, data);
+	}
 	if (ret)
 		goto out;
 	useraddr += sizeof(tuna);
@@ -2493,12 +2498,14 @@ static int get_phy_tunable(struct net_device *dev, void __user *useraddr)
 
 static int set_phy_tunable(struct net_device *dev, void __user *useraddr)
 {
-	int ret;
-	struct ethtool_tunable tuna;
 	struct phy_device *phydev = dev->phydev;
+	struct ethtool_tunable tuna;
+	bool phy_drv_tunable;
 	void *data;
+	int ret;
 
-	if (!(phydev && phydev->drv && phydev->drv->set_tunable))
+	phy_drv_tunable = phydev && phydev->drv && phydev->drv->get_tunable;
+	if (!phy_drv_tunable && !dev->ethtool_ops->set_phy_tunable)
 		return -EOPNOTSUPP;
 	if (copy_from_user(&tuna, useraddr, sizeof(tuna)))
 		return -EFAULT;
@@ -2509,9 +2516,13 @@ static int set_phy_tunable(struct net_device *dev, void __user *useraddr)
 	data = memdup_user(useraddr, tuna.len);
 	if (IS_ERR(data))
 		return PTR_ERR(data);
-	mutex_lock(&phydev->lock);
-	ret = phydev->drv->set_tunable(phydev, &tuna, data);
-	mutex_unlock(&phydev->lock);
+	if (phy_drv_tunable) {
+		mutex_lock(&phydev->lock);
+		ret = phydev->drv->set_tunable(phydev, &tuna, data);
+		mutex_unlock(&phydev->lock);
+	} else {
+		ret = dev->ethtool_ops->set_phy_tunable(dev, &tuna, data);
+	}
 
 	kfree(data);
 	return ret;
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 net-next 2/3] net: atlantic: implement phy downshift feature
  2020-10-02 13:39 [PATCH v2 net-next 0/3] net: atlantic: phy tunables from mac driver Igor Russkikh
  2020-10-02 13:39 ` [PATCH v2 net-next 1/3] ethtool: allow netdev driver to define phy tunables Igor Russkikh
@ 2020-10-02 13:39 ` Igor Russkikh
  2020-10-02 14:20   ` Andrew Lunn
  2020-10-02 13:39 ` [PATCH v2 net-next 3/3] net: atlantic: implement media detect feature via phy tunables Igor Russkikh
  2 siblings, 1 reply; 8+ messages in thread
From: Igor Russkikh @ 2020-10-02 13:39 UTC (permalink / raw)
  To: netdev; +Cc: David S . Miller, Jakub Kicinski, Andrew Lunn, Igor Russkikh

PHY downshift allows phy to try renegotiate if link is unstable
and can carry higher speed.

AQC devices has integrated PHY which is controlled by MAC firmware.
Thus, driver defines new ethtool callbacks to implement phy tunables
via netdev.

Signed-off-by: Igor Russkikh <irusskikh@marvell.com>
---
 .../ethernet/aquantia/atlantic/aq_ethtool.c   | 41 +++++++++++++++++++
 .../net/ethernet/aquantia/atlantic/aq_hw.h    |  2 +
 .../net/ethernet/aquantia/atlantic/aq_nic.c   | 23 +++++++++++
 .../net/ethernet/aquantia/atlantic/aq_nic.h   |  2 +
 .../atlantic/hw_atl/hw_atl_utils_fw2x.c       | 22 ++++++++++
 .../atlantic/hw_atl2/hw_atl2_utils_fw.c       | 13 ++++++
 6 files changed, 103 insertions(+)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c b/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
index 1ab5314c4c1b..3f87cc6e2538 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
@@ -917,6 +917,45 @@ static int aq_ethtool_set_priv_flags(struct net_device *ndev, u32 flags)
 	return ret;
 }
 
+static int aq_ethtool_get_phy_tunable(struct net_device *ndev,
+				      const struct ethtool_tunable *tuna, void *data)
+{
+	struct aq_nic_s *aq_nic = netdev_priv(ndev);
+
+	switch (tuna->id) {
+	case ETHTOOL_PHY_DOWNSHIFT: {
+		u8 *val = data;
+
+		*val = (u8)aq_nic->aq_nic_cfg.downshift_counter;
+		break;
+	}
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	return 0;
+}
+
+static int aq_ethtool_set_phy_tunable(struct net_device *ndev,
+				      const struct ethtool_tunable *tuna, const void *data)
+{
+	int err = -EOPNOTSUPP;
+	struct aq_nic_s *aq_nic = netdev_priv(ndev);
+
+	switch (tuna->id) {
+	case ETHTOOL_PHY_DOWNSHIFT: {
+		const u8 *val = data;
+
+		err = aq_nic_set_downshift(aq_nic, *val);
+		break;
+	}
+	default:
+		break;
+	}
+
+	return err;
+}
+
 const struct ethtool_ops aq_ethtool_ops = {
 	.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
 				     ETHTOOL_COALESCE_MAX_FRAMES,
@@ -952,4 +991,6 @@ const struct ethtool_ops aq_ethtool_ops = {
 	.get_coalesce	     = aq_ethtool_get_coalesce,
 	.set_coalesce	     = aq_ethtool_set_coalesce,
 	.get_ts_info         = aq_ethtool_get_ts_info,
+	.get_phy_tunable     = aq_ethtool_get_phy_tunable,
+	.set_phy_tunable     = aq_ethtool_set_phy_tunable,
 };
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_hw.h b/drivers/net/ethernet/aquantia/atlantic/aq_hw.h
index 7df74015fbc9..a17077b0dd49 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_hw.h
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_hw.h
@@ -386,6 +386,8 @@ struct aq_fw_ops {
 	int (*get_eee_rate)(struct aq_hw_s *self, u32 *rate,
 			    u32 *supported_rates);
 
+	int (*set_downshift)(struct aq_hw_s *self, u32 counter);
+
 	u32 (*get_link_capabilities)(struct aq_hw_s *self);
 
 	int (*send_macsec_req)(struct aq_hw_s *self,
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index c6bdf1d677d1..088aa3c3d19c 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -405,6 +405,8 @@ int aq_nic_init(struct aq_nic_s *self)
 	mutex_unlock(&self->fwreq_mutex);
 	if (err < 0)
 		goto err_exit;
+	/* Restore default settings */
+	aq_nic_set_downshift(self, self->aq_nic_cfg.downshift_counter);
 
 	err = self->aq_hw_ops->hw_init(self->aq_hw,
 				       aq_nic_get_ndev(self)->dev_addr);
@@ -1398,6 +1400,27 @@ void aq_nic_release_filter(struct aq_nic_s *self, enum aq_rx_filter_type type,
 	}
 }
 
+int aq_nic_set_downshift(struct aq_nic_s *self, int val)
+{
+	int err = 0;
+	struct aq_nic_cfg_s *cfg = &self->aq_nic_cfg;
+
+	if (!self->aq_fw_ops->set_downshift)
+		return -EOPNOTSUPP;
+
+	if (val > 15) {
+		netdev_err(self->ndev, "downshift counter should be <= 15\n");
+		return -EINVAL;
+	}
+	cfg->downshift_counter = val;
+
+	mutex_lock(&self->fwreq_mutex);
+	err = self->aq_fw_ops->set_downshift(self->aq_hw, cfg->downshift_counter);
+	mutex_unlock(&self->fwreq_mutex);
+
+	return err;
+}
+
 int aq_nic_setup_tc_mqprio(struct aq_nic_s *self, u32 tcs, u8 *prio_tc_map)
 {
 	struct aq_nic_cfg_s *cfg = &self->aq_nic_cfg;
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.h b/drivers/net/ethernet/aquantia/atlantic/aq_nic.h
index eb7d8430f2f5..61e0e627e959 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.h
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.h
@@ -62,6 +62,7 @@ struct aq_nic_cfg_s {
 	bool is_lro;
 	bool is_qos;
 	bool is_ptp;
+	int downshift_counter;
 	enum aq_tc_mode tc_mode;
 	u32 priv_flags;
 	u8  tcs;
@@ -195,6 +196,7 @@ int aq_nic_set_link_ksettings(struct aq_nic_s *self,
 struct aq_nic_cfg_s *aq_nic_get_cfg(struct aq_nic_s *self);
 u32 aq_nic_get_fw_version(struct aq_nic_s *self);
 int aq_nic_set_loopback(struct aq_nic_s *self);
+int aq_nic_set_downshift(struct aq_nic_s *self, int val);
 int aq_nic_update_interrupt_moderation_settings(struct aq_nic_s *self);
 void aq_nic_shutdown(struct aq_nic_s *self);
 u8 aq_nic_reserve_filter(struct aq_nic_s *self, enum aq_rx_filter_type type);
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c
index 93c06dfa6c55..09500a95380b 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c
@@ -612,6 +612,27 @@ static u32 aq_fw2x_state2_get(struct aq_hw_s *self)
 	return aq_hw_read_reg(self, HW_ATL_FW2X_MPI_STATE2_ADDR);
 }
 
+static int aq_fw2x_set_downshift(struct aq_hw_s *self, u32 counter)
+{
+	int err = 0;
+	u32 mpi_opts;
+	u32 offset;
+
+	offset = offsetof(struct hw_atl_utils_settings, downshift_retry_count);
+	err = hw_atl_write_fwsettings_dwords(self, offset, &counter, 1);
+	if (err)
+		return err;
+
+	mpi_opts = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR);
+	if (counter)
+		mpi_opts |= HW_ATL_FW2X_CTRL_DOWNSHIFT;
+	else
+		mpi_opts &= ~HW_ATL_FW2X_CTRL_DOWNSHIFT;
+	aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_opts);
+
+	return err;
+}
+
 static u32 aq_fw2x_get_link_capabilities(struct aq_hw_s *self)
 {
 	int err = 0;
@@ -692,6 +713,7 @@ const struct aq_fw_ops aq_fw_2x_ops = {
 	.enable_ptp         = aq_fw3x_enable_ptp,
 	.led_control        = aq_fw2x_led_control,
 	.set_phyloopback    = aq_fw2x_set_phyloopback,
+	.set_downshift      = aq_fw2x_set_downshift,
 	.adjust_ptp         = aq_fw3x_adjust_ptp,
 	.get_link_capabilities = aq_fw2x_get_link_capabilities,
 	.send_macsec_req    = aq_fw2x_send_macsec_req,
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2_utils_fw.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2_utils_fw.c
index 85628acbcc1d..dd259c8f2f4f 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2_utils_fw.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2_utils_fw.c
@@ -519,6 +519,18 @@ int hw_atl2_utils_get_action_resolve_table_caps(struct aq_hw_s *self,
 	return 0;
 }
 
+static int aq_a2_fw_set_downshift(struct aq_hw_s *self, u32 counter)
+{
+	struct link_options_s link_options;
+
+	hw_atl2_shared_buffer_get(self, link_options, link_options);
+	link_options.downshift = !!counter;
+	link_options.downshift_retry = counter;
+	hw_atl2_shared_buffer_write(self, link_options, link_options);
+
+	return hw_atl2_shared_buffer_finish_ack(self);
+}
+
 const struct aq_fw_ops aq_a2_fw_ops = {
 	.init               = aq_a2_fw_init,
 	.deinit             = aq_a2_fw_deinit,
@@ -536,4 +548,5 @@ const struct aq_fw_ops aq_a2_fw_ops = {
 	.set_flow_control   = aq_a2_fw_set_flow_control,
 	.get_flow_control   = aq_a2_fw_get_flow_control,
 	.set_phyloopback    = aq_a2_fw_set_phyloopback,
+	.set_downshift      = aq_a2_fw_set_downshift,
 };
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 net-next 3/3] net: atlantic: implement media detect feature via phy tunables
  2020-10-02 13:39 [PATCH v2 net-next 0/3] net: atlantic: phy tunables from mac driver Igor Russkikh
  2020-10-02 13:39 ` [PATCH v2 net-next 1/3] ethtool: allow netdev driver to define phy tunables Igor Russkikh
  2020-10-02 13:39 ` [PATCH v2 net-next 2/3] net: atlantic: implement phy downshift feature Igor Russkikh
@ 2020-10-02 13:39 ` Igor Russkikh
  2020-10-02 14:24   ` Andrew Lunn
  2 siblings, 1 reply; 8+ messages in thread
From: Igor Russkikh @ 2020-10-02 13:39 UTC (permalink / raw)
  To: netdev; +Cc: David S . Miller, Jakub Kicinski, Andrew Lunn, Igor Russkikh

Mediadetect is another name for the EDPD (energy detect power down).
This feature allows device to save extra power when no link is available.

PHY goes into the extreme power saving mode and only periodically wakes up
and checks for the link.

AQC devices has fixed check period of 6 seconds

The feature may increase linkup time.

Signed-off-by: Igor Russkikh <irusskikh@marvell.com>
---
 .../ethernet/aquantia/atlantic/aq_ethtool.c   | 12 +++++++++
 .../net/ethernet/aquantia/atlantic/aq_hw.h    |  4 +++
 .../net/ethernet/aquantia/atlantic/aq_nic.c   | 26 +++++++++++++++++++
 .../net/ethernet/aquantia/atlantic/aq_nic.h   |  2 ++
 .../atlantic/hw_atl/hw_atl_utils_fw2x.c       | 15 +++++++++++
 5 files changed, 59 insertions(+)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c b/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
index 3f87cc6e2538..de2a9348bc3f 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
@@ -923,6 +923,12 @@ static int aq_ethtool_get_phy_tunable(struct net_device *ndev,
 	struct aq_nic_s *aq_nic = netdev_priv(ndev);
 
 	switch (tuna->id) {
+	case ETHTOOL_PHY_EDPD: {
+		u16 *val = data;
+
+		*val = aq_nic->aq_nic_cfg.is_media_detect ? AQ_HW_MEDIA_DETECT_CNT : 0;
+		break;
+	}
 	case ETHTOOL_PHY_DOWNSHIFT: {
 		u8 *val = data;
 
@@ -943,6 +949,12 @@ static int aq_ethtool_set_phy_tunable(struct net_device *ndev,
 	struct aq_nic_s *aq_nic = netdev_priv(ndev);
 
 	switch (tuna->id) {
+	case ETHTOOL_PHY_EDPD: {
+		const u16 *val = data;
+
+		err = aq_nic_set_media_detect(aq_nic, *val);
+		break;
+	}
 	case ETHTOOL_PHY_DOWNSHIFT: {
 		const u8 *val = data;
 
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_hw.h b/drivers/net/ethernet/aquantia/atlantic/aq_hw.h
index a17077b0dd49..bed481816ea3 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_hw.h
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_hw.h
@@ -143,6 +143,8 @@ struct aq_stats_s {
 #define AQ_HW_LED_BLINK    0x2U
 #define AQ_HW_LED_DEFAULT  0x0U
 
+#define AQ_HW_MEDIA_DETECT_CNT 6000
+
 enum aq_priv_flags {
 	AQ_HW_LOOPBACK_DMA_SYS,
 	AQ_HW_LOOPBACK_PKT_SYS,
@@ -388,6 +390,8 @@ struct aq_fw_ops {
 
 	int (*set_downshift)(struct aq_hw_s *self, u32 counter);
 
+	int (*set_media_detect)(struct aq_hw_s *self, bool enable);
+
 	u32 (*get_link_capabilities)(struct aq_hw_s *self);
 
 	int (*send_macsec_req)(struct aq_hw_s *self,
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index 088aa3c3d19c..688920ed6c88 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -407,6 +407,8 @@ int aq_nic_init(struct aq_nic_s *self)
 		goto err_exit;
 	/* Restore default settings */
 	aq_nic_set_downshift(self, self->aq_nic_cfg.downshift_counter);
+	aq_nic_set_media_detect(self, self->aq_nic_cfg.is_media_detect ?
+				AQ_HW_MEDIA_DETECT_CNT : 0);
 
 	err = self->aq_hw_ops->hw_init(self->aq_hw,
 				       aq_nic_get_ndev(self)->dev_addr);
@@ -1421,6 +1423,30 @@ int aq_nic_set_downshift(struct aq_nic_s *self, int val)
 	return err;
 }
 
+int aq_nic_set_media_detect(struct aq_nic_s *self, int val)
+{
+	struct aq_nic_cfg_s *cfg = &self->aq_nic_cfg;
+	int err = 0;
+
+	if (!self->aq_fw_ops->set_media_detect)
+		return -EOPNOTSUPP;
+
+	if (val > 0 && val != AQ_HW_MEDIA_DETECT_CNT) {
+		netdev_err(self->ndev, "EDPD on this device could have only fixed value of %d\n",
+			   AQ_HW_MEDIA_DETECT_CNT);
+		return -EINVAL;
+	}
+
+	/* msecs plays no role - configuration is always fixed in PHY */
+	cfg->is_media_detect = val ? 1 : 0;
+
+	mutex_lock(&self->fwreq_mutex);
+	err = self->aq_fw_ops->set_media_detect(self->aq_hw, cfg->is_media_detect);
+	mutex_unlock(&self->fwreq_mutex);
+
+	return err;
+}
+
 int aq_nic_setup_tc_mqprio(struct aq_nic_s *self, u32 tcs, u8 *prio_tc_map)
 {
 	struct aq_nic_cfg_s *cfg = &self->aq_nic_cfg;
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.h b/drivers/net/ethernet/aquantia/atlantic/aq_nic.h
index 61e0e627e959..926cca9a0c83 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.h
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.h
@@ -62,6 +62,7 @@ struct aq_nic_cfg_s {
 	bool is_lro;
 	bool is_qos;
 	bool is_ptp;
+	bool is_media_detect;
 	int downshift_counter;
 	enum aq_tc_mode tc_mode;
 	u32 priv_flags;
@@ -197,6 +198,7 @@ struct aq_nic_cfg_s *aq_nic_get_cfg(struct aq_nic_s *self);
 u32 aq_nic_get_fw_version(struct aq_nic_s *self);
 int aq_nic_set_loopback(struct aq_nic_s *self);
 int aq_nic_set_downshift(struct aq_nic_s *self, int val);
+int aq_nic_set_media_detect(struct aq_nic_s *self, int val);
 int aq_nic_update_interrupt_moderation_settings(struct aq_nic_s *self);
 void aq_nic_shutdown(struct aq_nic_s *self);
 u8 aq_nic_reserve_filter(struct aq_nic_s *self, enum aq_rx_filter_type type);
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c
index 09500a95380b..ee0c22d04935 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c
@@ -633,6 +633,20 @@ static int aq_fw2x_set_downshift(struct aq_hw_s *self, u32 counter)
 	return err;
 }
 
+static int aq_fw2x_set_media_detect(struct aq_hw_s *self, bool on)
+{
+	u32 enable;
+	u32 offset;
+
+	if (self->fw_ver_actual < HW_ATL_FW_VER_MEDIA_CONTROL)
+		return -EOPNOTSUPP;
+
+	offset = offsetof(struct hw_atl_utils_settings, media_detect);
+	enable = on;
+
+	return hw_atl_write_fwsettings_dwords(self, offset, &enable, 1);
+}
+
 static u32 aq_fw2x_get_link_capabilities(struct aq_hw_s *self)
 {
 	int err = 0;
@@ -714,6 +728,7 @@ const struct aq_fw_ops aq_fw_2x_ops = {
 	.led_control        = aq_fw2x_led_control,
 	.set_phyloopback    = aq_fw2x_set_phyloopback,
 	.set_downshift      = aq_fw2x_set_downshift,
+	.set_media_detect   = aq_fw2x_set_media_detect,
 	.adjust_ptp         = aq_fw3x_adjust_ptp,
 	.get_link_capabilities = aq_fw2x_get_link_capabilities,
 	.send_macsec_req    = aq_fw2x_send_macsec_req,
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 net-next 2/3] net: atlantic: implement phy downshift feature
  2020-10-02 13:39 ` [PATCH v2 net-next 2/3] net: atlantic: implement phy downshift feature Igor Russkikh
@ 2020-10-02 14:20   ` Andrew Lunn
  0 siblings, 0 replies; 8+ messages in thread
From: Andrew Lunn @ 2020-10-02 14:20 UTC (permalink / raw)
  To: Igor Russkikh; +Cc: netdev, David S . Miller, Jakub Kicinski

On Fri, Oct 02, 2020 at 04:39:22PM +0300, Igor Russkikh wrote:
> PHY downshift allows phy to try renegotiate if link is unstable
> and can carry higher speed.
> 
> AQC devices has integrated PHY which is controlled by MAC firmware.
> Thus, driver defines new ethtool callbacks to implement phy tunables
> via netdev.
> 
> Signed-off-by: Igor Russkikh <irusskikh@marvell.com>

I guess extack is not going to happen right now, so

Reviewed-by: Andrew Lunn <andrew@lunn.ch>

    Andrew

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 net-next 3/3] net: atlantic: implement media detect feature via phy tunables
  2020-10-02 13:39 ` [PATCH v2 net-next 3/3] net: atlantic: implement media detect feature via phy tunables Igor Russkikh
@ 2020-10-02 14:24   ` Andrew Lunn
  2020-10-02 14:41     ` [EXT] " Igor Russkikh
  0 siblings, 1 reply; 8+ messages in thread
From: Andrew Lunn @ 2020-10-02 14:24 UTC (permalink / raw)
  To: Igor Russkikh; +Cc: netdev, David S . Miller, Jakub Kicinski

> +	if (val > 0 && val != AQ_HW_MEDIA_DETECT_CNT) {
> +		netdev_err(self->ndev, "EDPD on this device could have only fixed value of %d\n",
> +			   AQ_HW_MEDIA_DETECT_CNT);
> +		return -EINVAL;
> +	}
> +
> +	/* msecs plays no role - configuration is always fixed in PHY */
> +	cfg->is_media_detect = val ? 1 : 0;
> +
> +	mutex_lock(&self->fwreq_mutex);
> +	err = self->aq_fw_ops->set_media_detect(self->aq_hw, cfg->is_media_detect);
> +	mutex_unlock(&self->fwreq_mutex);
> +
> +	return err;
> +}

> +static int aq_fw2x_set_media_detect(struct aq_hw_s *self, bool on)
> +{
> +	u32 enable;
> +	u32 offset;
> +
> +	if (self->fw_ver_actual < HW_ATL_FW_VER_MEDIA_CONTROL)
> +		return -EOPNOTSUPP;

So if the firmware is tool old, you return -EOPNOTSUPP. But it appears
cfg->is_media_detect has already been changed?

     Andrew

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 net-next 1/3] ethtool: allow netdev driver to define phy tunables
  2020-10-02 13:39 ` [PATCH v2 net-next 1/3] ethtool: allow netdev driver to define phy tunables Igor Russkikh
@ 2020-10-02 14:25   ` Andrew Lunn
  0 siblings, 0 replies; 8+ messages in thread
From: Andrew Lunn @ 2020-10-02 14:25 UTC (permalink / raw)
  To: Igor Russkikh; +Cc: netdev, David S . Miller, Jakub Kicinski

On Fri, Oct 02, 2020 at 04:39:21PM +0300, Igor Russkikh wrote:
> Define get/set phy tunable callbacks in ethtool ops.
> This will allow MAC drivers with integrated PHY still to implement
> these tunables.
> 
> Signed-off-by: Igor Russkikh <irusskikh@marvell.com>

Reviewed-by: Andrew Lunn <andrew@lunn.ch>

    Andrew

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [EXT] Re: [PATCH v2 net-next 3/3] net: atlantic: implement media detect feature via phy tunables
  2020-10-02 14:24   ` Andrew Lunn
@ 2020-10-02 14:41     ` Igor Russkikh
  0 siblings, 0 replies; 8+ messages in thread
From: Igor Russkikh @ 2020-10-02 14:41 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: netdev, David S . Miller, Jakub Kicinski



>> +	if (val > 0 && val != AQ_HW_MEDIA_DETECT_CNT) {
>> +		netdev_err(self->ndev, "EDPD on this device could have
> only fixed value of %d\n",
>> +			   AQ_HW_MEDIA_DETECT_CNT);
>> +		return -EINVAL;
>> +	}
>> +
>> +	/* msecs plays no role - configuration is always fixed in PHY */
>> +	cfg->is_media_detect = val ? 1 : 0;
>> +
>> +	mutex_lock(&self->fwreq_mutex);
>> +	err = self->aq_fw_ops->set_media_detect(self->aq_hw,
> cfg->is_media_detect);
>> +	mutex_unlock(&self->fwreq_mutex);
>> +
>> +	return err;
>> +}
> 
>> +static int aq_fw2x_set_media_detect(struct aq_hw_s *self, bool on)
>> +{
>> +	u32 enable;
>> +	u32 offset;
>> +
>> +	if (self->fw_ver_actual < HW_ATL_FW_VER_MEDIA_CONTROL)
>> +		return -EOPNOTSUPP;
> 
> So if the firmware is tool old, you return -EOPNOTSUPP. But it appears
> cfg->is_media_detect has already been changed?

Hmm, right. The problem here will be that next --get edpd will return "enabled".

This'll also happen if by some reason FW command will fail to enable EDPD.

Think I have to save 'is_media_detect' only after successful FW operation.

Will send v3, thanks, good catch.

Regards,
  Igor

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2020-10-02 14:42 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-02 13:39 [PATCH v2 net-next 0/3] net: atlantic: phy tunables from mac driver Igor Russkikh
2020-10-02 13:39 ` [PATCH v2 net-next 1/3] ethtool: allow netdev driver to define phy tunables Igor Russkikh
2020-10-02 14:25   ` Andrew Lunn
2020-10-02 13:39 ` [PATCH v2 net-next 2/3] net: atlantic: implement phy downshift feature Igor Russkikh
2020-10-02 14:20   ` Andrew Lunn
2020-10-02 13:39 ` [PATCH v2 net-next 3/3] net: atlantic: implement media detect feature via phy tunables Igor Russkikh
2020-10-02 14:24   ` Andrew Lunn
2020-10-02 14:41     ` [EXT] " Igor Russkikh

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.