All of lore.kernel.org
 help / color / mirror / Atom feed
From: Igor Russkikh <irusskikh@marvell.com>
To: <netdev@vger.kernel.org>
Cc: "David S . Miller" <davem@davemloft.net>,
	Mark Starovoytov <mstarovoitov@marvell.com>,
	Jakub Kicinski <kuba@kernel.org>,
	Igor Russkikh <irusskikh@marvell.com>, <andrew@lunn.ch>
Subject: [PATCH net-next 01/10] net: atlantic: media detect
Date: Mon, 13 Jul 2020 14:42:24 +0300	[thread overview]
Message-ID: <20200713114233.436-2-irusskikh@marvell.com> (raw)
In-Reply-To: <20200713114233.436-1-irusskikh@marvell.com>

This patch adds support for low-power autoneg in PHY (media detect).
This is a custom feature of AQC107 builtin PHY, but configuration is only
done through MAC management firmware.
Some of our customers uses it for low power saving systems.

There is no any standard ethtool/phy interface for anything like this,
thus making this available through private flag.

Signed-off-by: Igor Russkikh <irusskikh@marvell.com>
CC: andrew@lunn.ch
---
 .../ethernet/aquantia/atlantic/aq_ethtool.c   |  7 +++++++
 .../ethernet/aquantia/atlantic/aq_ethtool.h   | 10 +++++----
 .../net/ethernet/aquantia/atlantic/aq_hw.h    |  4 ++++
 .../net/ethernet/aquantia/atlantic/aq_nic.c   | 19 +++++++++++++++++
 .../net/ethernet/aquantia/atlantic/aq_nic.h   |  1 +
 .../atlantic/hw_atl/hw_atl_utils_fw2x.c       | 21 +++++++++++++++++++
 6 files changed, 58 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c b/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
index a8f0fbbbd91a..d36afeaae525 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
@@ -160,6 +160,7 @@ static const char aq_ethtool_priv_flag_names[][ETH_GSTRING_LEN] = {
 	"DMANetworkLoopback",
 	"PHYInternalLoopback",
 	"PHYExternalLoopback",
+	"MediaDetect"
 };
 
 static u32 aq_ethtool_n_stats(struct net_device *ndev)
@@ -852,6 +853,12 @@ static int aq_ethtool_set_priv_flags(struct net_device *ndev, u32 flags)
 
 	cfg->priv_flags = flags;
 
+	if ((priv_flags ^ flags) & AQ_HW_MEDIA_DETECT_MASK) {
+		aq_nic_set_media_detect(aq_nic);
+		/* Restart aneg to make FW apply the new settings */
+		aq_nic->aq_fw_ops->renegotiate(aq_nic->aq_hw);
+	}
+
 	if ((priv_flags ^ flags) & BIT(AQ_HW_LOOPBACK_DMA_NET)) {
 		if (netif_running(ndev)) {
 			dev_close(ndev);
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.h b/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.h
index 6d5be5ebeb13..c0025340af38 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.h
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.h
@@ -1,7 +1,8 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * aQuantia Corporation Network Driver
- * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved
+/* Atlantic Network Driver
+ *
+ * Copyright (C) 2014-2019 aQuantia Corporation
+ * Copyright (C) 2019-2020 Marvell International Ltd.
  */
 
 /* File aq_ethtool.h: Declaration of ethertool related functions. */
@@ -12,6 +13,7 @@
 #include "aq_common.h"
 
 extern const struct ethtool_ops aq_ethtool_ops;
-#define AQ_PRIV_FLAGS_MASK   (AQ_HW_LOOPBACK_MASK)
+#define AQ_PRIV_FLAGS_MASK   ((AQ_HW_LOOPBACK_MASK) |\
+			      (AQ_HW_MEDIA_DETECT_MASK))
 
 #endif /* AQ_ETHTOOL_H */
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_hw.h b/drivers/net/ethernet/aquantia/atlantic/aq_hw.h
index f2663ad22209..6358bed3d64e 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_hw.h
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_hw.h
@@ -145,6 +145,7 @@ enum aq_priv_flags {
 	AQ_HW_LOOPBACK_DMA_NET,
 	AQ_HW_LOOPBACK_PHYINT_SYS,
 	AQ_HW_LOOPBACK_PHYEXT_SYS,
+	AQ_HW_MEDIA_DETECT,
 };
 
 #define AQ_HW_LOOPBACK_MASK	(BIT(AQ_HW_LOOPBACK_DMA_SYS) |\
@@ -152,6 +153,7 @@ enum aq_priv_flags {
 				 BIT(AQ_HW_LOOPBACK_DMA_NET) |\
 				 BIT(AQ_HW_LOOPBACK_PHYINT_SYS) |\
 				 BIT(AQ_HW_LOOPBACK_PHYEXT_SYS))
+#define AQ_HW_MEDIA_DETECT_MASK (BIT(AQ_HW_MEDIA_DETECT))
 
 #define ATL_HW_CHIP_MIPS         0x00000001U
 #define ATL_HW_CHIP_TPO2         0x00000002U
@@ -378,6 +380,8 @@ struct aq_fw_ops {
 	int (*get_eee_rate)(struct aq_hw_s *self, u32 *rate,
 			    u32 *supported_rates);
 
+	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 43b8914c3ef5..f2f02908109e 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -405,6 +405,7 @@ int aq_nic_init(struct aq_nic_s *self)
 	mutex_unlock(&self->fwreq_mutex);
 	if (err < 0)
 		goto err_exit;
+	aq_nic_set_media_detect(self);
 
 	err = self->aq_hw_ops->hw_init(self->aq_hw,
 				       aq_nic_get_ndev(self)->dev_addr);
@@ -1389,6 +1390,24 @@ void aq_nic_release_filter(struct aq_nic_s *self, enum aq_rx_filter_type type,
 	}
 }
 
+int aq_nic_set_media_detect(struct aq_nic_s *self)
+{
+	struct aq_nic_cfg_s *cfg = &self->aq_nic_cfg;
+	int err = 0;
+
+	if (!self->aq_fw_ops->set_media_detect)
+		return -EOPNOTSUPP;
+
+	mutex_lock(&self->fwreq_mutex);
+	err = self->aq_fw_ops->set_media_detect(self->aq_hw,
+						!!(cfg->priv_flags &
+						   AQ_HW_MEDIA_DETECT_MASK));
+
+	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 317bfc646f0a..b1e4a5b5284a 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.h
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.h
@@ -193,6 +193,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_media_detect(struct aq_nic_s *self);
 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 013676cd38e4..360195b564cf 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,26 @@ 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_media_detect(struct aq_hw_s *self, bool on)
+{
+	int err = 0;
+	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;
+
+	err = hw_atl_write_fwsettings_dwords(self, offset, &enable, 1);
+
+	if (err)
+		return err;
+
+	return 0;
+}
+
 static u32 aq_fw2x_get_link_capabilities(struct aq_hw_s *self)
 {
 	int err = 0;
@@ -691,6 +711,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_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


  reply	other threads:[~2020-07-13 11:42 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-07-13 11:42 [PATCH net-next 00/10] net: atlantic: various features Igor Russkikh
2020-07-13 11:42 ` Igor Russkikh [this message]
2020-07-13 14:25   ` [PATCH net-next 01/10] net: atlantic: media detect Andrew Lunn
2020-07-15  7:41     ` [EXT] " Igor Russkikh
2020-07-15 15:46       ` Andrew Lunn
2020-07-17  7:34         ` Igor Russkikh
2020-07-13 11:42 ` [PATCH net-next 02/10] net: atlantic: move FRAC_PER_NS to aq_hw.h Igor Russkikh
2020-07-13 11:42 ` [PATCH net-next 03/10] net: atlantic: additional per-queue stats Igor Russkikh
2020-07-13 22:03   ` Jakub Kicinski
2020-07-15  7:58     ` [EXT] " Igor Russkikh
2020-07-13 11:42 ` [PATCH net-next 04/10] net: atlantic: PTP statistics Igor Russkikh
2020-07-13 11:42 ` [PATCH net-next 05/10] net: atlantic: enable ipv6 support for TCP LSO and UDP GSO Igor Russkikh
2020-07-13 11:42 ` [PATCH net-next 06/10] net: atlantic: add support for 64-bit reads/writes Igor Russkikh
2020-07-13 22:07   ` Jakub Kicinski
2020-07-13 11:42 ` [PATCH net-next 07/10] net: atlantic: use U32_MAX in aq_hw_utils.c Igor Russkikh
2020-07-13 11:42 ` [PATCH net-next 08/10] net: atlantic: use intermediate variable to improve readability a bit Igor Russkikh
2020-07-13 11:42 ` [PATCH net-next 09/10] net: atlantic: A0 ntuple filters Igor Russkikh
2020-07-13 11:42 ` [PATCH net-next 10/10] net: atlantic: add hwmon getter for MAC temperature Igor Russkikh

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200713114233.436-2-irusskikh@marvell.com \
    --to=irusskikh@marvell.com \
    --cc=andrew@lunn.ch \
    --cc=davem@davemloft.net \
    --cc=kuba@kernel.org \
    --cc=mstarovoitov@marvell.com \
    --cc=netdev@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.