123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385 |
- From fd993fd59d96d5e2d5972ec4ca1f9651025c987b Mon Sep 17 00:00:00 2001
- From: "Russell King (Oracle)" <[email protected]>
- 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 <[email protected]>
- Signed-off-by: Russell King (Oracle) <[email protected]>
- Signed-off-by: Paolo Abeni <[email protected]>
- ---
- 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
- @@ -25,6 +25,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"),
- @@ -2631,12 +2636,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. */
- @@ -2662,6 +2666,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)
- @@ -2737,9 +2744,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 */
- @@ -2796,6 +2804,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)
- @@ -2857,17 +2883,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)
- @@ -2877,16 +2892,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,
- @@ -2899,8 +2911,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
- @@ -2978,6 +2988,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);
-
- @@ -3017,16 +3029,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);
- @@ -3053,8 +3062,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
- @@ -3096,32 +3103,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;
- @@ -3134,6 +3158,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;
- }
-
- @@ -3195,9 +3226,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,
- @@ -3207,36 +3237,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,
- },
- };
-
- @@ -3294,7 +3322,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
- @@ -768,6 +768,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
- @@ -779,18 +785,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);
- @@ -801,15 +803,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
- @@ -851,6 +847,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;
|