summaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2023-07-14 08:51:49 +0100
committerDavid S. Miller <davem@davemloft.net>2023-07-14 08:51:49 +0100
commita8fbe1eeef700c64a819330b5e3476de9bbb318d (patch)
tree50cacaabfbce743efd5993f49d8368c327e73b9e /include/linux
parent6963e463256e4a5fa1635b3636aa38b058668122 (diff)
parentd20acfdd3f88fc2a68897c202310194654988276 (diff)
Merge branch 'mv88e6xxx-phylink_pcs'
Russell King says: ==================== Convert mv88e6xxx to phylink_pcs This series (previously posted with further patches on the 26 June as RFC) converts mv88e6xxx to phylink_pcs, and thus moves it from being a pre-March 2020 legacy driver. The first four patches lay the ground-work for the conversion by adding four new methods to the phylink_pcs operations structure: pcs_enable() - called when the PCS is going to start to be used pcs_disable() - called when the PCS is no longer being used pcs_pre_config() - called before the MAC configuration method pcs_post_config() - called after the MAC configuration method Both of these are necessary for some of the mv88e639x workarounds. We also add the ability to inform phylink of a change to the PCS state without involving the MAC later, by providing phylink_pcs_change() which takes a phylink_pcs structure rather than a phylink structure. phylink maintains which instance the PCS is conencted to, so internally it can do the right thing when the PCS is in-use. Then we provide some additional mdiobus and mdiodev accessors that we will be using in the new PCS drivers. The changes for mv88e6xxx follow, and the first one needs to be explicitly pointed out - we (Andrew and myself) have both decided that all possible approaches to maintaining backwards compatibility with DT have been exhaused - everyone has some objection to everything that has been proposed. So, after many years of trying, we have decided that this is just an impossibility, and with this patch, we are now intentionally and knowingly breaking any DT that does not specify the CPU and DSA port fixed-link parameters. Hence why Andrew has recently been submitting DT update patches. It is regrettable that it has come to this. Following this, we start preparing 88e6xxx for phylink_pcs conversion by padding the mac_select_pcs() DSA method, and the internal hooks to create and tear-down PCS instances. Rather than bloat the already very large mv88e6xxx_ops structure, I decided that it would be better that the new internal chip specific PCS methods are all grouped within their own structure - and this structure can be declared in the PCS drivers themselves. Then we have the actual conversion patches, one for each family of PCS. Lastly, we clean up the driver after conversion, removing all the now redundant code. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/mdio.h26
-rw-r--r--include/linux/phylink.h29
2 files changed, 55 insertions, 0 deletions
diff --git a/include/linux/mdio.h b/include/linux/mdio.h
index c1b7008826e5..8fa23bdcedbf 100644
--- a/include/linux/mdio.h
+++ b/include/linux/mdio.h
@@ -537,6 +537,8 @@ static inline void mii_c73_mod_linkmode(unsigned long *adv, u16 *lpa)
int __mdiobus_read(struct mii_bus *bus, int addr, u32 regnum);
int __mdiobus_write(struct mii_bus *bus, int addr, u32 regnum, u16 val);
+int __mdiobus_modify(struct mii_bus *bus, int addr, u32 regnum, u16 mask,
+ u16 set);
int __mdiobus_modify_changed(struct mii_bus *bus, int addr, u32 regnum,
u16 mask, u16 set);
@@ -564,6 +566,30 @@ int mdiobus_c45_modify(struct mii_bus *bus, int addr, int devad, u32 regnum,
int mdiobus_c45_modify_changed(struct mii_bus *bus, int addr, int devad,
u32 regnum, u16 mask, u16 set);
+static inline int __mdiodev_read(struct mdio_device *mdiodev, u32 regnum)
+{
+ return __mdiobus_read(mdiodev->bus, mdiodev->addr, regnum);
+}
+
+static inline int __mdiodev_write(struct mdio_device *mdiodev, u32 regnum,
+ u16 val)
+{
+ return __mdiobus_write(mdiodev->bus, mdiodev->addr, regnum, val);
+}
+
+static inline int __mdiodev_modify(struct mdio_device *mdiodev, u32 regnum,
+ u16 mask, u16 set)
+{
+ return __mdiobus_modify(mdiodev->bus, mdiodev->addr, regnum, mask, set);
+}
+
+static inline int __mdiodev_modify_changed(struct mdio_device *mdiodev,
+ u32 regnum, u16 mask, u16 set)
+{
+ return __mdiobus_modify_changed(mdiodev->bus, mdiodev->addr, regnum,
+ mask, set);
+}
+
static inline int mdiodev_read(struct mdio_device *mdiodev, u32 regnum)
{
return mdiobus_read(mdiodev->bus, mdiodev->addr, regnum);
diff --git a/include/linux/phylink.h b/include/linux/phylink.h
index 1817940a3418..b28aa3eef7d5 100644
--- a/include/linux/phylink.h
+++ b/include/linux/phylink.h
@@ -9,6 +9,7 @@ struct device_node;
struct ethtool_cmd;
struct fwnode_handle;
struct net_device;
+struct phylink;
enum {
MLO_PAUSE_NONE,
@@ -520,14 +521,19 @@ struct phylink_pcs_ops;
/**
* struct phylink_pcs - PHYLINK PCS instance
* @ops: a pointer to the &struct phylink_pcs_ops structure
+ * @phylink: pointer to &struct phylink_config
* @neg_mode: provide PCS neg mode via "mode" argument
* @poll: poll the PCS for link changes
*
* This structure is designed to be embedded within the PCS private data,
* and will be passed between phylink and the PCS.
+ *
+ * The @phylink member is private to phylink and must not be touched by
+ * the PCS driver.
*/
struct phylink_pcs {
const struct phylink_pcs_ops *ops;
+ struct phylink *phylink;
bool neg_mode;
bool poll;
};
@@ -535,6 +541,10 @@ struct phylink_pcs {
/**
* struct phylink_pcs_ops - MAC PCS operations structure.
* @pcs_validate: validate the link configuration.
+ * @pcs_enable: enable the PCS.
+ * @pcs_disable: disable the PCS.
+ * @pcs_pre_config: pre-mac_config method (for errata)
+ * @pcs_post_config: post-mac_config method (for arrata)
* @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.
@@ -544,6 +554,12 @@ struct phylink_pcs {
struct phylink_pcs_ops {
int (*pcs_validate)(struct phylink_pcs *pcs, unsigned long *supported,
const struct phylink_link_state *state);
+ int (*pcs_enable)(struct phylink_pcs *pcs);
+ void (*pcs_disable)(struct phylink_pcs *pcs);
+ void (*pcs_pre_config)(struct phylink_pcs *pcs,
+ phy_interface_t interface);
+ int (*pcs_post_config)(struct phylink_pcs *pcs,
+ phy_interface_t interface);
void (*pcs_get_state)(struct phylink_pcs *pcs,
struct phylink_link_state *state);
int (*pcs_config)(struct phylink_pcs *pcs, unsigned int neg_mode,
@@ -574,6 +590,18 @@ int pcs_validate(struct phylink_pcs *pcs, unsigned long *supported,
const struct phylink_link_state *state);
/**
+ * pcs_enable() - enable the PCS.
+ * @pcs: a pointer to a &struct phylink_pcs.
+ */
+int pcs_enable(struct phylink_pcs *pcs);
+
+/**
+ * pcs_disable() - disable the PCS.
+ * @pcs: a pointer to a &struct phylink_pcs.
+ */
+void pcs_disable(struct phylink_pcs *pcs);
+
+/**
* 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.
@@ -677,6 +705,7 @@ int phylink_fwnode_phy_connect(struct phylink *pl,
void phylink_disconnect_phy(struct phylink *);
void phylink_mac_change(struct phylink *, bool up);
+void phylink_pcs_change(struct phylink_pcs *, bool up);
void phylink_start(struct phylink *);
void phylink_stop(struct phylink *);