net: dsa: improve serdes integration
Subsystems (4)
cover net: dsa: improve serdes integration
Depends on "net: mii clause 37 helpers".
Andrew Lunn mentioned that the Serdes PCS found in Marvell DSA switches does not automatically update the switch MACs with the link parameters. Currently, the DSA code implements a work-around for this.
This series improves the Serdes integration, making use of the recent phylink changes to support split MAC/PCS setups. One noticable improvement for userspace is that ethtool can now report the link partner's advertisement.
This repost has no changes compared to the previous posting; however, the regression Andrew had found which exists even without this patch set has now been fixed by Andrew and merged into the net-next tree.
drivers/net/dsa/mv88e6xxx/chip.c | 437 +++++++++++++++++++++---------------- drivers/net/dsa/mv88e6xxx/chip.h | 35 +-- drivers/net/dsa/mv88e6xxx/port.c | 285 +++++------------------- drivers/net/dsa/mv88e6xxx/port.h | 29 ++- drivers/net/dsa/mv88e6xxx/serdes.c | 375 +++++++++++++++++++++++++------ drivers/net/dsa/mv88e6xxx/serdes.h | 34 ++- net/dsa/port.c | 7 +- 7 files changed, 667 insertions(+), 535 deletions(-)
Signature · 2 lines
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/ FTTC broadband for 0.8mile line in suburbia: sync at 10.2Mbps down 587kbps up
PATCH 1/8 net: dsa: warn if phylink_mac_link_state returns error
Issue a warning to the kernel log if phylink_mac_link_state() returns an error. This should not occur, but let's make it visible.
--- net/dsa/port.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
net/dsa/port.c +6 -1
@@ -457,6 +457,7 @@ static void dsa_port_phylink_mac_pcs_get_state(struct phylink_config *config, { struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);struct dsa_switch *ds = dp->ds; +int err;/* Only called for inband modes */ if (!ds->ops->phylink_mac_link_state) {
@@ -464,8 +465,12 @@ static void dsa_port_phylink_mac_pcs_get_state(struct phylink_config *config,return ; } -if (ds->ops->phylink_mac_link_state (ds, dp->index, state) <0 ) + err = ds->ops->phylink_mac_link_state (ds, dp->index, state); +if (err <0 ) { +dev_err (ds->dev,"p%d: phylink_mac_link_state() failed: %d\n" , + dp->index, err); state->link =0 ; + } } static void dsa_port_phylink_mac_config(struct phylink_config *config,
Signature · 1 line
2.20.1
Re: [PATCH net-next 1/8] net: dsa: warn if phylink_mac_link_state returns error
Quoted 4 lines · Russell King
Issue a warning to the kernel log if
phylink_mac_link_state()returns an error. This should not occur, but let's make it visible.Signed-off-by Russell King <[email protected]>
Andrew
PATCH 2/8 net: dsa: mv88e6xxx: use BMCR definitions for serdes control register
In reply to Russell King - ARM Linux adminThe SGMII/1000base-X serdes register set is a clause 22 register set offset at 0x2000 in the PHYXS device. Rather than inventing our own defintions, use those that already exist, and name the register MV88E6390_SGMII_BMCR. Also remove the unused MV88E6390_SGMII_STATUS definitions.
--- drivers/net/dsa/mv88e6xxx/serdes.c | 10 ++++------ drivers/net/dsa/mv88e6xxx/serdes.h | 9 +-------- 2 files changed, 5 insertions(+), 14 deletions(-)
drivers/net/dsa/mv88e6xxx/serdes.c +4 -6
@@ -410,20 +410,18 @@ static int mv88e6390_serdes_power_sgmii(struct mv88e6xxx_chip *chip, u8 lane,int err; err =mv88e6390_serdes_read (chip, lane,MDIO_MMD_PHYXS , -MV88E6390_SGMII_CONTROL , &val); +MV88E6390_SGMII_BMCR , &val);if (err)return err;if (up) - new_val = val & ~(MV88E6390_SGMII_CONTROL_RESET | -MV88E6390_SGMII_CONTROL_LOOPBACK | -MV88E6390_SGMII_CONTROL_PDOWN ); + new_val = val & ~(BMCR_RESET |BMCR_LOOPBACK |BMCR_PDOWN );else - new_val = val |MV88E6390_SGMII_CONTROL_PDOWN ; + new_val = val |BMCR_PDOWN ;if (val != new_val) err =mv88e6390_serdes_write (chip, lane,MDIO_MMD_PHYXS , -MV88E6390_SGMII_CONTROL , new_val); +MV88E6390_SGMII_BMCR , new_val);return err; }
drivers/net/dsa/mv88e6xxx/serdes.h +1 -8
@@ -47,14 +47,7 @@#define MV88E6390_PCS_CONTROL_1_PDOWN BIT(11)/* 1000BASE-X and SGMII */ -#define MV88E6390_SGMII_CONTROL 0x2000 -#define MV88E6390_SGMII_CONTROL_RESET BIT(15) -#define MV88E6390_SGMII_CONTROL_LOOPBACK BIT(14) -#define MV88E6390_SGMII_CONTROL_PDOWN BIT(11) -#define MV88E6390_SGMII_STATUS 0x2001 -#define MV88E6390_SGMII_STATUS_AN_DONE BIT(5) -#define MV88E6390_SGMII_STATUS_REMOTE_FAULT BIT(4) -#define MV88E6390_SGMII_STATUS_LINK BIT(2) +#define MV88E6390_SGMII_BMCR (0x2000 + MII_BMCR)#define MV88E6390_SGMII_INT_ENABLE 0xa001#define MV88E6390_SGMII_INT_SPEED_CHANGE BIT(14)#define MV88E6390_SGMII_INT_DUPLEX_CHANGE BIT(13)
Signature · 1 line
2.20.1
Re: [PATCH net-next 2/8] net: dsa: mv88e6xxx: use BMCR definitions for serdes control register
Quoted 7 lines · Russell King
The SGMII/1000base-X serdes register set is a clause 22 register set offset at
0x2000in the PHYXS device. Rather than inventing our own defintions, use those that already exist, and name the registerMV88E6390_SGMII_BMCR. Also remove the unusedMV88E6390_SGMII_STATUSdefinitions.Signed-off-by Russell King <[email protected]>
Andrew
PATCH 3/8 net: dsa: mv88e6xxx: configure interface settings in mac_config
In reply to Russell King - ARM Linux adminOnly configure the interface settings in mac_config(), leaving the speed and duplex settings to mac_link_up to deal with.
--- drivers/net/dsa/mv88e6xxx/chip.c | 67 +++++++++++++++++--------------- 1 file changed, 35 insertions(+), 32 deletions(-)
drivers/net/dsa/mv88e6xxx/chip.c +35 -32
@@ -397,6 +397,28 @@ static void mv88e6xxx_irq_poll_free(struct mv88e6xxx_chip *chip)mv88e6xxx_reg_unlock (chip); } +static int mv88e6xxx_port_config_interface (struct mv88e6xxx_chip *chip, +int port,phy_interface_t interface) +{ +int err; + +if (chip->info->ops->port_set_rgmii_delay) { + err = chip->info->ops->port_set_rgmii_delay (chip, port, + interface); +if (err && err != -EOPNOTSUPP ) +return err; + } + +if (chip->info->ops->port_set_cmode) { + err = chip->info->ops->port_set_cmode (chip, port, + interface); +if (err && err != -EOPNOTSUPP ) +return err; + } + +return 0 ; +} +int mv88e6xxx_port_setup_mac (struct mv88e6xxx_chip *chip,int port,int link,int speed,int duplex,int pause,phy_interface_t mode)
@@ -451,19 +473,7 @@ int mv88e6xxx_port_setup_mac(struct mv88e6xxx_chip *chip, int port, int link, goto restore_link; } -if (chip->info->ops->port_set_rgmii_delay) { - err = chip->info->ops->port_set_rgmii_delay (chip, port, mode); -if (err && err != -EOPNOTSUPP ) - goto restore_link; - } - -if (chip->info->ops->port_set_cmode) { - err = chip->info->ops->port_set_cmode (chip, port, mode); -if (err && err != -EOPNOTSUPP ) - goto restore_link; - } - - err =0 ; + err =mv88e6xxx_port_config_interface (chip, port, mode); restore_link:if (chip->info->ops->port_set_link (chip, port, link))dev_err (chip->dev,"p%d: failed to restore MAC's link\n" , port);
@@ -603,33 +613,26 @@ static void mv88e6xxx_mac_config(struct dsa_switch *ds, int port, const struct phylink_link_state *state) {struct mv88e6xxx_chip *chip = ds->priv; -int speed, duplex, link, pause, err; +int err; +/* FIXME: is this the correct test? If we're in fixed mode on an +* internal port, why should we process this any different from +* PHY mode? On the other hand, the port may be automedia between +* an internal PHY and the serdes... +*/ if ((mode ==MLO_AN_PHY ) &&mv88e6xxx_phy_is_internal (ds, port))return ; -if (mode ==MLO_AN_FIXED ) { - link =LINK_FORCED_UP ; - speed = state->speed; - duplex = state->duplex; - }else if (!mv88e6xxx_phy_is_internal (ds, port)) { - link = state->link; - speed = state->speed; - duplex = state->duplex; - }else { - speed =SPEED_UNFORCED ; - duplex =DUPLEX_UNFORCED ; - link =LINK_UNFORCED ; - } - pause = !!phylink_test (state->advertising, Pause); -mv88e6xxx_reg_lock (chip); - err =mv88e6xxx_port_setup_mac (chip, port, link, speed, duplex, pause, - state->interface); +/* FIXME: should we force the link down here - but if we do, how +* do we restore the link force/unforce state? The driver layering +* gets in the way. +*/ + err =mv88e6xxx_port_config_interface (chip, port, state->interface);mv88e6xxx_reg_unlock (chip);if (err && err != -EOPNOTSUPP ) -dev_err (ds->dev,"p%d: failed to configure MAC\n" , port); +dev_err (ds->dev,"p%d: failed to configure MAC/PCS\n" , port); } static void mv88e6xxx_mac_link_down(struct dsa_switch *ds, int port,
Signature · 1 line
2.20.1
Re: [PATCH net-next 3/8] net: dsa: mv88e6xxx: configure interface settings in mac_config
Quoted 14 lines · Russell King
Only configure the interface settings in
mac_config(), leaving the speed and duplex settings tomac_link_upto deal with.Signed-off-by Russell King <[email protected]>drivers/net/dsa/mv88e6xxx/chip.c +4
-1@@ -603,33 +613,26 @@ static void mv88e6xxx_mac_config(struct dsa_switch *ds, int port, const struct phylink_link_state *state) {struct mv88e6xxx_chip *chip = ds->priv; -int speed, duplex, link, pause, err; +int err; +/* FIXME: is this the correct test? If we're in fixed mode on an +* internal port, why should we process this any different from +* PHY mode? On the other hand, the port may be automedia between
drivers/net/dsa/mv88e6xxx/chip.c static void mv88e6xxx_mac_config(struct dsa_switch *ds, int port, · line 628
Quoted 10 lines
drivers/net/dsa/mv88e6xxx/chip.c +7
-2+* an internal PHY and the serdes... +*/ - err =mv88e6xxx_port_setup_mac (chip, port, link, speed, duplex, pause, - state->interface); +/* FIXME: should we force the link down here - but if we do, how +* do we restore the link force/unforce state? The driver layering +* gets in the way. +*/ + err =mv88e6xxx_port_config_interface (chip, port, state->interface);
Hi Russell
I'm not too keen on these FIXMEs, but i don't have time at the moment to take a closer look.
Andrew
PATCH 4/8 net: dsa: mv88e6xxx: extend phylink to Serdes PHYs
In reply to Russell King - ARM Linux adminExtend the mv88e6xxx phylink implementation down to Serdes PHYs, which handle the PCS layer of such links.
- Implement phylink PCS link state reading, so that we can provide ethtool with the linkmodes and link speed in the expected manner.
Note: this will only be called for in-band negotiation, which is only supported by the serdes interfaces.
- Implement phylink PCS configuration, so that the in-band AN and advertisement can be configured.
- Implement phylink PCS negotiation restart, so that the in-band AN can be restarted.
- Implement phylink PCS link up, so that when operating out-of-band, the Serdes can be configured for the appropriate fixed speed mode.
--- drivers/net/dsa/mv88e6xxx/chip.c | 174 +++++++++++++-- drivers/net/dsa/mv88e6xxx/chip.h | 14 +- drivers/net/dsa/mv88e6xxx/serdes.c | 342 ++++++++++++++++++++++++----- drivers/net/dsa/mv88e6xxx/serdes.h | 24 ++ 4 files changed, 480 insertions(+), 74 deletions(-)
drivers/net/dsa/mv88e6xxx/chip.c +153 -21
@@ -419,9 +419,9 @@ static int mv88e6xxx_port_config_interface(struct mv88e6xxx_chip *chip,return 0 ; } -int mv88e6xxx_port_setup_mac (struct mv88e6xxx_chip *chip,int port,int link, -int speed,int duplex,int pause, -phy_interface_t mode) +static int mv88e6xxx_port_setup_mac (struct mv88e6xxx_chip *chip,int port, +int link,int speed,int duplex,int pause, +phy_interface_t mode) {struct phylink_link_state state;int err;
@@ -488,6 +488,81 @@ static int mv88e6xxx_phy_is_internal(struct dsa_switch *ds, int port)return port < chip->info->num_internal_phys; } +static int mv88e6xxx_serdes_pcs_get_state (struct dsa_switch *ds,int port, +struct phylink_link_state *state) +{ +struct mv88e6xxx_chip *chip = ds->priv; +u8 lane; +int err; + +mv88e6xxx_reg_lock (chip); + lane =mv88e6xxx_serdes_get_lane (chip, port); +if (lane && chip->info->ops->serdes_pcs_get_state) + err = chip->info->ops->serdes_pcs_get_state (chip, port, lane, + state); +else + err = -EOPNOTSUPP ; +mv88e6xxx_reg_unlock (chip); + +return err; +} + +static int mv88e6xxx_serdes_pcs_config (struct mv88e6xxx_chip *chip,int port, +unsigned int mode, +phy_interface_t interface, +const unsigned long *advertise) +{ +const struct mv88e6xxx_ops *ops = chip->info->ops; +u8 lane; + +if (ops->serdes_pcs_config) { + lane =mv88e6xxx_serdes_get_lane (chip, port); +if (lane) +return ops->serdes_pcs_config (chip, port, lane, mode, + interface, advertise); + } + +return 0 ; +} + +static void mv88e6xxx_serdes_pcs_an_restart (struct dsa_switch *ds,int port) +{ +struct mv88e6xxx_chip *chip = ds->priv; +const struct mv88e6xxx_ops *ops; +int err =0 ; +u8 lane; + + ops = chip->info->ops; + +if (ops->serdes_pcs_an_restart) { +mv88e6xxx_reg_lock (chip); + lane =mv88e6xxx_serdes_get_lane (chip, port); +if (lane) + err = ops->serdes_pcs_an_restart (chip, port, lane); +mv88e6xxx_reg_unlock (chip); + +if (err) +dev_err (ds->dev,"p%d: failed to restart AN\n" , port); + } +} + +static int mv88e6xxx_serdes_pcs_link_up (struct mv88e6xxx_chip *chip,int port, +unsigned int mode, +int speed,int duplex) +{ +const struct mv88e6xxx_ops *ops = chip->info->ops; +u8 lane; + +if (!phylink_autoneg_inband (mode) && ops->serdes_pcs_link_up) { + lane =mv88e6xxx_serdes_get_lane (chip, port); +if (lane) +return ops->serdes_pcs_link_up (chip, port, lane, + speed, duplex); + } + +return 0 ; +} +static void mv88e6065_phylink_validate (struct mv88e6xxx_chip *chip,int port,unsigned long *mask,struct phylink_link_state *state)
@@ -592,22 +667,6 @@ static void mv88e6xxx_validate(struct dsa_switch *ds, int port,phylink_helper_basex_speed (state); } -static int mv88e6xxx_link_state (struct dsa_switch *ds,int port, -struct phylink_link_state *state) -{ -struct mv88e6xxx_chip *chip = ds->priv; -int err; - -mv88e6xxx_reg_lock (chip); -if (chip->info->ops->port_link_state) - err = chip->info->ops->port_link_state (chip, port, state); -else - err = -EOPNOTSUPP ; -mv88e6xxx_reg_unlock (chip); - -return err; -} -static void mv88e6xxx_mac_config (struct dsa_switch *ds,int port,unsigned int mode,const struct phylink_link_state *state)
@@ -629,6 +688,18 @@ static void mv88e6xxx_mac_config(struct dsa_switch *ds, int port,* gets in the way. */ err =mv88e6xxx_port_config_interface (chip, port, state->interface); +if (err && err != -EOPNOTSUPP ) + goto err_unlock; + + err =mv88e6xxx_serdes_pcs_config (chip, port, mode, state->interface, + state->advertising); +/* FIXME: we should restart negotiation if something changed - which +* is something we get if we convert to using phylinks PCS operations. +*/ +if (err >0 ) + err =0 ; + +err_unlock:mv88e6xxx_reg_unlock (chip);if (err && err != -EOPNOTSUPP )
@@ -683,9 +754,14 @@ static void mv88e6xxx_mac_link_up(struct dsa_switch *ds, int port,/* FIXME: for an automedia port, should we force the link * down here - what if the link comes up due to "other" media * while we're bringing the port up, how is the exclusivity -* handled in the Marvell hardware? E.g. port 4 on 88E6532 +* handled in the Marvell hardware? E.g. port 2 on 88E6390 * shared between internal PHY and Serdes. */ + err =mv88e6xxx_serdes_pcs_link_up (chip, port, mode, speed, + duplex); +if (err) + goto error; +if (ops->port_set_speed) { err = ops->port_set_speed (chip, port, speed);if (err && err != -EOPNOTSUPP )
@@ -3557,6 +3633,11 @@ static const struct mv88e6xxx_ops mv88e6141_ops = { .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge, .serdes_power = mv88e6390_serdes_power, .serdes_get_lane = mv88e6341_serdes_get_lane, +/* Check status register pause & lpa register */ + .serdes_pcs_get_state = mv88e6390_serdes_pcs_get_state, + .serdes_pcs_config = mv88e6390_serdes_pcs_config, + .serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart, + .serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up, .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, .serdes_irq_enable = mv88e6390_serdes_irq_enable, .serdes_irq_status = mv88e6390_serdes_irq_status,
@@ -3729,6 +3810,10 @@ static const struct mv88e6xxx_ops mv88e6172_ops = { .vtu_getnext = mv88e6352_g1_vtu_getnext, .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge, .serdes_get_lane = mv88e6352_serdes_get_lane, + .serdes_pcs_get_state = mv88e6352_serdes_pcs_get_state, + .serdes_pcs_config = mv88e6352_serdes_pcs_config, + .serdes_pcs_an_restart = mv88e6352_serdes_pcs_an_restart, + .serdes_pcs_link_up = mv88e6352_serdes_pcs_link_up, .serdes_power = mv88e6352_serdes_power, .serdes_get_regs_len = mv88e6352_serdes_get_regs_len, .serdes_get_regs = mv88e6352_serdes_get_regs,
@@ -3822,6 +3907,10 @@ static const struct mv88e6xxx_ops mv88e6176_ops = { .vtu_getnext = mv88e6352_g1_vtu_getnext, .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge, .serdes_get_lane = mv88e6352_serdes_get_lane, + .serdes_pcs_get_state = mv88e6352_serdes_pcs_get_state, + .serdes_pcs_config = mv88e6352_serdes_pcs_config, + .serdes_pcs_an_restart = mv88e6352_serdes_pcs_an_restart, + .serdes_pcs_link_up = mv88e6352_serdes_pcs_link_up, .serdes_power = mv88e6352_serdes_power, .serdes_irq_mapping = mv88e6352_serdes_irq_mapping, .serdes_irq_enable = mv88e6352_serdes_irq_enable,
@@ -3912,6 +4001,11 @@ static const struct mv88e6xxx_ops mv88e6190_ops = { .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge, .serdes_power = mv88e6390_serdes_power, .serdes_get_lane = mv88e6390_serdes_get_lane, +/* Check status register pause & lpa register */ + .serdes_pcs_get_state = mv88e6390_serdes_pcs_get_state, + .serdes_pcs_config = mv88e6390_serdes_pcs_config, + .serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart, + .serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up, .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, .serdes_irq_enable = mv88e6390_serdes_irq_enable, .serdes_irq_status = mv88e6390_serdes_irq_status,
@@ -3968,6 +4062,11 @@ static const struct mv88e6xxx_ops mv88e6190x_ops = { .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge, .serdes_power = mv88e6390_serdes_power, .serdes_get_lane = mv88e6390x_serdes_get_lane, +/* Check status register pause & lpa register */ + .serdes_pcs_get_state = mv88e6390_serdes_pcs_get_state, + .serdes_pcs_config = mv88e6390_serdes_pcs_config, + .serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart, + .serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up, .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, .serdes_irq_enable = mv88e6390_serdes_irq_enable, .serdes_irq_status = mv88e6390_serdes_irq_status,
@@ -4023,6 +4122,11 @@ static const struct mv88e6xxx_ops mv88e6191_ops = { .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge, .serdes_power = mv88e6390_serdes_power, .serdes_get_lane = mv88e6390_serdes_get_lane, +/* Check status register pause & lpa register */ + .serdes_pcs_get_state = mv88e6390_serdes_pcs_get_state, + .serdes_pcs_config = mv88e6390_serdes_pcs_config, + .serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart, + .serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up, .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, .serdes_irq_enable = mv88e6390_serdes_irq_enable, .serdes_irq_status = mv88e6390_serdes_irq_status,
@@ -4080,6 +4184,10 @@ static const struct mv88e6xxx_ops mv88e6240_ops = { .vtu_getnext = mv88e6352_g1_vtu_getnext, .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge, .serdes_get_lane = mv88e6352_serdes_get_lane, + .serdes_pcs_get_state = mv88e6352_serdes_pcs_get_state, + .serdes_pcs_config = mv88e6352_serdes_pcs_config, + .serdes_pcs_an_restart = mv88e6352_serdes_pcs_an_restart, + .serdes_pcs_link_up = mv88e6352_serdes_pcs_link_up, .serdes_power = mv88e6352_serdes_power, .serdes_irq_mapping = mv88e6352_serdes_irq_mapping, .serdes_irq_enable = mv88e6352_serdes_irq_enable,
@@ -4176,6 +4284,11 @@ static const struct mv88e6xxx_ops mv88e6290_ops = { .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge, .serdes_power = mv88e6390_serdes_power, .serdes_get_lane = mv88e6390_serdes_get_lane, +/* Check status register pause & lpa register */ + .serdes_pcs_get_state = mv88e6390_serdes_pcs_get_state, + .serdes_pcs_config = mv88e6390_serdes_pcs_config, + .serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart, + .serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up, .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, .serdes_irq_enable = mv88e6390_serdes_irq_enable, .serdes_irq_status = mv88e6390_serdes_irq_status,
@@ -4319,6 +4432,11 @@ static const struct mv88e6xxx_ops mv88e6341_ops = { .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge, .serdes_power = mv88e6390_serdes_power, .serdes_get_lane = mv88e6341_serdes_get_lane, +/* Check status register pause & lpa register */ + .serdes_pcs_get_state = mv88e6390_serdes_pcs_get_state, + .serdes_pcs_config = mv88e6390_serdes_pcs_config, + .serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart, + .serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up, .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, .serdes_irq_enable = mv88e6390_serdes_irq_enable, .serdes_irq_status = mv88e6390_serdes_irq_status,
@@ -4458,6 +4576,10 @@ static const struct mv88e6xxx_ops mv88e6352_ops = { .vtu_getnext = mv88e6352_g1_vtu_getnext, .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge, .serdes_get_lane = mv88e6352_serdes_get_lane, + .serdes_pcs_get_state = mv88e6352_serdes_pcs_get_state, + .serdes_pcs_config = mv88e6352_serdes_pcs_config, + .serdes_pcs_an_restart = mv88e6352_serdes_pcs_an_restart, + .serdes_pcs_link_up = mv88e6352_serdes_pcs_link_up, .serdes_power = mv88e6352_serdes_power, .serdes_irq_mapping = mv88e6352_serdes_irq_mapping, .serdes_irq_enable = mv88e6352_serdes_irq_enable,
@@ -4519,6 +4641,11 @@ static const struct mv88e6xxx_ops mv88e6390_ops = { .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge, .serdes_power = mv88e6390_serdes_power, .serdes_get_lane = mv88e6390_serdes_get_lane, +/* Check status register pause & lpa register */ + .serdes_pcs_get_state = mv88e6390_serdes_pcs_get_state, + .serdes_pcs_config = mv88e6390_serdes_pcs_config, + .serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart, + .serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up, .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, .serdes_irq_enable = mv88e6390_serdes_irq_enable, .serdes_irq_status = mv88e6390_serdes_irq_status,
@@ -4579,6 +4706,10 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = { .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge, .serdes_power = mv88e6390_serdes_power, .serdes_get_lane = mv88e6390x_serdes_get_lane, + .serdes_pcs_get_state = mv88e6390_serdes_pcs_get_state, + .serdes_pcs_config = mv88e6390_serdes_pcs_config, + .serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart, + .serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up, .serdes_irq_mapping = mv88e6390_serdes_irq_mapping, .serdes_irq_enable = mv88e6390_serdes_irq_enable, .serdes_irq_status = mv88e6390_serdes_irq_status,
@@ -5457,8 +5588,9 @@ static const struct dsa_switch_ops mv88e6xxx_switch_ops = { .setup = mv88e6xxx_setup, .teardown = mv88e6xxx_teardown, .phylink_validate = mv88e6xxx_validate, - .phylink_mac_link_state = mv88e6xxx_link_state, + .phylink_mac_link_state = mv88e6xxx_serdes_pcs_get_state, .phylink_mac_config = mv88e6xxx_mac_config, + .phylink_mac_an_restart = mv88e6xxx_serdes_pcs_an_restart, .phylink_mac_link_down = mv88e6xxx_mac_link_down, .phylink_mac_link_up = mv88e6xxx_mac_link_up, .get_strings = mv88e6xxx_get_strings,
drivers/net/dsa/mv88e6xxx/chip.h +11 -3
@@ -502,6 +502,17 @@ struct mv88e6xxx_ops {/* SERDES lane mapping */ u8 (*serdes_get_lane)(struct mv88e6xxx_chip *chip,int port); +int (*serdes_pcs_get_state)(struct mv88e6xxx_chip *chip,int port, +u8 lane,struct phylink_link_state *state); +int (*serdes_pcs_config)(struct mv88e6xxx_chip *chip,int port, +u8 lane,unsigned int mode, +phy_interface_t interface, +const unsigned long *advertise); +int (*serdes_pcs_an_restart)(struct mv88e6xxx_chip *chip,int port, +u8 lane); +int (*serdes_pcs_link_up)(struct mv88e6xxx_chip *chip,int port, +u8 lane,int speed,int duplex); +/* SERDES interrupt handling */ unsigned int (*serdes_irq_mapping)(struct mv88e6xxx_chip *chip,int port);
@@ -669,9 +680,6 @@ int mv88e6xxx_wait_mask(struct mv88e6xxx_chip *chip, int addr, int reg, u16 mask, u16 val);int mv88e6xxx_wait_bit (struct mv88e6xxx_chip *chip,int addr,int reg,int bit,int val); -int mv88e6xxx_port_setup_mac (struct mv88e6xxx_chip *chip,int port,int link, -int speed,int duplex,int pause, -phy_interface_t mode);struct mii_bus *mv88e6xxx_default_mdio_bus (struct mv88e6xxx_chip *chip);static inline void mv88e6xxx_reg_lock (struct mv88e6xxx_chip *chip)
drivers/net/dsa/mv88e6xxx/serdes.c +292 -50
375 lines not on this page · raw message
drivers/net/dsa/mv88e6xxx/serdes.h +24 -0
@@ -48,6 +48,8 @@/* 1000BASE-X and SGMII */ #define MV88E6390_SGMII_BMCR (0x2000 + MII_BMCR) +#define MV88E6390_SGMII_ADVERTISE (0x2000 + MII_ADVERTISE) +#define MV88E6390_SGMII_LPA (0x2000 + MII_LPA)#define MV88E6390_SGMII_INT_ENABLE 0xa001#define MV88E6390_SGMII_INT_SPEED_CHANGE BIT(14)#define MV88E6390_SGMII_INT_DUPLEX_CHANGE BIT(13)
@@ -66,6 +68,8 @@#define MV88E6390_SGMII_PHY_STATUS_DUPLEX_FULL BIT(13)#define MV88E6390_SGMII_PHY_STATUS_SPD_DPL_VALID BIT(11)#define MV88E6390_SGMII_PHY_STATUS_LINK BIT(10) +#define MV88E6390_SGMII_PHY_STATUS_TX_PAUSE BIT(3) +#define MV88E6390_SGMII_PHY_STATUS_RX_PAUSE BIT(2)/* Packet generator pad packet checker */ #define MV88E6390_PG_CONTROL 0xf010
@@ -75,6 +79,26 @@ u8 mv88e6341_serdes_get_lane(struct mv88e6xxx_chip *chip, int port);u8 mv88e6352_serdes_get_lane (struct mv88e6xxx_chip *chip,int port);u8 mv88e6390_serdes_get_lane (struct mv88e6xxx_chip *chip,int port);u8 mv88e6390x_serdes_get_lane (struct mv88e6xxx_chip *chip,int port); +int mv88e6352_serdes_pcs_config (struct mv88e6xxx_chip *chip,int port, +u8 lane,unsigned int mode, +phy_interface_t interface, +const unsigned long *advertise); +int mv88e6390_serdes_pcs_config (struct mv88e6xxx_chip *chip,int port, +u8 lane,unsigned int mode, +phy_interface_t interface, +const unsigned long *advertise); +int mv88e6352_serdes_pcs_get_state (struct mv88e6xxx_chip *chip,int port, +u8 lane,struct phylink_link_state *state); +int mv88e6390_serdes_pcs_get_state (struct mv88e6xxx_chip *chip,int port, +u8 lane,struct phylink_link_state *state); +int mv88e6352_serdes_pcs_an_restart (struct mv88e6xxx_chip *chip,int port, +u8 lane); +int mv88e6390_serdes_pcs_an_restart (struct mv88e6xxx_chip *chip,int port, +u8 lane); +int mv88e6352_serdes_pcs_link_up (struct mv88e6xxx_chip *chip,int port, +u8 lane,int speed,int duplex); +int mv88e6390_serdes_pcs_link_up (struct mv88e6xxx_chip *chip,int port, +u8 lane,int speed,int duplex);unsigned int mv88e6352_serdes_irq_mapping (struct mv88e6xxx_chip *chip,int port); unsigned int mv88e6390_serdes_irq_mapping(struct mv88e6xxx_chip *chip,
Signature · 1 line
2.20.1
Re: [PATCH net-next 4/8] net: dsa: mv88e6xxx: extend phylink to Serdes PHYs
drivers/net/dsa/mv88e6xxx/chip.c static void mv88e6xxx_mac_link_up(struct dsa_switch *ds, int port, · line 759
Quoted 8 lines
drivers/net/dsa/mv88e6xxx/chip.c +1
-1@@ -683,9 +754,14 @@ static void mv88e6xxx_mac_link_up(struct dsa_switch *ds, int port,/* FIXME: for an automedia port, should we force the link * down here - what if the link comes up due to "other" media * while we're bringing the port up, how is the exclusivity -* handled in the Marvell hardware? E.g. port 4 on 88E6532 +* handled in the Marvell hardware? E.g. port 2 on 88E6390 * shared between internal PHY and Serdes. */
automedia makes things interesting. You have to read the cmode to know if the internal PHY or the SERDES has 'won'. I thimk my preference would of been to keep it simple and look at phy-mode in DT. If it is 1000BaseX, turn on the SERDES and turn off the internal PHY. But i know of at lease one person who wants auto media.
drivers/net/dsa/mv88e6xxx/serdes.c static int mv88e6390_serdes_write(struct mv88e6xxx_chip *chip, · line 55
Quoted 4 lines
drivers/net/dsa/mv88e6xxx/serdes.c +4
-0+static int mv88e6xxx_serdes_pcs_get_state (struct mv88e6xxx_chip *chip, +u16 status,u16 lpa, +struct phylink_link_state *state) +{
At some point in the future, we might want to rename this. If i remember correct, the 1000BaseX and SGMII PCS uses different registers to the 10G PCS. We will need to look at the cmode to determine which PCS is in operation.
Andrew
PATCH 5/8 net: dsa: mv88e6xxx: fix Serdes link changes
In reply to Russell King - ARM Linux adminphylink_mac_change() is supposed to be called with a 'false' argument if the link has gone down since it was last reported up; this is to ensure that link events along with renegotiation events are always correctly reported to userspace.
Read the BMSR once when we have an interrupt, and report the link latched status to phylink via phylink_mac_change(). phylink will deal automatically with re-reading the link state once it has processed the link-down event.
--- drivers/net/dsa/mv88e6xxx/serdes.c | 33 +++++++++++------------------- drivers/net/dsa/mv88e6xxx/serdes.h | 1 + 2 files changed, 13 insertions(+), 21 deletions(-)
drivers/net/dsa/mv88e6xxx/serdes.c +12 -21
@@ -340,26 +340,17 @@ int mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port,static void mv88e6352_serdes_irq_link (struct mv88e6xxx_chip *chip,int port) { -struct dsa_switch *ds = chip->ds; -u16 status; -bool up; +u16 bmsr;int err; - err =mv88e6352_serdes_read (chip,MII_BMSR , &status); -if (err) -return ; - -/* Status must be read twice in order to give the current link -* status. Otherwise the change in link status since the last -* read of the register is returned. -*/ - err =mv88e6352_serdes_read (chip,MII_BMSR , &status); -if (err) +/* If the link has dropped, we want to know about it. */ + err =mv88e6352_serdes_read (chip,MII_BMSR , &bmsr); +if (err) { +dev_err (chip->dev,"can't read Serdes BMSR: %d\n" , err);return ; + } - up = status &BMSR_LSTATUS ; - -dsa_port_phylink_mac_change (ds, port, up); +dsa_port_phylink_mac_change (chip->ds, port, !!(bmsr &BMSR_LSTATUS )); } irqreturn_t mv88e6352_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
@@ -833,18 +824,18 @@ int mv88e6390_serdes_pcs_link_up(struct mv88e6xxx_chip *chip, int port,static void mv88e6390_serdes_irq_link_sgmii (struct mv88e6xxx_chip *chip,int port,u8 lane) { -u16 status; +u16 bmsr;int err; +/* If the link has dropped, we want to know about it. */ err =mv88e6390_serdes_read (chip, lane,MDIO_MMD_PHYXS , -MV88E6390_SGMII_PHY_STATUS , &status); +MV88E6390_SGMII_BMSR , &bmsr);if (err) { -dev_err (chip->dev,"can't read SGMII PHY status: %d\n" , err); +dev_err (chip->dev,"can't read Serdes BMSR: %d\n" , err);return ; } -dsa_port_phylink_mac_change (chip->ds, port, - !!(status &MV88E6390_SGMII_PHY_STATUS_LINK )); +dsa_port_phylink_mac_change (chip->ds, port, !!(bmsr &BMSR_LSTATUS )); } static int mv88e6390_serdes_irq_enable_sgmii(struct mv88e6xxx_chip *chip,
drivers/net/dsa/mv88e6xxx/serdes.h +1 -0
@@ -48,6 +48,7 @@/* 1000BASE-X and SGMII */ #define MV88E6390_SGMII_BMCR (0x2000 + MII_BMCR) +#define MV88E6390_SGMII_BMSR (0x2000 + MII_BMSR)#define MV88E6390_SGMII_ADVERTISE (0x2000 + MII_ADVERTISE)#define MV88E6390_SGMII_LPA (0x2000 + MII_LPA)#define MV88E6390_SGMII_INT_ENABLE 0xa001
Signature · 1 line
2.20.1
Re: [PATCH net-next 5/8] net: dsa: mv88e6xxx: fix Serdes link changes
Quoted 11 lines · Russell King
phylink_mac_change()is supposed to be called with a 'false' argument if the link has gone down since it was last reported up; this is to ensure that link events along with renegotiation events are always correctly reported to userspace.Read the BMSR once when we have an interrupt, and report the link latched status to phylink via
phylink_mac_change(). phylink will deal automatically with re-reading the link state once it has processed the link-down event.Signed-off-by Russell King <[email protected]>
Andrew
PATCH 6/8 net: dsa: mv88e6xxx: combine port_set_speed and port_set_duplex
In reply to Russell King - ARM Linux adminSetting the speed independently of duplex makes little sense; the two parameters result from negotiation or fixed setup, and may have inter- dependencies. Moreover, they are always controlled via the same register - having them split means we have to read-modify-write this register twice.
Combine the two operations into a single port_set_speed_duplex() operation. Not only is this more efficient, it reduces the size of the code as well.
--- drivers/net/dsa/mv88e6xxx/chip.c | 103 ++++++++++------------------- drivers/net/dsa/mv88e6xxx/chip.h | 18 ++---- drivers/net/dsa/mv88e6xxx/port.c | 108 +++++++++++++++---------------- drivers/net/dsa/mv88e6xxx/port.h | 23 ++++--- 4 files changed, 107 insertions(+), 145 deletions(-)
drivers/net/dsa/mv88e6xxx/chip.c +33 -70
@@ -452,8 +452,9 @@ static int mv88e6xxx_port_setup_mac(struct mv88e6xxx_chip *chip, int port,if (err)return err; -if (chip->info->ops->port_set_speed) { - err = chip->info->ops->port_set_speed (chip, port, speed); +if (chip->info->ops->port_set_speed_duplex) { + err = chip->info->ops->port_set_speed_duplex (chip, port, + speed, duplex);if (err && err != -EOPNOTSUPP ) goto restore_link; }
@@ -467,12 +468,6 @@ static int mv88e6xxx_port_setup_mac(struct mv88e6xxx_chip *chip, int port, goto restore_link; } -if (chip->info->ops->port_set_duplex) { - err = chip->info->ops->port_set_duplex (chip, port, duplex); -if (err && err != -EOPNOTSUPP ) - goto restore_link; - } - err =mv88e6xxx_port_config_interface (chip, port, mode); restore_link:if (chip->info->ops->port_set_link (chip, port, link))
@@ -762,14 +757,9 @@ static void mv88e6xxx_mac_link_up(struct dsa_switch *ds, int port,if (err) goto error; -if (ops->port_set_speed) { - err = ops->port_set_speed (chip, port, speed); -if (err && err != -EOPNOTSUPP ) - goto error; - } - -if (ops->port_set_duplex) { - err = ops->port_set_duplex (chip, port, duplex); +if (ops->port_set_speed_duplex) { + err = ops->port_set_speed_duplex (chip, port, + speed, duplex);if (err && err != -EOPNOTSUPP ) goto error; }
@@ -3412,8 +3402,7 @@ static const struct mv88e6xxx_ops mv88e6085_ops = { .phy_read = mv88e6185_phy_ppu_read, .phy_write = mv88e6185_phy_ppu_write, .port_set_link = mv88e6xxx_port_set_link, - .port_set_duplex = mv88e6xxx_port_set_duplex, - .port_set_speed = mv88e6185_port_set_speed, + .port_set_speed_duplex = mv88e6185_port_set_speed_duplex, .port_tag_remap = mv88e6095_port_tag_remap, .port_set_frame_mode = mv88e6351_port_set_frame_mode, .port_set_egress_floods = mv88e6352_port_set_egress_floods,
@@ -3452,8 +3441,7 @@ static const struct mv88e6xxx_ops mv88e6095_ops = { .phy_read = mv88e6185_phy_ppu_read, .phy_write = mv88e6185_phy_ppu_write, .port_set_link = mv88e6xxx_port_set_link, - .port_set_duplex = mv88e6xxx_port_set_duplex, - .port_set_speed = mv88e6185_port_set_speed, + .port_set_speed_duplex = mv88e6185_port_set_speed_duplex, .port_set_frame_mode = mv88e6085_port_set_frame_mode, .port_set_egress_floods = mv88e6185_port_set_egress_floods, .port_set_upstream_port = mv88e6095_port_set_upstream_port,
@@ -3483,8 +3471,7 @@ static const struct mv88e6xxx_ops mv88e6097_ops = { .phy_read = mv88e6xxx_g2_smi_phy_read, .phy_write = mv88e6xxx_g2_smi_phy_write, .port_set_link = mv88e6xxx_port_set_link, - .port_set_duplex = mv88e6xxx_port_set_duplex, - .port_set_speed = mv88e6185_port_set_speed, + .port_set_speed_duplex = mv88e6185_port_set_speed_duplex, .port_tag_remap = mv88e6095_port_tag_remap, .port_set_frame_mode = mv88e6351_port_set_frame_mode, .port_set_egress_floods = mv88e6352_port_set_egress_floods,
@@ -3523,8 +3510,7 @@ static const struct mv88e6xxx_ops mv88e6123_ops = { .phy_read = mv88e6xxx_g2_smi_phy_read, .phy_write = mv88e6xxx_g2_smi_phy_write, .port_set_link = mv88e6xxx_port_set_link, - .port_set_duplex = mv88e6xxx_port_set_duplex, - .port_set_speed = mv88e6185_port_set_speed, + .port_set_speed_duplex = mv88e6185_port_set_speed_duplex, .port_set_frame_mode = mv88e6085_port_set_frame_mode, .port_set_egress_floods = mv88e6352_port_set_egress_floods, .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
@@ -3558,8 +3544,7 @@ static const struct mv88e6xxx_ops mv88e6131_ops = { .phy_read = mv88e6185_phy_ppu_read, .phy_write = mv88e6185_phy_ppu_write, .port_set_link = mv88e6xxx_port_set_link, - .port_set_duplex = mv88e6xxx_port_set_duplex, - .port_set_speed = mv88e6185_port_set_speed, + .port_set_speed_duplex = mv88e6185_port_set_speed_duplex, .port_tag_remap = mv88e6095_port_tag_remap, .port_set_frame_mode = mv88e6351_port_set_frame_mode, .port_set_egress_floods = mv88e6185_port_set_egress_floods,
@@ -3601,9 +3586,8 @@ static const struct mv88e6xxx_ops mv88e6141_ops = { .phy_read = mv88e6xxx_g2_smi_phy_read, .phy_write = mv88e6xxx_g2_smi_phy_write, .port_set_link = mv88e6xxx_port_set_link, - .port_set_duplex = mv88e6xxx_port_set_duplex, .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay, - .port_set_speed = mv88e6341_port_set_speed, + .port_set_speed_duplex = mv88e6341_port_set_speed_duplex, .port_max_speed_mode = mv88e6341_port_max_speed_mode, .port_tag_remap = mv88e6095_port_tag_remap, .port_set_frame_mode = mv88e6351_port_set_frame_mode,
@@ -3654,8 +3638,7 @@ static const struct mv88e6xxx_ops mv88e6161_ops = { .phy_read = mv88e6xxx_g2_smi_phy_read, .phy_write = mv88e6xxx_g2_smi_phy_write, .port_set_link = mv88e6xxx_port_set_link, - .port_set_duplex = mv88e6xxx_port_set_duplex, - .port_set_speed = mv88e6185_port_set_speed, + .port_set_speed_duplex = mv88e6185_port_set_speed_duplex, .port_tag_remap = mv88e6095_port_tag_remap, .port_set_frame_mode = mv88e6351_port_set_frame_mode, .port_set_egress_floods = mv88e6352_port_set_egress_floods,
@@ -3697,8 +3680,7 @@ static const struct mv88e6xxx_ops mv88e6165_ops = { .phy_read = mv88e6165_phy_read, .phy_write = mv88e6165_phy_write, .port_set_link = mv88e6xxx_port_set_link, - .port_set_duplex = mv88e6xxx_port_set_duplex, - .port_set_speed = mv88e6185_port_set_speed, + .port_set_speed_duplex = mv88e6185_port_set_speed_duplex, .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, .port_link_state = mv88e6352_port_link_state,
@@ -3733,9 +3715,8 @@ static const struct mv88e6xxx_ops mv88e6171_ops = { .phy_read = mv88e6xxx_g2_smi_phy_read, .phy_write = mv88e6xxx_g2_smi_phy_write, .port_set_link = mv88e6xxx_port_set_link, - .port_set_duplex = mv88e6xxx_port_set_duplex, .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay, - .port_set_speed = mv88e6185_port_set_speed, + .port_set_speed_duplex = mv88e6185_port_set_speed_duplex, .port_tag_remap = mv88e6095_port_tag_remap, .port_set_frame_mode = mv88e6351_port_set_frame_mode, .port_set_egress_floods = mv88e6352_port_set_egress_floods,
@@ -3777,9 +3758,8 @@ static const struct mv88e6xxx_ops mv88e6172_ops = { .phy_read = mv88e6xxx_g2_smi_phy_read, .phy_write = mv88e6xxx_g2_smi_phy_write, .port_set_link = mv88e6xxx_port_set_link, - .port_set_duplex = mv88e6xxx_port_set_duplex, .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay, - .port_set_speed = mv88e6352_port_set_speed, + .port_set_speed_duplex = mv88e6352_port_set_speed_duplex, .port_tag_remap = mv88e6095_port_tag_remap, .port_set_policy = mv88e6352_port_set_policy, .port_set_frame_mode = mv88e6351_port_set_frame_mode,
@@ -3830,9 +3810,8 @@ static const struct mv88e6xxx_ops mv88e6175_ops = { .phy_read = mv88e6xxx_g2_smi_phy_read, .phy_write = mv88e6xxx_g2_smi_phy_write, .port_set_link = mv88e6xxx_port_set_link, - .port_set_duplex = mv88e6xxx_port_set_duplex, .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay, - .port_set_speed = mv88e6185_port_set_speed, + .port_set_speed_duplex = mv88e6185_port_set_speed_duplex, .port_tag_remap = mv88e6095_port_tag_remap, .port_set_frame_mode = mv88e6351_port_set_frame_mode, .port_set_egress_floods = mv88e6352_port_set_egress_floods,
@@ -3874,9 +3853,8 @@ static const struct mv88e6xxx_ops mv88e6176_ops = { .phy_read = mv88e6xxx_g2_smi_phy_read, .phy_write = mv88e6xxx_g2_smi_phy_write, .port_set_link = mv88e6xxx_port_set_link, - .port_set_duplex = mv88e6xxx_port_set_duplex, .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay, - .port_set_speed = mv88e6352_port_set_speed, + .port_set_speed_duplex = mv88e6352_port_set_speed_duplex, .port_tag_remap = mv88e6095_port_tag_remap, .port_set_policy = mv88e6352_port_set_policy, .port_set_frame_mode = mv88e6351_port_set_frame_mode,
@@ -3929,8 +3907,7 @@ static const struct mv88e6xxx_ops mv88e6185_ops = { .phy_read = mv88e6185_phy_ppu_read, .phy_write = mv88e6185_phy_ppu_write, .port_set_link = mv88e6xxx_port_set_link, - .port_set_duplex = mv88e6xxx_port_set_duplex, - .port_set_speed = mv88e6185_port_set_speed, + .port_set_speed_duplex = mv88e6185_port_set_speed_duplex, .port_set_frame_mode = mv88e6085_port_set_frame_mode, .port_set_egress_floods = mv88e6185_port_set_egress_floods, .port_egress_rate_limiting = mv88e6095_port_egress_rate_limiting,
@@ -3967,9 +3944,8 @@ static const struct mv88e6xxx_ops mv88e6190_ops = { .phy_read = mv88e6xxx_g2_smi_phy_read, .phy_write = mv88e6xxx_g2_smi_phy_write, .port_set_link = mv88e6xxx_port_set_link, - .port_set_duplex = mv88e6xxx_port_set_duplex, .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay, - .port_set_speed = mv88e6390_port_set_speed, + .port_set_speed_duplex = mv88e6390_port_set_speed_duplex, .port_max_speed_mode = mv88e6390_port_max_speed_mode, .port_tag_remap = mv88e6390_port_tag_remap, .port_set_policy = mv88e6352_port_set_policy,
@@ -4028,9 +4004,8 @@ static const struct mv88e6xxx_ops mv88e6190x_ops = { .phy_read = mv88e6xxx_g2_smi_phy_read, .phy_write = mv88e6xxx_g2_smi_phy_write, .port_set_link = mv88e6xxx_port_set_link, - .port_set_duplex = mv88e6xxx_port_set_duplex, .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay, - .port_set_speed = mv88e6390x_port_set_speed, + .port_set_speed_duplex = mv88e6390x_port_set_speed_duplex, .port_max_speed_mode = mv88e6390x_port_max_speed_mode, .port_tag_remap = mv88e6390_port_tag_remap, .port_set_policy = mv88e6352_port_set_policy,
@@ -4089,9 +4064,8 @@ static const struct mv88e6xxx_ops mv88e6191_ops = { .phy_read = mv88e6xxx_g2_smi_phy_read, .phy_write = mv88e6xxx_g2_smi_phy_write, .port_set_link = mv88e6xxx_port_set_link, - .port_set_duplex = mv88e6xxx_port_set_duplex, .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay, - .port_set_speed = mv88e6390_port_set_speed, + .port_set_speed_duplex = mv88e6390_port_set_speed_duplex, .port_max_speed_mode = mv88e6390_port_max_speed_mode, .port_tag_remap = mv88e6390_port_tag_remap, .port_set_frame_mode = mv88e6351_port_set_frame_mode,
@@ -4151,9 +4125,8 @@ static const struct mv88e6xxx_ops mv88e6240_ops = { .phy_read = mv88e6xxx_g2_smi_phy_read, .phy_write = mv88e6xxx_g2_smi_phy_write, .port_set_link = mv88e6xxx_port_set_link, - .port_set_duplex = mv88e6xxx_port_set_duplex, .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay, - .port_set_speed = mv88e6352_port_set_speed, + .port_set_speed_duplex = mv88e6352_port_set_speed_duplex, .port_tag_remap = mv88e6095_port_tag_remap, .port_set_policy = mv88e6352_port_set_policy, .port_set_frame_mode = mv88e6351_port_set_frame_mode,
@@ -4211,9 +4184,8 @@ static const struct mv88e6xxx_ops mv88e6250_ops = { .phy_read = mv88e6xxx_g2_smi_phy_read, .phy_write = mv88e6xxx_g2_smi_phy_write, .port_set_link = mv88e6xxx_port_set_link, - .port_set_duplex = mv88e6xxx_port_set_duplex, .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay, - .port_set_speed = mv88e6250_port_set_speed, + .port_set_speed_duplex = mv88e6250_port_set_speed_duplex, .port_tag_remap = mv88e6095_port_tag_remap, .port_set_frame_mode = mv88e6351_port_set_frame_mode, .port_set_egress_floods = mv88e6352_port_set_egress_floods,
@@ -4250,9 +4222,8 @@ static const struct mv88e6xxx_ops mv88e6290_ops = { .phy_read = mv88e6xxx_g2_smi_phy_read, .phy_write = mv88e6xxx_g2_smi_phy_write, .port_set_link = mv88e6xxx_port_set_link, - .port_set_duplex = mv88e6xxx_port_set_duplex, .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay, - .port_set_speed = mv88e6390_port_set_speed, + .port_set_speed_duplex = mv88e6390_port_set_speed_duplex, .port_max_speed_mode = mv88e6390_port_max_speed_mode, .port_tag_remap = mv88e6390_port_tag_remap, .port_set_policy = mv88e6352_port_set_policy,
@@ -4314,8 +4285,7 @@ static const struct mv88e6xxx_ops mv88e6320_ops = { .phy_read = mv88e6xxx_g2_smi_phy_read, .phy_write = mv88e6xxx_g2_smi_phy_write, .port_set_link = mv88e6xxx_port_set_link, - .port_set_duplex = mv88e6xxx_port_set_duplex, - .port_set_speed = mv88e6185_port_set_speed, + .port_set_speed_duplex = mv88e6185_port_set_speed_duplex, .port_tag_remap = mv88e6095_port_tag_remap, .port_set_frame_mode = mv88e6351_port_set_frame_mode, .port_set_egress_floods = mv88e6352_port_set_egress_floods,
@@ -4358,8 +4328,7 @@ static const struct mv88e6xxx_ops mv88e6321_ops = { .phy_read = mv88e6xxx_g2_smi_phy_read, .phy_write = mv88e6xxx_g2_smi_phy_write, .port_set_link = mv88e6xxx_port_set_link, - .port_set_duplex = mv88e6xxx_port_set_duplex, - .port_set_speed = mv88e6185_port_set_speed, + .port_set_speed_duplex = mv88e6185_port_set_speed_duplex, .port_tag_remap = mv88e6095_port_tag_remap, .port_set_frame_mode = mv88e6351_port_set_frame_mode, .port_set_egress_floods = mv88e6352_port_set_egress_floods,
@@ -4400,9 +4369,8 @@ static const struct mv88e6xxx_ops mv88e6341_ops = { .phy_read = mv88e6xxx_g2_smi_phy_read, .phy_write = mv88e6xxx_g2_smi_phy_write, .port_set_link = mv88e6xxx_port_set_link, - .port_set_duplex = mv88e6xxx_port_set_duplex, .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay, - .port_set_speed = mv88e6341_port_set_speed, + .port_set_speed_duplex = mv88e6341_port_set_speed_duplex, .port_max_speed_mode = mv88e6341_port_max_speed_mode, .port_tag_remap = mv88e6095_port_tag_remap, .port_set_frame_mode = mv88e6351_port_set_frame_mode,
@@ -4455,9 +4423,8 @@ static const struct mv88e6xxx_ops mv88e6350_ops = { .phy_read = mv88e6xxx_g2_smi_phy_read, .phy_write = mv88e6xxx_g2_smi_phy_write, .port_set_link = mv88e6xxx_port_set_link, - .port_set_duplex = mv88e6xxx_port_set_duplex, .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay, - .port_set_speed = mv88e6185_port_set_speed, + .port_set_speed_duplex = mv88e6185_port_set_speed_duplex, .port_tag_remap = mv88e6095_port_tag_remap, .port_set_frame_mode = mv88e6351_port_set_frame_mode, .port_set_egress_floods = mv88e6352_port_set_egress_floods,
@@ -4497,9 +4464,8 @@ static const struct mv88e6xxx_ops mv88e6351_ops = { .phy_read = mv88e6xxx_g2_smi_phy_read, .phy_write = mv88e6xxx_g2_smi_phy_write, .port_set_link = mv88e6xxx_port_set_link, - .port_set_duplex = mv88e6xxx_port_set_duplex, .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay, - .port_set_speed = mv88e6185_port_set_speed, + .port_set_speed_duplex = mv88e6185_port_set_speed_duplex, .port_tag_remap = mv88e6095_port_tag_remap, .port_set_frame_mode = mv88e6351_port_set_frame_mode, .port_set_egress_floods = mv88e6352_port_set_egress_floods,
@@ -4543,9 +4509,8 @@ static const struct mv88e6xxx_ops mv88e6352_ops = { .phy_read = mv88e6xxx_g2_smi_phy_read, .phy_write = mv88e6xxx_g2_smi_phy_write, .port_set_link = mv88e6xxx_port_set_link, - .port_set_duplex = mv88e6xxx_port_set_duplex, .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay, - .port_set_speed = mv88e6352_port_set_speed, + .port_set_speed_duplex = mv88e6352_port_set_speed_duplex, .port_tag_remap = mv88e6095_port_tag_remap, .port_set_policy = mv88e6352_port_set_policy, .port_set_frame_mode = mv88e6351_port_set_frame_mode,
@@ -4605,9 +4570,8 @@ static const struct mv88e6xxx_ops mv88e6390_ops = { .phy_read = mv88e6xxx_g2_smi_phy_read, .phy_write = mv88e6xxx_g2_smi_phy_write, .port_set_link = mv88e6xxx_port_set_link, - .port_set_duplex = mv88e6xxx_port_set_duplex, .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay, - .port_set_speed = mv88e6390_port_set_speed, + .port_set_speed_duplex = mv88e6390_port_set_speed_duplex, .port_max_speed_mode = mv88e6390_port_max_speed_mode, .port_tag_remap = mv88e6390_port_tag_remap, .port_set_policy = mv88e6352_port_set_policy,
@@ -4670,9 +4634,8 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = { .phy_read = mv88e6xxx_g2_smi_phy_read, .phy_write = mv88e6xxx_g2_smi_phy_write, .port_set_link = mv88e6xxx_port_set_link, - .port_set_duplex = mv88e6xxx_port_set_duplex, .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay, - .port_set_speed = mv88e6390x_port_set_speed, + .port_set_speed_duplex = mv88e6390x_port_set_speed_duplex, .port_max_speed_mode = mv88e6390x_port_max_speed_mode, .port_tag_remap = mv88e6390_port_tag_remap, .port_set_policy = mv88e6352_port_set_policy,
drivers/net/dsa/mv88e6xxx/chip.h +7 -11
@@ -399,15 +399,6 @@ struct mv88e6xxx_ops {*/ int (*port_set_link)(struct mv88e6xxx_chip *chip,int port,int link); -#define DUPLEX_UNFORCED -2 - -/* Port's MAC duplex mode -* -* Use DUPLEX_HALF or DUPLEX_FULL to force half or full duplex, -* or DUPLEX_UNFORCED for normal duplex detection. -*/ -int (*port_set_duplex)(struct mv88e6xxx_chip *chip,int port,int dup); -#define PAUSE_ON 1#define PAUSE_OFF 0
@@ -417,13 +408,18 @@ struct mv88e6xxx_ops {#define SPEED_MAX INT_MAX#define SPEED_UNFORCED -2 +#define DUPLEX_UNFORCED -2 -/* Port's MAC speed (in Mbps) +/* Port's MAC speed (in Mbps) and MAC duplex mode * * Depending on the chip, 10, 100, 200, 1000, 2500, 10000 are valid. * Use SPEED_UNFORCED for normal detection, SPEED_MAX for max value. +* +* Use DUPLEX_HALF or DUPLEX_FULL to force half or full duplex, +* or DUPLEX_UNFORCED for normal duplex detection. */ -int (*port_set_speed)(struct mv88e6xxx_chip *chip,int port,int speed); +int (*port_set_speed_duplex)(struct mv88e6xxx_chip *chip,int port, +int speed,int duplex);/* What interface mode should be used for maximum speed? */ phy_interface_t (*port_max_speed_mode)(int port);
drivers/net/dsa/mv88e6xxx/port.c +53 -55
201 lines not on this page · raw message
drivers/net/dsa/mv88e6xxx/port.h +14 -9
@@ -298,15 +298,20 @@ int mv88e6390_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port,int mv88e6xxx_port_set_link (struct mv88e6xxx_chip *chip,int port,int link); -int mv88e6xxx_port_set_duplex (struct mv88e6xxx_chip *chip,int port,int dup); - -int mv88e6065_port_set_speed (struct mv88e6xxx_chip *chip,int port,int speed); -int mv88e6185_port_set_speed (struct mv88e6xxx_chip *chip,int port,int speed); -int mv88e6250_port_set_speed (struct mv88e6xxx_chip *chip,int port,int speed); -int mv88e6341_port_set_speed (struct mv88e6xxx_chip *chip,int port,int speed); -int mv88e6352_port_set_speed (struct mv88e6xxx_chip *chip,int port,int speed); -int mv88e6390_port_set_speed (struct mv88e6xxx_chip *chip,int port,int speed); -int mv88e6390x_port_set_speed (struct mv88e6xxx_chip *chip,int port,int speed); +int mv88e6065_port_set_speed_duplex (struct mv88e6xxx_chip *chip,int port, +int speed,int duplex); +int mv88e6185_port_set_speed_duplex (struct mv88e6xxx_chip *chip,int port, +int speed,int duplex); +int mv88e6250_port_set_speed_duplex (struct mv88e6xxx_chip *chip,int port, +int speed,int duplex); +int mv88e6341_port_set_speed_duplex (struct mv88e6xxx_chip *chip,int port, +int speed,int duplex); +int mv88e6352_port_set_speed_duplex (struct mv88e6xxx_chip *chip,int port, +int speed,int duplex); +int mv88e6390_port_set_speed_duplex (struct mv88e6xxx_chip *chip,int port, +int speed,int duplex); +int mv88e6390x_port_set_speed_duplex (struct mv88e6xxx_chip *chip,int port, +int speed,int duplex);phy_interface_t mv88e6341_port_max_speed_mode (int port);phy_interface_t mv88e6390_port_max_speed_mode (int port);
Signature · 1 line
2.20.1
Re: [PATCH net-next 6/8] net: dsa: mv88e6xxx: combine port_set_speed and port_set_duplex
Quoted 11 lines · Russell King
Setting the speed independently of duplex makes little sense; the two parameters result from negotiation or fixed setup, and may have inter- dependencies. Moreover, they are always controlled via the same register - having them split means we have to read-modify-write this register twice.
Combine the two operations into a single
port_set_speed_duplex()operation. Not only is this more efficient, it reduces the size of the code as well.Signed-off-by Russell King <[email protected]>
Andrew
PATCH 7/8 net: dsa: mv88e6xxx: remove port_link_state functions
In reply to Russell King - ARM Linux adminThe port_link_state method is only used by mv88e6xxx_port_setup_mac(), which is now only called during port setup, rather than also being called via phylink's mac_config method.
Remove this now unnecessary optimisation, which allows us to remove the port_link_state methods as well.
--- drivers/net/dsa/mv88e6xxx/chip.c | 46 -------- drivers/net/dsa/mv88e6xxx/chip.h | 3 - drivers/net/dsa/mv88e6xxx/port.c | 177 ------------------------------- drivers/net/dsa/mv88e6xxx/port.h | 6 -- 4 files changed, 232 deletions(-)
drivers/net/dsa/mv88e6xxx/chip.c +0 -46
@@ -423,30 +423,11 @@ static int mv88e6xxx_port_setup_mac(struct mv88e6xxx_chip *chip, int port, int link, int speed, int duplex, int pause, phy_interface_t mode) { - struct phylink_link_state state; int err;if (!chip->info->ops->port_set_link)return 0 ; -if (!chip->info->ops->port_link_state) -return 0 ; - - err = chip->info->ops->port_link_state (chip, port, &state); -if (err) -return err; - -/* Has anything actually changed? We don't expect the -* interface mode to change without one of the other -* parameters also changing -*/ -if (state.link == link && - state.speed == speed && - state.duplex == duplex && - (state.interface == mode || - state.interface ==PHY_INTERFACE_MODE_NA )) -return 0 ; -/* Port's MAC control must not be changed unless the link is down */ err = chip->info->ops->port_set_link (chip, port,LINK_FORCED_DOWN );if (err)
@@ -3411,7 +3392,6 @@ static const struct mv88e6xxx_ops mv88e6085_ops = { .port_pause_limit = mv88e6097_port_pause_limit, .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, - .port_link_state = mv88e6352_port_link_state, .port_get_cmode = mv88e6185_port_get_cmode, .port_setup_message_port = mv88e6xxx_setup_message_port, .stats_snapshot = mv88e6xxx_g1_stats_snapshot,
@@ -3445,7 +3425,6 @@ static const struct mv88e6xxx_ops mv88e6095_ops = { .port_set_frame_mode = mv88e6085_port_set_frame_mode, .port_set_egress_floods = mv88e6185_port_set_egress_floods, .port_set_upstream_port = mv88e6095_port_set_upstream_port, - .port_link_state = mv88e6185_port_link_state, .port_get_cmode = mv88e6185_port_get_cmode, .port_setup_message_port = mv88e6xxx_setup_message_port, .stats_snapshot = mv88e6xxx_g1_stats_snapshot,
@@ -3481,7 +3460,6 @@ static const struct mv88e6xxx_ops mv88e6097_ops = { .port_pause_limit = mv88e6097_port_pause_limit, .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, - .port_link_state = mv88e6352_port_link_state, .port_get_cmode = mv88e6185_port_get_cmode, .port_setup_message_port = mv88e6xxx_setup_message_port, .stats_snapshot = mv88e6xxx_g1_stats_snapshot,
@@ -3515,7 +3493,6 @@ static const struct mv88e6xxx_ops mv88e6123_ops = { .port_set_egress_floods = mv88e6352_port_set_egress_floods, .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, - .port_link_state = mv88e6352_port_link_state, .port_get_cmode = mv88e6185_port_get_cmode, .port_setup_message_port = mv88e6xxx_setup_message_port, .stats_snapshot = mv88e6320_g1_stats_snapshot,
@@ -3554,7 +3531,6 @@ static const struct mv88e6xxx_ops mv88e6131_ops = { .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting, .port_pause_limit = mv88e6097_port_pause_limit, .port_set_pause = mv88e6185_port_set_pause, - .port_link_state = mv88e6352_port_link_state, .port_get_cmode = mv88e6185_port_get_cmode, .port_setup_message_port = mv88e6xxx_setup_message_port, .stats_snapshot = mv88e6xxx_g1_stats_snapshot,
@@ -3598,7 +3574,6 @@ static const struct mv88e6xxx_ops mv88e6141_ops = { .port_pause_limit = mv88e6097_port_pause_limit, .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, - .port_link_state = mv88e6352_port_link_state, .port_get_cmode = mv88e6352_port_get_cmode, .port_set_cmode = mv88e6341_port_set_cmode, .port_setup_message_port = mv88e6xxx_setup_message_port,
@@ -3648,7 +3623,6 @@ static const struct mv88e6xxx_ops mv88e6161_ops = { .port_pause_limit = mv88e6097_port_pause_limit, .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, - .port_link_state = mv88e6352_port_link_state, .port_get_cmode = mv88e6185_port_get_cmode, .port_setup_message_port = mv88e6xxx_setup_message_port, .stats_snapshot = mv88e6xxx_g1_stats_snapshot,
@@ -3683,7 +3657,6 @@ static const struct mv88e6xxx_ops mv88e6165_ops = { .port_set_speed_duplex = mv88e6185_port_set_speed_duplex, .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, - .port_link_state = mv88e6352_port_link_state, .port_get_cmode = mv88e6185_port_get_cmode, .port_setup_message_port = mv88e6xxx_setup_message_port, .stats_snapshot = mv88e6xxx_g1_stats_snapshot,
@@ -3726,7 +3699,6 @@ static const struct mv88e6xxx_ops mv88e6171_ops = { .port_pause_limit = mv88e6097_port_pause_limit, .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, - .port_link_state = mv88e6352_port_link_state, .port_get_cmode = mv88e6352_port_get_cmode, .port_setup_message_port = mv88e6xxx_setup_message_port, .stats_snapshot = mv88e6320_g1_stats_snapshot,
@@ -3770,7 +3742,6 @@ static const struct mv88e6xxx_ops mv88e6172_ops = { .port_pause_limit = mv88e6097_port_pause_limit, .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, - .port_link_state = mv88e6352_port_link_state, .port_get_cmode = mv88e6352_port_get_cmode, .port_setup_message_port = mv88e6xxx_setup_message_port, .stats_snapshot = mv88e6320_g1_stats_snapshot,
@@ -3821,7 +3792,6 @@ static const struct mv88e6xxx_ops mv88e6175_ops = { .port_pause_limit = mv88e6097_port_pause_limit, .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, - .port_link_state = mv88e6352_port_link_state, .port_get_cmode = mv88e6352_port_get_cmode, .port_setup_message_port = mv88e6xxx_setup_message_port, .stats_snapshot = mv88e6320_g1_stats_snapshot,
@@ -3865,7 +3835,6 @@ static const struct mv88e6xxx_ops mv88e6176_ops = { .port_pause_limit = mv88e6097_port_pause_limit, .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, - .port_link_state = mv88e6352_port_link_state, .port_get_cmode = mv88e6352_port_get_cmode, .port_setup_message_port = mv88e6xxx_setup_message_port, .stats_snapshot = mv88e6320_g1_stats_snapshot,
@@ -3913,7 +3882,6 @@ static const struct mv88e6xxx_ops mv88e6185_ops = { .port_egress_rate_limiting = mv88e6095_port_egress_rate_limiting, .port_set_upstream_port = mv88e6095_port_set_upstream_port, .port_set_pause = mv88e6185_port_set_pause, - .port_link_state = mv88e6185_port_link_state, .port_get_cmode = mv88e6185_port_get_cmode, .port_setup_message_port = mv88e6xxx_setup_message_port, .stats_snapshot = mv88e6xxx_g1_stats_snapshot,
@@ -3955,7 +3923,6 @@ static const struct mv88e6xxx_ops mv88e6190_ops = { .port_pause_limit = mv88e6390_port_pause_limit, .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, - .port_link_state = mv88e6352_port_link_state, .port_get_cmode = mv88e6352_port_get_cmode, .port_set_cmode = mv88e6390_port_set_cmode, .port_setup_message_port = mv88e6xxx_setup_message_port,
@@ -4015,7 +3982,6 @@ static const struct mv88e6xxx_ops mv88e6190x_ops = { .port_pause_limit = mv88e6390_port_pause_limit, .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, - .port_link_state = mv88e6352_port_link_state, .port_get_cmode = mv88e6352_port_get_cmode, .port_set_cmode = mv88e6390x_port_set_cmode, .port_setup_message_port = mv88e6xxx_setup_message_port,
@@ -4074,7 +4040,6 @@ static const struct mv88e6xxx_ops mv88e6191_ops = { .port_pause_limit = mv88e6390_port_pause_limit, .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, - .port_link_state = mv88e6352_port_link_state, .port_get_cmode = mv88e6352_port_get_cmode, .port_set_cmode = mv88e6390_port_set_cmode, .port_setup_message_port = mv88e6xxx_setup_message_port,
@@ -4137,7 +4102,6 @@ static const struct mv88e6xxx_ops mv88e6240_ops = { .port_pause_limit = mv88e6097_port_pause_limit, .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, - .port_link_state = mv88e6352_port_link_state, .port_get_cmode = mv88e6352_port_get_cmode, .port_setup_message_port = mv88e6xxx_setup_message_port, .stats_snapshot = mv88e6320_g1_stats_snapshot,
@@ -4193,7 +4157,6 @@ static const struct mv88e6xxx_ops mv88e6250_ops = { .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting, .port_pause_limit = mv88e6097_port_pause_limit, .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, - .port_link_state = mv88e6250_port_link_state, .stats_snapshot = mv88e6320_g1_stats_snapshot, .stats_set_histogram = mv88e6095_g1_stats_set_histogram, .stats_get_sset_count = mv88e6250_stats_get_sset_count,
@@ -4233,7 +4196,6 @@ static const struct mv88e6xxx_ops mv88e6290_ops = { .port_pause_limit = mv88e6390_port_pause_limit, .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, - .port_link_state = mv88e6352_port_link_state, .port_get_cmode = mv88e6352_port_get_cmode, .port_set_cmode = mv88e6390_port_set_cmode, .port_setup_message_port = mv88e6xxx_setup_message_port,
@@ -4295,7 +4257,6 @@ static const struct mv88e6xxx_ops mv88e6320_ops = { .port_pause_limit = mv88e6097_port_pause_limit, .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, - .port_link_state = mv88e6352_port_link_state, .port_get_cmode = mv88e6352_port_get_cmode, .port_setup_message_port = mv88e6xxx_setup_message_port, .stats_snapshot = mv88e6320_g1_stats_snapshot,
@@ -4338,7 +4299,6 @@ static const struct mv88e6xxx_ops mv88e6321_ops = { .port_pause_limit = mv88e6097_port_pause_limit, .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, - .port_link_state = mv88e6352_port_link_state, .port_get_cmode = mv88e6352_port_get_cmode, .port_setup_message_port = mv88e6xxx_setup_message_port, .stats_snapshot = mv88e6320_g1_stats_snapshot,
@@ -4381,7 +4341,6 @@ static const struct mv88e6xxx_ops mv88e6341_ops = { .port_pause_limit = mv88e6097_port_pause_limit, .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, - .port_link_state = mv88e6352_port_link_state, .port_get_cmode = mv88e6352_port_get_cmode, .port_set_cmode = mv88e6341_port_set_cmode, .port_setup_message_port = mv88e6xxx_setup_message_port,
@@ -4434,7 +4393,6 @@ static const struct mv88e6xxx_ops mv88e6350_ops = { .port_pause_limit = mv88e6097_port_pause_limit, .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, - .port_link_state = mv88e6352_port_link_state, .port_get_cmode = mv88e6352_port_get_cmode, .port_setup_message_port = mv88e6xxx_setup_message_port, .stats_snapshot = mv88e6320_g1_stats_snapshot,
@@ -4475,7 +4433,6 @@ static const struct mv88e6xxx_ops mv88e6351_ops = { .port_pause_limit = mv88e6097_port_pause_limit, .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, - .port_link_state = mv88e6352_port_link_state, .port_get_cmode = mv88e6352_port_get_cmode, .port_setup_message_port = mv88e6xxx_setup_message_port, .stats_snapshot = mv88e6320_g1_stats_snapshot,
@@ -4521,7 +4478,6 @@ static const struct mv88e6xxx_ops mv88e6352_ops = { .port_pause_limit = mv88e6097_port_pause_limit, .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, - .port_link_state = mv88e6352_port_link_state, .port_get_cmode = mv88e6352_port_get_cmode, .port_setup_message_port = mv88e6xxx_setup_message_port, .stats_snapshot = mv88e6320_g1_stats_snapshot,
@@ -4583,7 +4539,6 @@ static const struct mv88e6xxx_ops mv88e6390_ops = { .port_pause_limit = mv88e6390_port_pause_limit, .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, - .port_link_state = mv88e6352_port_link_state, .port_get_cmode = mv88e6352_port_get_cmode, .port_set_cmode = mv88e6390_port_set_cmode, .port_setup_message_port = mv88e6xxx_setup_message_port,
@@ -4647,7 +4602,6 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = { .port_pause_limit = mv88e6390_port_pause_limit, .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, - .port_link_state = mv88e6352_port_link_state, .port_get_cmode = mv88e6352_port_get_cmode, .port_set_cmode = mv88e6390x_port_set_cmode, .port_setup_message_port = mv88e6xxx_setup_message_port,
drivers/net/dsa/mv88e6xxx/chip.h +0 -3
@@ -458,9 +458,6 @@ struct mv88e6xxx_ops {*/ int (*port_set_upstream_port)(struct mv88e6xxx_chip *chip,int port,int upstream_port); -/* Return the port link state, as required by phylink */ -int (*port_link_state)(struct mv88e6xxx_chip *chip,int port, -struct phylink_link_state *state);/* Snapshot the statistics for a port. The statistics can then * be read back a leisure but still with a consistent view.
drivers/net/dsa/mv88e6xxx/port.c +0 -177
183 lines not on this page · raw message
drivers/net/dsa/mv88e6xxx/port.h +0 -6
@@ -364,12 +364,6 @@ int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port, phy_interface_t mode);int mv88e6185_port_get_cmode (struct mv88e6xxx_chip *chip,int port,u8 *cmode);int mv88e6352_port_get_cmode (struct mv88e6xxx_chip *chip,int port,u8 *cmode); -int mv88e6185_port_link_state (struct mv88e6xxx_chip *chip,int port, -struct phylink_link_state *state); -int mv88e6250_port_link_state (struct mv88e6xxx_chip *chip,int port, -struct phylink_link_state *state); -int mv88e6352_port_link_state (struct mv88e6xxx_chip *chip,int port, -struct phylink_link_state *state);int mv88e6xxx_port_set_map_da (struct mv88e6xxx_chip *chip,int port);int mv88e6095_port_set_upstream_port (struct mv88e6xxx_chip *chip,int port,int upstream_port);
Signature · 1 line
2.20.1
Re: [PATCH net-next 7/8] net: dsa: mv88e6xxx: remove port_link_state functions
Quoted 8 lines · Russell King
The
port_link_statemethod is only used bymv88e6xxx_port_setup_mac(), which is now only called during port setup, rather than also being called via phylink'smac_configmethod.Remove this now unnecessary optimisation, which allows us to remove the
port_link_statemethods as well.Signed-off-by Russell King <[email protected]>
Andrew
PATCH 8/8 net: dsa: mv88e6xxx: use PHY_DETECT in mac_link_up/mac_link_down
In reply to Russell King - ARM Linux adminUse the status of the PHY_DETECT bit to determine whether we need to force the MAC settings in mac_link_up() and mac_link_down().
--- drivers/net/dsa/mv88e6xxx/chip.c | 53 +++++++++++++++++--------------- 1 file changed, 29 insertions(+), 24 deletions(-)
drivers/net/dsa/mv88e6xxx/chip.c +29 -24
@@ -464,6 +464,22 @@ static int mv88e6xxx_phy_is_internal(struct dsa_switch *ds, int port)return port < chip->info->num_internal_phys; } +static int mv88e6xxx_port_ppu_updates (struct mv88e6xxx_chip *chip,int port) +{ +u16 reg; +int err; + + err =mv88e6xxx_port_read (chip, port,MV88E6XXX_PORT_STS , ®); +if (err) { +dev_err (chip->dev, +"p%d: %s: failed to read port status\n" , + port, __func__); +return err; + } + +return !!(reg &MV88E6XXX_PORT_STS_PHY_DETECT ); +} +static int mv88e6xxx_serdes_pcs_get_state (struct dsa_switch *ds,int port,struct phylink_link_state *state) {
@@ -692,20 +708,14 @@ static void mv88e6xxx_mac_link_down(struct dsa_switch *ds, int port, ops = chip->info->ops; -/* Internal PHYs propagate their configuration directly to the MAC. -* External PHYs depend on whether the PPU is enabled for this port. -* FIXME: we should be using the PPU enable state here. What about -* an automedia port? -*/ -if (!mv88e6xxx_phy_is_internal (ds, port) && ops->port_set_link) { -mv88e6xxx_reg_lock (chip); +mv88e6xxx_reg_lock (chip); +if (!mv88e6xxx_port_ppu_updates (chip, port) && ops->port_set_link) err = ops->port_set_link (chip, port,LINK_FORCED_DOWN ); -mv88e6xxx_reg_unlock (chip); +mv88e6xxx_reg_unlock (chip); -if (err) -dev_err (chip->dev, -"p%d: failed to force MAC link down\n" , port); - } +if (err) +dev_err (chip->dev, +"p%d: failed to force MAC link down\n" , port); } static void mv88e6xxx_mac_link_up(struct dsa_switch *ds, int port,
@@ -720,13 +730,8 @@ static void mv88e6xxx_mac_link_up(struct dsa_switch *ds, int port, ops = chip->info->ops; -/* Internal PHYs propagate their configuration directly to the MAC. -* External PHYs depend on whether the PPU is enabled for this port. -* FIXME: we should be using the PPU enable state here. What about -* an automedia port? -*/ -if (!mv88e6xxx_phy_is_internal (ds, port)) { -mv88e6xxx_reg_lock (chip); +mv88e6xxx_reg_lock (chip); +if (!mv88e6xxx_port_ppu_updates (chip, port)) {/* FIXME: for an automedia port, should we force the link * down here - what if the link comes up due to "other" media * while we're bringing the port up, how is the exclusivity
@@ -747,13 +752,13 @@ static void mv88e6xxx_mac_link_up(struct dsa_switch *ds, int port,if (ops->port_set_link) err = ops->port_set_link (chip, port,LINK_FORCED_UP ); + } error: -mv88e6xxx_reg_unlock (chip); +mv88e6xxx_reg_unlock (chip); -if (err && err != -EOPNOTSUPP ) -dev_err (ds->dev, -"p%d: failed to configure MAC link up\n" , port); - } +if (err && err != -EOPNOTSUPP ) +dev_err (ds->dev, +"p%d: failed to configure MAC link up\n" , port); }static int mv88e6xxx_stats_snapshot (struct mv88e6xxx_chip *chip,int port)
Signature · 1 line
2.20.1
Re: [PATCH net-next 8/8] net: dsa: mv88e6xxx: use PHY_DETECT in mac_link_up/mac_link_down
Quoted 4 lines · Russell King
Use the status of the
PHY_DETECTbit to determine whether we need to force the MAC settings inmac_link_up()andmac_link_down().Signed-off-by Russell King <[email protected]>
Andrew
Andrew Lunn
maintainerQuoted 6 lines · Russell King - ARM Linux admin
Depends on "net: mii clause 37 helpers".
Andrew Lunn mentioned that the Serdes PCS found in Marvell DSA switches does not automatically update the switch MACs with the link parameters. Currently, the DSA code implements a work-around for this.
Quoted 8 lines
This series improves the Serdes integration, making use of the recent phylink changes to support split MAC/PCS setups. One noticable improvement for userspace is that ethtool can now report the link partner's advertisement.
This repost has no changes compared to the previous posting; however, the regression Andrew had found which exists even without this patch set has now been fixed by Andrew and merged into the net-next tree.
Hi Russell
With the CPU port being broken with the last version, i did not give this much testing. Unfortunately, I'm not in a position to test this at the moment. So i'm just going to review it. If anything breaks, we can fix it up later.
Andrew
David Miller
maintainerFrom: Russell King - ARM Linux admin <[email protected]>
Date: Sat, 14 Mar 2020 10:14:31 +0000
Quoted 6 lines
Depends on "net: mii clause 37 helpers".
Andrew Lunn mentioned that the Serdes PCS found in Marvell DSA switches does not automatically update the switch MACs with the link parameters. Currently, the DSA code implements a work-around for this.
Quoted 8 lines
This series improves the Serdes integration, making use of the recent phylink changes to support split MAC/PCS setups. One noticable improvement for userspace is that ethtool can now report the link partner's advertisement.
This repost has no changes compared to the previous posting; however, the regression Andrew had found which exists even without this patch set has now been fixed by Andrew and merged into the net-next tree.
Series applied.