mirror of
https://github.com/openwrt/openwrt.git
synced 2025-02-21 09:42:09 +00:00
kernel: backport generic phylink validate
Backport generic phylink validate series and make use of it for mtk_eth_soc Ethernet driver as well as mt7530 DSA driver. Signed-off-by: Daniel Golle <daniel@makrotopia.org>
This commit is contained in:
parent
2984a04206
commit
aab466f422
@ -0,0 +1,24 @@
|
||||
From 38c310eb46f5f80213a92093af11af270c209a76 Mon Sep 17 00:00:00 2001
|
||||
From: Russell King <rmk+kernel@armlinux.org.uk>
|
||||
Date: Tue, 26 Oct 2021 11:06:06 +0100
|
||||
Subject: [PATCH] net: phylink: add MAC phy_interface_t bitmap
|
||||
|
||||
Add a phy_interface_t bitmap so the MAC driver can specifiy which PHY
|
||||
interface modes it supports.
|
||||
|
||||
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
include/linux/phylink.h | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
--- a/include/linux/phylink.h
|
||||
+++ b/include/linux/phylink.h
|
||||
@@ -76,6 +76,7 @@ struct phylink_config {
|
||||
bool ovr_an_inband;
|
||||
void (*get_fixed_state)(struct phylink_config *config,
|
||||
struct phylink_link_state *state);
|
||||
+ DECLARE_PHY_INTERFACE_MASK(supported_interfaces);
|
||||
};
|
||||
|
||||
/**
|
@ -0,0 +1,98 @@
|
||||
From d25f3a74f30aace819163dfa54f2a4b8ca1dc932 Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Tue, 26 Oct 2021 11:06:11 +0100
|
||||
Subject: [PATCH] net: phylink: use supported_interfaces for phylink
|
||||
validation
|
||||
|
||||
If the network device supplies a supported interface bitmap, we can use
|
||||
that during phylink's validation to simplify MAC drivers in two ways by
|
||||
using the supported_interfaces bitmap to:
|
||||
|
||||
1. reject unsupported interfaces before calling into the MAC driver.
|
||||
2. generate the set of all supported link modes across all supported
|
||||
interfaces (used mainly for SFP, but also some 10G PHYs.)
|
||||
|
||||
Suggested-by: Sean Anderson <sean.anderson@seco.com>
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/phy/phylink.c | 36 ++++++++++++++++++++++++++++++++++++
|
||||
include/linux/phylink.h | 12 ++++++++++--
|
||||
2 files changed, 46 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/phylink.c
|
||||
+++ b/drivers/net/phy/phylink.c
|
||||
@@ -155,9 +155,45 @@ static const char *phylink_an_mode_str(u
|
||||
return mode < ARRAY_SIZE(modestr) ? modestr[mode] : "unknown";
|
||||
}
|
||||
|
||||
+static int phylink_validate_any(struct phylink *pl, unsigned long *supported,
|
||||
+ struct phylink_link_state *state)
|
||||
+{
|
||||
+ __ETHTOOL_DECLARE_LINK_MODE_MASK(all_adv) = { 0, };
|
||||
+ __ETHTOOL_DECLARE_LINK_MODE_MASK(all_s) = { 0, };
|
||||
+ __ETHTOOL_DECLARE_LINK_MODE_MASK(s);
|
||||
+ struct phylink_link_state t;
|
||||
+ int intf;
|
||||
+
|
||||
+ for (intf = 0; intf < PHY_INTERFACE_MODE_MAX; intf++) {
|
||||
+ if (test_bit(intf, pl->config->supported_interfaces)) {
|
||||
+ linkmode_copy(s, supported);
|
||||
+
|
||||
+ t = *state;
|
||||
+ t.interface = intf;
|
||||
+ pl->mac_ops->validate(pl->config, s, &t);
|
||||
+ linkmode_or(all_s, all_s, s);
|
||||
+ linkmode_or(all_adv, all_adv, t.advertising);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ linkmode_copy(supported, all_s);
|
||||
+ linkmode_copy(state->advertising, all_adv);
|
||||
+
|
||||
+ return phylink_is_empty_linkmode(supported) ? -EINVAL : 0;
|
||||
+}
|
||||
+
|
||||
static int phylink_validate(struct phylink *pl, unsigned long *supported,
|
||||
struct phylink_link_state *state)
|
||||
{
|
||||
+ if (!phy_interface_empty(pl->config->supported_interfaces)) {
|
||||
+ if (state->interface == PHY_INTERFACE_MODE_NA)
|
||||
+ return phylink_validate_any(pl, supported, state);
|
||||
+
|
||||
+ if (!test_bit(state->interface,
|
||||
+ pl->config->supported_interfaces))
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
pl->mac_ops->validate(pl->config, supported, state);
|
||||
|
||||
return phylink_is_empty_linkmode(supported) ? -EINVAL : 0;
|
||||
--- a/include/linux/phylink.h
|
||||
+++ b/include/linux/phylink.h
|
||||
@@ -67,6 +67,8 @@ enum phylink_op_type {
|
||||
* @ovr_an_inband: if true, override PCS to MLO_AN_INBAND
|
||||
* @get_fixed_state: callback to execute to determine the fixed link state,
|
||||
* if MAC link is at %MLO_AN_FIXED mode.
|
||||
+ * @supported_interfaces: bitmap describing which PHY_INTERFACE_MODE_xxx
|
||||
+ * are supported by the MAC/PCS.
|
||||
*/
|
||||
struct phylink_config {
|
||||
struct device *dev;
|
||||
@@ -134,8 +136,14 @@ struct phylink_mac_ops {
|
||||
* based on @state->advertising and/or @state->speed and update
|
||||
* @state->interface accordingly. See phylink_helper_basex_speed().
|
||||
*
|
||||
- * When @state->interface is %PHY_INTERFACE_MODE_NA, phylink expects the
|
||||
- * MAC driver to return all supported link modes.
|
||||
+ * When @config->supported_interfaces has been set, phylink will iterate
|
||||
+ * over the supported interfaces to determine the full capability of the
|
||||
+ * MAC. The validation function must not print errors if @state->interface
|
||||
+ * is set to an unexpected value.
|
||||
+ *
|
||||
+ * When @config->supported_interfaces is empty, phylink will call this
|
||||
+ * function with @state->interface set to %PHY_INTERFACE_MODE_NA, and
|
||||
+ * expects the MAC driver to return all supported link modes.
|
||||
*
|
||||
* If the @state->interface mode is not supported, then the @supported
|
||||
* mask must be cleared.
|
@ -0,0 +1,63 @@
|
||||
From c07c6e8eb4b38bae921f9e2f108d1e7f8e14226e Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
|
||||
Date: Thu, 28 Oct 2021 18:00:14 +0100
|
||||
Subject: [PATCH] net: dsa: populate supported_interfaces member
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Add a new DSA switch operation, phylink_get_interfaces, which should
|
||||
fill in which PHY_INTERFACE_MODE_* are supported by given port.
|
||||
|
||||
Use this before phylink_create() to fill phylinks supported_interfaces
|
||||
member, allowing phylink to determine which PHY_INTERFACE_MODEs are
|
||||
supported.
|
||||
|
||||
Signed-off-by: Marek Behún <kabel@kernel.org>
|
||||
[tweaked patch and description to add more complete support -- rmk]
|
||||
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
include/net/dsa.h | 2 ++
|
||||
net/dsa/port.c | 4 ++++
|
||||
net/dsa/slave.c | 4 ++++
|
||||
3 files changed, 10 insertions(+)
|
||||
|
||||
--- a/include/net/dsa.h
|
||||
+++ b/include/net/dsa.h
|
||||
@@ -626,6 +626,8 @@ struct dsa_switch_ops {
|
||||
/*
|
||||
* PHYLINK integration
|
||||
*/
|
||||
+ void (*phylink_get_interfaces)(struct dsa_switch *ds, int port,
|
||||
+ unsigned long *supported_interfaces);
|
||||
void (*phylink_validate)(struct dsa_switch *ds, int port,
|
||||
unsigned long *supported,
|
||||
struct phylink_link_state *state);
|
||||
--- a/net/dsa/port.c
|
||||
+++ b/net/dsa/port.c
|
||||
@@ -1172,6 +1172,10 @@ static int dsa_port_phylink_register(str
|
||||
dp->pl_config.type = PHYLINK_DEV;
|
||||
dp->pl_config.pcs_poll = ds->pcs_poll;
|
||||
|
||||
+ if (ds->ops->phylink_get_interfaces)
|
||||
+ ds->ops->phylink_get_interfaces(ds, dp->index,
|
||||
+ dp->pl_config.supported_interfaces);
|
||||
+
|
||||
dp->pl = phylink_create(&dp->pl_config, of_fwnode_handle(port_dn),
|
||||
mode, &dsa_port_phylink_mac_ops);
|
||||
if (IS_ERR(dp->pl)) {
|
||||
--- a/net/dsa/slave.c
|
||||
+++ b/net/dsa/slave.c
|
||||
@@ -1837,6 +1837,10 @@ static int dsa_slave_phy_setup(struct ne
|
||||
dp->pl_config.poll_fixed_state = true;
|
||||
}
|
||||
|
||||
+ if (ds->ops->phylink_get_interfaces)
|
||||
+ ds->ops->phylink_get_interfaces(ds, dp->index,
|
||||
+ dp->pl_config.supported_interfaces);
|
||||
+
|
||||
dp->pl = phylink_create(&dp->pl_config, of_fwnode_handle(port_dn), mode,
|
||||
&dsa_port_phylink_mac_ops);
|
||||
if (IS_ERR(dp->pl)) {
|
@ -0,0 +1,149 @@
|
||||
From 21bd64bd717dedac96f53b668144cbe37d3c12d4 Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Tue, 30 Nov 2021 13:09:55 +0000
|
||||
Subject: [PATCH] net: dsa: consolidate phylink creation
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The code in port.c and slave.c creating the phylink instance is very
|
||||
similar - let's consolidate this into a single function.
|
||||
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Reviewed-by: Marek Behún <kabel@kernel.org>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
net/dsa/dsa_priv.h | 2 +-
|
||||
net/dsa/port.c | 44 ++++++++++++++++++++++++++++----------------
|
||||
net/dsa/slave.c | 19 +++----------------
|
||||
3 files changed, 32 insertions(+), 33 deletions(-)
|
||||
|
||||
--- a/net/dsa/dsa_priv.h
|
||||
+++ b/net/dsa/dsa_priv.h
|
||||
@@ -260,13 +260,13 @@ int dsa_port_mrp_add_ring_role(const str
|
||||
const struct switchdev_obj_ring_role_mrp *mrp);
|
||||
int dsa_port_mrp_del_ring_role(const struct dsa_port *dp,
|
||||
const struct switchdev_obj_ring_role_mrp *mrp);
|
||||
+int dsa_port_phylink_create(struct dsa_port *dp);
|
||||
int dsa_port_link_register_of(struct dsa_port *dp);
|
||||
void dsa_port_link_unregister_of(struct dsa_port *dp);
|
||||
int dsa_port_hsr_join(struct dsa_port *dp, struct net_device *hsr);
|
||||
void dsa_port_hsr_leave(struct dsa_port *dp, struct net_device *hsr);
|
||||
int dsa_port_tag_8021q_vlan_add(struct dsa_port *dp, u16 vid, bool broadcast);
|
||||
void dsa_port_tag_8021q_vlan_del(struct dsa_port *dp, u16 vid, bool broadcast);
|
||||
-extern const struct phylink_mac_ops dsa_port_phylink_mac_ops;
|
||||
|
||||
static inline bool dsa_port_offloads_bridge_port(struct dsa_port *dp,
|
||||
const struct net_device *dev)
|
||||
--- a/net/dsa/port.c
|
||||
+++ b/net/dsa/port.c
|
||||
@@ -1076,7 +1076,7 @@ static void dsa_port_phylink_mac_link_up
|
||||
speed, duplex, tx_pause, rx_pause);
|
||||
}
|
||||
|
||||
-const struct phylink_mac_ops dsa_port_phylink_mac_ops = {
|
||||
+static const struct phylink_mac_ops dsa_port_phylink_mac_ops = {
|
||||
.validate = dsa_port_phylink_validate,
|
||||
.mac_pcs_get_state = dsa_port_phylink_mac_pcs_get_state,
|
||||
.mac_config = dsa_port_phylink_mac_config,
|
||||
@@ -1085,6 +1085,30 @@ const struct phylink_mac_ops dsa_port_ph
|
||||
.mac_link_up = dsa_port_phylink_mac_link_up,
|
||||
};
|
||||
|
||||
+int dsa_port_phylink_create(struct dsa_port *dp)
|
||||
+{
|
||||
+ struct dsa_switch *ds = dp->ds;
|
||||
+ phy_interface_t mode;
|
||||
+ int err;
|
||||
+
|
||||
+ err = of_get_phy_mode(dp->dn, &mode);
|
||||
+ if (err)
|
||||
+ mode = PHY_INTERFACE_MODE_NA;
|
||||
+
|
||||
+ if (ds->ops->phylink_get_interfaces)
|
||||
+ ds->ops->phylink_get_interfaces(ds, dp->index,
|
||||
+ dp->pl_config.supported_interfaces);
|
||||
+
|
||||
+ dp->pl = phylink_create(&dp->pl_config, of_fwnode_handle(dp->dn),
|
||||
+ mode, &dsa_port_phylink_mac_ops);
|
||||
+ if (IS_ERR(dp->pl)) {
|
||||
+ pr_err("error creating PHYLINK: %ld\n", PTR_ERR(dp->pl));
|
||||
+ return PTR_ERR(dp->pl);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int dsa_port_setup_phy_of(struct dsa_port *dp, bool enable)
|
||||
{
|
||||
struct dsa_switch *ds = dp->ds;
|
||||
@@ -1161,27 +1185,15 @@ static int dsa_port_phylink_register(str
|
||||
{
|
||||
struct dsa_switch *ds = dp->ds;
|
||||
struct device_node *port_dn = dp->dn;
|
||||
- phy_interface_t mode;
|
||||
int err;
|
||||
|
||||
- err = of_get_phy_mode(port_dn, &mode);
|
||||
- if (err)
|
||||
- mode = PHY_INTERFACE_MODE_NA;
|
||||
-
|
||||
dp->pl_config.dev = ds->dev;
|
||||
dp->pl_config.type = PHYLINK_DEV;
|
||||
dp->pl_config.pcs_poll = ds->pcs_poll;
|
||||
|
||||
- if (ds->ops->phylink_get_interfaces)
|
||||
- ds->ops->phylink_get_interfaces(ds, dp->index,
|
||||
- dp->pl_config.supported_interfaces);
|
||||
-
|
||||
- dp->pl = phylink_create(&dp->pl_config, of_fwnode_handle(port_dn),
|
||||
- mode, &dsa_port_phylink_mac_ops);
|
||||
- if (IS_ERR(dp->pl)) {
|
||||
- pr_err("error creating PHYLINK: %ld\n", PTR_ERR(dp->pl));
|
||||
- return PTR_ERR(dp->pl);
|
||||
- }
|
||||
+ err = dsa_port_phylink_create(dp);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
|
||||
err = phylink_of_phy_connect(dp->pl, port_dn, 0);
|
||||
if (err && err != -ENODEV) {
|
||||
--- a/net/dsa/slave.c
|
||||
+++ b/net/dsa/slave.c
|
||||
@@ -1817,14 +1817,9 @@ static int dsa_slave_phy_setup(struct ne
|
||||
struct dsa_port *dp = dsa_slave_to_port(slave_dev);
|
||||
struct device_node *port_dn = dp->dn;
|
||||
struct dsa_switch *ds = dp->ds;
|
||||
- phy_interface_t mode;
|
||||
u32 phy_flags = 0;
|
||||
int ret;
|
||||
|
||||
- ret = of_get_phy_mode(port_dn, &mode);
|
||||
- if (ret)
|
||||
- mode = PHY_INTERFACE_MODE_NA;
|
||||
-
|
||||
dp->pl_config.dev = &slave_dev->dev;
|
||||
dp->pl_config.type = PHYLINK_NETDEV;
|
||||
|
||||
@@ -1837,17 +1832,9 @@ static int dsa_slave_phy_setup(struct ne
|
||||
dp->pl_config.poll_fixed_state = true;
|
||||
}
|
||||
|
||||
- if (ds->ops->phylink_get_interfaces)
|
||||
- ds->ops->phylink_get_interfaces(ds, dp->index,
|
||||
- dp->pl_config.supported_interfaces);
|
||||
-
|
||||
- dp->pl = phylink_create(&dp->pl_config, of_fwnode_handle(port_dn), mode,
|
||||
- &dsa_port_phylink_mac_ops);
|
||||
- if (IS_ERR(dp->pl)) {
|
||||
- netdev_err(slave_dev,
|
||||
- "error creating PHYLINK: %ld\n", PTR_ERR(dp->pl));
|
||||
- return PTR_ERR(dp->pl);
|
||||
- }
|
||||
+ ret = dsa_port_phylink_create(dp);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
|
||||
if (ds->ops->get_phy_flags)
|
||||
phy_flags = ds->ops->get_phy_flags(ds, dp->index);
|
@ -0,0 +1,51 @@
|
||||
From 072eea6c22b2af680c3949e64f9adde278c71e68 Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Tue, 30 Nov 2021 13:10:01 +0000
|
||||
Subject: [PATCH] net: dsa: replace phylink_get_interfaces() with
|
||||
phylink_get_caps()
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Phylink needs slightly more information than phylink_get_interfaces()
|
||||
allows us to get from the DSA drivers - we need the MAC capabilities.
|
||||
Replace the phylink_get_interfaces() method with phylink_get_caps() to
|
||||
allow DSA drivers to fill in the phylink_config MAC capabilities field
|
||||
as well.
|
||||
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Reviewed-by: Marek Behún <kabel@kernel.org>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
include/net/dsa.h | 4 ++--
|
||||
net/dsa/port.c | 5 ++---
|
||||
2 files changed, 4 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/include/net/dsa.h
|
||||
+++ b/include/net/dsa.h
|
||||
@@ -626,8 +626,8 @@ struct dsa_switch_ops {
|
||||
/*
|
||||
* PHYLINK integration
|
||||
*/
|
||||
- void (*phylink_get_interfaces)(struct dsa_switch *ds, int port,
|
||||
- unsigned long *supported_interfaces);
|
||||
+ void (*phylink_get_caps)(struct dsa_switch *ds, int port,
|
||||
+ struct phylink_config *config);
|
||||
void (*phylink_validate)(struct dsa_switch *ds, int port,
|
||||
unsigned long *supported,
|
||||
struct phylink_link_state *state);
|
||||
--- a/net/dsa/port.c
|
||||
+++ b/net/dsa/port.c
|
||||
@@ -1095,9 +1095,8 @@ int dsa_port_phylink_create(struct dsa_p
|
||||
if (err)
|
||||
mode = PHY_INTERFACE_MODE_NA;
|
||||
|
||||
- if (ds->ops->phylink_get_interfaces)
|
||||
- ds->ops->phylink_get_interfaces(ds, dp->index,
|
||||
- dp->pl_config.supported_interfaces);
|
||||
+ if (ds->ops->phylink_get_caps)
|
||||
+ ds->ops->phylink_get_caps(ds, dp->index, &dp->pl_config);
|
||||
|
||||
dp->pl = phylink_create(&dp->pl_config, of_fwnode_handle(dp->dn),
|
||||
mode, &dsa_port_phylink_mac_ops);
|
@ -0,0 +1,59 @@
|
||||
From bde018222c6b084ac32933a9f933581dd83da18e Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Thu, 17 Feb 2022 18:30:35 +0000
|
||||
Subject: [PATCH] net: dsa: add support for phylink mac_select_pcs()
|
||||
|
||||
Add DSA support for the phylink mac_select_pcs() method so DSA drivers
|
||||
can return provide phylink with the appropriate PCS for the PHY
|
||||
interface mode.
|
||||
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
include/net/dsa.h | 3 +++
|
||||
net/dsa/port.c | 15 +++++++++++++++
|
||||
2 files changed, 18 insertions(+)
|
||||
|
||||
--- a/include/net/dsa.h
|
||||
+++ b/include/net/dsa.h
|
||||
@@ -631,6 +631,9 @@ struct dsa_switch_ops {
|
||||
void (*phylink_validate)(struct dsa_switch *ds, int port,
|
||||
unsigned long *supported,
|
||||
struct phylink_link_state *state);
|
||||
+ struct phylink_pcs *(*phylink_mac_select_pcs)(struct dsa_switch *ds,
|
||||
+ int port,
|
||||
+ phy_interface_t iface);
|
||||
int (*phylink_mac_link_state)(struct dsa_switch *ds, int port,
|
||||
struct phylink_link_state *state);
|
||||
void (*phylink_mac_config)(struct dsa_switch *ds, int port,
|
||||
--- a/net/dsa/port.c
|
||||
+++ b/net/dsa/port.c
|
||||
@@ -1012,6 +1012,20 @@ static void dsa_port_phylink_mac_pcs_get
|
||||
}
|
||||
}
|
||||
|
||||
+static struct phylink_pcs *
|
||||
+dsa_port_phylink_mac_select_pcs(struct phylink_config *config,
|
||||
+ phy_interface_t interface)
|
||||
+{
|
||||
+ struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
|
||||
+ struct dsa_switch *ds = dp->ds;
|
||||
+ struct phylink_pcs *pcs = NULL;
|
||||
+
|
||||
+ if (ds->ops->phylink_mac_select_pcs)
|
||||
+ pcs = ds->ops->phylink_mac_select_pcs(ds, dp->index, interface);
|
||||
+
|
||||
+ return pcs;
|
||||
+}
|
||||
+
|
||||
static void dsa_port_phylink_mac_config(struct phylink_config *config,
|
||||
unsigned int mode,
|
||||
const struct phylink_link_state *state)
|
||||
@@ -1078,6 +1092,7 @@ static void dsa_port_phylink_mac_link_up
|
||||
|
||||
static const struct phylink_mac_ops dsa_port_phylink_mac_ops = {
|
||||
.validate = dsa_port_phylink_validate,
|
||||
+ .mac_select_pcs = dsa_port_phylink_mac_select_pcs,
|
||||
.mac_pcs_get_state = dsa_port_phylink_mac_pcs_get_state,
|
||||
.mac_config = dsa_port_phylink_mac_config,
|
||||
.mac_an_restart = dsa_port_phylink_mac_an_restart,
|
@ -0,0 +1,61 @@
|
||||
From 8e20f591f204f8db7f1182918f8e2285d3f589e0 Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Tue, 26 Oct 2021 11:06:01 +0100
|
||||
Subject: [PATCH] net: phy: add phy_interface_t bitmap support
|
||||
|
||||
Add support for a bitmap for phy interface modes, which includes:
|
||||
- a macro to declare the interface bitmap
|
||||
- an inline helper to zero the interface bitmap
|
||||
- an inline helper to detect an empty interface bitmap
|
||||
- inline helpers to do a bitwise AND and OR operations on two interface
|
||||
bitmaps
|
||||
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
include/linux/phy.h | 34 ++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 34 insertions(+)
|
||||
|
||||
--- a/include/linux/phy.h
|
||||
+++ b/include/linux/phy.h
|
||||
@@ -155,6 +155,40 @@ typedef enum {
|
||||
PHY_INTERFACE_MODE_MAX,
|
||||
} phy_interface_t;
|
||||
|
||||
+/* PHY interface mode bitmap handling */
|
||||
+#define DECLARE_PHY_INTERFACE_MASK(name) \
|
||||
+ DECLARE_BITMAP(name, PHY_INTERFACE_MODE_MAX)
|
||||
+
|
||||
+static inline void phy_interface_zero(unsigned long *intf)
|
||||
+{
|
||||
+ bitmap_zero(intf, PHY_INTERFACE_MODE_MAX);
|
||||
+}
|
||||
+
|
||||
+static inline bool phy_interface_empty(const unsigned long *intf)
|
||||
+{
|
||||
+ return bitmap_empty(intf, PHY_INTERFACE_MODE_MAX);
|
||||
+}
|
||||
+
|
||||
+static inline void phy_interface_and(unsigned long *dst, const unsigned long *a,
|
||||
+ const unsigned long *b)
|
||||
+{
|
||||
+ bitmap_and(dst, a, b, PHY_INTERFACE_MODE_MAX);
|
||||
+}
|
||||
+
|
||||
+static inline void phy_interface_or(unsigned long *dst, const unsigned long *a,
|
||||
+ const unsigned long *b)
|
||||
+{
|
||||
+ bitmap_or(dst, a, b, PHY_INTERFACE_MODE_MAX);
|
||||
+}
|
||||
+
|
||||
+static inline void phy_interface_set_rgmii(unsigned long *intf)
|
||||
+{
|
||||
+ __set_bit(PHY_INTERFACE_MODE_RGMII, intf);
|
||||
+ __set_bit(PHY_INTERFACE_MODE_RGMII_ID, intf);
|
||||
+ __set_bit(PHY_INTERFACE_MODE_RGMII_RXID, intf);
|
||||
+ __set_bit(PHY_INTERFACE_MODE_RGMII_TXID, intf);
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* phy_supported_speeds - return all speeds currently supported by a PHY device
|
||||
*/
|
@ -0,0 +1,197 @@
|
||||
From d1e86325af377129adb7fc6f34eb044ca6068b47 Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Wed, 15 Dec 2021 15:34:15 +0000
|
||||
Subject: [PATCH] net: phylink: add mac_select_pcs() method to phylink_mac_ops
|
||||
|
||||
mac_select_pcs() allows us to have an explicit point to query which
|
||||
PCS the MAC wishes to use for a particular PHY interface mode, thereby
|
||||
allowing us to add support to validate the link settings with the PCS.
|
||||
|
||||
Phylink will also use this to select the PCS to be used during a major
|
||||
configuration event without the MAC driver needing to call
|
||||
phylink_set_pcs().
|
||||
|
||||
Note that if mac_select_pcs() is present, the supported_interfaces
|
||||
bitmap must be filled in; this avoids mac_select_pcs() being called
|
||||
with PHY_INTERFACE_MODE_NA when we want to get support for all
|
||||
interface types. Phylink will return an error in phylink_create()
|
||||
unless this condition is satisfied.
|
||||
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/phy/phylink.c | 68 +++++++++++++++++++++++++++++++++------
|
||||
include/linux/phylink.h | 18 +++++++++++
|
||||
2 files changed, 77 insertions(+), 9 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/phylink.c
|
||||
+++ b/drivers/net/phy/phylink.c
|
||||
@@ -155,6 +155,23 @@ static const char *phylink_an_mode_str(u
|
||||
return mode < ARRAY_SIZE(modestr) ? modestr[mode] : "unknown";
|
||||
}
|
||||
|
||||
+static int phylink_validate_mac_and_pcs(struct phylink *pl,
|
||||
+ unsigned long *supported,
|
||||
+ struct phylink_link_state *state)
|
||||
+{
|
||||
+ struct phylink_pcs *pcs;
|
||||
+
|
||||
+ if (pl->mac_ops->mac_select_pcs) {
|
||||
+ pcs = pl->mac_ops->mac_select_pcs(pl->config, state->interface);
|
||||
+ if (IS_ERR(pcs))
|
||||
+ return PTR_ERR(pcs);
|
||||
+ }
|
||||
+
|
||||
+ pl->mac_ops->validate(pl->config, supported, state);
|
||||
+
|
||||
+ return phylink_is_empty_linkmode(supported) ? -EINVAL : 0;
|
||||
+}
|
||||
+
|
||||
static int phylink_validate_any(struct phylink *pl, unsigned long *supported,
|
||||
struct phylink_link_state *state)
|
||||
{
|
||||
@@ -170,9 +187,10 @@ static int phylink_validate_any(struct p
|
||||
|
||||
t = *state;
|
||||
t.interface = intf;
|
||||
- pl->mac_ops->validate(pl->config, s, &t);
|
||||
- linkmode_or(all_s, all_s, s);
|
||||
- linkmode_or(all_adv, all_adv, t.advertising);
|
||||
+ if (!phylink_validate_mac_and_pcs(pl, s, &t)) {
|
||||
+ linkmode_or(all_s, all_s, s);
|
||||
+ linkmode_or(all_adv, all_adv, t.advertising);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,9 +212,7 @@ static int phylink_validate(struct phyli
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
- pl->mac_ops->validate(pl->config, supported, state);
|
||||
-
|
||||
- return phylink_is_empty_linkmode(supported) ? -EINVAL : 0;
|
||||
+ return phylink_validate_mac_and_pcs(pl, supported, state);
|
||||
}
|
||||
|
||||
static int phylink_parse_fixedlink(struct phylink *pl,
|
||||
@@ -486,10 +502,21 @@ static void phylink_mac_pcs_an_restart(s
|
||||
static void phylink_major_config(struct phylink *pl, bool restart,
|
||||
const struct phylink_link_state *state)
|
||||
{
|
||||
+ struct phylink_pcs *pcs = NULL;
|
||||
int err;
|
||||
|
||||
phylink_dbg(pl, "major config %s\n", phy_modes(state->interface));
|
||||
|
||||
+ if (pl->mac_ops->mac_select_pcs) {
|
||||
+ pcs = pl->mac_ops->mac_select_pcs(pl->config, state->interface);
|
||||
+ if (IS_ERR(pcs)) {
|
||||
+ phylink_err(pl,
|
||||
+ "mac_select_pcs unexpectedly failed: %pe\n",
|
||||
+ pcs);
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (pl->mac_ops->mac_prepare) {
|
||||
err = pl->mac_ops->mac_prepare(pl->config, pl->cur_link_an_mode,
|
||||
state->interface);
|
||||
@@ -500,6 +527,12 @@ static void phylink_major_config(struct
|
||||
}
|
||||
}
|
||||
|
||||
+ /* If we have a new PCS, switch to the new PCS after preparing the MAC
|
||||
+ * for the change.
|
||||
+ */
|
||||
+ if (pcs)
|
||||
+ phylink_set_pcs(pl, pcs);
|
||||
+
|
||||
phylink_mac_config(pl, state);
|
||||
|
||||
if (pl->pcs_ops) {
|
||||
@@ -879,6 +912,14 @@ struct phylink *phylink_create(struct ph
|
||||
struct phylink *pl;
|
||||
int ret;
|
||||
|
||||
+ /* Validate the supplied configuration */
|
||||
+ if (mac_ops->mac_select_pcs &&
|
||||
+ phy_interface_empty(config->supported_interfaces)) {
|
||||
+ dev_err(config->dev,
|
||||
+ "phylink: error: empty supported_interfaces but mac_select_pcs() method present\n");
|
||||
+ return ERR_PTR(-EINVAL);
|
||||
+ }
|
||||
+
|
||||
pl = kzalloc(sizeof(*pl), GFP_KERNEL);
|
||||
if (!pl)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
@@ -946,9 +987,10 @@ EXPORT_SYMBOL_GPL(phylink_create);
|
||||
* @pl: a pointer to a &struct phylink returned from phylink_create()
|
||||
* @pcs: a pointer to the &struct phylink_pcs
|
||||
*
|
||||
- * Bind the MAC PCS to phylink. This may be called after phylink_create(),
|
||||
- * in mac_prepare() or mac_config() methods if it is desired to dynamically
|
||||
- * change the PCS.
|
||||
+ * Bind the MAC PCS to phylink. This may be called after phylink_create().
|
||||
+ * If it is desired to dynamically change the PCS, then the preferred method
|
||||
+ * is to use mac_select_pcs(), but it may also be called in mac_prepare()
|
||||
+ * or mac_config().
|
||||
*
|
||||
* Please note that there are behavioural changes with the mac_config()
|
||||
* callback if a PCS is present (denoting a newer setup) so removing a PCS
|
||||
@@ -959,6 +1001,14 @@ void phylink_set_pcs(struct phylink *pl,
|
||||
{
|
||||
pl->pcs = pcs;
|
||||
pl->pcs_ops = pcs->ops;
|
||||
+
|
||||
+ if (!pl->phylink_disable_state &&
|
||||
+ pl->cfg_link_an_mode == MLO_AN_INBAND) {
|
||||
+ if (pl->config->pcs_poll || pcs->poll)
|
||||
+ mod_timer(&pl->link_poll, jiffies + HZ);
|
||||
+ else
|
||||
+ del_timer(&pl->link_poll);
|
||||
+ }
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(phylink_set_pcs);
|
||||
|
||||
--- a/include/linux/phylink.h
|
||||
+++ b/include/linux/phylink.h
|
||||
@@ -84,6 +84,7 @@ struct phylink_config {
|
||||
/**
|
||||
* struct phylink_mac_ops - MAC operations structure.
|
||||
* @validate: Validate and update the link configuration.
|
||||
+ * @mac_select_pcs: Select a PCS for the interface mode.
|
||||
* @mac_pcs_get_state: Read the current link state from the hardware.
|
||||
* @mac_prepare: prepare for a major reconfiguration of the interface.
|
||||
* @mac_config: configure the MAC for the selected mode and state.
|
||||
@@ -98,6 +99,8 @@ struct phylink_mac_ops {
|
||||
void (*validate)(struct phylink_config *config,
|
||||
unsigned long *supported,
|
||||
struct phylink_link_state *state);
|
||||
+ struct phylink_pcs *(*mac_select_pcs)(struct phylink_config *config,
|
||||
+ phy_interface_t interface);
|
||||
void (*mac_pcs_get_state)(struct phylink_config *config,
|
||||
struct phylink_link_state *state);
|
||||
int (*mac_prepare)(struct phylink_config *config, unsigned int mode,
|
||||
@@ -150,6 +153,21 @@ struct phylink_mac_ops {
|
||||
*/
|
||||
void validate(struct phylink_config *config, unsigned long *supported,
|
||||
struct phylink_link_state *state);
|
||||
+/**
|
||||
+ * mac_select_pcs: Select a PCS for the interface mode.
|
||||
+ * @config: a pointer to a &struct phylink_config.
|
||||
+ * @interface: PHY interface mode for PCS
|
||||
+ *
|
||||
+ * Return the &struct phylink_pcs for the specified interface mode, or
|
||||
+ * NULL if none is required, or an error pointer on error.
|
||||
+ *
|
||||
+ * This must not modify any state. It is used to query which PCS should
|
||||
+ * be used. Phylink will use this during validation to ensure that the
|
||||
+ * configuration is valid, and when setting a configuration to internally
|
||||
+ * set the PCS that will be used.
|
||||
+ */
|
||||
+struct phylink_pcs *mac_select_pcs(struct phylink_config *config,
|
||||
+ phy_interface_t interface);
|
||||
|
||||
/**
|
||||
* mac_pcs_get_state() - Read the current inband link state from the hardware
|
@ -0,0 +1,341 @@
|
||||
From 34ae2c09d46a2d0abd907e139b466f798e4095a8 Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Mon, 15 Nov 2021 10:00:27 +0000
|
||||
Subject: [PATCH] net: phylink: add generic validate implementation
|
||||
|
||||
Add a generic validate() implementation using the supported_interfaces
|
||||
and a bitmask of MAC pause/speed/duplex capabilities. This allows us
|
||||
to entirely eliminate many driver private validate() implementations.
|
||||
|
||||
We expose the underlying phylink_get_linkmodes() function so that
|
||||
drivers which have special needs can still benefit from conversion.
|
||||
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/phy/phylink.c | 252 ++++++++++++++++++++++++++++++++++++++
|
||||
include/linux/phylink.h | 31 +++++
|
||||
2 files changed, 283 insertions(+)
|
||||
|
||||
--- a/drivers/net/phy/phylink.c
|
||||
+++ b/drivers/net/phy/phylink.c
|
||||
@@ -172,6 +172,258 @@ static int phylink_validate_mac_and_pcs(
|
||||
return phylink_is_empty_linkmode(supported) ? -EINVAL : 0;
|
||||
}
|
||||
|
||||
+static void phylink_caps_to_linkmodes(unsigned long *linkmodes,
|
||||
+ unsigned long caps)
|
||||
+{
|
||||
+ if (caps & MAC_SYM_PAUSE)
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_Pause_BIT, linkmodes);
|
||||
+
|
||||
+ if (caps & MAC_ASYM_PAUSE)
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, linkmodes);
|
||||
+
|
||||
+ if (caps & MAC_10HD)
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, linkmodes);
|
||||
+
|
||||
+ if (caps & MAC_10FD)
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, linkmodes);
|
||||
+
|
||||
+ if (caps & MAC_100HD) {
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_100baseFX_Half_BIT, linkmodes);
|
||||
+ }
|
||||
+
|
||||
+ if (caps & MAC_100FD) {
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_100baseT1_Full_BIT, linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_100baseFX_Full_BIT, linkmodes);
|
||||
+ }
|
||||
+
|
||||
+ if (caps & MAC_1000HD)
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, linkmodes);
|
||||
+
|
||||
+ if (caps & MAC_1000FD) {
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT, linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_1000baseT1_Full_BIT, linkmodes);
|
||||
+ }
|
||||
+
|
||||
+ if (caps & MAC_2500FD) {
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_2500baseX_Full_BIT, linkmodes);
|
||||
+ }
|
||||
+
|
||||
+ if (caps & MAC_5000FD)
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT, linkmodes);
|
||||
+
|
||||
+ if (caps & MAC_10000FD) {
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT, linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT, linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_10000baseKR_Full_BIT, linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_10000baseR_FEC_BIT, linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_10000baseCR_Full_BIT, linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_10000baseSR_Full_BIT, linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_10000baseLR_Full_BIT, linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_10000baseLRM_Full_BIT, linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_10000baseER_Full_BIT, linkmodes);
|
||||
+ }
|
||||
+
|
||||
+ if (caps & MAC_25000FD) {
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_25000baseCR_Full_BIT, linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_25000baseKR_Full_BIT, linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_25000baseSR_Full_BIT, linkmodes);
|
||||
+ }
|
||||
+
|
||||
+ if (caps & MAC_40000FD) {
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT, linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT, linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT, linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT, linkmodes);
|
||||
+ }
|
||||
+
|
||||
+ if (caps & MAC_50000FD) {
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT, linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT, linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT, linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_50000baseKR_Full_BIT, linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_50000baseSR_Full_BIT, linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_50000baseCR_Full_BIT, linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT,
|
||||
+ linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_50000baseDR_Full_BIT, linkmodes);
|
||||
+ }
|
||||
+
|
||||
+ if (caps & MAC_56000FD) {
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_56000baseKR4_Full_BIT, linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_56000baseCR4_Full_BIT, linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_56000baseSR4_Full_BIT, linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_56000baseLR4_Full_BIT, linkmodes);
|
||||
+ }
|
||||
+
|
||||
+ if (caps & MAC_100000FD) {
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT, linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT, linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT, linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT,
|
||||
+ linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_100000baseKR2_Full_BIT, linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_100000baseSR2_Full_BIT, linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_100000baseCR2_Full_BIT, linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_100000baseLR2_ER2_FR2_Full_BIT,
|
||||
+ linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_100000baseDR2_Full_BIT, linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_100000baseKR_Full_BIT, linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_100000baseSR_Full_BIT, linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_100000baseLR_ER_FR_Full_BIT,
|
||||
+ linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_100000baseCR_Full_BIT, linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_100000baseDR_Full_BIT, linkmodes);
|
||||
+ }
|
||||
+
|
||||
+ if (caps & MAC_200000FD) {
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_200000baseKR4_Full_BIT, linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_200000baseSR4_Full_BIT, linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_200000baseLR4_ER4_FR4_Full_BIT,
|
||||
+ linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_200000baseDR4_Full_BIT, linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_200000baseCR4_Full_BIT, linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_200000baseKR2_Full_BIT, linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_200000baseSR2_Full_BIT, linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_200000baseLR2_ER2_FR2_Full_BIT,
|
||||
+ linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_200000baseDR2_Full_BIT, linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_200000baseCR2_Full_BIT, linkmodes);
|
||||
+ }
|
||||
+
|
||||
+ if (caps & MAC_400000FD) {
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_400000baseKR8_Full_BIT, linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_400000baseSR8_Full_BIT, linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_400000baseLR8_ER8_FR8_Full_BIT,
|
||||
+ linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_400000baseDR8_Full_BIT, linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_400000baseCR8_Full_BIT, linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_400000baseKR4_Full_BIT, linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_400000baseSR4_Full_BIT, linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_400000baseLR4_ER4_FR4_Full_BIT,
|
||||
+ linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_400000baseDR4_Full_BIT, linkmodes);
|
||||
+ __set_bit(ETHTOOL_LINK_MODE_400000baseCR4_Full_BIT, linkmodes);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * phylink_get_linkmodes() - get acceptable link modes
|
||||
+ * @linkmodes: ethtool linkmode mask (must be already initialised)
|
||||
+ * @interface: phy interface mode defined by &typedef phy_interface_t
|
||||
+ * @mac_capabilities: bitmask of MAC capabilities
|
||||
+ *
|
||||
+ * Set all possible pause, speed and duplex linkmodes in @linkmodes that
|
||||
+ * are supported by the @interface mode and @mac_capabilities. @linkmodes
|
||||
+ * must have been initialised previously.
|
||||
+ */
|
||||
+void phylink_get_linkmodes(unsigned long *linkmodes, phy_interface_t interface,
|
||||
+ unsigned long mac_capabilities)
|
||||
+{
|
||||
+ unsigned long caps = MAC_SYM_PAUSE | MAC_ASYM_PAUSE;
|
||||
+
|
||||
+ switch (interface) {
|
||||
+ case PHY_INTERFACE_MODE_USXGMII:
|
||||
+ caps |= MAC_10000FD | MAC_5000FD | MAC_2500FD;
|
||||
+ fallthrough;
|
||||
+
|
||||
+ case PHY_INTERFACE_MODE_RGMII_TXID:
|
||||
+ case PHY_INTERFACE_MODE_RGMII_RXID:
|
||||
+ case PHY_INTERFACE_MODE_RGMII_ID:
|
||||
+ case PHY_INTERFACE_MODE_RGMII:
|
||||
+ case PHY_INTERFACE_MODE_QSGMII:
|
||||
+ case PHY_INTERFACE_MODE_SGMII:
|
||||
+ case PHY_INTERFACE_MODE_GMII:
|
||||
+ caps |= MAC_1000HD | MAC_1000FD;
|
||||
+ fallthrough;
|
||||
+
|
||||
+ case PHY_INTERFACE_MODE_REVRMII:
|
||||
+ case PHY_INTERFACE_MODE_RMII:
|
||||
+ case PHY_INTERFACE_MODE_REVMII:
|
||||
+ case PHY_INTERFACE_MODE_MII:
|
||||
+ caps |= MAC_10HD | MAC_10FD;
|
||||
+ fallthrough;
|
||||
+
|
||||
+ case PHY_INTERFACE_MODE_100BASEX:
|
||||
+ caps |= MAC_100HD | MAC_100FD;
|
||||
+ break;
|
||||
+
|
||||
+ case PHY_INTERFACE_MODE_TBI:
|
||||
+ case PHY_INTERFACE_MODE_MOCA:
|
||||
+ case PHY_INTERFACE_MODE_RTBI:
|
||||
+ case PHY_INTERFACE_MODE_1000BASEX:
|
||||
+ caps |= MAC_1000HD;
|
||||
+ fallthrough;
|
||||
+ case PHY_INTERFACE_MODE_TRGMII:
|
||||
+ caps |= MAC_1000FD;
|
||||
+ break;
|
||||
+
|
||||
+ case PHY_INTERFACE_MODE_2500BASEX:
|
||||
+ caps |= MAC_2500FD;
|
||||
+ break;
|
||||
+
|
||||
+ case PHY_INTERFACE_MODE_5GBASER:
|
||||
+ caps |= MAC_5000FD;
|
||||
+ break;
|
||||
+
|
||||
+ case PHY_INTERFACE_MODE_XGMII:
|
||||
+ case PHY_INTERFACE_MODE_RXAUI:
|
||||
+ case PHY_INTERFACE_MODE_XAUI:
|
||||
+ case PHY_INTERFACE_MODE_10GBASER:
|
||||
+ case PHY_INTERFACE_MODE_10GKR:
|
||||
+ caps |= MAC_10000FD;
|
||||
+ break;
|
||||
+
|
||||
+ case PHY_INTERFACE_MODE_25GBASER:
|
||||
+ caps |= MAC_25000FD;
|
||||
+ break;
|
||||
+
|
||||
+ case PHY_INTERFACE_MODE_XLGMII:
|
||||
+ caps |= MAC_40000FD;
|
||||
+ break;
|
||||
+
|
||||
+ case PHY_INTERFACE_MODE_INTERNAL:
|
||||
+ caps |= ~0;
|
||||
+ break;
|
||||
+
|
||||
+ case PHY_INTERFACE_MODE_NA:
|
||||
+ case PHY_INTERFACE_MODE_MAX:
|
||||
+ case PHY_INTERFACE_MODE_SMII:
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ phylink_caps_to_linkmodes(linkmodes, caps & mac_capabilities);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(phylink_get_linkmodes);
|
||||
+
|
||||
+/**
|
||||
+ * phylink_generic_validate() - generic validate() callback implementation
|
||||
+ * @config: a pointer to a &struct phylink_config.
|
||||
+ * @supported: ethtool bitmask for supported link modes.
|
||||
+ * @state: a pointer to a &struct phylink_link_state.
|
||||
+ *
|
||||
+ * Generic implementation of the validate() callback that MAC drivers can
|
||||
+ * use when they pass the range of supported interfaces and MAC capabilities.
|
||||
+ * This makes use of phylink_get_linkmodes().
|
||||
+ */
|
||||
+void phylink_generic_validate(struct phylink_config *config,
|
||||
+ unsigned long *supported,
|
||||
+ struct phylink_link_state *state)
|
||||
+{
|
||||
+ __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
|
||||
+
|
||||
+ phylink_set_port_modes(mask);
|
||||
+ phylink_set(mask, Autoneg);
|
||||
+ phylink_get_linkmodes(mask, state->interface, config->mac_capabilities);
|
||||
+
|
||||
+ linkmode_and(supported, supported, mask);
|
||||
+ linkmode_and(state->advertising, state->advertising, mask);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(phylink_generic_validate);
|
||||
+
|
||||
static int phylink_validate_any(struct phylink *pl, unsigned long *supported,
|
||||
struct phylink_link_state *state)
|
||||
{
|
||||
--- a/include/linux/phylink.h
|
||||
+++ b/include/linux/phylink.h
|
||||
@@ -20,6 +20,29 @@ enum {
|
||||
MLO_AN_PHY = 0, /* Conventional PHY */
|
||||
MLO_AN_FIXED, /* Fixed-link mode */
|
||||
MLO_AN_INBAND, /* In-band protocol */
|
||||
+
|
||||
+ MAC_SYM_PAUSE = BIT(0),
|
||||
+ MAC_ASYM_PAUSE = BIT(1),
|
||||
+ MAC_10HD = BIT(2),
|
||||
+ MAC_10FD = BIT(3),
|
||||
+ MAC_10 = MAC_10HD | MAC_10FD,
|
||||
+ MAC_100HD = BIT(4),
|
||||
+ MAC_100FD = BIT(5),
|
||||
+ MAC_100 = MAC_100HD | MAC_100FD,
|
||||
+ MAC_1000HD = BIT(6),
|
||||
+ MAC_1000FD = BIT(7),
|
||||
+ MAC_1000 = MAC_1000HD | MAC_1000FD,
|
||||
+ MAC_2500FD = BIT(8),
|
||||
+ MAC_5000FD = BIT(9),
|
||||
+ MAC_10000FD = BIT(10),
|
||||
+ MAC_20000FD = BIT(11),
|
||||
+ MAC_25000FD = BIT(12),
|
||||
+ MAC_40000FD = BIT(13),
|
||||
+ MAC_50000FD = BIT(14),
|
||||
+ MAC_56000FD = BIT(15),
|
||||
+ MAC_100000FD = BIT(16),
|
||||
+ MAC_200000FD = BIT(17),
|
||||
+ MAC_400000FD = BIT(18),
|
||||
};
|
||||
|
||||
static inline bool phylink_autoneg_inband(unsigned int mode)
|
||||
@@ -69,6 +92,7 @@ enum phylink_op_type {
|
||||
* if MAC link is at %MLO_AN_FIXED mode.
|
||||
* @supported_interfaces: bitmap describing which PHY_INTERFACE_MODE_xxx
|
||||
* are supported by the MAC/PCS.
|
||||
+ * @mac_capabilities: MAC pause/speed/duplex capabilities.
|
||||
*/
|
||||
struct phylink_config {
|
||||
struct device *dev;
|
||||
@@ -79,6 +103,7 @@ struct phylink_config {
|
||||
void (*get_fixed_state)(struct phylink_config *config,
|
||||
struct phylink_link_state *state);
|
||||
DECLARE_PHY_INTERFACE_MASK(supported_interfaces);
|
||||
+ unsigned long mac_capabilities;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -460,6 +485,12 @@ void pcs_link_up(struct phylink_pcs *pcs
|
||||
phy_interface_t interface, int speed, int duplex);
|
||||
#endif
|
||||
|
||||
+void phylink_get_linkmodes(unsigned long *linkmodes, phy_interface_t interface,
|
||||
+ unsigned long mac_capabilities);
|
||||
+void phylink_generic_validate(struct phylink_config *config,
|
||||
+ unsigned long *supported,
|
||||
+ struct phylink_link_state *state);
|
||||
+
|
||||
struct phylink *phylink_create(struct phylink_config *, struct fwnode_handle *,
|
||||
phy_interface_t iface,
|
||||
const struct phylink_mac_ops *mac_ops);
|
@ -0,0 +1,68 @@
|
||||
From 82b318983c515f29b8b3a0dad9f6a5fe8a68a7f4 Mon Sep 17 00:00:00 2001
|
||||
From: Vladimir Oltean <vladimir.oltean@nxp.com>
|
||||
Date: Wed, 20 Oct 2021 20:49:49 +0300
|
||||
Subject: [PATCH] net: dsa: introduce helpers for iterating through ports using
|
||||
dp
|
||||
|
||||
Since the DSA conversion from the ds->ports array into the dst->ports
|
||||
list, the DSA API has encouraged driver writers, as well as the core
|
||||
itself, to write inefficient code.
|
||||
|
||||
Currently, code that wants to filter by a specific type of port when
|
||||
iterating, like {!unused, user, cpu, dsa}, uses the dsa_is_*_port helper.
|
||||
Under the hood, this uses dsa_to_port which iterates again through
|
||||
dst->ports. But the driver iterates through the port list already, so
|
||||
the complexity is quadratic for the typical case of a single-switch
|
||||
tree.
|
||||
|
||||
This patch introduces some iteration helpers where the iterator is
|
||||
already a struct dsa_port *dp, so that the other variant of the
|
||||
filtering functions, dsa_port_is_{unused,user,cpu_dsa}, can be used
|
||||
directly on the iterator. This eliminates the second lookup.
|
||||
|
||||
These functions can be used both by the core and by drivers.
|
||||
|
||||
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
|
||||
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
include/net/dsa.h | 28 ++++++++++++++++++++++++++++
|
||||
1 file changed, 28 insertions(+)
|
||||
|
||||
--- a/include/net/dsa.h
|
||||
+++ b/include/net/dsa.h
|
||||
@@ -476,6 +476,34 @@ static inline bool dsa_is_user_port(stru
|
||||
return dsa_to_port(ds, p)->type == DSA_PORT_TYPE_USER;
|
||||
}
|
||||
|
||||
+#define dsa_tree_for_each_user_port(_dp, _dst) \
|
||||
+ list_for_each_entry((_dp), &(_dst)->ports, list) \
|
||||
+ if (dsa_port_is_user((_dp)))
|
||||
+
|
||||
+#define dsa_switch_for_each_port(_dp, _ds) \
|
||||
+ list_for_each_entry((_dp), &(_ds)->dst->ports, list) \
|
||||
+ if ((_dp)->ds == (_ds))
|
||||
+
|
||||
+#define dsa_switch_for_each_port_safe(_dp, _next, _ds) \
|
||||
+ list_for_each_entry_safe((_dp), (_next), &(_ds)->dst->ports, list) \
|
||||
+ if ((_dp)->ds == (_ds))
|
||||
+
|
||||
+#define dsa_switch_for_each_port_continue_reverse(_dp, _ds) \
|
||||
+ list_for_each_entry_continue_reverse((_dp), &(_ds)->dst->ports, list) \
|
||||
+ if ((_dp)->ds == (_ds))
|
||||
+
|
||||
+#define dsa_switch_for_each_available_port(_dp, _ds) \
|
||||
+ dsa_switch_for_each_port((_dp), (_ds)) \
|
||||
+ if (!dsa_port_is_unused((_dp)))
|
||||
+
|
||||
+#define dsa_switch_for_each_user_port(_dp, _ds) \
|
||||
+ dsa_switch_for_each_port((_dp), (_ds)) \
|
||||
+ if (dsa_port_is_user((_dp)))
|
||||
+
|
||||
+#define dsa_switch_for_each_cpu_port(_dp, _ds) \
|
||||
+ dsa_switch_for_each_port((_dp), (_ds)) \
|
||||
+ if (dsa_port_is_cpu((_dp)))
|
||||
+
|
||||
static inline u32 dsa_user_ports(struct dsa_switch *ds)
|
||||
{
|
||||
u32 mask = 0;
|
@ -0,0 +1,106 @@
|
||||
From 0d22d4b626a4eaa3196019092eb6c1919e9f8caa Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Wed, 15 Dec 2021 15:34:20 +0000
|
||||
Subject: [PATCH] net: phylink: add pcs_validate() method
|
||||
|
||||
Add a hook for PCS to validate the link parameters. This avoids MAC
|
||||
drivers having to have knowledge of their PCS in their validate()
|
||||
method, thereby allowing several MAC drivers to be simplfied.
|
||||
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/phy/phylink.c | 31 +++++++++++++++++++++++++++++++
|
||||
include/linux/phylink.h | 20 ++++++++++++++++++++
|
||||
2 files changed, 51 insertions(+)
|
||||
|
||||
--- a/drivers/net/phy/phylink.c
|
||||
+++ b/drivers/net/phy/phylink.c
|
||||
@@ -160,13 +160,44 @@ static int phylink_validate_mac_and_pcs(
|
||||
struct phylink_link_state *state)
|
||||
{
|
||||
struct phylink_pcs *pcs;
|
||||
+ int ret;
|
||||
|
||||
+ /* Get the PCS for this interface mode */
|
||||
if (pl->mac_ops->mac_select_pcs) {
|
||||
pcs = pl->mac_ops->mac_select_pcs(pl->config, state->interface);
|
||||
if (IS_ERR(pcs))
|
||||
return PTR_ERR(pcs);
|
||||
+ } else {
|
||||
+ pcs = pl->pcs;
|
||||
}
|
||||
|
||||
+ if (pcs) {
|
||||
+ /* The PCS, if present, must be setup before phylink_create()
|
||||
+ * has been called. If the ops is not initialised, print an
|
||||
+ * error and backtrace rather than oopsing the kernel.
|
||||
+ */
|
||||
+ if (!pcs->ops) {
|
||||
+ phylink_err(pl, "interface %s: uninitialised PCS\n",
|
||||
+ phy_modes(state->interface));
|
||||
+ dump_stack();
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ /* Validate the link parameters with the PCS */
|
||||
+ if (pcs->ops->pcs_validate) {
|
||||
+ ret = pcs->ops->pcs_validate(pcs, supported, state);
|
||||
+ if (ret < 0 || phylink_is_empty_linkmode(supported))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ /* Ensure the advertising mask is a subset of the
|
||||
+ * supported mask.
|
||||
+ */
|
||||
+ linkmode_and(state->advertising, state->advertising,
|
||||
+ supported);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* Then validate the link parameters with the MAC */
|
||||
pl->mac_ops->validate(pl->config, supported, state);
|
||||
|
||||
return phylink_is_empty_linkmode(supported) ? -EINVAL : 0;
|
||||
--- a/include/linux/phylink.h
|
||||
+++ b/include/linux/phylink.h
|
||||
@@ -396,6 +396,7 @@ struct phylink_pcs {
|
||||
|
||||
/**
|
||||
* struct phylink_pcs_ops - MAC PCS operations structure.
|
||||
+ * @pcs_validate: validate the link configuration.
|
||||
* @pcs_get_state: read the current MAC PCS link state from the hardware.
|
||||
* @pcs_config: configure the MAC PCS for the selected mode and state.
|
||||
* @pcs_an_restart: restart 802.3z BaseX autonegotiation.
|
||||
@@ -403,6 +404,8 @@ struct phylink_pcs {
|
||||
* (where necessary).
|
||||
*/
|
||||
struct phylink_pcs_ops {
|
||||
+ int (*pcs_validate)(struct phylink_pcs *pcs, unsigned long *supported,
|
||||
+ const struct phylink_link_state *state);
|
||||
void (*pcs_get_state)(struct phylink_pcs *pcs,
|
||||
struct phylink_link_state *state);
|
||||
int (*pcs_config)(struct phylink_pcs *pcs, unsigned int mode,
|
||||
@@ -416,6 +419,23 @@ struct phylink_pcs_ops {
|
||||
|
||||
#if 0 /* For kernel-doc purposes only. */
|
||||
/**
|
||||
+ * pcs_validate() - validate the link configuration.
|
||||
+ * @pcs: a pointer to a &struct phylink_pcs.
|
||||
+ * @supported: ethtool bitmask for supported link modes.
|
||||
+ * @state: a const pointer to a &struct phylink_link_state.
|
||||
+ *
|
||||
+ * Validate the interface mode, and advertising's autoneg bit, removing any
|
||||
+ * media ethtool link modes that would not be supportable from the supported
|
||||
+ * mask. Phylink will propagate the changes to the advertising mask. See the
|
||||
+ * &struct phylink_mac_ops validate() method.
|
||||
+ *
|
||||
+ * Returns -EINVAL if the interface mode/autoneg mode is not supported.
|
||||
+ * Returns non-zero positive if the link state can be supported.
|
||||
+ */
|
||||
+int pcs_validate(struct phylink_pcs *pcs, unsigned long *supported,
|
||||
+ const struct phylink_link_state *state);
|
||||
+
|
||||
+/**
|
||||
* pcs_get_state() - Read the current inband link state from the hardware
|
||||
* @pcs: a pointer to a &struct phylink_pcs.
|
||||
* @state: a pointer to a &struct phylink_link_state.
|
@ -0,0 +1,43 @@
|
||||
From 3e5b1feccea7db576353ffc302f78d522e4116e6 Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Thu, 9 Dec 2021 13:11:32 +0000
|
||||
Subject: [PATCH] net: phylink: add legacy_pre_march2020 indicator
|
||||
|
||||
Add a boolean to phylink_config to indicate whether a driver has not
|
||||
been updated for the changes in commit 7cceb599d15d ("net: phylink:
|
||||
avoid mac_config calls"), and thus are reliant on the old behaviour.
|
||||
|
||||
We were currently keying the phylink behaviour on the presence of a
|
||||
PCS, but this is sub-optimal for modern drivers that may not have a
|
||||
PCS.
|
||||
|
||||
This commit merely introduces the new flag, but does not add any use,
|
||||
since we need all legacy drivers to set this flag before it can be
|
||||
used. Once these legacy drivers have been updated, we can remove this
|
||||
flag.
|
||||
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
include/linux/phylink.h | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
--- a/include/linux/phylink.h
|
||||
+++ b/include/linux/phylink.h
|
||||
@@ -84,6 +84,8 @@ enum phylink_op_type {
|
||||
* struct phylink_config - PHYLINK configuration structure
|
||||
* @dev: a pointer to a struct device associated with the MAC
|
||||
* @type: operation type of PHYLINK instance
|
||||
+ * @legacy_pre_march2020: driver has not been updated for March 2020 updates
|
||||
+ * (See commit 7cceb599d15d ("net: phylink: avoid mac_config calls")
|
||||
* @pcs_poll: MAC PCS cannot provide link change interrupt
|
||||
* @poll_fixed_state: if true, starts link_poll,
|
||||
* if MAC link is at %MLO_AN_FIXED mode.
|
||||
@@ -97,6 +99,7 @@ enum phylink_op_type {
|
||||
struct phylink_config {
|
||||
struct device *dev;
|
||||
enum phylink_op_type type;
|
||||
+ bool legacy_pre_march2020;
|
||||
bool pcs_poll;
|
||||
bool poll_fixed_state;
|
||||
bool ovr_an_inband;
|
@ -0,0 +1,36 @@
|
||||
From 0a9f0794d9bd67e590a9488afe87fbb0419d9539 Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Thu, 9 Dec 2021 13:11:38 +0000
|
||||
Subject: [PATCH] net: dsa: mark DSA phylink as legacy_pre_march2020
|
||||
|
||||
The majority of DSA drivers do not make use of the PCS support, and
|
||||
thus operate in legacy mode. In order to preserve this behaviour in
|
||||
future, we need to set the legacy_pre_march2020 flag so phylink knows
|
||||
this may require the legacy calls.
|
||||
|
||||
There are some DSA drivers that do make use of PCS support, and these
|
||||
will continue operating as before - legacy_pre_march2020 will not
|
||||
prevent split-PCS support enabling the newer phylink behaviour.
|
||||
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
net/dsa/port.c | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
--- a/net/dsa/port.c
|
||||
+++ b/net/dsa/port.c
|
||||
@@ -1110,6 +1110,13 @@ int dsa_port_phylink_create(struct dsa_p
|
||||
if (err)
|
||||
mode = PHY_INTERFACE_MODE_NA;
|
||||
|
||||
+ /* Presence of phylink_mac_link_state or phylink_mac_an_restart is
|
||||
+ * an indicator of a legacy phylink driver.
|
||||
+ */
|
||||
+ if (ds->ops->phylink_mac_link_state ||
|
||||
+ ds->ops->phylink_mac_an_restart)
|
||||
+ dp->pl_config.legacy_pre_march2020 = true;
|
||||
+
|
||||
if (ds->ops->phylink_get_caps)
|
||||
ds->ops->phylink_get_caps(ds, dp->index, &dp->pl_config);
|
||||
|
@ -0,0 +1,115 @@
|
||||
From 001f4261fe4d5ae710cf1f445b6cae6d9d3ae26e Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Thu, 9 Dec 2021 13:11:48 +0000
|
||||
Subject: [PATCH] net: phylink: use legacy_pre_march2020
|
||||
|
||||
Use the legacy flag to indicate whether we should operate in legacy
|
||||
mode. This allows us to stop using the presence of a PCS as an
|
||||
indicator to the age of the phylink user, and make PCS presence
|
||||
optional.
|
||||
|
||||
Legacy mode involves:
|
||||
1) calling mac_config() whenever the link comes up
|
||||
2) calling mac_config() whenever the inband advertisement changes,
|
||||
possibly followed by a call to mac_an_restart()
|
||||
3) making use of mac_an_restart()
|
||||
4) making use of mac_pcs_get_state()
|
||||
|
||||
All the above functionality was moved to a seperate "PCS" block of
|
||||
operations in March 2020.
|
||||
|
||||
Update the documents to indicate that the differences that this flag
|
||||
makes.
|
||||
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/phy/phylink.c | 12 ++++++------
|
||||
include/linux/phylink.h | 17 +++++++++++++++++
|
||||
2 files changed, 23 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/phylink.c
|
||||
+++ b/drivers/net/phy/phylink.c
|
||||
@@ -777,7 +777,7 @@ static void phylink_mac_pcs_an_restart(s
|
||||
phylink_autoneg_inband(pl->cur_link_an_mode)) {
|
||||
if (pl->pcs_ops)
|
||||
pl->pcs_ops->pcs_an_restart(pl->pcs);
|
||||
- else
|
||||
+ else if (pl->config->legacy_pre_march2020)
|
||||
pl->mac_ops->mac_an_restart(pl->config);
|
||||
}
|
||||
}
|
||||
@@ -855,7 +855,7 @@ static int phylink_change_inband_advert(
|
||||
if (test_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state))
|
||||
return 0;
|
||||
|
||||
- if (!pl->pcs_ops) {
|
||||
+ if (!pl->pcs_ops && pl->config->legacy_pre_march2020) {
|
||||
/* Legacy method */
|
||||
phylink_mac_config(pl, &pl->link_config);
|
||||
phylink_mac_pcs_an_restart(pl);
|
||||
@@ -900,7 +900,8 @@ static void phylink_mac_pcs_get_state(st
|
||||
|
||||
if (pl->pcs_ops)
|
||||
pl->pcs_ops->pcs_get_state(pl->pcs, state);
|
||||
- else if (pl->mac_ops->mac_pcs_get_state)
|
||||
+ else if (pl->mac_ops->mac_pcs_get_state &&
|
||||
+ pl->config->legacy_pre_march2020)
|
||||
pl->mac_ops->mac_pcs_get_state(pl->config, state);
|
||||
else
|
||||
state->link = 0;
|
||||
@@ -1094,12 +1095,11 @@ static void phylink_resolve(struct work_
|
||||
}
|
||||
phylink_major_config(pl, false, &link_state);
|
||||
pl->link_config.interface = link_state.interface;
|
||||
- } else if (!pl->pcs_ops) {
|
||||
+ } else if (!pl->pcs_ops && pl->config->legacy_pre_march2020) {
|
||||
/* The interface remains unchanged, only the speed,
|
||||
* duplex or pause settings have changed. Call the
|
||||
* old mac_config() method to configure the MAC/PCS
|
||||
- * only if we do not have a PCS installed (an
|
||||
- * unconverted user.)
|
||||
+ * only if we do not have a legacy MAC driver.
|
||||
*/
|
||||
phylink_mac_config(pl, &link_state);
|
||||
}
|
||||
--- a/include/linux/phylink.h
|
||||
+++ b/include/linux/phylink.h
|
||||
@@ -208,6 +208,10 @@ struct phylink_pcs *mac_select_pcs(struc
|
||||
* negotiation completion state in @state->an_complete, and link up state
|
||||
* in @state->link. If possible, @state->lp_advertising should also be
|
||||
* populated.
|
||||
+ *
|
||||
+ * Note: This is a legacy method. This function will not be called unless
|
||||
+ * legacy_pre_march2020 is set in &struct phylink_config and there is no
|
||||
+ * PCS attached.
|
||||
*/
|
||||
void mac_pcs_get_state(struct phylink_config *config,
|
||||
struct phylink_link_state *state);
|
||||
@@ -248,6 +252,15 @@ int mac_prepare(struct phylink_config *c
|
||||
* guaranteed to be correct, and so any mac_config() implementation must
|
||||
* never reference these fields.
|
||||
*
|
||||
+ * Note: For legacy March 2020 drivers (drivers with legacy_pre_march2020 set
|
||||
+ * in their &phylnk_config and which don't have a PCS), this function will be
|
||||
+ * called on each link up event, and to also change the in-band advert. For
|
||||
+ * non-legacy drivers, it will only be called to reconfigure the MAC for a
|
||||
+ * "major" change in e.g. interface mode. It will not be called for changes
|
||||
+ * in speed, duplex or pause modes or to change the in-band advertisement.
|
||||
+ * In any case, it is strongly preferred that speed, duplex and pause settings
|
||||
+ * are handled in the mac_link_up() method and not in this method.
|
||||
+ *
|
||||
* (this requires a rewrite - please refer to mac_link_up() for situations
|
||||
* where the PCS and MAC are not tightly integrated.)
|
||||
*
|
||||
@@ -332,6 +345,10 @@ int mac_finish(struct phylink_config *co
|
||||
/**
|
||||
* mac_an_restart() - restart 802.3z BaseX autonegotiation
|
||||
* @config: a pointer to a &struct phylink_config.
|
||||
+ *
|
||||
+ * Note: This is a legacy method. This function will not be called unless
|
||||
+ * legacy_pre_march2020 is set in &struct phylink_config and there is no
|
||||
+ * PCS attached.
|
||||
*/
|
||||
void mac_an_restart(struct phylink_config *config);
|
||||
|
@ -0,0 +1,43 @@
|
||||
From 83800d29f0c578e82554e7d4c6bfdbdf9b6cf428 Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Tue, 16 Nov 2021 10:06:43 +0000
|
||||
Subject: [PATCH] net: mtk_eth_soc: populate supported_interfaces member
|
||||
|
||||
Populate the phy interface mode bitmap for the Mediatek driver with
|
||||
interfaces modes supported by the MAC.
|
||||
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 20 ++++++++++++++++++++
|
||||
1 file changed, 20 insertions(+)
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
@@ -3352,6 +3352,26 @@ static int mtk_add_mac(struct mtk_eth *e
|
||||
|
||||
mac->phylink_config.dev = ð->netdev[id]->dev;
|
||||
mac->phylink_config.type = PHYLINK_NETDEV;
|
||||
+ __set_bit(PHY_INTERFACE_MODE_MII,
|
||||
+ mac->phylink_config.supported_interfaces);
|
||||
+ __set_bit(PHY_INTERFACE_MODE_GMII,
|
||||
+ mac->phylink_config.supported_interfaces);
|
||||
+
|
||||
+ if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_RGMII))
|
||||
+ phy_interface_set_rgmii(mac->phylink_config.supported_interfaces);
|
||||
+
|
||||
+ if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_TRGMII) && !mac->id)
|
||||
+ __set_bit(PHY_INTERFACE_MODE_TRGMII,
|
||||
+ mac->phylink_config.supported_interfaces);
|
||||
+
|
||||
+ if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_SGMII)) {
|
||||
+ __set_bit(PHY_INTERFACE_MODE_SGMII,
|
||||
+ mac->phylink_config.supported_interfaces);
|
||||
+ __set_bit(PHY_INTERFACE_MODE_1000BASEX,
|
||||
+ mac->phylink_config.supported_interfaces);
|
||||
+ __set_bit(PHY_INTERFACE_MODE_2500BASEX,
|
||||
+ mac->phylink_config.supported_interfaces);
|
||||
+ }
|
||||
|
||||
phylink = phylink_create(&mac->phylink_config,
|
||||
of_fwnode_handle(mac->of_node),
|
@ -0,0 +1,75 @@
|
||||
From db81ca153814475d7e07365d46a4d1134bd122e2 Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Tue, 16 Nov 2021 10:06:48 +0000
|
||||
Subject: [PATCH] net: mtk_eth_soc: remove interface checks in mtk_validate()
|
||||
|
||||
As phylink checks the interface mode against the supported_interfaces
|
||||
bitmap, we no longer need to validate the interface mode, nor handle
|
||||
PHY_INTERFACE_MODE_NA in the validation function. Remove these to
|
||||
simplify the implementation.
|
||||
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 34 ---------------------
|
||||
1 file changed, 34 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
@@ -567,24 +567,8 @@ static void mtk_validate(struct phylink_
|
||||
unsigned long *supported,
|
||||
struct phylink_link_state *state)
|
||||
{
|
||||
- struct mtk_mac *mac = container_of(config, struct mtk_mac,
|
||||
- phylink_config);
|
||||
__ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
|
||||
|
||||
- if (state->interface != PHY_INTERFACE_MODE_NA &&
|
||||
- state->interface != PHY_INTERFACE_MODE_MII &&
|
||||
- state->interface != PHY_INTERFACE_MODE_GMII &&
|
||||
- !(MTK_HAS_CAPS(mac->hw->soc->caps, MTK_RGMII) &&
|
||||
- phy_interface_mode_is_rgmii(state->interface)) &&
|
||||
- !(MTK_HAS_CAPS(mac->hw->soc->caps, MTK_TRGMII) &&
|
||||
- !mac->id && state->interface == PHY_INTERFACE_MODE_TRGMII) &&
|
||||
- !(MTK_HAS_CAPS(mac->hw->soc->caps, MTK_SGMII) &&
|
||||
- (state->interface == PHY_INTERFACE_MODE_SGMII ||
|
||||
- phy_interface_mode_is_8023z(state->interface)))) {
|
||||
- linkmode_zero(supported);
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
phylink_set_port_modes(mask);
|
||||
phylink_set(mask, Autoneg);
|
||||
|
||||
@@ -611,7 +595,6 @@ static void mtk_validate(struct phylink_
|
||||
case PHY_INTERFACE_MODE_MII:
|
||||
case PHY_INTERFACE_MODE_RMII:
|
||||
case PHY_INTERFACE_MODE_REVMII:
|
||||
- case PHY_INTERFACE_MODE_NA:
|
||||
default:
|
||||
phylink_set(mask, 10baseT_Half);
|
||||
phylink_set(mask, 10baseT_Full);
|
||||
@@ -620,23 +603,6 @@ static void mtk_validate(struct phylink_
|
||||
break;
|
||||
}
|
||||
|
||||
- if (state->interface == PHY_INTERFACE_MODE_NA) {
|
||||
- if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_SGMII)) {
|
||||
- phylink_set(mask, 1000baseT_Full);
|
||||
- phylink_set(mask, 1000baseX_Full);
|
||||
- phylink_set(mask, 2500baseX_Full);
|
||||
- }
|
||||
- if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_RGMII)) {
|
||||
- phylink_set(mask, 1000baseT_Full);
|
||||
- phylink_set(mask, 1000baseT_Half);
|
||||
- phylink_set(mask, 1000baseX_Full);
|
||||
- }
|
||||
- if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_GEPHY)) {
|
||||
- phylink_set(mask, 1000baseT_Full);
|
||||
- phylink_set(mask, 1000baseT_Half);
|
||||
- }
|
||||
- }
|
||||
-
|
||||
phylink_set(mask, Pause);
|
||||
phylink_set(mask, Asym_Pause);
|
||||
|
@ -0,0 +1,42 @@
|
||||
From 71d927494463c4f016d828e1134da26b7e961af5 Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Tue, 16 Nov 2021 10:06:53 +0000
|
||||
Subject: [PATCH] net: mtk_eth_soc: drop use of phylink_helper_basex_speed()
|
||||
|
||||
Now that we have a better method to select SFP interface modes, we
|
||||
no longer need to use phylink_helper_basex_speed() in a driver's
|
||||
validation function, and we can also get rid of our hack to indicate
|
||||
both 1000base-X and 2500base-X if the comphy is present to make that
|
||||
work. Remove this hack and use of phylink_helper_basex_speed().
|
||||
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 8 ++------
|
||||
1 file changed, 2 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
@@ -577,8 +577,9 @@ static void mtk_validate(struct phylink_
|
||||
phylink_set(mask, 1000baseT_Full);
|
||||
break;
|
||||
case PHY_INTERFACE_MODE_1000BASEX:
|
||||
- case PHY_INTERFACE_MODE_2500BASEX:
|
||||
phylink_set(mask, 1000baseX_Full);
|
||||
+ break;
|
||||
+ case PHY_INTERFACE_MODE_2500BASEX:
|
||||
phylink_set(mask, 2500baseX_Full);
|
||||
break;
|
||||
case PHY_INTERFACE_MODE_GMII:
|
||||
@@ -608,11 +609,6 @@ static void mtk_validate(struct phylink_
|
||||
|
||||
linkmode_and(supported, supported, mask);
|
||||
linkmode_and(state->advertising, state->advertising, mask);
|
||||
-
|
||||
- /* We can only operate at 2500BaseX or 1000BaseX. If requested
|
||||
- * to advertise both, only report advertising at 2500BaseX.
|
||||
- */
|
||||
- phylink_helper_basex_speed(state);
|
||||
}
|
||||
|
||||
static const struct phylink_mac_ops mtk_phylink_ops = {
|
@ -0,0 +1,84 @@
|
||||
From a4238f6ce151afa331375d74a5033b76da637644 Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Tue, 16 Nov 2021 10:06:58 +0000
|
||||
Subject: [PATCH] net: mtk_eth_soc: use phylink_generic_validate()
|
||||
|
||||
mtk_eth_soc has no special behaviour in its validation implementation,
|
||||
so can be switched to phylink_generic_validate().
|
||||
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 53 ++-------------------
|
||||
1 file changed, 4 insertions(+), 49 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
@@ -563,56 +563,8 @@ static void mtk_mac_link_up(struct phyli
|
||||
mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id));
|
||||
}
|
||||
|
||||
-static void mtk_validate(struct phylink_config *config,
|
||||
- unsigned long *supported,
|
||||
- struct phylink_link_state *state)
|
||||
-{
|
||||
- __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
|
||||
-
|
||||
- phylink_set_port_modes(mask);
|
||||
- phylink_set(mask, Autoneg);
|
||||
-
|
||||
- switch (state->interface) {
|
||||
- case PHY_INTERFACE_MODE_TRGMII:
|
||||
- phylink_set(mask, 1000baseT_Full);
|
||||
- break;
|
||||
- case PHY_INTERFACE_MODE_1000BASEX:
|
||||
- phylink_set(mask, 1000baseX_Full);
|
||||
- break;
|
||||
- case PHY_INTERFACE_MODE_2500BASEX:
|
||||
- phylink_set(mask, 2500baseX_Full);
|
||||
- break;
|
||||
- case PHY_INTERFACE_MODE_GMII:
|
||||
- case PHY_INTERFACE_MODE_RGMII:
|
||||
- case PHY_INTERFACE_MODE_RGMII_ID:
|
||||
- case PHY_INTERFACE_MODE_RGMII_RXID:
|
||||
- case PHY_INTERFACE_MODE_RGMII_TXID:
|
||||
- phylink_set(mask, 1000baseT_Half);
|
||||
- fallthrough;
|
||||
- case PHY_INTERFACE_MODE_SGMII:
|
||||
- phylink_set(mask, 1000baseT_Full);
|
||||
- phylink_set(mask, 1000baseX_Full);
|
||||
- fallthrough;
|
||||
- case PHY_INTERFACE_MODE_MII:
|
||||
- case PHY_INTERFACE_MODE_RMII:
|
||||
- case PHY_INTERFACE_MODE_REVMII:
|
||||
- default:
|
||||
- phylink_set(mask, 10baseT_Half);
|
||||
- phylink_set(mask, 10baseT_Full);
|
||||
- phylink_set(mask, 100baseT_Half);
|
||||
- phylink_set(mask, 100baseT_Full);
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
- phylink_set(mask, Pause);
|
||||
- phylink_set(mask, Asym_Pause);
|
||||
-
|
||||
- linkmode_and(supported, supported, mask);
|
||||
- linkmode_and(state->advertising, state->advertising, mask);
|
||||
-}
|
||||
-
|
||||
static const struct phylink_mac_ops mtk_phylink_ops = {
|
||||
- .validate = mtk_validate,
|
||||
+ .validate = phylink_generic_validate,
|
||||
.mac_pcs_get_state = mtk_mac_pcs_get_state,
|
||||
.mac_an_restart = mtk_mac_an_restart,
|
||||
.mac_config = mtk_mac_config,
|
||||
@@ -3314,6 +3266,9 @@ static int mtk_add_mac(struct mtk_eth *e
|
||||
|
||||
mac->phylink_config.dev = ð->netdev[id]->dev;
|
||||
mac->phylink_config.type = PHYLINK_NETDEV;
|
||||
+ mac->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
|
||||
+ MAC_10 | MAC_100 | MAC_1000 | MAC_2500FD;
|
||||
+
|
||||
__set_bit(PHY_INTERFACE_MODE_MII,
|
||||
mac->phylink_config.supported_interfaces);
|
||||
__set_bit(PHY_INTERFACE_MODE_GMII,
|
@ -0,0 +1,29 @@
|
||||
From b06515367facfadcf5e70cf6f39db749cf4eb5e3 Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Thu, 9 Dec 2021 13:11:43 +0000
|
||||
Subject: [PATCH] net: mtk_eth_soc: mark as a legacy_pre_march2020 driver
|
||||
|
||||
mtk_eth_soc has not been updated for commit 7cceb599d15d ("net: phylink:
|
||||
avoid mac_config calls"), and makes use of state->speed and
|
||||
state->duplex in contravention of the phylink documentation. This makes
|
||||
reliant on the legacy behaviours, so mark it as a legacy driver.
|
||||
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
@@ -3266,6 +3266,10 @@ static int mtk_add_mac(struct mtk_eth *e
|
||||
|
||||
mac->phylink_config.dev = ð->netdev[id]->dev;
|
||||
mac->phylink_config.type = PHYLINK_NETDEV;
|
||||
+ /* This driver makes use of state->speed/state->duplex in
|
||||
+ * mac_config
|
||||
+ */
|
||||
+ mac->phylink_config.legacy_pre_march2020 = true;
|
||||
mac->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
|
||||
MAC_10 | MAC_100 | MAC_1000 | MAC_2500FD;
|
||||
|
@ -0,0 +1,40 @@
|
||||
From 889e3691b9d6573de133da1f5e78f590e52152cd Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Kicinski <kuba@kernel.org>
|
||||
Date: Thu, 28 Apr 2022 14:23:13 -0700
|
||||
Subject: [PATCH] eth: mtk_eth_soc: remove a copy of the NAPI_POLL_WEIGHT
|
||||
define
|
||||
|
||||
Defining local versions of NAPI_POLL_WEIGHT with the same
|
||||
values in the drivers just makes refactoring harder.
|
||||
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 4 ++--
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 1 -
|
||||
2 files changed, 2 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
@@ -3565,9 +3565,9 @@ static int mtk_probe(struct platform_dev
|
||||
*/
|
||||
init_dummy_netdev(ð->dummy_dev);
|
||||
netif_napi_add(ð->dummy_dev, ð->tx_napi, mtk_napi_tx,
|
||||
- MTK_NAPI_WEIGHT);
|
||||
+ NAPI_POLL_WEIGHT);
|
||||
netif_napi_add(ð->dummy_dev, ð->rx_napi, mtk_napi_rx,
|
||||
- MTK_NAPI_WEIGHT);
|
||||
+ NAPI_POLL_WEIGHT);
|
||||
|
||||
platform_set_drvdata(pdev, eth);
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
@@ -25,7 +25,6 @@
|
||||
#define MTK_TX_DMA_BUF_LEN 0x3fff
|
||||
#define MTK_TX_DMA_BUF_LEN_V2 0xffff
|
||||
#define MTK_DMA_SIZE 512
|
||||
-#define MTK_NAPI_WEIGHT 64
|
||||
#define MTK_MAC_COUNT 2
|
||||
#define MTK_RX_ETH_HLEN (ETH_HLEN + ETH_FCS_LEN)
|
||||
#define MTK_RX_HLEN (NET_SKB_PAD + MTK_RX_ETH_HLEN + NET_IP_ALIGN)
|
@ -0,0 +1,35 @@
|
||||
From 0600bdde1fae75fb9bad72033d28edddc72b44b2 Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Wed, 18 May 2022 15:54:31 +0100
|
||||
Subject: [PATCH 01/12] net: mtk_eth_soc: remove unused mac->mode
|
||||
|
||||
mac->mode is only ever written to in one location, and is thus
|
||||
superflous. Remove it.
|
||||
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 1 -
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 1 -
|
||||
2 files changed, 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
@@ -3261,7 +3261,6 @@ static int mtk_add_mac(struct mtk_eth *e
|
||||
|
||||
/* mac config is not set */
|
||||
mac->interface = PHY_INTERFACE_MODE_NA;
|
||||
- mac->mode = MLO_AN_PHY;
|
||||
mac->speed = SPEED_UNKNOWN;
|
||||
|
||||
mac->phylink_config.dev = ð->netdev[id]->dev;
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
@@ -1085,7 +1085,6 @@ struct mtk_eth {
|
||||
struct mtk_mac {
|
||||
int id;
|
||||
phy_interface_t interface;
|
||||
- unsigned int mode;
|
||||
int speed;
|
||||
struct device_node *of_node;
|
||||
struct phylink *phylink;
|
@ -0,0 +1,40 @@
|
||||
From 5a7a2f4b29d7546244da7d8bbc1962fce5b230f2 Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Wed, 18 May 2022 15:54:36 +0100
|
||||
Subject: [PATCH 02/12] net: mtk_eth_soc: remove unused sgmii flags
|
||||
|
||||
The "flags" member of struct mtk_sgmii appears to be unused, as are
|
||||
the MTK_SGMII_PHYSPEED_* and MTK_HAS_FLAGS() macros. Remove them.
|
||||
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 8 --------
|
||||
1 file changed, 8 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
@@ -956,23 +956,15 @@ struct mtk_soc_data {
|
||||
/* currently no SoC has more than 2 macs */
|
||||
#define MTK_MAX_DEVS 2
|
||||
|
||||
-#define MTK_SGMII_PHYSPEED_AN BIT(31)
|
||||
-#define MTK_SGMII_PHYSPEED_MASK GENMASK(2, 0)
|
||||
-#define MTK_SGMII_PHYSPEED_1000 BIT(0)
|
||||
-#define MTK_SGMII_PHYSPEED_2500 BIT(1)
|
||||
-#define MTK_HAS_FLAGS(flags, _x) (((flags) & (_x)) == (_x))
|
||||
-
|
||||
/* struct mtk_sgmii - This is the structure holding sgmii regmap and its
|
||||
* characteristics
|
||||
* @regmap: The register map pointing at the range used to setup
|
||||
* SGMII modes
|
||||
- * @flags: The enum refers to which mode the sgmii wants to run on
|
||||
* @ana_rgc3: The offset refers to register ANA_RGC3 related to regmap
|
||||
*/
|
||||
|
||||
struct mtk_sgmii {
|
||||
struct regmap *regmap[MTK_MAX_DEVS];
|
||||
- u32 flags[MTK_MAX_DEVS];
|
||||
u32 ana_rgc3;
|
||||
};
|
||||
|
@ -0,0 +1,40 @@
|
||||
From bc5e93e0cd22e360eda23859b939280205567580 Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Wed, 18 May 2022 15:54:42 +0100
|
||||
Subject: [PATCH 03/12] net: mtk_eth_soc: add mask and update PCS speed
|
||||
definitions
|
||||
|
||||
The PCS speed setting is a two bit field, but it is defined as two
|
||||
separate bits. Add a bitfield mask for the speed definitions, an
|
||||
use the FIELD_PREP() macro to define each PCS speed.
|
||||
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 8 +++++---
|
||||
1 file changed, 5 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <linux/phylink.h>
|
||||
#include <linux/rhashtable.h>
|
||||
#include <linux/dim.h>
|
||||
+#include <linux/bitfield.h>
|
||||
#include "mtk_ppe.h"
|
||||
|
||||
#define MTK_QDMA_PAGE_SIZE 2048
|
||||
@@ -473,9 +474,10 @@
|
||||
#define SGMSYS_SGMII_MODE 0x20
|
||||
#define SGMII_IF_MODE_BIT0 BIT(0)
|
||||
#define SGMII_SPEED_DUPLEX_AN BIT(1)
|
||||
-#define SGMII_SPEED_10 0x0
|
||||
-#define SGMII_SPEED_100 BIT(2)
|
||||
-#define SGMII_SPEED_1000 BIT(3)
|
||||
+#define SGMII_SPEED_MASK GENMASK(3, 2)
|
||||
+#define SGMII_SPEED_10 FIELD_PREP(SGMII_SPEED_MASK, 0)
|
||||
+#define SGMII_SPEED_100 FIELD_PREP(SGMII_SPEED_MASK, 1)
|
||||
+#define SGMII_SPEED_1000 FIELD_PREP(SGMII_SPEED_MASK, 2)
|
||||
#define SGMII_DUPLEX_FULL BIT(4)
|
||||
#define SGMII_IF_MODE_BIT5 BIT(5)
|
||||
#define SGMII_REMOTE_FAULT_DIS BIT(8)
|
@ -0,0 +1,60 @@
|
||||
From 7da3f901f8ecb425105fad39a0f5de73306abe52 Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Wed, 18 May 2022 15:54:47 +0100
|
||||
Subject: [PATCH 04/12] net: mtk_eth_soc: correct 802.3z speed setting
|
||||
|
||||
Phylink does not guarantee that state->speed will be set correctly in
|
||||
the mac_config() call, so it's a bug that the driver makes use of it.
|
||||
Moreover, it is making use of it in a function that is only ever called
|
||||
for 1000BASE-X and 2500BASE-X which operate at a fixed speed which
|
||||
happens to be the same setting irrespective of the interface mode. We
|
||||
can simply remove the switch statement and just set the SGMII interface
|
||||
speed.
|
||||
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/mediatek/mtk_sgmii.c | 18 +++++-------------
|
||||
1 file changed, 5 insertions(+), 13 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
|
||||
@@ -34,6 +34,7 @@ int mtk_sgmii_init(struct mtk_sgmii *ss,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+/* For SGMII interface mode */
|
||||
int mtk_sgmii_setup_mode_an(struct mtk_sgmii *ss, int id)
|
||||
{
|
||||
unsigned int val;
|
||||
@@ -60,6 +61,9 @@ int mtk_sgmii_setup_mode_an(struct mtk_s
|
||||
return 0;
|
||||
}
|
||||
|
||||
+/* For 1000BASE-X and 2500BASE-X interface modes, which operate at a
|
||||
+ * fixed speed.
|
||||
+ */
|
||||
int mtk_sgmii_setup_mode_force(struct mtk_sgmii *ss, int id,
|
||||
const struct phylink_link_state *state)
|
||||
{
|
||||
@@ -82,19 +86,7 @@ int mtk_sgmii_setup_mode_force(struct mt
|
||||
/* SGMII force mode setting */
|
||||
regmap_read(ss->regmap[id], SGMSYS_SGMII_MODE, &val);
|
||||
val &= ~SGMII_IF_MODE_MASK;
|
||||
-
|
||||
- switch (state->speed) {
|
||||
- case SPEED_10:
|
||||
- val |= SGMII_SPEED_10;
|
||||
- break;
|
||||
- case SPEED_100:
|
||||
- val |= SGMII_SPEED_100;
|
||||
- break;
|
||||
- case SPEED_2500:
|
||||
- case SPEED_1000:
|
||||
- val |= SGMII_SPEED_1000;
|
||||
- break;
|
||||
- }
|
||||
+ val |= SGMII_SPEED_1000;
|
||||
|
||||
if (state->duplex == DUPLEX_FULL)
|
||||
val |= SGMII_DUPLEX_FULL;
|
@ -0,0 +1,101 @@
|
||||
From a459187390bb221827f9c07866c3a5ffbdf9622b Mon Sep 17 00:00:00 2001
|
||||
From: Russell King <rmk+kernel@armlinux.org.uk>
|
||||
Date: Wed, 18 May 2022 15:54:52 +0100
|
||||
Subject: [PATCH 05/12] net: mtk_eth_soc: correct 802.3z duplex setting
|
||||
|
||||
Phylink does not guarantee that state->duplex will be set correctly in
|
||||
the mac_config() call, so it's a bug that the driver makes use of it.
|
||||
|
||||
Move the 802.3z PCS duplex configuration to mac_link_up().
|
||||
|
||||
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 16 +++++++++++----
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 1 +
|
||||
drivers/net/ethernet/mediatek/mtk_sgmii.c | 22 +++++++++++++++------
|
||||
3 files changed, 29 insertions(+), 10 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
@@ -532,8 +532,18 @@ static void mtk_mac_link_up(struct phyli
|
||||
{
|
||||
struct mtk_mac *mac = container_of(config, struct mtk_mac,
|
||||
phylink_config);
|
||||
- u32 mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
|
||||
+ u32 mcr;
|
||||
|
||||
+ if (phy_interface_mode_is_8023z(interface)) {
|
||||
+ struct mtk_eth *eth = mac->hw;
|
||||
+
|
||||
+ /* Decide how GMAC and SGMIISYS be mapped */
|
||||
+ int sid = (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII)) ?
|
||||
+ 0 : mac->id;
|
||||
+ mtk_sgmii_link_up(eth->sgmii, sid, speed, duplex);
|
||||
+ }
|
||||
+
|
||||
+ mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
|
||||
mcr &= ~(MAC_MCR_SPEED_100 | MAC_MCR_SPEED_1000 |
|
||||
MAC_MCR_FORCE_DPX | MAC_MCR_FORCE_TX_FC |
|
||||
MAC_MCR_FORCE_RX_FC);
|
||||
@@ -3265,9 +3275,7 @@ static int mtk_add_mac(struct mtk_eth *e
|
||||
|
||||
mac->phylink_config.dev = ð->netdev[id]->dev;
|
||||
mac->phylink_config.type = PHYLINK_NETDEV;
|
||||
- /* This driver makes use of state->speed/state->duplex in
|
||||
- * mac_config
|
||||
- */
|
||||
+ /* This driver makes use of state->speed in mac_config */
|
||||
mac->phylink_config.legacy_pre_march2020 = true;
|
||||
mac->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
|
||||
MAC_10 | MAC_100 | MAC_1000 | MAC_2500FD;
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
@@ -1103,6 +1103,7 @@ int mtk_sgmii_init(struct mtk_sgmii *ss,
|
||||
int mtk_sgmii_setup_mode_an(struct mtk_sgmii *ss, int id);
|
||||
int mtk_sgmii_setup_mode_force(struct mtk_sgmii *ss, int id,
|
||||
const struct phylink_link_state *state);
|
||||
+void mtk_sgmii_link_up(struct mtk_sgmii *ss, int id, int speed, int duplex);
|
||||
void mtk_sgmii_restart_an(struct mtk_eth *eth, int mac_id);
|
||||
|
||||
int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id);
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
|
||||
@@ -83,14 +83,10 @@ int mtk_sgmii_setup_mode_force(struct mt
|
||||
val &= ~SGMII_AN_ENABLE;
|
||||
regmap_write(ss->regmap[id], SGMSYS_PCS_CONTROL_1, val);
|
||||
|
||||
- /* SGMII force mode setting */
|
||||
+ /* Set the speed etc but leave the duplex unchanged */
|
||||
regmap_read(ss->regmap[id], SGMSYS_SGMII_MODE, &val);
|
||||
- val &= ~SGMII_IF_MODE_MASK;
|
||||
+ val &= SGMII_DUPLEX_FULL | ~SGMII_IF_MODE_MASK;
|
||||
val |= SGMII_SPEED_1000;
|
||||
-
|
||||
- if (state->duplex == DUPLEX_FULL)
|
||||
- val |= SGMII_DUPLEX_FULL;
|
||||
-
|
||||
regmap_write(ss->regmap[id], SGMSYS_SGMII_MODE, val);
|
||||
|
||||
/* Release PHYA power down state */
|
||||
@@ -101,6 +97,20 @@ int mtk_sgmii_setup_mode_force(struct mt
|
||||
return 0;
|
||||
}
|
||||
|
||||
+/* For 1000BASE-X and 2500BASE-X interface modes */
|
||||
+void mtk_sgmii_link_up(struct mtk_sgmii *ss, int id, int speed, int duplex)
|
||||
+{
|
||||
+ unsigned int val;
|
||||
+
|
||||
+ /* SGMII force duplex setting */
|
||||
+ regmap_read(ss->regmap[id], SGMSYS_SGMII_MODE, &val);
|
||||
+ val &= ~SGMII_DUPLEX_FULL;
|
||||
+ if (duplex == DUPLEX_FULL)
|
||||
+ val |= SGMII_DUPLEX_FULL;
|
||||
+
|
||||
+ regmap_write(ss->regmap[id], SGMSYS_SGMII_MODE, val);
|
||||
+}
|
||||
+
|
||||
void mtk_sgmii_restart_an(struct mtk_eth *eth, int mac_id)
|
||||
{
|
||||
struct mtk_sgmii *ss = eth->sgmii;
|
@ -0,0 +1,60 @@
|
||||
From 4ce5a0bd3958ed248f0325bfcb95339f7c74feb2 Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Wed, 18 May 2022 15:54:57 +0100
|
||||
Subject: [PATCH 06/12] net: mtk_eth_soc: stop passing phylink state to sgmii
|
||||
setup
|
||||
|
||||
Now that mtk_sgmii_setup_mode_force() only uses the interface mode
|
||||
from the phylink state, pass just the interface mode into this
|
||||
function.
|
||||
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 2 +-
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 2 +-
|
||||
drivers/net/ethernet/mediatek/mtk_sgmii.c | 4 ++--
|
||||
3 files changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
@@ -437,7 +437,7 @@ static void mtk_mac_config(struct phylin
|
||||
/* Setup SGMIISYS with the determined property */
|
||||
if (state->interface != PHY_INTERFACE_MODE_SGMII)
|
||||
err = mtk_sgmii_setup_mode_force(eth->sgmii, sid,
|
||||
- state);
|
||||
+ state->interface);
|
||||
else if (phylink_autoneg_inband(mode))
|
||||
err = mtk_sgmii_setup_mode_an(eth->sgmii, sid);
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
@@ -1102,7 +1102,7 @@ int mtk_sgmii_init(struct mtk_sgmii *ss,
|
||||
u32 ana_rgc3);
|
||||
int mtk_sgmii_setup_mode_an(struct mtk_sgmii *ss, int id);
|
||||
int mtk_sgmii_setup_mode_force(struct mtk_sgmii *ss, int id,
|
||||
- const struct phylink_link_state *state);
|
||||
+ phy_interface_t interface);
|
||||
void mtk_sgmii_link_up(struct mtk_sgmii *ss, int id, int speed, int duplex);
|
||||
void mtk_sgmii_restart_an(struct mtk_eth *eth, int mac_id);
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
|
||||
@@ -65,7 +65,7 @@ int mtk_sgmii_setup_mode_an(struct mtk_s
|
||||
* fixed speed.
|
||||
*/
|
||||
int mtk_sgmii_setup_mode_force(struct mtk_sgmii *ss, int id,
|
||||
- const struct phylink_link_state *state)
|
||||
+ phy_interface_t interface)
|
||||
{
|
||||
unsigned int val;
|
||||
|
||||
@@ -74,7 +74,7 @@ int mtk_sgmii_setup_mode_force(struct mt
|
||||
|
||||
regmap_read(ss->regmap[id], ss->ana_rgc3, &val);
|
||||
val &= ~RG_PHY_SPEED_MASK;
|
||||
- if (state->interface == PHY_INTERFACE_MODE_2500BASEX)
|
||||
+ if (interface == PHY_INTERFACE_MODE_2500BASEX)
|
||||
val |= RG_PHY_SPEED_3_125G;
|
||||
regmap_write(ss->regmap[id], ss->ana_rgc3, val);
|
||||
|
@ -0,0 +1,89 @@
|
||||
From 1ec619ee4a052fb9ac48b57554ac2722a0bfe73c Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Wed, 18 May 2022 15:55:02 +0100
|
||||
Subject: [PATCH 07/12] net: mtk_eth_soc: provide mtk_sgmii_config()
|
||||
|
||||
Provide mtk_sgmii_config() to wrap up the decisions about which SGMII
|
||||
configuration will be called.
|
||||
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 7 +------
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 5 ++---
|
||||
drivers/net/ethernet/mediatek/mtk_sgmii.c | 20 +++++++++++++++++---
|
||||
3 files changed, 20 insertions(+), 12 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
@@ -435,12 +435,7 @@ static void mtk_mac_config(struct phylin
|
||||
0 : mac->id;
|
||||
|
||||
/* Setup SGMIISYS with the determined property */
|
||||
- if (state->interface != PHY_INTERFACE_MODE_SGMII)
|
||||
- err = mtk_sgmii_setup_mode_force(eth->sgmii, sid,
|
||||
- state->interface);
|
||||
- else if (phylink_autoneg_inband(mode))
|
||||
- err = mtk_sgmii_setup_mode_an(eth->sgmii, sid);
|
||||
-
|
||||
+ err = mtk_sgmii_config(eth->sgmii, sid, mode, state->interface);
|
||||
if (err)
|
||||
goto init_err;
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
@@ -1100,9 +1100,8 @@ u32 mtk_r32(struct mtk_eth *eth, unsigne
|
||||
|
||||
int mtk_sgmii_init(struct mtk_sgmii *ss, struct device_node *np,
|
||||
u32 ana_rgc3);
|
||||
-int mtk_sgmii_setup_mode_an(struct mtk_sgmii *ss, int id);
|
||||
-int mtk_sgmii_setup_mode_force(struct mtk_sgmii *ss, int id,
|
||||
- phy_interface_t interface);
|
||||
+int mtk_sgmii_config(struct mtk_sgmii *ss, int id, unsigned int mode,
|
||||
+ phy_interface_t interface);
|
||||
void mtk_sgmii_link_up(struct mtk_sgmii *ss, int id, int speed, int duplex);
|
||||
void mtk_sgmii_restart_an(struct mtk_eth *eth, int mac_id);
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
|
||||
@@ -35,7 +35,7 @@ int mtk_sgmii_init(struct mtk_sgmii *ss,
|
||||
}
|
||||
|
||||
/* For SGMII interface mode */
|
||||
-int mtk_sgmii_setup_mode_an(struct mtk_sgmii *ss, int id)
|
||||
+static int mtk_sgmii_setup_mode_an(struct mtk_sgmii *ss, int id)
|
||||
{
|
||||
unsigned int val;
|
||||
|
||||
@@ -64,8 +64,8 @@ int mtk_sgmii_setup_mode_an(struct mtk_s
|
||||
/* For 1000BASE-X and 2500BASE-X interface modes, which operate at a
|
||||
* fixed speed.
|
||||
*/
|
||||
-int mtk_sgmii_setup_mode_force(struct mtk_sgmii *ss, int id,
|
||||
- phy_interface_t interface)
|
||||
+static int mtk_sgmii_setup_mode_force(struct mtk_sgmii *ss, int id,
|
||||
+ phy_interface_t interface)
|
||||
{
|
||||
unsigned int val;
|
||||
|
||||
@@ -97,6 +97,20 @@ int mtk_sgmii_setup_mode_force(struct mt
|
||||
return 0;
|
||||
}
|
||||
|
||||
+int mtk_sgmii_config(struct mtk_sgmii *ss, int id, unsigned int mode,
|
||||
+ phy_interface_t interface)
|
||||
+{
|
||||
+ int err = 0;
|
||||
+
|
||||
+ /* Setup SGMIISYS with the determined property */
|
||||
+ if (interface != PHY_INTERFACE_MODE_SGMII)
|
||||
+ err = mtk_sgmii_setup_mode_force(ss, id, interface);
|
||||
+ else if (phylink_autoneg_inband(mode))
|
||||
+ err = mtk_sgmii_setup_mode_an(ss, id);
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
/* For 1000BASE-X and 2500BASE-X interface modes */
|
||||
void mtk_sgmii_link_up(struct mtk_sgmii *ss, int id, int speed, int duplex)
|
||||
{
|
@ -0,0 +1,38 @@
|
||||
From 650a49bc65df6b0e0051a8f62d7c22d95a8f350d Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Wed, 18 May 2022 15:55:07 +0100
|
||||
Subject: [PATCH 08/12] net: mtk_eth_soc: add fixme comment for state->speed
|
||||
use
|
||||
|
||||
Add a fixme comment for the last remaining incorrect usage of
|
||||
state->speed in the mac_config() method, which is strangely in a code
|
||||
path which is only run when the PHY interface mode changes.
|
||||
|
||||
This means if we are in RGMII mode, changes in state->speed will not
|
||||
cause the INTF_MODE, TRGMII_RCK_CTRL and TRGMII_TCK_CTRL registers to
|
||||
be set according to the speed, nor will the TRGPLL clock be set to the
|
||||
correct value.
|
||||
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 8 ++++++++
|
||||
1 file changed, 8 insertions(+)
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
@@ -374,6 +374,14 @@ static void mtk_mac_config(struct phylin
|
||||
state->interface))
|
||||
goto err_phy;
|
||||
} else {
|
||||
+ /* FIXME: this is incorrect. Not only does it
|
||||
+ * use state->speed (which is not guaranteed
|
||||
+ * to be correct) but it also makes use of it
|
||||
+ * in a code path that will only be reachable
|
||||
+ * when the PHY interface mode changes, not
|
||||
+ * when the speed changes. Consequently, RGMII
|
||||
+ * is probably broken.
|
||||
+ */
|
||||
mtk_gmac0_rgmii_adjust(mac->hw,
|
||||
state->interface,
|
||||
state->speed);
|
@ -0,0 +1,79 @@
|
||||
From 0e37ad71b2ff772009595002da2860999e98e14e Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Wed, 18 May 2022 15:55:12 +0100
|
||||
Subject: [PATCH 09/12] net: mtk_eth_soc: move MAC_MCR setting to mac_finish()
|
||||
|
||||
Move the setting of the MTK_MAC_MCR register from the end of mac_config
|
||||
into the phylink mac_finish() method, to keep it as the very last write
|
||||
that is done during configuration.
|
||||
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 33 ++++++++++++++-------
|
||||
1 file changed, 22 insertions(+), 11 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
@@ -316,8 +316,8 @@ static void mtk_mac_config(struct phylin
|
||||
struct mtk_mac *mac = container_of(config, struct mtk_mac,
|
||||
phylink_config);
|
||||
struct mtk_eth *eth = mac->hw;
|
||||
- u32 mcr_cur, mcr_new, sid, i;
|
||||
int val, ge_mode, err = 0;
|
||||
+ u32 sid, i;
|
||||
|
||||
/* MT76x8 has no hardware settings between for the MAC */
|
||||
if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) &&
|
||||
@@ -455,16 +455,6 @@ static void mtk_mac_config(struct phylin
|
||||
return;
|
||||
}
|
||||
|
||||
- /* Setup gmac */
|
||||
- mcr_cur = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
|
||||
- mcr_new = mcr_cur;
|
||||
- mcr_new |= MAC_MCR_IPG_CFG | MAC_MCR_FORCE_MODE |
|
||||
- MAC_MCR_BACKOFF_EN | MAC_MCR_BACKPR_EN | MAC_MCR_FORCE_LINK;
|
||||
-
|
||||
- /* Only update control register when needed! */
|
||||
- if (mcr_new != mcr_cur)
|
||||
- mtk_w32(mac->hw, mcr_new, MTK_MAC_MCR(mac->id));
|
||||
-
|
||||
return;
|
||||
|
||||
err_phy:
|
||||
@@ -477,6 +467,26 @@ init_err:
|
||||
mac->id, phy_modes(state->interface), err);
|
||||
}
|
||||
|
||||
+static int mtk_mac_finish(struct phylink_config *config, unsigned int mode,
|
||||
+ phy_interface_t interface)
|
||||
+{
|
||||
+ struct mtk_mac *mac = container_of(config, struct mtk_mac,
|
||||
+ phylink_config);
|
||||
+ u32 mcr_cur, mcr_new;
|
||||
+
|
||||
+ /* Setup gmac */
|
||||
+ mcr_cur = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
|
||||
+ mcr_new = mcr_cur;
|
||||
+ mcr_new |= MAC_MCR_IPG_CFG | MAC_MCR_FORCE_MODE |
|
||||
+ MAC_MCR_BACKOFF_EN | MAC_MCR_BACKPR_EN | MAC_MCR_FORCE_LINK;
|
||||
+
|
||||
+ /* Only update control register when needed! */
|
||||
+ if (mcr_new != mcr_cur)
|
||||
+ mtk_w32(mac->hw, mcr_new, MTK_MAC_MCR(mac->id));
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static void mtk_mac_pcs_get_state(struct phylink_config *config,
|
||||
struct phylink_link_state *state)
|
||||
{
|
||||
@@ -581,6 +591,7 @@ static const struct phylink_mac_ops mtk_
|
||||
.mac_pcs_get_state = mtk_mac_pcs_get_state,
|
||||
.mac_an_restart = mtk_mac_an_restart,
|
||||
.mac_config = mtk_mac_config,
|
||||
+ .mac_finish = mtk_mac_finish,
|
||||
.mac_link_down = mtk_mac_link_down,
|
||||
.mac_link_up = mtk_mac_link_up,
|
||||
};
|
@ -0,0 +1,57 @@
|
||||
From 21089867278deb2a110b685e3cd33f64f9ce41e2 Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Wed, 18 May 2022 15:55:17 +0100
|
||||
Subject: [PATCH 10/12] net: mtk_eth_soc: move restoration of SYSCFG0 to
|
||||
mac_finish()
|
||||
|
||||
The SGMIISYS configuration is performed while ETHSYS_SYSCFG0 is in a
|
||||
disabled state. In order to preserve this when we switch to phylink_pcs
|
||||
we need to move the restoration of this register to the mac_finish()
|
||||
callback.
|
||||
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 11 +++++++++--
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 1 +
|
||||
2 files changed, 10 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
@@ -447,8 +447,8 @@ static void mtk_mac_config(struct phylin
|
||||
if (err)
|
||||
goto init_err;
|
||||
|
||||
- regmap_update_bits(eth->ethsys, ETHSYS_SYSCFG0,
|
||||
- SYSCFG0_SGMII_MASK, val);
|
||||
+ /* Save the syscfg0 value for mac_finish */
|
||||
+ mac->syscfg0 = val;
|
||||
} else if (phylink_autoneg_inband(mode)) {
|
||||
dev_err(eth->dev,
|
||||
"In-band mode not supported in non SGMII mode!\n");
|
||||
@@ -472,8 +472,15 @@ static int mtk_mac_finish(struct phylink
|
||||
{
|
||||
struct mtk_mac *mac = container_of(config, struct mtk_mac,
|
||||
phylink_config);
|
||||
+ struct mtk_eth *eth = mac->hw;
|
||||
u32 mcr_cur, mcr_new;
|
||||
|
||||
+ /* Enable SGMII */
|
||||
+ if (interface == PHY_INTERFACE_MODE_SGMII ||
|
||||
+ phy_interface_mode_is_8023z(interface))
|
||||
+ regmap_update_bits(eth->ethsys, ETHSYS_SYSCFG0,
|
||||
+ SYSCFG0_SGMII_MASK, mac->syscfg0);
|
||||
+
|
||||
/* Setup gmac */
|
||||
mcr_cur = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
|
||||
mcr_new = mcr_cur;
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
@@ -1087,6 +1087,7 @@ struct mtk_mac {
|
||||
struct mtk_hw_stats *hw_stats;
|
||||
__be32 hwlro_ip[MTK_MAX_LRO_IP_CNT];
|
||||
int hwlro_ip_cnt;
|
||||
+ unsigned int syscfg0;
|
||||
};
|
||||
|
||||
/* the struct describing the SoC. these are declared in the soc_xyz.c files */
|
@ -0,0 +1,254 @@
|
||||
From 901f3fbe13c3e56f0742e02717ccbfabbc95c463 Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Wed, 18 May 2022 15:55:22 +0100
|
||||
Subject: [PATCH 11/12] net: mtk_eth_soc: convert code structure to suit split
|
||||
PCS support
|
||||
|
||||
Provide a mtk_pcs structure which encapsulates everything that the PCS
|
||||
functions need (the regmap and ana_rgc3 offset), and use this in the
|
||||
PCS functions. Provide shim functions to convert from the existing
|
||||
"mtk_sgmii_*" interface to the converted PCS functions.
|
||||
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 15 ++-
|
||||
drivers/net/ethernet/mediatek/mtk_sgmii.c | 123 +++++++++++---------
|
||||
2 files changed, 79 insertions(+), 59 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
@@ -958,16 +958,23 @@ struct mtk_soc_data {
|
||||
/* currently no SoC has more than 2 macs */
|
||||
#define MTK_MAX_DEVS 2
|
||||
|
||||
-/* struct mtk_sgmii - This is the structure holding sgmii regmap and its
|
||||
- * characteristics
|
||||
+/* struct mtk_pcs - This structure holds each sgmii regmap and associated
|
||||
+ * data
|
||||
* @regmap: The register map pointing at the range used to setup
|
||||
* SGMII modes
|
||||
* @ana_rgc3: The offset refers to register ANA_RGC3 related to regmap
|
||||
*/
|
||||
+struct mtk_pcs {
|
||||
+ struct regmap *regmap;
|
||||
+ u32 ana_rgc3;
|
||||
+};
|
||||
|
||||
+/* struct mtk_sgmii - This is the structure holding sgmii regmap and its
|
||||
+ * characteristics
|
||||
+ * @pcs Array of individual PCS structures
|
||||
+ */
|
||||
struct mtk_sgmii {
|
||||
- struct regmap *regmap[MTK_MAX_DEVS];
|
||||
- u32 ana_rgc3;
|
||||
+ struct mtk_pcs pcs[MTK_MAX_DEVS];
|
||||
};
|
||||
|
||||
/* struct mtk_eth - This is the main datasructure for holding the state
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
|
||||
@@ -9,90 +9,71 @@
|
||||
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/of.h>
|
||||
+#include <linux/phylink.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#include "mtk_eth_soc.h"
|
||||
|
||||
-int mtk_sgmii_init(struct mtk_sgmii *ss, struct device_node *r, u32 ana_rgc3)
|
||||
-{
|
||||
- struct device_node *np;
|
||||
- int i;
|
||||
-
|
||||
- ss->ana_rgc3 = ana_rgc3;
|
||||
-
|
||||
- for (i = 0; i < MTK_MAX_DEVS; i++) {
|
||||
- np = of_parse_phandle(r, "mediatek,sgmiisys", i);
|
||||
- if (!np)
|
||||
- break;
|
||||
-
|
||||
- ss->regmap[i] = syscon_node_to_regmap(np);
|
||||
- of_node_put(np);
|
||||
- if (IS_ERR(ss->regmap[i]))
|
||||
- return PTR_ERR(ss->regmap[i]);
|
||||
- }
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
/* For SGMII interface mode */
|
||||
-static int mtk_sgmii_setup_mode_an(struct mtk_sgmii *ss, int id)
|
||||
+static int mtk_pcs_setup_mode_an(struct mtk_pcs *mpcs)
|
||||
{
|
||||
unsigned int val;
|
||||
|
||||
- if (!ss->regmap[id])
|
||||
+ if (!mpcs->regmap)
|
||||
return -EINVAL;
|
||||
|
||||
/* Setup the link timer and QPHY power up inside SGMIISYS */
|
||||
- regmap_write(ss->regmap[id], SGMSYS_PCS_LINK_TIMER,
|
||||
+ regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER,
|
||||
SGMII_LINK_TIMER_DEFAULT);
|
||||
|
||||
- regmap_read(ss->regmap[id], SGMSYS_SGMII_MODE, &val);
|
||||
+ regmap_read(mpcs->regmap, SGMSYS_SGMII_MODE, &val);
|
||||
val |= SGMII_REMOTE_FAULT_DIS;
|
||||
- regmap_write(ss->regmap[id], SGMSYS_SGMII_MODE, val);
|
||||
+ regmap_write(mpcs->regmap, SGMSYS_SGMII_MODE, val);
|
||||
|
||||
- regmap_read(ss->regmap[id], SGMSYS_PCS_CONTROL_1, &val);
|
||||
+ regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &val);
|
||||
val |= SGMII_AN_RESTART;
|
||||
- regmap_write(ss->regmap[id], SGMSYS_PCS_CONTROL_1, val);
|
||||
+ regmap_write(mpcs->regmap, SGMSYS_PCS_CONTROL_1, val);
|
||||
|
||||
- regmap_read(ss->regmap[id], SGMSYS_QPHY_PWR_STATE_CTRL, &val);
|
||||
+ regmap_read(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, &val);
|
||||
val &= ~SGMII_PHYA_PWD;
|
||||
- regmap_write(ss->regmap[id], SGMSYS_QPHY_PWR_STATE_CTRL, val);
|
||||
+ regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, val);
|
||||
|
||||
return 0;
|
||||
+
|
||||
}
|
||||
|
||||
/* For 1000BASE-X and 2500BASE-X interface modes, which operate at a
|
||||
* fixed speed.
|
||||
*/
|
||||
-static int mtk_sgmii_setup_mode_force(struct mtk_sgmii *ss, int id,
|
||||
- phy_interface_t interface)
|
||||
+static int mtk_pcs_setup_mode_force(struct mtk_pcs *mpcs,
|
||||
+ phy_interface_t interface)
|
||||
{
|
||||
unsigned int val;
|
||||
|
||||
- if (!ss->regmap[id])
|
||||
+ if (!mpcs->regmap)
|
||||
return -EINVAL;
|
||||
|
||||
- regmap_read(ss->regmap[id], ss->ana_rgc3, &val);
|
||||
+ regmap_read(mpcs->regmap, mpcs->ana_rgc3, &val);
|
||||
val &= ~RG_PHY_SPEED_MASK;
|
||||
if (interface == PHY_INTERFACE_MODE_2500BASEX)
|
||||
val |= RG_PHY_SPEED_3_125G;
|
||||
- regmap_write(ss->regmap[id], ss->ana_rgc3, val);
|
||||
+ regmap_write(mpcs->regmap, mpcs->ana_rgc3, val);
|
||||
|
||||
/* Disable SGMII AN */
|
||||
- regmap_read(ss->regmap[id], SGMSYS_PCS_CONTROL_1, &val);
|
||||
+ regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &val);
|
||||
val &= ~SGMII_AN_ENABLE;
|
||||
- regmap_write(ss->regmap[id], SGMSYS_PCS_CONTROL_1, val);
|
||||
+ regmap_write(mpcs->regmap, SGMSYS_PCS_CONTROL_1, val);
|
||||
|
||||
/* Set the speed etc but leave the duplex unchanged */
|
||||
- regmap_read(ss->regmap[id], SGMSYS_SGMII_MODE, &val);
|
||||
+ regmap_read(mpcs->regmap, SGMSYS_SGMII_MODE, &val);
|
||||
val &= SGMII_DUPLEX_FULL | ~SGMII_IF_MODE_MASK;
|
||||
val |= SGMII_SPEED_1000;
|
||||
- regmap_write(ss->regmap[id], SGMSYS_SGMII_MODE, val);
|
||||
+ regmap_write(mpcs->regmap, SGMSYS_SGMII_MODE, val);
|
||||
|
||||
/* Release PHYA power down state */
|
||||
- regmap_read(ss->regmap[id], SGMSYS_QPHY_PWR_STATE_CTRL, &val);
|
||||
+ regmap_read(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, &val);
|
||||
val &= ~SGMII_PHYA_PWD;
|
||||
- regmap_write(ss->regmap[id], SGMSYS_QPHY_PWR_STATE_CTRL, val);
|
||||
+ regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -100,44 +81,76 @@ static int mtk_sgmii_setup_mode_force(st
|
||||
int mtk_sgmii_config(struct mtk_sgmii *ss, int id, unsigned int mode,
|
||||
phy_interface_t interface)
|
||||
{
|
||||
+ struct mtk_pcs *mpcs = &ss->pcs[id];
|
||||
int err = 0;
|
||||
|
||||
/* Setup SGMIISYS with the determined property */
|
||||
if (interface != PHY_INTERFACE_MODE_SGMII)
|
||||
- err = mtk_sgmii_setup_mode_force(ss, id, interface);
|
||||
+ err = mtk_pcs_setup_mode_force(mpcs, interface);
|
||||
else if (phylink_autoneg_inband(mode))
|
||||
- err = mtk_sgmii_setup_mode_an(ss, id);
|
||||
+ err = mtk_pcs_setup_mode_an(mpcs);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
-/* For 1000BASE-X and 2500BASE-X interface modes */
|
||||
-void mtk_sgmii_link_up(struct mtk_sgmii *ss, int id, int speed, int duplex)
|
||||
+static void mtk_pcs_restart_an(struct mtk_pcs *mpcs)
|
||||
+{
|
||||
+ unsigned int val;
|
||||
+
|
||||
+ if (!mpcs->regmap)
|
||||
+ return;
|
||||
+
|
||||
+ regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &val);
|
||||
+ val |= SGMII_AN_RESTART;
|
||||
+ regmap_write(mpcs->regmap, SGMSYS_PCS_CONTROL_1, val);
|
||||
+}
|
||||
+
|
||||
+static void mtk_pcs_link_up(struct mtk_pcs *mpcs, int speed, int duplex)
|
||||
{
|
||||
unsigned int val;
|
||||
|
||||
/* SGMII force duplex setting */
|
||||
- regmap_read(ss->regmap[id], SGMSYS_SGMII_MODE, &val);
|
||||
+ regmap_read(mpcs->regmap, SGMSYS_SGMII_MODE, &val);
|
||||
val &= ~SGMII_DUPLEX_FULL;
|
||||
if (duplex == DUPLEX_FULL)
|
||||
val |= SGMII_DUPLEX_FULL;
|
||||
|
||||
- regmap_write(ss->regmap[id], SGMSYS_SGMII_MODE, val);
|
||||
+ regmap_write(mpcs->regmap, SGMSYS_SGMII_MODE, val);
|
||||
+}
|
||||
+
|
||||
+/* For 1000BASE-X and 2500BASE-X interface modes */
|
||||
+void mtk_sgmii_link_up(struct mtk_sgmii *ss, int id, int speed, int duplex)
|
||||
+{
|
||||
+ mtk_pcs_link_up(&ss->pcs[id], speed, duplex);
|
||||
+}
|
||||
+
|
||||
+int mtk_sgmii_init(struct mtk_sgmii *ss, struct device_node *r, u32 ana_rgc3)
|
||||
+{
|
||||
+ struct device_node *np;
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < MTK_MAX_DEVS; i++) {
|
||||
+ np = of_parse_phandle(r, "mediatek,sgmiisys", i);
|
||||
+ if (!np)
|
||||
+ break;
|
||||
+
|
||||
+ ss->pcs[i].ana_rgc3 = ana_rgc3;
|
||||
+ ss->pcs[i].regmap = syscon_node_to_regmap(np);
|
||||
+ of_node_put(np);
|
||||
+ if (IS_ERR(ss->pcs[i].regmap))
|
||||
+ return PTR_ERR(ss->pcs[i].regmap);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
void mtk_sgmii_restart_an(struct mtk_eth *eth, int mac_id)
|
||||
{
|
||||
- struct mtk_sgmii *ss = eth->sgmii;
|
||||
- unsigned int val, sid;
|
||||
+ unsigned int sid;
|
||||
|
||||
/* Decide how GMAC and SGMIISYS be mapped */
|
||||
sid = (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII)) ?
|
||||
0 : mac_id;
|
||||
|
||||
- if (!ss->regmap[sid])
|
||||
- return;
|
||||
-
|
||||
- regmap_read(ss->regmap[sid], SGMSYS_PCS_CONTROL_1, &val);
|
||||
- val |= SGMII_AN_RESTART;
|
||||
- regmap_write(ss->regmap[sid], SGMSYS_PCS_CONTROL_1, val);
|
||||
+ mtk_pcs_restart_an(ð->sgmii->pcs[sid]);
|
||||
}
|
@ -0,0 +1,262 @@
|
||||
From 14a44ab0330d290fade1403a920e299cc56d7300 Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Wed, 18 May 2022 15:55:28 +0100
|
||||
Subject: [PATCH 12/12] net: mtk_eth_soc: partially convert to phylink_pcs
|
||||
|
||||
Partially convert mtk_eth_soc to phylink_pcs, moving the configuration,
|
||||
link up and AN restart over. However, it seems mac_pcs_get_state()
|
||||
doesn't actually get the state from the PCS, so we can't convert that
|
||||
over without a better understanding of the hardware.
|
||||
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 49 ++++++++----------
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 7 ++-
|
||||
drivers/net/ethernet/mediatek/mtk_sgmii.c | 55 +++++++++++----------
|
||||
3 files changed, 53 insertions(+), 58 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
@@ -310,6 +310,25 @@ static void mtk_gmac0_rgmii_adjust(struc
|
||||
mtk_w32(eth, val, TRGMII_TCK_CTRL);
|
||||
}
|
||||
|
||||
+static struct phylink_pcs *mtk_mac_select_pcs(struct phylink_config *config,
|
||||
+ phy_interface_t interface)
|
||||
+{
|
||||
+ struct mtk_mac *mac = container_of(config, struct mtk_mac,
|
||||
+ phylink_config);
|
||||
+ struct mtk_eth *eth = mac->hw;
|
||||
+ unsigned int sid;
|
||||
+
|
||||
+ if (interface == PHY_INTERFACE_MODE_SGMII ||
|
||||
+ phy_interface_mode_is_8023z(interface)) {
|
||||
+ sid = (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII)) ?
|
||||
+ 0 : mac->id;
|
||||
+
|
||||
+ return mtk_sgmii_select_pcs(eth->sgmii, sid);
|
||||
+ }
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
static void mtk_mac_config(struct phylink_config *config, unsigned int mode,
|
||||
const struct phylink_link_state *state)
|
||||
{
|
||||
@@ -317,7 +336,7 @@ static void mtk_mac_config(struct phylin
|
||||
phylink_config);
|
||||
struct mtk_eth *eth = mac->hw;
|
||||
int val, ge_mode, err = 0;
|
||||
- u32 sid, i;
|
||||
+ u32 i;
|
||||
|
||||
/* MT76x8 has no hardware settings between for the MAC */
|
||||
if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) &&
|
||||
@@ -438,15 +457,6 @@ static void mtk_mac_config(struct phylin
|
||||
SYSCFG0_SGMII_MASK,
|
||||
~(u32)SYSCFG0_SGMII_MASK);
|
||||
|
||||
- /* Decide how GMAC and SGMIISYS be mapped */
|
||||
- sid = (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII)) ?
|
||||
- 0 : mac->id;
|
||||
-
|
||||
- /* Setup SGMIISYS with the determined property */
|
||||
- err = mtk_sgmii_config(eth->sgmii, sid, mode, state->interface);
|
||||
- if (err)
|
||||
- goto init_err;
|
||||
-
|
||||
/* Save the syscfg0 value for mac_finish */
|
||||
mac->syscfg0 = val;
|
||||
} else if (phylink_autoneg_inband(mode)) {
|
||||
@@ -526,14 +536,6 @@ static void mtk_mac_pcs_get_state(struct
|
||||
state->pause |= MLO_PAUSE_TX;
|
||||
}
|
||||
|
||||
-static void mtk_mac_an_restart(struct phylink_config *config)
|
||||
-{
|
||||
- struct mtk_mac *mac = container_of(config, struct mtk_mac,
|
||||
- phylink_config);
|
||||
-
|
||||
- mtk_sgmii_restart_an(mac->hw, mac->id);
|
||||
-}
|
||||
-
|
||||
static void mtk_mac_link_down(struct phylink_config *config, unsigned int mode,
|
||||
phy_interface_t interface)
|
||||
{
|
||||
@@ -554,15 +556,6 @@ static void mtk_mac_link_up(struct phyli
|
||||
phylink_config);
|
||||
u32 mcr;
|
||||
|
||||
- if (phy_interface_mode_is_8023z(interface)) {
|
||||
- struct mtk_eth *eth = mac->hw;
|
||||
-
|
||||
- /* Decide how GMAC and SGMIISYS be mapped */
|
||||
- int sid = (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII)) ?
|
||||
- 0 : mac->id;
|
||||
- mtk_sgmii_link_up(eth->sgmii, sid, speed, duplex);
|
||||
- }
|
||||
-
|
||||
mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
|
||||
mcr &= ~(MAC_MCR_SPEED_100 | MAC_MCR_SPEED_1000 |
|
||||
MAC_MCR_FORCE_DPX | MAC_MCR_FORCE_TX_FC |
|
||||
@@ -595,8 +588,8 @@ static void mtk_mac_link_up(struct phyli
|
||||
|
||||
static const struct phylink_mac_ops mtk_phylink_ops = {
|
||||
.validate = phylink_generic_validate,
|
||||
+ .mac_select_pcs = mtk_mac_select_pcs,
|
||||
.mac_pcs_get_state = mtk_mac_pcs_get_state,
|
||||
- .mac_an_restart = mtk_mac_an_restart,
|
||||
.mac_config = mtk_mac_config,
|
||||
.mac_finish = mtk_mac_finish,
|
||||
.mac_link_down = mtk_mac_link_down,
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
@@ -963,10 +963,12 @@ struct mtk_soc_data {
|
||||
* @regmap: The register map pointing at the range used to setup
|
||||
* SGMII modes
|
||||
* @ana_rgc3: The offset refers to register ANA_RGC3 related to regmap
|
||||
+ * @pcs: Phylink PCS structure
|
||||
*/
|
||||
struct mtk_pcs {
|
||||
struct regmap *regmap;
|
||||
u32 ana_rgc3;
|
||||
+ struct phylink_pcs pcs;
|
||||
};
|
||||
|
||||
/* struct mtk_sgmii - This is the structure holding sgmii regmap and its
|
||||
@@ -1106,12 +1108,9 @@ void mtk_stats_update_mac(struct mtk_mac
|
||||
void mtk_w32(struct mtk_eth *eth, u32 val, unsigned reg);
|
||||
u32 mtk_r32(struct mtk_eth *eth, unsigned reg);
|
||||
|
||||
+struct phylink_pcs *mtk_sgmii_select_pcs(struct mtk_sgmii *ss, int id);
|
||||
int mtk_sgmii_init(struct mtk_sgmii *ss, struct device_node *np,
|
||||
u32 ana_rgc3);
|
||||
-int mtk_sgmii_config(struct mtk_sgmii *ss, int id, unsigned int mode,
|
||||
- phy_interface_t interface);
|
||||
-void mtk_sgmii_link_up(struct mtk_sgmii *ss, int id, int speed, int duplex);
|
||||
-void mtk_sgmii_restart_an(struct mtk_eth *eth, int mac_id);
|
||||
|
||||
int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id);
|
||||
int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id);
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
|
||||
@@ -14,14 +14,16 @@
|
||||
|
||||
#include "mtk_eth_soc.h"
|
||||
|
||||
+static struct mtk_pcs *pcs_to_mtk_pcs(struct phylink_pcs *pcs)
|
||||
+{
|
||||
+ return container_of(pcs, struct mtk_pcs, pcs);
|
||||
+}
|
||||
+
|
||||
/* For SGMII interface mode */
|
||||
static int mtk_pcs_setup_mode_an(struct mtk_pcs *mpcs)
|
||||
{
|
||||
unsigned int val;
|
||||
|
||||
- if (!mpcs->regmap)
|
||||
- return -EINVAL;
|
||||
-
|
||||
/* Setup the link timer and QPHY power up inside SGMIISYS */
|
||||
regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER,
|
||||
SGMII_LINK_TIMER_DEFAULT);
|
||||
@@ -50,9 +52,6 @@ static int mtk_pcs_setup_mode_force(stru
|
||||
{
|
||||
unsigned int val;
|
||||
|
||||
- if (!mpcs->regmap)
|
||||
- return -EINVAL;
|
||||
-
|
||||
regmap_read(mpcs->regmap, mpcs->ana_rgc3, &val);
|
||||
val &= ~RG_PHY_SPEED_MASK;
|
||||
if (interface == PHY_INTERFACE_MODE_2500BASEX)
|
||||
@@ -78,10 +77,12 @@ static int mtk_pcs_setup_mode_force(stru
|
||||
return 0;
|
||||
}
|
||||
|
||||
-int mtk_sgmii_config(struct mtk_sgmii *ss, int id, unsigned int mode,
|
||||
- phy_interface_t interface)
|
||||
+static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
|
||||
+ phy_interface_t interface,
|
||||
+ const unsigned long *advertising,
|
||||
+ bool permit_pause_to_mac)
|
||||
{
|
||||
- struct mtk_pcs *mpcs = &ss->pcs[id];
|
||||
+ struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
|
||||
int err = 0;
|
||||
|
||||
/* Setup SGMIISYS with the determined property */
|
||||
@@ -93,22 +94,25 @@ int mtk_sgmii_config(struct mtk_sgmii *s
|
||||
return err;
|
||||
}
|
||||
|
||||
-static void mtk_pcs_restart_an(struct mtk_pcs *mpcs)
|
||||
+static void mtk_pcs_restart_an(struct phylink_pcs *pcs)
|
||||
{
|
||||
+ struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
|
||||
unsigned int val;
|
||||
|
||||
- if (!mpcs->regmap)
|
||||
- return;
|
||||
-
|
||||
regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &val);
|
||||
val |= SGMII_AN_RESTART;
|
||||
regmap_write(mpcs->regmap, SGMSYS_PCS_CONTROL_1, val);
|
||||
}
|
||||
|
||||
-static void mtk_pcs_link_up(struct mtk_pcs *mpcs, int speed, int duplex)
|
||||
+static void mtk_pcs_link_up(struct phylink_pcs *pcs, unsigned int mode,
|
||||
+ phy_interface_t interface, int speed, int duplex)
|
||||
{
|
||||
+ struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
|
||||
unsigned int val;
|
||||
|
||||
+ if (!phy_interface_mode_is_8023z(interface))
|
||||
+ return;
|
||||
+
|
||||
/* SGMII force duplex setting */
|
||||
regmap_read(mpcs->regmap, SGMSYS_SGMII_MODE, &val);
|
||||
val &= ~SGMII_DUPLEX_FULL;
|
||||
@@ -118,11 +122,11 @@ static void mtk_pcs_link_up(struct mtk_p
|
||||
regmap_write(mpcs->regmap, SGMSYS_SGMII_MODE, val);
|
||||
}
|
||||
|
||||
-/* For 1000BASE-X and 2500BASE-X interface modes */
|
||||
-void mtk_sgmii_link_up(struct mtk_sgmii *ss, int id, int speed, int duplex)
|
||||
-{
|
||||
- mtk_pcs_link_up(&ss->pcs[id], speed, duplex);
|
||||
-}
|
||||
+static const struct phylink_pcs_ops mtk_pcs_ops = {
|
||||
+ .pcs_config = mtk_pcs_config,
|
||||
+ .pcs_an_restart = mtk_pcs_restart_an,
|
||||
+ .pcs_link_up = mtk_pcs_link_up,
|
||||
+};
|
||||
|
||||
int mtk_sgmii_init(struct mtk_sgmii *ss, struct device_node *r, u32 ana_rgc3)
|
||||
{
|
||||
@@ -139,18 +143,17 @@ int mtk_sgmii_init(struct mtk_sgmii *ss,
|
||||
of_node_put(np);
|
||||
if (IS_ERR(ss->pcs[i].regmap))
|
||||
return PTR_ERR(ss->pcs[i].regmap);
|
||||
+
|
||||
+ ss->pcs[i].pcs.ops = &mtk_pcs_ops;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
-void mtk_sgmii_restart_an(struct mtk_eth *eth, int mac_id)
|
||||
+struct phylink_pcs *mtk_sgmii_select_pcs(struct mtk_sgmii *ss, int id)
|
||||
{
|
||||
- unsigned int sid;
|
||||
-
|
||||
- /* Decide how GMAC and SGMIISYS be mapped */
|
||||
- sid = (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII)) ?
|
||||
- 0 : mac_id;
|
||||
+ if (!ss->pcs[id].regmap)
|
||||
+ return NULL;
|
||||
|
||||
- mtk_pcs_restart_an(ð->sgmii->pcs[sid]);
|
||||
+ return &ss->pcs[id].pcs;
|
||||
}
|
@ -0,0 +1,106 @@
|
||||
From 505560028b6deb9b4385cf6100f05ca6f4aacaf8 Mon Sep 17 00:00:00 2001
|
||||
From: Vladimir Oltean <vladimir.oltean@nxp.com>
|
||||
Date: Mon, 6 Dec 2021 18:57:49 +0200
|
||||
Subject: [PATCH 01/13] net: dsa: mt7530: iterate using
|
||||
dsa_switch_for_each_user_port in bridging ops
|
||||
|
||||
Avoid repeated calls to dsa_to_port() (some hidden behind dsa_is_user_port
|
||||
and some in plain sight) by keeping two struct dsa_port references: one
|
||||
to the port passed as argument, and another to the other ports of the
|
||||
switch that we're iterating over.
|
||||
|
||||
dsa_to_port(ds, i) gets replaced by other_dp, i gets replaced by
|
||||
other_port which is derived from other_dp->index, dsa_is_user_port is
|
||||
handled by the DSA iterator.
|
||||
|
||||
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 52 +++++++++++++++++++++++-----------------
|
||||
1 file changed, 30 insertions(+), 22 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -1188,27 +1188,31 @@ static int
|
||||
mt7530_port_bridge_join(struct dsa_switch *ds, int port,
|
||||
struct net_device *bridge)
|
||||
{
|
||||
- struct mt7530_priv *priv = ds->priv;
|
||||
+ struct dsa_port *dp = dsa_to_port(ds, port), *other_dp;
|
||||
u32 port_bitmap = BIT(MT7530_CPU_PORT);
|
||||
- int i;
|
||||
+ struct mt7530_priv *priv = ds->priv;
|
||||
|
||||
mutex_lock(&priv->reg_mutex);
|
||||
|
||||
- for (i = 0; i < MT7530_NUM_PORTS; i++) {
|
||||
+ dsa_switch_for_each_user_port(other_dp, ds) {
|
||||
+ int other_port = other_dp->index;
|
||||
+
|
||||
+ if (dp == other_dp)
|
||||
+ continue;
|
||||
+
|
||||
/* Add this port to the port matrix of the other ports in the
|
||||
* same bridge. If the port is disabled, port matrix is kept
|
||||
* and not being setup until the port becomes enabled.
|
||||
*/
|
||||
- if (dsa_is_user_port(ds, i) && i != port) {
|
||||
- if (dsa_to_port(ds, i)->bridge_dev != bridge)
|
||||
- continue;
|
||||
- if (priv->ports[i].enable)
|
||||
- mt7530_set(priv, MT7530_PCR_P(i),
|
||||
- PCR_MATRIX(BIT(port)));
|
||||
- priv->ports[i].pm |= PCR_MATRIX(BIT(port));
|
||||
+ if (other_dp->bridge_dev != bridge)
|
||||
+ continue;
|
||||
|
||||
- port_bitmap |= BIT(i);
|
||||
- }
|
||||
+ if (priv->ports[other_port].enable)
|
||||
+ mt7530_set(priv, MT7530_PCR_P(other_port),
|
||||
+ PCR_MATRIX(BIT(port)));
|
||||
+ priv->ports[other_port].pm |= PCR_MATRIX(BIT(port));
|
||||
+
|
||||
+ port_bitmap |= BIT(other_port);
|
||||
}
|
||||
|
||||
/* Add the all other ports to this port matrix. */
|
||||
@@ -1301,24 +1305,28 @@ static void
|
||||
mt7530_port_bridge_leave(struct dsa_switch *ds, int port,
|
||||
struct net_device *bridge)
|
||||
{
|
||||
+ struct dsa_port *dp = dsa_to_port(ds, port), *other_dp;
|
||||
struct mt7530_priv *priv = ds->priv;
|
||||
- int i;
|
||||
|
||||
mutex_lock(&priv->reg_mutex);
|
||||
|
||||
- for (i = 0; i < MT7530_NUM_PORTS; i++) {
|
||||
+ dsa_switch_for_each_user_port(other_dp, ds) {
|
||||
+ int other_port = other_dp->index;
|
||||
+
|
||||
+ if (dp == other_dp)
|
||||
+ continue;
|
||||
+
|
||||
/* Remove this port from the port matrix of the other ports
|
||||
* in the same bridge. If the port is disabled, port matrix
|
||||
* is kept and not being setup until the port becomes enabled.
|
||||
*/
|
||||
- if (dsa_is_user_port(ds, i) && i != port) {
|
||||
- if (dsa_to_port(ds, i)->bridge_dev != bridge)
|
||||
- continue;
|
||||
- if (priv->ports[i].enable)
|
||||
- mt7530_clear(priv, MT7530_PCR_P(i),
|
||||
- PCR_MATRIX(BIT(port)));
|
||||
- priv->ports[i].pm &= ~PCR_MATRIX(BIT(port));
|
||||
- }
|
||||
+ if (other_dp->bridge_dev != bridge)
|
||||
+ continue;
|
||||
+
|
||||
+ if (priv->ports[other_port].enable)
|
||||
+ mt7530_clear(priv, MT7530_PCR_P(other_port),
|
||||
+ PCR_MATRIX(BIT(port)));
|
||||
+ priv->ports[other_port].pm &= ~PCR_MATRIX(BIT(port));
|
||||
}
|
||||
|
||||
/* Set the cpu port to be the only one in the port matrix of
|
@ -0,0 +1,166 @@
|
||||
From a1da54bcd664fc27169386db966575675ac3ccb0 Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Mon, 11 Apr 2022 10:46:01 +0100
|
||||
Subject: [PATCH 02/13] net: dsa: mt7530: populate supported_interfaces and
|
||||
mac_capabilities
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Populate the supported interfaces and MAC capabilities for mt7530,
|
||||
mt7531 and mt7621 DSA switches. Filling this in will enable phylink
|
||||
to pre-check the PHY interface mode against the the supported
|
||||
interfaces bitmap prior to calling the validate function, and will
|
||||
eventually allow us to convert to using the generic validation.
|
||||
|
||||
Tested-by: Marek Behún <kabel@kernel.org>
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 74 ++++++++++++++++++++++++++++++++++++++++
|
||||
drivers/net/dsa/mt7530.h | 2 ++
|
||||
2 files changed, 76 insertions(+)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -2385,6 +2385,32 @@ mt7531_setup(struct dsa_switch *ds)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static void mt7530_mac_port_get_caps(struct dsa_switch *ds, int port,
|
||||
+ struct phylink_config *config)
|
||||
+{
|
||||
+ switch (port) {
|
||||
+ case 0 ... 4: /* Internal phy */
|
||||
+ __set_bit(PHY_INTERFACE_MODE_GMII,
|
||||
+ config->supported_interfaces);
|
||||
+ break;
|
||||
+
|
||||
+ case 5: /* 2nd cpu port with phy of port 0 or 4 / external phy */
|
||||
+ phy_interface_set_rgmii(config->supported_interfaces);
|
||||
+ __set_bit(PHY_INTERFACE_MODE_MII,
|
||||
+ config->supported_interfaces);
|
||||
+ __set_bit(PHY_INTERFACE_MODE_GMII,
|
||||
+ config->supported_interfaces);
|
||||
+ break;
|
||||
+
|
||||
+ case 6: /* 1st cpu port */
|
||||
+ __set_bit(PHY_INTERFACE_MODE_RGMII,
|
||||
+ config->supported_interfaces);
|
||||
+ __set_bit(PHY_INTERFACE_MODE_TRGMII,
|
||||
+ config->supported_interfaces);
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static bool
|
||||
mt7530_phy_mode_supported(struct dsa_switch *ds, int port,
|
||||
const struct phylink_link_state *state)
|
||||
@@ -2421,6 +2447,37 @@ static bool mt7531_is_rgmii_port(struct
|
||||
return (port == 5) && (priv->p5_intf_sel != P5_INTF_SEL_GMAC5_SGMII);
|
||||
}
|
||||
|
||||
+static void mt7531_mac_port_get_caps(struct dsa_switch *ds, int port,
|
||||
+ struct phylink_config *config)
|
||||
+{
|
||||
+ struct mt7530_priv *priv = ds->priv;
|
||||
+
|
||||
+ switch (port) {
|
||||
+ case 0 ... 4: /* Internal phy */
|
||||
+ __set_bit(PHY_INTERFACE_MODE_GMII,
|
||||
+ config->supported_interfaces);
|
||||
+ break;
|
||||
+
|
||||
+ case 5: /* 2nd cpu port supports either rgmii or sgmii/8023z */
|
||||
+ if (mt7531_is_rgmii_port(priv, port)) {
|
||||
+ phy_interface_set_rgmii(config->supported_interfaces);
|
||||
+ break;
|
||||
+ }
|
||||
+ fallthrough;
|
||||
+
|
||||
+ case 6: /* 1st cpu port supports sgmii/8023z only */
|
||||
+ __set_bit(PHY_INTERFACE_MODE_SGMII,
|
||||
+ config->supported_interfaces);
|
||||
+ __set_bit(PHY_INTERFACE_MODE_1000BASEX,
|
||||
+ config->supported_interfaces);
|
||||
+ __set_bit(PHY_INTERFACE_MODE_2500BASEX,
|
||||
+ config->supported_interfaces);
|
||||
+
|
||||
+ config->mac_capabilities |= MAC_2500FD;
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static bool
|
||||
mt7531_phy_mode_supported(struct dsa_switch *ds, int port,
|
||||
const struct phylink_link_state *state)
|
||||
@@ -2899,6 +2956,18 @@ mt7531_cpu_port_config(struct dsa_switch
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static void mt753x_phylink_get_caps(struct dsa_switch *ds, int port,
|
||||
+ struct phylink_config *config)
|
||||
+{
|
||||
+ struct mt7530_priv *priv = ds->priv;
|
||||
+
|
||||
+ /* This switch only supports full-duplex at 1Gbps */
|
||||
+ config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
|
||||
+ MAC_10 | MAC_100 | MAC_1000FD;
|
||||
+
|
||||
+ priv->info->mac_port_get_caps(ds, port, config);
|
||||
+}
|
||||
+
|
||||
static void
|
||||
mt7530_mac_port_validate(struct dsa_switch *ds, int port,
|
||||
unsigned long *supported)
|
||||
@@ -3134,6 +3203,7 @@ static const struct dsa_switch_ops mt753
|
||||
.port_vlan_del = mt7530_port_vlan_del,
|
||||
.port_mirror_add = mt753x_port_mirror_add,
|
||||
.port_mirror_del = mt753x_port_mirror_del,
|
||||
+ .phylink_get_caps = mt753x_phylink_get_caps,
|
||||
.phylink_validate = mt753x_phylink_validate,
|
||||
.phylink_mac_link_state = mt753x_phylink_mac_link_state,
|
||||
.phylink_mac_config = mt753x_phylink_mac_config,
|
||||
@@ -3151,6 +3221,7 @@ static const struct mt753x_info mt753x_t
|
||||
.phy_read = mt7530_phy_read,
|
||||
.phy_write = mt7530_phy_write,
|
||||
.pad_setup = mt7530_pad_clk_setup,
|
||||
+ .mac_port_get_caps = mt7530_mac_port_get_caps,
|
||||
.phy_mode_supported = mt7530_phy_mode_supported,
|
||||
.mac_port_validate = mt7530_mac_port_validate,
|
||||
.mac_port_get_state = mt7530_phylink_mac_link_state,
|
||||
@@ -3162,6 +3233,7 @@ static const struct mt753x_info mt753x_t
|
||||
.phy_read = mt7530_phy_read,
|
||||
.phy_write = mt7530_phy_write,
|
||||
.pad_setup = mt7530_pad_clk_setup,
|
||||
+ .mac_port_get_caps = mt7530_mac_port_get_caps,
|
||||
.phy_mode_supported = mt7530_phy_mode_supported,
|
||||
.mac_port_validate = mt7530_mac_port_validate,
|
||||
.mac_port_get_state = mt7530_phylink_mac_link_state,
|
||||
@@ -3174,6 +3246,7 @@ static const struct mt753x_info mt753x_t
|
||||
.phy_write = mt7531_ind_phy_write,
|
||||
.pad_setup = mt7531_pad_setup,
|
||||
.cpu_port_config = mt7531_cpu_port_config,
|
||||
+ .mac_port_get_caps = mt7531_mac_port_get_caps,
|
||||
.phy_mode_supported = mt7531_phy_mode_supported,
|
||||
.mac_port_validate = mt7531_mac_port_validate,
|
||||
.mac_port_get_state = mt7531_phylink_mac_link_state,
|
||||
@@ -3236,6 +3309,7 @@ mt7530_probe(struct mdio_device *mdiodev
|
||||
*/
|
||||
if (!priv->info->sw_setup || !priv->info->pad_setup ||
|
||||
!priv->info->phy_read || !priv->info->phy_write ||
|
||||
+ !priv->info->mac_port_get_caps ||
|
||||
!priv->info->phy_mode_supported ||
|
||||
!priv->info->mac_port_validate ||
|
||||
!priv->info->mac_port_get_state || !priv->info->mac_port_config)
|
||||
--- a/drivers/net/dsa/mt7530.h
|
||||
+++ b/drivers/net/dsa/mt7530.h
|
||||
@@ -769,6 +769,8 @@ struct mt753x_info {
|
||||
int (*phy_write)(struct mt7530_priv *priv, int port, int regnum, u16 val);
|
||||
int (*pad_setup)(struct dsa_switch *ds, phy_interface_t interface);
|
||||
int (*cpu_port_config)(struct dsa_switch *ds, int port);
|
||||
+ void (*mac_port_get_caps)(struct dsa_switch *ds, int port,
|
||||
+ struct phylink_config *config);
|
||||
bool (*phy_mode_supported)(struct dsa_switch *ds, int port,
|
||||
const struct phylink_link_state *state);
|
||||
void (*mac_port_validate)(struct dsa_switch *ds, int port,
|
@ -0,0 +1,172 @@
|
||||
From e3f6719e2269868ca129b05da50cd55786848954 Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Mon, 11 Apr 2022 10:46:06 +0100
|
||||
Subject: [PATCH 03/13] net: dsa: mt7530: remove interface checks
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
As phylink checks the interface mode against the supported_interfaces
|
||||
bitmap, we no longer need to validate the interface mode, nor handle
|
||||
PHY_INTERFACE_MODE_NA in the validation function. Remove these to
|
||||
simplify the implementation.
|
||||
|
||||
Tested-by: Marek Behún <kabel@kernel.org>
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 82 ----------------------------------------
|
||||
drivers/net/dsa/mt7530.h | 2 -
|
||||
2 files changed, 84 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -2411,37 +2411,6 @@ static void mt7530_mac_port_get_caps(str
|
||||
}
|
||||
}
|
||||
|
||||
-static bool
|
||||
-mt7530_phy_mode_supported(struct dsa_switch *ds, int port,
|
||||
- const struct phylink_link_state *state)
|
||||
-{
|
||||
- struct mt7530_priv *priv = ds->priv;
|
||||
-
|
||||
- switch (port) {
|
||||
- case 0 ... 4: /* Internal phy */
|
||||
- if (state->interface != PHY_INTERFACE_MODE_GMII)
|
||||
- return false;
|
||||
- break;
|
||||
- case 5: /* 2nd cpu port with phy of port 0 or 4 / external phy */
|
||||
- if (!phy_interface_mode_is_rgmii(state->interface) &&
|
||||
- state->interface != PHY_INTERFACE_MODE_MII &&
|
||||
- state->interface != PHY_INTERFACE_MODE_GMII)
|
||||
- return false;
|
||||
- break;
|
||||
- case 6: /* 1st cpu port */
|
||||
- if (state->interface != PHY_INTERFACE_MODE_RGMII &&
|
||||
- state->interface != PHY_INTERFACE_MODE_TRGMII)
|
||||
- return false;
|
||||
- break;
|
||||
- default:
|
||||
- dev_err(priv->dev, "%s: unsupported port: %i\n", __func__,
|
||||
- port);
|
||||
- return false;
|
||||
- }
|
||||
-
|
||||
- return true;
|
||||
-}
|
||||
-
|
||||
static bool mt7531_is_rgmii_port(struct mt7530_priv *priv, u32 port)
|
||||
{
|
||||
return (port == 5) && (priv->p5_intf_sel != P5_INTF_SEL_GMAC5_SGMII);
|
||||
@@ -2478,44 +2447,6 @@ static void mt7531_mac_port_get_caps(str
|
||||
}
|
||||
}
|
||||
|
||||
-static bool
|
||||
-mt7531_phy_mode_supported(struct dsa_switch *ds, int port,
|
||||
- const struct phylink_link_state *state)
|
||||
-{
|
||||
- struct mt7530_priv *priv = ds->priv;
|
||||
-
|
||||
- switch (port) {
|
||||
- case 0 ... 4: /* Internal phy */
|
||||
- if (state->interface != PHY_INTERFACE_MODE_GMII)
|
||||
- return false;
|
||||
- break;
|
||||
- case 5: /* 2nd cpu port supports either rgmii or sgmii/8023z */
|
||||
- if (mt7531_is_rgmii_port(priv, port))
|
||||
- return phy_interface_mode_is_rgmii(state->interface);
|
||||
- fallthrough;
|
||||
- case 6: /* 1st cpu port supports sgmii/8023z only */
|
||||
- if (state->interface != PHY_INTERFACE_MODE_SGMII &&
|
||||
- !phy_interface_mode_is_8023z(state->interface))
|
||||
- return false;
|
||||
- break;
|
||||
- default:
|
||||
- dev_err(priv->dev, "%s: unsupported port: %i\n", __func__,
|
||||
- port);
|
||||
- return false;
|
||||
- }
|
||||
-
|
||||
- return true;
|
||||
-}
|
||||
-
|
||||
-static bool
|
||||
-mt753x_phy_mode_supported(struct dsa_switch *ds, int port,
|
||||
- const struct phylink_link_state *state)
|
||||
-{
|
||||
- struct mt7530_priv *priv = ds->priv;
|
||||
-
|
||||
- return priv->info->phy_mode_supported(ds, port, state);
|
||||
-}
|
||||
-
|
||||
static int
|
||||
mt753x_pad_setup(struct dsa_switch *ds, const struct phylink_link_state *state)
|
||||
{
|
||||
@@ -2770,9 +2701,6 @@ mt753x_phylink_mac_config(struct dsa_swi
|
||||
struct mt7530_priv *priv = ds->priv;
|
||||
u32 mcr_cur, mcr_new;
|
||||
|
||||
- if (!mt753x_phy_mode_supported(ds, port, state))
|
||||
- goto unsupported;
|
||||
-
|
||||
switch (port) {
|
||||
case 0 ... 4: /* Internal phy */
|
||||
if (state->interface != PHY_INTERFACE_MODE_GMII)
|
||||
@@ -2990,12 +2918,6 @@ mt753x_phylink_validate(struct dsa_switc
|
||||
__ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
|
||||
struct mt7530_priv *priv = ds->priv;
|
||||
|
||||
- if (state->interface != PHY_INTERFACE_MODE_NA &&
|
||||
- !mt753x_phy_mode_supported(ds, port, state)) {
|
||||
- linkmode_zero(supported);
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
phylink_set_port_modes(mask);
|
||||
|
||||
if (state->interface != PHY_INTERFACE_MODE_TRGMII &&
|
||||
@@ -3222,7 +3144,6 @@ static const struct mt753x_info mt753x_t
|
||||
.phy_write = mt7530_phy_write,
|
||||
.pad_setup = mt7530_pad_clk_setup,
|
||||
.mac_port_get_caps = mt7530_mac_port_get_caps,
|
||||
- .phy_mode_supported = mt7530_phy_mode_supported,
|
||||
.mac_port_validate = mt7530_mac_port_validate,
|
||||
.mac_port_get_state = mt7530_phylink_mac_link_state,
|
||||
.mac_port_config = mt7530_mac_config,
|
||||
@@ -3234,7 +3155,6 @@ static const struct mt753x_info mt753x_t
|
||||
.phy_write = mt7530_phy_write,
|
||||
.pad_setup = mt7530_pad_clk_setup,
|
||||
.mac_port_get_caps = mt7530_mac_port_get_caps,
|
||||
- .phy_mode_supported = mt7530_phy_mode_supported,
|
||||
.mac_port_validate = mt7530_mac_port_validate,
|
||||
.mac_port_get_state = mt7530_phylink_mac_link_state,
|
||||
.mac_port_config = mt7530_mac_config,
|
||||
@@ -3247,7 +3167,6 @@ static const struct mt753x_info mt753x_t
|
||||
.pad_setup = mt7531_pad_setup,
|
||||
.cpu_port_config = mt7531_cpu_port_config,
|
||||
.mac_port_get_caps = mt7531_mac_port_get_caps,
|
||||
- .phy_mode_supported = mt7531_phy_mode_supported,
|
||||
.mac_port_validate = mt7531_mac_port_validate,
|
||||
.mac_port_get_state = mt7531_phylink_mac_link_state,
|
||||
.mac_port_config = mt7531_mac_config,
|
||||
@@ -3310,7 +3229,6 @@ mt7530_probe(struct mdio_device *mdiodev
|
||||
if (!priv->info->sw_setup || !priv->info->pad_setup ||
|
||||
!priv->info->phy_read || !priv->info->phy_write ||
|
||||
!priv->info->mac_port_get_caps ||
|
||||
- !priv->info->phy_mode_supported ||
|
||||
!priv->info->mac_port_validate ||
|
||||
!priv->info->mac_port_get_state || !priv->info->mac_port_config)
|
||||
return -EINVAL;
|
||||
--- a/drivers/net/dsa/mt7530.h
|
||||
+++ b/drivers/net/dsa/mt7530.h
|
||||
@@ -771,8 +771,6 @@ struct mt753x_info {
|
||||
int (*cpu_port_config)(struct dsa_switch *ds, int port);
|
||||
void (*mac_port_get_caps)(struct dsa_switch *ds, int port,
|
||||
struct phylink_config *config);
|
||||
- bool (*phy_mode_supported)(struct dsa_switch *ds, int port,
|
||||
- const struct phylink_link_state *state);
|
||||
void (*mac_port_validate)(struct dsa_switch *ds, int port,
|
||||
unsigned long *supported);
|
||||
int (*mac_port_get_state)(struct dsa_switch *ds, int port,
|
@ -0,0 +1,34 @@
|
||||
From 58344a3b85f1bd5ffddfc2c11f6f2bf688b5f990 Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Mon, 11 Apr 2022 10:46:12 +0100
|
||||
Subject: [PATCH 04/13] net: dsa: mt7530: drop use of
|
||||
phylink_helper_basex_speed()
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Now that we have a better method to select SFP interface modes, we
|
||||
no longer need to use phylink_helper_basex_speed() in a driver's
|
||||
validation function.
|
||||
|
||||
Tested-by: Marek Behún <kabel@kernel.org>
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 5 -----
|
||||
1 file changed, 5 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -2942,11 +2942,6 @@ mt753x_phylink_validate(struct dsa_switc
|
||||
|
||||
linkmode_and(supported, supported, mask);
|
||||
linkmode_and(state->advertising, state->advertising, mask);
|
||||
-
|
||||
- /* We can only operate at 2500BaseX or 1000BaseX. If requested
|
||||
- * to advertise both, only report advertising at 2500BaseX.
|
||||
- */
|
||||
- phylink_helper_basex_speed(state);
|
||||
}
|
||||
|
||||
static int
|
@ -0,0 +1,86 @@
|
||||
From 3c1d788a62dc648d1846049b66119ebb69dedd52 Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Mon, 11 Apr 2022 10:46:17 +0100
|
||||
Subject: [PATCH 05/13] net: dsa: mt7530: only indicate linkmodes that can be
|
||||
supported
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Now that mt7530 is not using the basex helper, it becomes unnecessary to
|
||||
indicate support for both 1000baseX and 2500baseX when one of the 803.3z
|
||||
PHY interface modes is being selected. Ensure that the driver indicates
|
||||
only those linkmodes that can actually be supported by the PHY interface
|
||||
mode.
|
||||
|
||||
Tested-by: Marek Behún <kabel@kernel.org>
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 12 ++++++++----
|
||||
drivers/net/dsa/mt7530.h | 1 +
|
||||
2 files changed, 9 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -2518,12 +2518,13 @@ static int mt7531_rgmii_setup(struct mt7
|
||||
}
|
||||
|
||||
static void mt7531_sgmii_validate(struct mt7530_priv *priv, int port,
|
||||
+ phy_interface_t interface,
|
||||
unsigned long *supported)
|
||||
{
|
||||
/* Port5 supports ethier RGMII or SGMII.
|
||||
* Port6 supports SGMII only.
|
||||
*/
|
||||
- if (port == 6) {
|
||||
+ if (port == 6 && interface == PHY_INTERFACE_MODE_2500BASEX) {
|
||||
phylink_set(supported, 2500baseX_Full);
|
||||
phylink_set(supported, 2500baseT_Full);
|
||||
}
|
||||
@@ -2898,16 +2899,18 @@ static void mt753x_phylink_get_caps(stru
|
||||
|
||||
static void
|
||||
mt7530_mac_port_validate(struct dsa_switch *ds, int port,
|
||||
+ phy_interface_t interface,
|
||||
unsigned long *supported)
|
||||
{
|
||||
}
|
||||
|
||||
static void mt7531_mac_port_validate(struct dsa_switch *ds, int port,
|
||||
+ phy_interface_t interface,
|
||||
unsigned long *supported)
|
||||
{
|
||||
struct mt7530_priv *priv = ds->priv;
|
||||
|
||||
- mt7531_sgmii_validate(priv, port, supported);
|
||||
+ mt7531_sgmii_validate(priv, port, interface, supported);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2930,12 +2933,13 @@ mt753x_phylink_validate(struct dsa_switc
|
||||
}
|
||||
|
||||
/* This switch only supports 1G full-duplex. */
|
||||
- if (state->interface != PHY_INTERFACE_MODE_MII) {
|
||||
+ if (state->interface != PHY_INTERFACE_MODE_MII &&
|
||||
+ state->interface != PHY_INTERFACE_MODE_2500BASEX) {
|
||||
phylink_set(mask, 1000baseT_Full);
|
||||
phylink_set(mask, 1000baseX_Full);
|
||||
}
|
||||
|
||||
- priv->info->mac_port_validate(ds, port, mask);
|
||||
+ priv->info->mac_port_validate(ds, port, state->interface, mask);
|
||||
|
||||
phylink_set(mask, Pause);
|
||||
phylink_set(mask, Asym_Pause);
|
||||
--- a/drivers/net/dsa/mt7530.h
|
||||
+++ b/drivers/net/dsa/mt7530.h
|
||||
@@ -772,6 +772,7 @@ struct mt753x_info {
|
||||
void (*mac_port_get_caps)(struct dsa_switch *ds, int port,
|
||||
struct phylink_config *config);
|
||||
void (*mac_port_validate)(struct dsa_switch *ds, int port,
|
||||
+ phy_interface_t interface,
|
||||
unsigned long *supported);
|
||||
int (*mac_port_get_state)(struct dsa_switch *ds, int port,
|
||||
struct phylink_link_state *state);
|
@ -0,0 +1,131 @@
|
||||
From 1c2211cb15dd3957fb26c0e1615eceb5db851ad6 Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Mon, 11 Apr 2022 10:46:22 +0100
|
||||
Subject: [PATCH 06/13] net: dsa: mt7530: switch to use phylink_get_linkmodes()
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Switch mt7530 to use phylink_get_linkmodes() to generate the ethtool
|
||||
linkmodes that can be supported. We are unable to use the generic
|
||||
helper for this as pause modes are dependent on the interface as
|
||||
the Autoneg bit depends on the interface mode.
|
||||
|
||||
Tested-by: Marek Behún <kabel@kernel.org>
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 57 ++++------------------------------------
|
||||
1 file changed, 5 insertions(+), 52 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -2517,19 +2517,6 @@ static int mt7531_rgmii_setup(struct mt7
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static void mt7531_sgmii_validate(struct mt7530_priv *priv, int port,
|
||||
- phy_interface_t interface,
|
||||
- unsigned long *supported)
|
||||
-{
|
||||
- /* Port5 supports ethier RGMII or SGMII.
|
||||
- * Port6 supports SGMII only.
|
||||
- */
|
||||
- if (port == 6 && interface == PHY_INTERFACE_MODE_2500BASEX) {
|
||||
- phylink_set(supported, 2500baseX_Full);
|
||||
- phylink_set(supported, 2500baseT_Full);
|
||||
- }
|
||||
-}
|
||||
-
|
||||
static void
|
||||
mt7531_sgmii_link_up_force(struct dsa_switch *ds, int port,
|
||||
unsigned int mode, phy_interface_t interface,
|
||||
@@ -2898,51 +2885,21 @@ static void mt753x_phylink_get_caps(stru
|
||||
}
|
||||
|
||||
static void
|
||||
-mt7530_mac_port_validate(struct dsa_switch *ds, int port,
|
||||
- phy_interface_t interface,
|
||||
- unsigned long *supported)
|
||||
-{
|
||||
-}
|
||||
-
|
||||
-static void mt7531_mac_port_validate(struct dsa_switch *ds, int port,
|
||||
- phy_interface_t interface,
|
||||
- unsigned long *supported)
|
||||
-{
|
||||
- struct mt7530_priv *priv = ds->priv;
|
||||
-
|
||||
- mt7531_sgmii_validate(priv, port, interface, supported);
|
||||
-}
|
||||
-
|
||||
-static void
|
||||
mt753x_phylink_validate(struct dsa_switch *ds, int port,
|
||||
unsigned long *supported,
|
||||
struct phylink_link_state *state)
|
||||
{
|
||||
__ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
|
||||
- struct mt7530_priv *priv = ds->priv;
|
||||
+ u32 caps;
|
||||
+
|
||||
+ caps = dsa_to_port(ds, port)->pl_config.mac_capabilities;
|
||||
|
||||
phylink_set_port_modes(mask);
|
||||
+ phylink_get_linkmodes(mask, state->interface, caps);
|
||||
|
||||
if (state->interface != PHY_INTERFACE_MODE_TRGMII &&
|
||||
- !phy_interface_mode_is_8023z(state->interface)) {
|
||||
- phylink_set(mask, 10baseT_Half);
|
||||
- phylink_set(mask, 10baseT_Full);
|
||||
- phylink_set(mask, 100baseT_Half);
|
||||
- phylink_set(mask, 100baseT_Full);
|
||||
+ !phy_interface_mode_is_8023z(state->interface))
|
||||
phylink_set(mask, Autoneg);
|
||||
- }
|
||||
-
|
||||
- /* This switch only supports 1G full-duplex. */
|
||||
- if (state->interface != PHY_INTERFACE_MODE_MII &&
|
||||
- state->interface != PHY_INTERFACE_MODE_2500BASEX) {
|
||||
- phylink_set(mask, 1000baseT_Full);
|
||||
- phylink_set(mask, 1000baseX_Full);
|
||||
- }
|
||||
-
|
||||
- priv->info->mac_port_validate(ds, port, state->interface, mask);
|
||||
-
|
||||
- phylink_set(mask, Pause);
|
||||
- phylink_set(mask, Asym_Pause);
|
||||
|
||||
linkmode_and(supported, supported, mask);
|
||||
linkmode_and(state->advertising, state->advertising, mask);
|
||||
@@ -3143,7 +3100,6 @@ static const struct mt753x_info mt753x_t
|
||||
.phy_write = mt7530_phy_write,
|
||||
.pad_setup = mt7530_pad_clk_setup,
|
||||
.mac_port_get_caps = mt7530_mac_port_get_caps,
|
||||
- .mac_port_validate = mt7530_mac_port_validate,
|
||||
.mac_port_get_state = mt7530_phylink_mac_link_state,
|
||||
.mac_port_config = mt7530_mac_config,
|
||||
},
|
||||
@@ -3154,7 +3110,6 @@ static const struct mt753x_info mt753x_t
|
||||
.phy_write = mt7530_phy_write,
|
||||
.pad_setup = mt7530_pad_clk_setup,
|
||||
.mac_port_get_caps = mt7530_mac_port_get_caps,
|
||||
- .mac_port_validate = mt7530_mac_port_validate,
|
||||
.mac_port_get_state = mt7530_phylink_mac_link_state,
|
||||
.mac_port_config = mt7530_mac_config,
|
||||
},
|
||||
@@ -3166,7 +3121,6 @@ static const struct mt753x_info mt753x_t
|
||||
.pad_setup = mt7531_pad_setup,
|
||||
.cpu_port_config = mt7531_cpu_port_config,
|
||||
.mac_port_get_caps = mt7531_mac_port_get_caps,
|
||||
- .mac_port_validate = mt7531_mac_port_validate,
|
||||
.mac_port_get_state = mt7531_phylink_mac_link_state,
|
||||
.mac_port_config = mt7531_mac_config,
|
||||
.mac_pcs_an_restart = mt7531_sgmii_restart_an,
|
||||
@@ -3228,7 +3182,6 @@ mt7530_probe(struct mdio_device *mdiodev
|
||||
if (!priv->info->sw_setup || !priv->info->pad_setup ||
|
||||
!priv->info->phy_read || !priv->info->phy_write ||
|
||||
!priv->info->mac_port_get_caps ||
|
||||
- !priv->info->mac_port_validate ||
|
||||
!priv->info->mac_port_get_state || !priv->info->mac_port_config)
|
||||
return -EINVAL;
|
||||
|
@ -0,0 +1,385 @@
|
||||
From fd993fd59d96d5e2d5972ec4ca1f9651025c987b Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Mon, 11 Apr 2022 10:46:27 +0100
|
||||
Subject: [PATCH 07/13] net: dsa: mt7530: partially convert to phylink_pcs
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Partially convert the mt7530 driver to use phylink's PCS support. This
|
||||
is a partial implementation as we don't move anything into the
|
||||
pcs_config method yet - this driver supports SGMII or 1000BASE-X
|
||||
without in-band.
|
||||
|
||||
Tested-by: Marek Behún <kabel@kernel.org>
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 144 +++++++++++++++++++++++----------------
|
||||
drivers/net/dsa/mt7530.h | 21 +++---
|
||||
2 files changed, 95 insertions(+), 70 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -24,6 +24,11 @@
|
||||
|
||||
#include "mt7530.h"
|
||||
|
||||
+static struct mt753x_pcs *pcs_to_mt753x_pcs(struct phylink_pcs *pcs)
|
||||
+{
|
||||
+ return container_of(pcs, struct mt753x_pcs, pcs);
|
||||
+}
|
||||
+
|
||||
/* String, offset, and register size in bytes if different from 4 bytes */
|
||||
static const struct mt7530_mib_desc mt7530_mib[] = {
|
||||
MIB_DESC(1, 0x00, "TxDrop"),
|
||||
@@ -2517,12 +2522,11 @@ static int mt7531_rgmii_setup(struct mt7
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static void
|
||||
-mt7531_sgmii_link_up_force(struct dsa_switch *ds, int port,
|
||||
- unsigned int mode, phy_interface_t interface,
|
||||
- int speed, int duplex)
|
||||
+static void mt7531_pcs_link_up(struct phylink_pcs *pcs, unsigned int mode,
|
||||
+ phy_interface_t interface, int speed, int duplex)
|
||||
{
|
||||
- struct mt7530_priv *priv = ds->priv;
|
||||
+ struct mt7530_priv *priv = pcs_to_mt753x_pcs(pcs)->priv;
|
||||
+ int port = pcs_to_mt753x_pcs(pcs)->port;
|
||||
unsigned int val;
|
||||
|
||||
/* For adjusting speed and duplex of SGMII force mode. */
|
||||
@@ -2548,6 +2552,9 @@ mt7531_sgmii_link_up_force(struct dsa_sw
|
||||
|
||||
/* MT7531 SGMII 1G force mode can only work in full duplex mode,
|
||||
* no matter MT7531_SGMII_FORCE_HALF_DUPLEX is set or not.
|
||||
+ *
|
||||
+ * The speed check is unnecessary as the MAC capabilities apply
|
||||
+ * this restriction. --rmk
|
||||
*/
|
||||
if ((speed == SPEED_10 || speed == SPEED_100) &&
|
||||
duplex != DUPLEX_FULL)
|
||||
@@ -2623,9 +2630,10 @@ static int mt7531_sgmii_setup_mode_an(st
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static void mt7531_sgmii_restart_an(struct dsa_switch *ds, int port)
|
||||
+static void mt7531_pcs_an_restart(struct phylink_pcs *pcs)
|
||||
{
|
||||
- struct mt7530_priv *priv = ds->priv;
|
||||
+ struct mt7530_priv *priv = pcs_to_mt753x_pcs(pcs)->priv;
|
||||
+ int port = pcs_to_mt753x_pcs(pcs)->port;
|
||||
u32 val;
|
||||
|
||||
/* Only restart AN when AN is enabled */
|
||||
@@ -2682,6 +2690,24 @@ mt753x_mac_config(struct dsa_switch *ds,
|
||||
return priv->info->mac_port_config(ds, port, mode, state->interface);
|
||||
}
|
||||
|
||||
+static struct phylink_pcs *
|
||||
+mt753x_phylink_mac_select_pcs(struct dsa_switch *ds, int port,
|
||||
+ phy_interface_t interface)
|
||||
+{
|
||||
+ struct mt7530_priv *priv = ds->priv;
|
||||
+
|
||||
+ switch (interface) {
|
||||
+ case PHY_INTERFACE_MODE_TRGMII:
|
||||
+ case PHY_INTERFACE_MODE_SGMII:
|
||||
+ case PHY_INTERFACE_MODE_1000BASEX:
|
||||
+ case PHY_INTERFACE_MODE_2500BASEX:
|
||||
+ return &priv->pcs[port].pcs;
|
||||
+
|
||||
+ default:
|
||||
+ return NULL;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void
|
||||
mt753x_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
|
||||
const struct phylink_link_state *state)
|
||||
@@ -2743,17 +2769,6 @@ unsupported:
|
||||
mt7530_write(priv, MT7530_PMCR_P(port), mcr_new);
|
||||
}
|
||||
|
||||
-static void
|
||||
-mt753x_phylink_mac_an_restart(struct dsa_switch *ds, int port)
|
||||
-{
|
||||
- struct mt7530_priv *priv = ds->priv;
|
||||
-
|
||||
- if (!priv->info->mac_pcs_an_restart)
|
||||
- return;
|
||||
-
|
||||
- priv->info->mac_pcs_an_restart(ds, port);
|
||||
-}
|
||||
-
|
||||
static void mt753x_phylink_mac_link_down(struct dsa_switch *ds, int port,
|
||||
unsigned int mode,
|
||||
phy_interface_t interface)
|
||||
@@ -2763,16 +2778,13 @@ static void mt753x_phylink_mac_link_down
|
||||
mt7530_clear(priv, MT7530_PMCR_P(port), PMCR_LINK_SETTINGS_MASK);
|
||||
}
|
||||
|
||||
-static void mt753x_mac_pcs_link_up(struct dsa_switch *ds, int port,
|
||||
- unsigned int mode, phy_interface_t interface,
|
||||
- int speed, int duplex)
|
||||
+static void mt753x_phylink_pcs_link_up(struct phylink_pcs *pcs,
|
||||
+ unsigned int mode,
|
||||
+ phy_interface_t interface,
|
||||
+ int speed, int duplex)
|
||||
{
|
||||
- struct mt7530_priv *priv = ds->priv;
|
||||
-
|
||||
- if (!priv->info->mac_pcs_link_up)
|
||||
- return;
|
||||
-
|
||||
- priv->info->mac_pcs_link_up(ds, port, mode, interface, speed, duplex);
|
||||
+ if (pcs->ops->pcs_link_up)
|
||||
+ pcs->ops->pcs_link_up(pcs, mode, interface, speed, duplex);
|
||||
}
|
||||
|
||||
static void mt753x_phylink_mac_link_up(struct dsa_switch *ds, int port,
|
||||
@@ -2785,8 +2797,6 @@ static void mt753x_phylink_mac_link_up(s
|
||||
struct mt7530_priv *priv = ds->priv;
|
||||
u32 mcr;
|
||||
|
||||
- mt753x_mac_pcs_link_up(ds, port, mode, interface, speed, duplex);
|
||||
-
|
||||
mcr = PMCR_RX_EN | PMCR_TX_EN | PMCR_FORCE_LNK;
|
||||
|
||||
/* MT753x MAC works in 1G full duplex mode for all up-clocked
|
||||
@@ -2866,6 +2876,8 @@ mt7531_cpu_port_config(struct dsa_switch
|
||||
return ret;
|
||||
mt7530_write(priv, MT7530_PMCR_P(port),
|
||||
PMCR_CPU_PORT_SETTING(priv->id));
|
||||
+ mt753x_phylink_pcs_link_up(&priv->pcs[port].pcs, MLO_AN_FIXED,
|
||||
+ interface, speed, DUPLEX_FULL);
|
||||
mt753x_phylink_mac_link_up(ds, port, MLO_AN_FIXED, interface, NULL,
|
||||
speed, DUPLEX_FULL, true, true);
|
||||
|
||||
@@ -2905,16 +2917,13 @@ mt753x_phylink_validate(struct dsa_switc
|
||||
linkmode_and(state->advertising, state->advertising, mask);
|
||||
}
|
||||
|
||||
-static int
|
||||
-mt7530_phylink_mac_link_state(struct dsa_switch *ds, int port,
|
||||
- struct phylink_link_state *state)
|
||||
+static void mt7530_pcs_get_state(struct phylink_pcs *pcs,
|
||||
+ struct phylink_link_state *state)
|
||||
{
|
||||
- struct mt7530_priv *priv = ds->priv;
|
||||
+ struct mt7530_priv *priv = pcs_to_mt753x_pcs(pcs)->priv;
|
||||
+ int port = pcs_to_mt753x_pcs(pcs)->port;
|
||||
u32 pmsr;
|
||||
|
||||
- if (port < 0 || port >= MT7530_NUM_PORTS)
|
||||
- return -EINVAL;
|
||||
-
|
||||
pmsr = mt7530_read(priv, MT7530_PMSR_P(port));
|
||||
|
||||
state->link = (pmsr & PMSR_LINK);
|
||||
@@ -2941,8 +2950,6 @@ mt7530_phylink_mac_link_state(struct dsa
|
||||
state->pause |= MLO_PAUSE_RX;
|
||||
if (pmsr & PMSR_TX_FC)
|
||||
state->pause |= MLO_PAUSE_TX;
|
||||
-
|
||||
- return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -2984,32 +2991,49 @@ mt7531_sgmii_pcs_get_state_an(struct mt7
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int
|
||||
-mt7531_phylink_mac_link_state(struct dsa_switch *ds, int port,
|
||||
- struct phylink_link_state *state)
|
||||
+static void mt7531_pcs_get_state(struct phylink_pcs *pcs,
|
||||
+ struct phylink_link_state *state)
|
||||
{
|
||||
- struct mt7530_priv *priv = ds->priv;
|
||||
+ struct mt7530_priv *priv = pcs_to_mt753x_pcs(pcs)->priv;
|
||||
+ int port = pcs_to_mt753x_pcs(pcs)->port;
|
||||
|
||||
if (state->interface == PHY_INTERFACE_MODE_SGMII)
|
||||
- return mt7531_sgmii_pcs_get_state_an(priv, port, state);
|
||||
-
|
||||
- return -EOPNOTSUPP;
|
||||
+ mt7531_sgmii_pcs_get_state_an(priv, port, state);
|
||||
+ else
|
||||
+ state->link = false;
|
||||
}
|
||||
|
||||
-static int
|
||||
-mt753x_phylink_mac_link_state(struct dsa_switch *ds, int port,
|
||||
- struct phylink_link_state *state)
|
||||
+static int mt753x_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
|
||||
+ phy_interface_t interface,
|
||||
+ const unsigned long *advertising,
|
||||
+ bool permit_pause_to_mac)
|
||||
{
|
||||
- struct mt7530_priv *priv = ds->priv;
|
||||
+ return 0;
|
||||
+}
|
||||
|
||||
- return priv->info->mac_port_get_state(ds, port, state);
|
||||
+static void mt7530_pcs_an_restart(struct phylink_pcs *pcs)
|
||||
+{
|
||||
}
|
||||
|
||||
+static const struct phylink_pcs_ops mt7530_pcs_ops = {
|
||||
+ .pcs_get_state = mt7530_pcs_get_state,
|
||||
+ .pcs_config = mt753x_pcs_config,
|
||||
+ .pcs_an_restart = mt7530_pcs_an_restart,
|
||||
+};
|
||||
+
|
||||
+static const struct phylink_pcs_ops mt7531_pcs_ops = {
|
||||
+ .pcs_get_state = mt7531_pcs_get_state,
|
||||
+ .pcs_config = mt753x_pcs_config,
|
||||
+ .pcs_an_restart = mt7531_pcs_an_restart,
|
||||
+ .pcs_link_up = mt7531_pcs_link_up,
|
||||
+};
|
||||
+
|
||||
static int
|
||||
mt753x_setup(struct dsa_switch *ds)
|
||||
{
|
||||
struct mt7530_priv *priv = ds->priv;
|
||||
int ret = priv->info->sw_setup(ds);
|
||||
+ int i;
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
@@ -3022,6 +3046,13 @@ mt753x_setup(struct dsa_switch *ds)
|
||||
if (ret && priv->irq)
|
||||
mt7530_free_irq_common(priv);
|
||||
|
||||
+ /* Initialise the PCS devices */
|
||||
+ for (i = 0; i < priv->ds->num_ports; i++) {
|
||||
+ priv->pcs[i].pcs.ops = priv->info->pcs_ops;
|
||||
+ priv->pcs[i].priv = priv;
|
||||
+ priv->pcs[i].port = i;
|
||||
+ }
|
||||
+
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -3083,9 +3114,8 @@ static const struct dsa_switch_ops mt753
|
||||
.port_mirror_del = mt753x_port_mirror_del,
|
||||
.phylink_get_caps = mt753x_phylink_get_caps,
|
||||
.phylink_validate = mt753x_phylink_validate,
|
||||
- .phylink_mac_link_state = mt753x_phylink_mac_link_state,
|
||||
+ .phylink_mac_select_pcs = mt753x_phylink_mac_select_pcs,
|
||||
.phylink_mac_config = mt753x_phylink_mac_config,
|
||||
- .phylink_mac_an_restart = mt753x_phylink_mac_an_restart,
|
||||
.phylink_mac_link_down = mt753x_phylink_mac_link_down,
|
||||
.phylink_mac_link_up = mt753x_phylink_mac_link_up,
|
||||
.get_mac_eee = mt753x_get_mac_eee,
|
||||
@@ -3095,36 +3125,34 @@ static const struct dsa_switch_ops mt753
|
||||
static const struct mt753x_info mt753x_table[] = {
|
||||
[ID_MT7621] = {
|
||||
.id = ID_MT7621,
|
||||
+ .pcs_ops = &mt7530_pcs_ops,
|
||||
.sw_setup = mt7530_setup,
|
||||
.phy_read = mt7530_phy_read,
|
||||
.phy_write = mt7530_phy_write,
|
||||
.pad_setup = mt7530_pad_clk_setup,
|
||||
.mac_port_get_caps = mt7530_mac_port_get_caps,
|
||||
- .mac_port_get_state = mt7530_phylink_mac_link_state,
|
||||
.mac_port_config = mt7530_mac_config,
|
||||
},
|
||||
[ID_MT7530] = {
|
||||
.id = ID_MT7530,
|
||||
+ .pcs_ops = &mt7530_pcs_ops,
|
||||
.sw_setup = mt7530_setup,
|
||||
.phy_read = mt7530_phy_read,
|
||||
.phy_write = mt7530_phy_write,
|
||||
.pad_setup = mt7530_pad_clk_setup,
|
||||
.mac_port_get_caps = mt7530_mac_port_get_caps,
|
||||
- .mac_port_get_state = mt7530_phylink_mac_link_state,
|
||||
.mac_port_config = mt7530_mac_config,
|
||||
},
|
||||
[ID_MT7531] = {
|
||||
.id = ID_MT7531,
|
||||
+ .pcs_ops = &mt7531_pcs_ops,
|
||||
.sw_setup = mt7531_setup,
|
||||
.phy_read = mt7531_ind_phy_read,
|
||||
.phy_write = mt7531_ind_phy_write,
|
||||
.pad_setup = mt7531_pad_setup,
|
||||
.cpu_port_config = mt7531_cpu_port_config,
|
||||
.mac_port_get_caps = mt7531_mac_port_get_caps,
|
||||
- .mac_port_get_state = mt7531_phylink_mac_link_state,
|
||||
.mac_port_config = mt7531_mac_config,
|
||||
- .mac_pcs_an_restart = mt7531_sgmii_restart_an,
|
||||
- .mac_pcs_link_up = mt7531_sgmii_link_up_force,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -3182,7 +3210,7 @@ mt7530_probe(struct mdio_device *mdiodev
|
||||
if (!priv->info->sw_setup || !priv->info->pad_setup ||
|
||||
!priv->info->phy_read || !priv->info->phy_write ||
|
||||
!priv->info->mac_port_get_caps ||
|
||||
- !priv->info->mac_port_get_state || !priv->info->mac_port_config)
|
||||
+ !priv->info->mac_port_config)
|
||||
return -EINVAL;
|
||||
|
||||
priv->id = priv->info->id;
|
||||
--- a/drivers/net/dsa/mt7530.h
|
||||
+++ b/drivers/net/dsa/mt7530.h
|
||||
@@ -741,6 +741,12 @@ static const char *p5_intf_modes(unsigne
|
||||
|
||||
struct mt7530_priv;
|
||||
|
||||
+struct mt753x_pcs {
|
||||
+ struct phylink_pcs pcs;
|
||||
+ struct mt7530_priv *priv;
|
||||
+ int port;
|
||||
+};
|
||||
+
|
||||
/* struct mt753x_info - This is the main data structure for holding the specific
|
||||
* part for each supported device
|
||||
* @sw_setup: Holding the handler to a device initialization
|
||||
@@ -752,18 +758,14 @@ struct mt7530_priv;
|
||||
* port
|
||||
* @mac_port_validate: Holding the way to set addition validate type for a
|
||||
* certan MAC port
|
||||
- * @mac_port_get_state: Holding the way getting the MAC/PCS state for a certain
|
||||
- * MAC port
|
||||
* @mac_port_config: Holding the way setting up the PHY attribute to a
|
||||
* certain MAC port
|
||||
- * @mac_pcs_an_restart Holding the way restarting PCS autonegotiation for a
|
||||
- * certain MAC port
|
||||
- * @mac_pcs_link_up: Holding the way setting up the PHY attribute to the pcs
|
||||
- * of the certain MAC port
|
||||
*/
|
||||
struct mt753x_info {
|
||||
enum mt753x_id id;
|
||||
|
||||
+ const struct phylink_pcs_ops *pcs_ops;
|
||||
+
|
||||
int (*sw_setup)(struct dsa_switch *ds);
|
||||
int (*phy_read)(struct mt7530_priv *priv, int port, int regnum);
|
||||
int (*phy_write)(struct mt7530_priv *priv, int port, int regnum, u16 val);
|
||||
@@ -774,15 +776,9 @@ struct mt753x_info {
|
||||
void (*mac_port_validate)(struct dsa_switch *ds, int port,
|
||||
phy_interface_t interface,
|
||||
unsigned long *supported);
|
||||
- int (*mac_port_get_state)(struct dsa_switch *ds, int port,
|
||||
- struct phylink_link_state *state);
|
||||
int (*mac_port_config)(struct dsa_switch *ds, int port,
|
||||
unsigned int mode,
|
||||
phy_interface_t interface);
|
||||
- void (*mac_pcs_an_restart)(struct dsa_switch *ds, int port);
|
||||
- void (*mac_pcs_link_up)(struct dsa_switch *ds, int port,
|
||||
- unsigned int mode, phy_interface_t interface,
|
||||
- int speed, int duplex);
|
||||
};
|
||||
|
||||
/* struct mt7530_priv - This is the main data structure for holding the state
|
||||
@@ -824,6 +820,7 @@ struct mt7530_priv {
|
||||
u8 mirror_tx;
|
||||
|
||||
struct mt7530_port ports[MT7530_NUM_PORTS];
|
||||
+ struct mt753x_pcs pcs[MT7530_NUM_PORTS];
|
||||
/* protect among processes for registers access*/
|
||||
struct mutex reg_mutex;
|
||||
int irq;
|
@ -0,0 +1,80 @@
|
||||
From 2b0ee6768f3ac09072e5fd60b36580924e1cfa1c Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Mon, 11 Apr 2022 10:46:32 +0100
|
||||
Subject: [PATCH 08/13] net: dsa: mt7530: move autoneg handling to PCS
|
||||
validation
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Move the autoneg bit handling to the PCS validation, which allows us to
|
||||
get rid of mt753x_phylink_validate() and rely on the default
|
||||
phylink_generic_validate() implementation for the MAC side.
|
||||
|
||||
Tested-by: Marek Behún <kabel@kernel.org>
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 28 ++++++++++------------------
|
||||
1 file changed, 10 insertions(+), 18 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -2896,25 +2896,16 @@ static void mt753x_phylink_get_caps(stru
|
||||
priv->info->mac_port_get_caps(ds, port, config);
|
||||
}
|
||||
|
||||
-static void
|
||||
-mt753x_phylink_validate(struct dsa_switch *ds, int port,
|
||||
- unsigned long *supported,
|
||||
- struct phylink_link_state *state)
|
||||
-{
|
||||
- __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
|
||||
- u32 caps;
|
||||
-
|
||||
- caps = dsa_to_port(ds, port)->pl_config.mac_capabilities;
|
||||
-
|
||||
- phylink_set_port_modes(mask);
|
||||
- phylink_get_linkmodes(mask, state->interface, caps);
|
||||
+static int mt753x_pcs_validate(struct phylink_pcs *pcs,
|
||||
+ unsigned long *supported,
|
||||
+ const struct phylink_link_state *state)
|
||||
+{
|
||||
+ /* Autonegotiation is not supported in TRGMII nor 802.3z modes */
|
||||
+ if (state->interface == PHY_INTERFACE_MODE_TRGMII ||
|
||||
+ phy_interface_mode_is_8023z(state->interface))
|
||||
+ phylink_clear(supported, Autoneg);
|
||||
|
||||
- if (state->interface != PHY_INTERFACE_MODE_TRGMII &&
|
||||
- !phy_interface_mode_is_8023z(state->interface))
|
||||
- phylink_set(mask, Autoneg);
|
||||
-
|
||||
- linkmode_and(supported, supported, mask);
|
||||
- linkmode_and(state->advertising, state->advertising, mask);
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static void mt7530_pcs_get_state(struct phylink_pcs *pcs,
|
||||
@@ -3016,12 +3007,14 @@ static void mt7530_pcs_an_restart(struct
|
||||
}
|
||||
|
||||
static const struct phylink_pcs_ops mt7530_pcs_ops = {
|
||||
+ .pcs_validate = mt753x_pcs_validate,
|
||||
.pcs_get_state = mt7530_pcs_get_state,
|
||||
.pcs_config = mt753x_pcs_config,
|
||||
.pcs_an_restart = mt7530_pcs_an_restart,
|
||||
};
|
||||
|
||||
static const struct phylink_pcs_ops mt7531_pcs_ops = {
|
||||
+ .pcs_validate = mt753x_pcs_validate,
|
||||
.pcs_get_state = mt7531_pcs_get_state,
|
||||
.pcs_config = mt753x_pcs_config,
|
||||
.pcs_an_restart = mt7531_pcs_an_restart,
|
||||
@@ -3113,7 +3106,6 @@ static const struct dsa_switch_ops mt753
|
||||
.port_mirror_add = mt753x_port_mirror_add,
|
||||
.port_mirror_del = mt753x_port_mirror_del,
|
||||
.phylink_get_caps = mt753x_phylink_get_caps,
|
||||
- .phylink_validate = mt753x_phylink_validate,
|
||||
.phylink_mac_select_pcs = mt753x_phylink_mac_select_pcs,
|
||||
.phylink_mac_config = mt753x_phylink_mac_config,
|
||||
.phylink_mac_link_down = mt753x_phylink_mac_link_down,
|
@ -0,0 +1,34 @@
|
||||
From 5bc26de9bfaa6bb5539c09d4435dced98f429cfc Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Mon, 11 Apr 2022 10:46:37 +0100
|
||||
Subject: [PATCH 09/13] net: dsa: mt7530: mark as non-legacy
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The mt7530 driver does not make use of the speed, duplex, pause or
|
||||
advertisement in its phylink_mac_config() implementation, so it can be
|
||||
marked as a non-legacy driver.
|
||||
|
||||
Tested-by: Marek Behún <kabel@kernel.org>
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -2893,6 +2893,12 @@ static void mt753x_phylink_get_caps(stru
|
||||
config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
|
||||
MAC_10 | MAC_100 | MAC_1000FD;
|
||||
|
||||
+ /* This driver does not make use of the speed, duplex, pause or the
|
||||
+ * advertisement in its mac_config, so it is safe to mark this driver
|
||||
+ * as non-legacy.
|
||||
+ */
|
||||
+ config->legacy_pre_march2020 = false;
|
||||
+
|
||||
priv->info->mac_port_get_caps(ds, port, config);
|
||||
}
|
||||
|
@ -0,0 +1,116 @@
|
||||
From 1f15b5e8733115cee65342bcaafeaf0368809fae Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Mon, 25 Apr 2022 22:28:02 +0100
|
||||
Subject: [PATCH 10/13] net: dsa: mt753x: fix pcs conversion regression
|
||||
|
||||
Daniel Golle reports that the conversion of mt753x to phylink PCS caused
|
||||
an oops as below.
|
||||
|
||||
The problem is with the placement of the PCS initialisation, which
|
||||
occurs after mt7531_setup() has been called. However, burited in this
|
||||
function is a call to setup the CPU port, which requires the PCS
|
||||
structure to be already setup.
|
||||
|
||||
Fix this by changing the initialisation order.
|
||||
|
||||
Unable to handle kernel NULL pointer dereference at virtual address 0000000000000020
|
||||
Mem abort info:
|
||||
ESR = 0x96000005
|
||||
EC = 0x25: DABT (current EL), IL = 32 bits
|
||||
SET = 0, FnV = 0
|
||||
EA = 0, S1PTW = 0
|
||||
FSC = 0x05: level 1 translation fault
|
||||
Data abort info:
|
||||
ISV = 0, ISS = 0x00000005
|
||||
CM = 0, WnR = 0
|
||||
user pgtable: 4k pages, 39-bit VAs, pgdp=0000000046057000
|
||||
[0000000000000020] pgd=0000000000000000, p4d=0000000000000000, pud=0000000000000000
|
||||
Internal error: Oops: 96000005 [#1] SMP
|
||||
Modules linked in:
|
||||
CPU: 0 PID: 32 Comm: kworker/u4:1 Tainted: G S 5.18.0-rc3-next-20220422+ #0
|
||||
Hardware name: Bananapi BPI-R64 (DT)
|
||||
Workqueue: events_unbound deferred_probe_work_func
|
||||
pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
|
||||
pc : mt7531_cpu_port_config+0xcc/0x1b0
|
||||
lr : mt7531_cpu_port_config+0xc0/0x1b0
|
||||
sp : ffffffc008d5b980
|
||||
x29: ffffffc008d5b990 x28: ffffff80060562c8 x27: 00000000f805633b
|
||||
x26: ffffff80001a8880 x25: 00000000000009c4 x24: 0000000000000016
|
||||
x23: ffffff8005eb6470 x22: 0000000000003600 x21: ffffff8006948080
|
||||
x20: 0000000000000000 x19: 0000000000000006 x18: 0000000000000000
|
||||
x17: 0000000000000001 x16: 0000000000000001 x15: 02963607fcee069e
|
||||
x14: 0000000000000000 x13: 0000000000000030 x12: 0101010101010101
|
||||
x11: ffffffc037302000 x10: 0000000000000870 x9 : ffffffc008d5b800
|
||||
x8 : ffffff800028f950 x7 : 0000000000000001 x6 : 00000000662b3000
|
||||
x5 : 00000000000002f0 x4 : 0000000000000000 x3 : ffffff800028f080
|
||||
x2 : 0000000000000000 x1 : ffffff800028f080 x0 : 0000000000000000
|
||||
Call trace:
|
||||
mt7531_cpu_port_config+0xcc/0x1b0
|
||||
mt753x_cpu_port_enable+0x24/0x1f0
|
||||
mt7531_setup+0x49c/0x5c0
|
||||
mt753x_setup+0x20/0x31c
|
||||
dsa_register_switch+0x8bc/0x1020
|
||||
mt7530_probe+0x118/0x200
|
||||
mdio_probe+0x30/0x64
|
||||
really_probe.part.0+0x98/0x280
|
||||
__driver_probe_device+0x94/0x140
|
||||
driver_probe_device+0x40/0x114
|
||||
__device_attach_driver+0xb0/0x10c
|
||||
bus_for_each_drv+0x64/0xa0
|
||||
__device_attach+0xa8/0x16c
|
||||
device_initial_probe+0x10/0x20
|
||||
bus_probe_device+0x94/0x9c
|
||||
deferred_probe_work_func+0x80/0xb4
|
||||
process_one_work+0x200/0x3a0
|
||||
worker_thread+0x260/0x4c0
|
||||
kthread+0xd4/0xe0
|
||||
ret_from_fork+0x10/0x20
|
||||
Code: 9409e911 937b7e60 8b0002a0 f9405800 (f9401005)
|
||||
---[ end trace 0000000000000000 ]---
|
||||
|
||||
Reported-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Tested-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Fixes: cbd1f243bc41 ("net: dsa: mt7530: partially convert to phylink_pcs")
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
|
||||
Link: https://lore.kernel.org/r/E1nj6FW-007WZB-5Y@rmk-PC.armlinux.org.uk
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 18 +++++++++---------
|
||||
1 file changed, 9 insertions(+), 9 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -3031,9 +3031,16 @@ static int
|
||||
mt753x_setup(struct dsa_switch *ds)
|
||||
{
|
||||
struct mt7530_priv *priv = ds->priv;
|
||||
- int ret = priv->info->sw_setup(ds);
|
||||
- int i;
|
||||
+ int i, ret;
|
||||
|
||||
+ /* Initialise the PCS devices */
|
||||
+ for (i = 0; i < priv->ds->num_ports; i++) {
|
||||
+ priv->pcs[i].pcs.ops = priv->info->pcs_ops;
|
||||
+ priv->pcs[i].priv = priv;
|
||||
+ priv->pcs[i].port = i;
|
||||
+ }
|
||||
+
|
||||
+ ret = priv->info->sw_setup(ds);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -3045,13 +3052,6 @@ mt753x_setup(struct dsa_switch *ds)
|
||||
if (ret && priv->irq)
|
||||
mt7530_free_irq_common(priv);
|
||||
|
||||
- /* Initialise the PCS devices */
|
||||
- for (i = 0; i < priv->ds->num_ports; i++) {
|
||||
- priv->pcs[i].pcs.ops = priv->info->pcs_ops;
|
||||
- priv->pcs[i].priv = priv;
|
||||
- priv->pcs[i].port = i;
|
||||
- }
|
||||
-
|
||||
return ret;
|
||||
}
|
||||
|
@ -0,0 +1,87 @@
|
||||
From e26be16262e1fc1e9f1798c12762663bd9c265c6 Mon Sep 17 00:00:00 2001
|
||||
From: Frank Wunderlich <frank-w@public-files.de>
|
||||
Date: Fri, 10 Jun 2022 19:05:37 +0200
|
||||
Subject: [PATCH 11/13] net: dsa: mt7530: rework mt7530_hw_vlan_{add,del}
|
||||
|
||||
Rework vlan_add/vlan_del functions in preparation for dynamic cpu port.
|
||||
|
||||
Currently BIT(MT7530_CPU_PORT) is added to new_members, even though
|
||||
mt7530_port_vlan_add() will be called on the CPU port too.
|
||||
|
||||
Let DSA core decide when to call port_vlan_add for the CPU port, rather
|
||||
than doing it implicitly.
|
||||
|
||||
We can do autonomous forwarding in a certain VLAN, but not add br0 to that
|
||||
VLAN and avoid flooding the CPU with those packets, if software knows it
|
||||
doesn't need to process them.
|
||||
|
||||
Suggested-by: Vladimir Oltean <olteanv@gmail.com>
|
||||
Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
|
||||
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
|
||||
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 30 ++++++++++++------------------
|
||||
1 file changed, 12 insertions(+), 18 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -1522,11 +1522,11 @@ static void
|
||||
mt7530_hw_vlan_add(struct mt7530_priv *priv,
|
||||
struct mt7530_hw_vlan_entry *entry)
|
||||
{
|
||||
+ struct dsa_port *dp = dsa_to_port(priv->ds, entry->port);
|
||||
u8 new_members;
|
||||
u32 val;
|
||||
|
||||
- new_members = entry->old_members | BIT(entry->port) |
|
||||
- BIT(MT7530_CPU_PORT);
|
||||
+ new_members = entry->old_members | BIT(entry->port);
|
||||
|
||||
/* Validate the entry with independent learning, create egress tag per
|
||||
* VLAN and joining the port as one of the port members.
|
||||
@@ -1537,22 +1537,20 @@ mt7530_hw_vlan_add(struct mt7530_priv *p
|
||||
|
||||
/* Decide whether adding tag or not for those outgoing packets from the
|
||||
* port inside the VLAN.
|
||||
- */
|
||||
- val = entry->untagged ? MT7530_VLAN_EGRESS_UNTAG :
|
||||
- MT7530_VLAN_EGRESS_TAG;
|
||||
- mt7530_rmw(priv, MT7530_VAWD2,
|
||||
- ETAG_CTRL_P_MASK(entry->port),
|
||||
- ETAG_CTRL_P(entry->port, val));
|
||||
-
|
||||
- /* CPU port is always taken as a tagged port for serving more than one
|
||||
+ * CPU port is always taken as a tagged port for serving more than one
|
||||
* VLANs across and also being applied with egress type stack mode for
|
||||
* that VLAN tags would be appended after hardware special tag used as
|
||||
* DSA tag.
|
||||
*/
|
||||
+ if (dsa_port_is_cpu(dp))
|
||||
+ val = MT7530_VLAN_EGRESS_STACK;
|
||||
+ else if (entry->untagged)
|
||||
+ val = MT7530_VLAN_EGRESS_UNTAG;
|
||||
+ else
|
||||
+ val = MT7530_VLAN_EGRESS_TAG;
|
||||
mt7530_rmw(priv, MT7530_VAWD2,
|
||||
- ETAG_CTRL_P_MASK(MT7530_CPU_PORT),
|
||||
- ETAG_CTRL_P(MT7530_CPU_PORT,
|
||||
- MT7530_VLAN_EGRESS_STACK));
|
||||
+ ETAG_CTRL_P_MASK(entry->port),
|
||||
+ ETAG_CTRL_P(entry->port, val));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1571,11 +1569,7 @@ mt7530_hw_vlan_del(struct mt7530_priv *p
|
||||
return;
|
||||
}
|
||||
|
||||
- /* If certain member apart from CPU port is still alive in the VLAN,
|
||||
- * the entry would be kept valid. Otherwise, the entry is got to be
|
||||
- * disabled.
|
||||
- */
|
||||
- if (new_members && new_members != BIT(MT7530_CPU_PORT)) {
|
||||
+ if (new_members) {
|
||||
val = IVL_MAC | VTAG_EN | PORT_MEM(new_members) |
|
||||
VLAN_VALID;
|
||||
mt7530_write(priv, MT7530_VAWD1, val);
|
@ -0,0 +1,75 @@
|
||||
From 1f0dfd443eea7fc3e818e96f7c8264913ba41859 Mon Sep 17 00:00:00 2001
|
||||
From: Frank Wunderlich <frank-w@public-files.de>
|
||||
Date: Fri, 10 Jun 2022 19:05:38 +0200
|
||||
Subject: [PATCH 12/13] net: dsa: mt7530: rework mt753[01]_setup
|
||||
|
||||
Enumerate available cpu-ports instead of using hardcoded constant.
|
||||
|
||||
Suggested-by: Vladimir Oltean <olteanv@gmail.com>
|
||||
Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
|
||||
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
|
||||
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 25 +++++++++++++++++++++----
|
||||
1 file changed, 21 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -2087,11 +2087,12 @@ static int
|
||||
mt7530_setup(struct dsa_switch *ds)
|
||||
{
|
||||
struct mt7530_priv *priv = ds->priv;
|
||||
+ struct device_node *dn = NULL;
|
||||
struct device_node *phy_node;
|
||||
struct device_node *mac_np;
|
||||
struct mt7530_dummy_poll p;
|
||||
phy_interface_t interface;
|
||||
- struct device_node *dn;
|
||||
+ struct dsa_port *cpu_dp;
|
||||
u32 id, val;
|
||||
int ret, i;
|
||||
|
||||
@@ -2099,7 +2100,19 @@ mt7530_setup(struct dsa_switch *ds)
|
||||
* controller also is the container for two GMACs nodes representing
|
||||
* as two netdev instances.
|
||||
*/
|
||||
- dn = dsa_to_port(ds, MT7530_CPU_PORT)->master->dev.of_node->parent;
|
||||
+ dsa_switch_for_each_cpu_port(cpu_dp, ds) {
|
||||
+ dn = cpu_dp->master->dev.of_node->parent;
|
||||
+ /* It doesn't matter which CPU port is found first,
|
||||
+ * their masters should share the same parent OF node
|
||||
+ */
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (!dn) {
|
||||
+ dev_err(ds->dev, "parent OF node of DSA master not found");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
ds->assisted_learning_on_cpu_port = true;
|
||||
ds->mtu_enforcement_ingress = true;
|
||||
|
||||
@@ -2261,6 +2274,7 @@ mt7531_setup(struct dsa_switch *ds)
|
||||
{
|
||||
struct mt7530_priv *priv = ds->priv;
|
||||
struct mt7530_dummy_poll p;
|
||||
+ struct dsa_port *cpu_dp;
|
||||
u32 val, id;
|
||||
int ret, i;
|
||||
|
||||
@@ -2333,8 +2347,11 @@ mt7531_setup(struct dsa_switch *ds)
|
||||
CORE_PLL_GROUP4, val);
|
||||
|
||||
/* BPDU to CPU port */
|
||||
- mt7530_rmw(priv, MT7531_CFC, MT7531_CPU_PMAP_MASK,
|
||||
- BIT(MT7530_CPU_PORT));
|
||||
+ dsa_switch_for_each_cpu_port(cpu_dp, ds) {
|
||||
+ mt7530_rmw(priv, MT7531_CFC, MT7531_CPU_PMAP_MASK,
|
||||
+ BIT(cpu_dp->index));
|
||||
+ break;
|
||||
+ }
|
||||
mt7530_rmw(priv, MT753X_BPC, MT753X_BPDU_PORT_FW_MASK,
|
||||
MT753X_BPDU_CPU_ONLY);
|
||||
|
@ -0,0 +1,117 @@
|
||||
From ad2606f6fafae3a7d41c4f2af5554c8f6adecbc7 Mon Sep 17 00:00:00 2001
|
||||
From: Frank Wunderlich <frank-w@public-files.de>
|
||||
Date: Fri, 10 Jun 2022 19:05:39 +0200
|
||||
Subject: [PATCH 13/13] net: dsa: mt7530: get cpu-port via dp->cpu_dp instead
|
||||
of constant
|
||||
|
||||
Replace last occurences of hardcoded cpu-port by cpu_dp member of
|
||||
dsa_port struct.
|
||||
|
||||
Now the constant can be dropped.
|
||||
|
||||
Suggested-by: Vladimir Oltean <olteanv@gmail.com>
|
||||
Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
|
||||
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
|
||||
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 27 ++++++++++++++++++++-------
|
||||
drivers/net/dsa/mt7530.h | 1 -
|
||||
2 files changed, 20 insertions(+), 8 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -1038,6 +1038,7 @@ static int
|
||||
mt7530_port_enable(struct dsa_switch *ds, int port,
|
||||
struct phy_device *phy)
|
||||
{
|
||||
+ struct dsa_port *dp = dsa_to_port(ds, port);
|
||||
struct mt7530_priv *priv = ds->priv;
|
||||
|
||||
mutex_lock(&priv->reg_mutex);
|
||||
@@ -1046,7 +1047,11 @@ mt7530_port_enable(struct dsa_switch *ds
|
||||
* restore the port matrix if the port is the member of a certain
|
||||
* bridge.
|
||||
*/
|
||||
- priv->ports[port].pm |= PCR_MATRIX(BIT(MT7530_CPU_PORT));
|
||||
+ if (dsa_port_is_user(dp)) {
|
||||
+ struct dsa_port *cpu_dp = dp->cpu_dp;
|
||||
+
|
||||
+ priv->ports[port].pm |= PCR_MATRIX(BIT(cpu_dp->index));
|
||||
+ }
|
||||
priv->ports[port].enable = true;
|
||||
mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK,
|
||||
priv->ports[port].pm);
|
||||
@@ -1194,7 +1199,8 @@ mt7530_port_bridge_join(struct dsa_switc
|
||||
struct net_device *bridge)
|
||||
{
|
||||
struct dsa_port *dp = dsa_to_port(ds, port), *other_dp;
|
||||
- u32 port_bitmap = BIT(MT7530_CPU_PORT);
|
||||
+ struct dsa_port *cpu_dp = dp->cpu_dp;
|
||||
+ u32 port_bitmap = BIT(cpu_dp->index);
|
||||
struct mt7530_priv *priv = ds->priv;
|
||||
|
||||
mutex_lock(&priv->reg_mutex);
|
||||
@@ -1271,9 +1277,12 @@ mt7530_port_set_vlan_unaware(struct dsa_
|
||||
* the CPU port get out of VLAN filtering mode.
|
||||
*/
|
||||
if (all_user_ports_removed) {
|
||||
- mt7530_write(priv, MT7530_PCR_P(MT7530_CPU_PORT),
|
||||
+ struct dsa_port *dp = dsa_to_port(ds, port);
|
||||
+ struct dsa_port *cpu_dp = dp->cpu_dp;
|
||||
+
|
||||
+ mt7530_write(priv, MT7530_PCR_P(cpu_dp->index),
|
||||
PCR_MATRIX(dsa_user_ports(priv->ds)));
|
||||
- mt7530_write(priv, MT7530_PVC_P(MT7530_CPU_PORT), PORT_SPEC_TAG
|
||||
+ mt7530_write(priv, MT7530_PVC_P(cpu_dp->index), PORT_SPEC_TAG
|
||||
| PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT));
|
||||
}
|
||||
}
|
||||
@@ -1311,6 +1320,7 @@ mt7530_port_bridge_leave(struct dsa_swit
|
||||
struct net_device *bridge)
|
||||
{
|
||||
struct dsa_port *dp = dsa_to_port(ds, port), *other_dp;
|
||||
+ struct dsa_port *cpu_dp = dp->cpu_dp;
|
||||
struct mt7530_priv *priv = ds->priv;
|
||||
|
||||
mutex_lock(&priv->reg_mutex);
|
||||
@@ -1339,8 +1349,8 @@ mt7530_port_bridge_leave(struct dsa_swit
|
||||
*/
|
||||
if (priv->ports[port].enable)
|
||||
mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK,
|
||||
- PCR_MATRIX(BIT(MT7530_CPU_PORT)));
|
||||
- priv->ports[port].pm = PCR_MATRIX(BIT(MT7530_CPU_PORT));
|
||||
+ PCR_MATRIX(BIT(cpu_dp->index)));
|
||||
+ priv->ports[port].pm = PCR_MATRIX(BIT(cpu_dp->index));
|
||||
|
||||
/* When a port is removed from the bridge, the port would be set up
|
||||
* back to the default as is at initial boot which is a VLAN-unaware
|
||||
@@ -1503,6 +1513,9 @@ static int
|
||||
mt7530_port_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
+ struct dsa_port *dp = dsa_to_port(ds, port);
|
||||
+ struct dsa_port *cpu_dp = dp->cpu_dp;
|
||||
+
|
||||
if (vlan_filtering) {
|
||||
/* The port is being kept as VLAN-unaware port when bridge is
|
||||
* set up with vlan_filtering not being set, Otherwise, the
|
||||
@@ -1510,7 +1523,7 @@ mt7530_port_vlan_filtering(struct dsa_sw
|
||||
* for becoming a VLAN-aware port.
|
||||
*/
|
||||
mt7530_port_set_vlan_aware(ds, port);
|
||||
- mt7530_port_set_vlan_aware(ds, MT7530_CPU_PORT);
|
||||
+ mt7530_port_set_vlan_aware(ds, cpu_dp->index);
|
||||
} else {
|
||||
mt7530_port_set_vlan_unaware(ds, port);
|
||||
}
|
||||
--- a/drivers/net/dsa/mt7530.h
|
||||
+++ b/drivers/net/dsa/mt7530.h
|
||||
@@ -8,7 +8,6 @@
|
||||
|
||||
#define MT7530_NUM_PORTS 7
|
||||
#define MT7530_NUM_PHYS 5
|
||||
-#define MT7530_CPU_PORT 6
|
||||
#define MT7530_NUM_FDB_RECORDS 2048
|
||||
#define MT7530_ALL_MEMBERS 0xff
|
||||
|
@ -22,7 +22,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
|
||||
--- a/net/dsa/slave.c
|
||||
+++ b/net/dsa/slave.c
|
||||
@@ -1986,13 +1986,6 @@ int dsa_slave_create(struct dsa_port *po
|
||||
@@ -1977,13 +1977,6 @@ int dsa_slave_create(struct dsa_port *po
|
||||
port->slave = slave_dev;
|
||||
dsa_slave_setup_tagger(slave_dev);
|
||||
|
||||
@ -36,7 +36,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
netif_carrier_off(slave_dev);
|
||||
|
||||
ret = dsa_slave_phy_setup(slave_dev);
|
||||
@@ -2004,6 +1997,13 @@ int dsa_slave_create(struct dsa_port *po
|
||||
@@ -1995,6 +1988,13 @@ int dsa_slave_create(struct dsa_port *po
|
||||
}
|
||||
|
||||
rtnl_lock();
|
||||
|
@ -16,7 +16,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
|
||||
--- a/net/dsa/slave.c
|
||||
+++ b/net/dsa/slave.c
|
||||
@@ -1997,14 +1997,12 @@ int dsa_slave_create(struct dsa_port *po
|
||||
@@ -1988,14 +1988,12 @@ int dsa_slave_create(struct dsa_port *po
|
||||
}
|
||||
|
||||
rtnl_lock();
|
||||
|
@ -68,7 +68,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
static inline bool dsa_is_unused_port(struct dsa_switch *ds, int p)
|
||||
{
|
||||
return dsa_to_port(ds, p)->type == DSA_PORT_TYPE_UNUSED;
|
||||
@@ -916,6 +926,13 @@ struct dsa_switch_ops {
|
||||
@@ -949,6 +959,13 @@ struct dsa_switch_ops {
|
||||
int (*tag_8021q_vlan_add)(struct dsa_switch *ds, int port, u16 vid,
|
||||
u16 flags);
|
||||
int (*tag_8021q_vlan_del)(struct dsa_switch *ds, int port, u16 vid);
|
||||
@ -175,7 +175,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
|
||||
--- a/net/dsa/slave.c
|
||||
+++ b/net/dsa/slave.c
|
||||
@@ -2320,6 +2320,36 @@ static int dsa_slave_netdevice_event(str
|
||||
@@ -2311,6 +2311,36 @@ static int dsa_slave_netdevice_event(str
|
||||
err = dsa_port_lag_change(dp, info->lower_state_info);
|
||||
return notifier_from_errno(err);
|
||||
}
|
||||
@ -212,7 +212,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
case NETDEV_GOING_DOWN: {
|
||||
struct dsa_port *dp, *cpu_dp;
|
||||
struct dsa_switch_tree *dst;
|
||||
@@ -2331,6 +2361,8 @@ static int dsa_slave_netdevice_event(str
|
||||
@@ -2322,6 +2352,8 @@ static int dsa_slave_netdevice_event(str
|
||||
cpu_dp = dev->dsa_ptr;
|
||||
dst = cpu_dp->ds->dst;
|
||||
|
||||
|
@ -10,7 +10,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
@@ -2443,8 +2443,8 @@ static irqreturn_t mtk_handle_irq_rx(int
|
||||
@@ -2381,8 +2381,8 @@ static irqreturn_t mtk_handle_irq_rx(int
|
||||
|
||||
eth->rx_events++;
|
||||
if (likely(napi_schedule_prep(ð->rx_napi))) {
|
||||
@ -20,7 +20,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
@@ -2456,8 +2456,8 @@ static irqreturn_t mtk_handle_irq_tx(int
|
||||
@@ -2394,8 +2394,8 @@ static irqreturn_t mtk_handle_irq_tx(int
|
||||
|
||||
eth->tx_events++;
|
||||
if (likely(napi_schedule_prep(ð->tx_napi))) {
|
||||
@ -30,12 +30,12 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
@@ -3623,6 +3623,8 @@ static int mtk_probe(struct platform_dev
|
||||
@@ -3585,6 +3585,8 @@ static int mtk_probe(struct platform_dev
|
||||
* for NAPI to work
|
||||
*/
|
||||
init_dummy_netdev(ð->dummy_dev);
|
||||
+ eth->dummy_dev.threaded = 1;
|
||||
+ strcpy(eth->dummy_dev.name, "mtk_eth");
|
||||
netif_napi_add(ð->dummy_dev, ð->tx_napi, mtk_napi_tx,
|
||||
MTK_NAPI_WEIGHT);
|
||||
NAPI_POLL_WEIGHT);
|
||||
netif_napi_add(ð->dummy_dev, ð->rx_napi, mtk_napi_rx,
|
||||
|
@ -23,7 +23,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
|
||||
sysfs_remove_link(&dev->dev.kobj, "phydev");
|
||||
--- a/include/linux/phy.h
|
||||
+++ b/include/linux/phy.h
|
||||
@@ -789,6 +789,12 @@ struct phy_driver {
|
||||
@@ -823,6 +823,12 @@ struct phy_driver {
|
||||
/** @handle_interrupt: Override default interrupt handling */
|
||||
irqreturn_t (*handle_interrupt)(struct phy_device *phydev);
|
||||
|
||||
|
@ -14,7 +14,7 @@ Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
@@ -3675,6 +3675,7 @@ static const struct mtk_soc_data mt2701_
|
||||
@@ -3637,6 +3637,7 @@ static const struct mtk_soc_data mt2701_
|
||||
.hw_features = MTK_HW_FEATURES,
|
||||
.required_clks = MT7623_CLKS_BITMAP,
|
||||
.required_pctl = true,
|
||||
|
@ -103,7 +103,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
|
||||
ret = mtk_mdio_busy_wait(eth);
|
||||
if (ret < 0)
|
||||
@@ -683,6 +726,7 @@ static int mtk_mdio_init(struct mtk_eth
|
||||
@@ -621,6 +664,7 @@ static int mtk_mdio_init(struct mtk_eth
|
||||
eth->mii_bus->name = "mdio";
|
||||
eth->mii_bus->read = mtk_mdio_read;
|
||||
eth->mii_bus->write = mtk_mdio_write;
|
||||
|
@ -1,10 +0,0 @@
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
@@ -667,6 +667,7 @@ static void mtk_validate(struct phylink_
|
||||
if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_SGMII)) {
|
||||
phylink_set(mask, 1000baseT_Full);
|
||||
phylink_set(mask, 1000baseX_Full);
|
||||
+ phylink_set(mask, 2500baseT_Full);
|
||||
phylink_set(mask, 2500baseX_Full);
|
||||
}
|
||||
if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_RGMII)) {
|
@ -14,7 +14,7 @@ Signed-off-by: René van Dorst <opensource@vdorst.com>
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
@@ -3290,6 +3290,7 @@ static const struct net_device_ops mtk_n
|
||||
@@ -3228,6 +3228,7 @@ static const struct net_device_ops mtk_n
|
||||
|
||||
static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np)
|
||||
{
|
||||
@ -22,7 +22,7 @@ Signed-off-by: René van Dorst <opensource@vdorst.com>
|
||||
const __be32 *_id = of_get_property(np, "reg", NULL);
|
||||
phy_interface_t phy_mode;
|
||||
struct phylink *phylink;
|
||||
@@ -3385,6 +3386,9 @@ static int mtk_add_mac(struct mtk_eth *e
|
||||
@@ -3347,6 +3348,9 @@ static int mtk_add_mac(struct mtk_eth *e
|
||||
else
|
||||
eth->netdev[id]->max_mtu = MTK_MAX_RX_LENGTH_2K - MTK_RX_ETH_HLEN;
|
||||
|
||||
|
@ -95,7 +95,7 @@ still required by target/linux/ramips/files/drivers/net/ethernet/ralink/mdio.c
|
||||
phydev->mii_ts->link_state(phydev->mii_ts, phydev);
|
||||
--- a/drivers/net/phy/phylink.c
|
||||
+++ b/drivers/net/phy/phylink.c
|
||||
@@ -946,7 +946,8 @@ void phylink_destroy(struct phylink *pl)
|
||||
@@ -1315,7 +1315,8 @@ void phylink_destroy(struct phylink *pl)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(phylink_destroy);
|
||||
|
||||
@ -107,7 +107,7 @@ still required by target/linux/ramips/files/drivers/net/ethernet/ralink/mdio.c
|
||||
bool tx_pause, rx_pause;
|
||||
--- a/include/linux/phy.h
|
||||
+++ b/include/linux/phy.h
|
||||
@@ -669,7 +669,7 @@ struct phy_device {
|
||||
@@ -703,7 +703,7 @@ struct phy_device {
|
||||
u8 mdix;
|
||||
u8 mdix_ctrl;
|
||||
|
||||
|
@ -37,7 +37,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
break;
|
||||
--- a/include/linux/phy.h
|
||||
+++ b/include/linux/phy.h
|
||||
@@ -586,6 +586,7 @@ struct phy_device {
|
||||
@@ -620,6 +620,7 @@ struct phy_device {
|
||||
unsigned downshifted_rate:1;
|
||||
unsigned is_on_sfp_module:1;
|
||||
unsigned mac_managed_pm:1;
|
||||
|
Loading…
x
Reference in New Issue
Block a user