Commit 2d2e1dd2 authored by Andrew Lunn's avatar Andrew Lunn Committed by David S. Miller

net: dsa: mv88e6xxx: Cache the port cmode

The ports CMODE indicates the type of link between the MAC and the
PHY. It is used often in the SERDES code. Rather than read it each
time, cache its value.
Signed-off-by: default avatarAndrew Lunn <andrew@lunn.ch>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent f8236a08
This diff is collapsed.
...@@ -197,6 +197,7 @@ struct mv88e6xxx_port { ...@@ -197,6 +197,7 @@ struct mv88e6xxx_port {
u64 atu_full_violation; u64 atu_full_violation;
u64 vtu_member_violation; u64 vtu_member_violation;
u64 vtu_miss_violation; u64 vtu_miss_violation;
u8 cmode;
}; };
struct mv88e6xxx_chip { struct mv88e6xxx_chip {
...@@ -390,6 +391,7 @@ struct mv88e6xxx_ops { ...@@ -390,6 +391,7 @@ struct mv88e6xxx_ops {
*/ */
int (*port_set_cmode)(struct mv88e6xxx_chip *chip, int port, int (*port_set_cmode)(struct mv88e6xxx_chip *chip, int port,
phy_interface_t mode); phy_interface_t mode);
int (*port_get_cmode)(struct mv88e6xxx_chip *chip, int port, u8 *cmode);
/* Some devices have a per port register indicating what is /* Some devices have a per port register indicating what is
* the upstream port this port should forward to. * the upstream port this port should forward to.
......
...@@ -385,11 +385,12 @@ int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port, ...@@ -385,11 +385,12 @@ int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
return err; return err;
} }
chip->ports[port].cmode = cmode;
return 0; return 0;
} }
/* mv88e6185 only has 3 bits for CMODE */ int mv88e6185_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode)
static int mv88e6185_port_get_cmode(struct mv88e6xxx_chip *chip, int port)
{ {
int err; int err;
u16 reg; u16 reg;
...@@ -398,10 +399,12 @@ static int mv88e6185_port_get_cmode(struct mv88e6xxx_chip *chip, int port) ...@@ -398,10 +399,12 @@ static int mv88e6185_port_get_cmode(struct mv88e6xxx_chip *chip, int port)
if (err) if (err)
return err; return err;
return reg & MV88E6185_PORT_STS_CMODE_MASK; *cmode = reg & MV88E6185_PORT_STS_CMODE_MASK;
return 0;
} }
int mv88e6xxx_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 err; int err;
u16 reg; u16 reg;
...@@ -457,10 +460,7 @@ int mv88e6185_port_link_state(struct mv88e6xxx_chip *chip, int port, ...@@ -457,10 +460,7 @@ int mv88e6185_port_link_state(struct mv88e6xxx_chip *chip, int port,
struct phylink_link_state *state) struct phylink_link_state *state)
{ {
if (state->interface == PHY_INTERFACE_MODE_1000BASEX) { if (state->interface == PHY_INTERFACE_MODE_1000BASEX) {
int cmode = mv88e6185_port_get_cmode(chip, port); u8 cmode = chip->ports[port].cmode;
if (cmode < 0)
return cmode;
/* When a port is in "Cross-chip serdes" mode, it uses /* When a port is in "Cross-chip serdes" mode, it uses
* 1000Base-X full duplex mode, but there is no automatic * 1000Base-X full duplex mode, but there is no automatic
......
...@@ -311,7 +311,8 @@ int mv88e6390_port_pause_limit(struct mv88e6xxx_chip *chip, int port, u8 in, ...@@ -311,7 +311,8 @@ int mv88e6390_port_pause_limit(struct mv88e6xxx_chip *chip, int port, u8 in,
u8 out); u8 out);
int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port, int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
phy_interface_t mode); phy_interface_t mode);
int mv88e6xxx_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode); 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, int mv88e6185_port_link_state(struct mv88e6xxx_chip *chip, int port,
struct phylink_link_state *state); struct phylink_link_state *state);
int mv88e6352_port_link_state(struct mv88e6xxx_chip *chip, int port, int mv88e6352_port_link_state(struct mv88e6xxx_chip *chip, int port,
......
...@@ -73,14 +73,7 @@ static int mv88e6352_serdes_power_set(struct mv88e6xxx_chip *chip, bool on) ...@@ -73,14 +73,7 @@ static int mv88e6352_serdes_power_set(struct mv88e6xxx_chip *chip, bool on)
static bool mv88e6352_port_has_serdes(struct mv88e6xxx_chip *chip, int port) static bool mv88e6352_port_has_serdes(struct mv88e6xxx_chip *chip, int port)
{ {
u8 cmode; u8 cmode = chip->ports[port].cmode;
int err;
err = mv88e6xxx_port_get_cmode(chip, port, &cmode);
if (err) {
dev_err(chip->dev, "failed to read cmode\n");
return false;
}
if ((cmode == MV88E6XXX_PORT_STS_CMODE_100BASE_X) || if ((cmode == MV88E6XXX_PORT_STS_CMODE_100BASE_X) ||
(cmode == MV88E6XXX_PORT_STS_CMODE_1000BASE_X) || (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASE_X) ||
...@@ -195,12 +188,7 @@ int mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port, ...@@ -195,12 +188,7 @@ int mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port,
*/ */
static int mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port) static int mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
{ {
u8 cmode; u8 cmode = chip->ports[port].cmode;
int err;
err = mv88e6xxx_port_get_cmode(chip, port, &cmode);
if (err)
return err;
switch (port) { switch (port) {
case 9: case 9:
...@@ -227,19 +215,10 @@ static int mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port) ...@@ -227,19 +215,10 @@ static int mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
static int mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port) static int mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
{ {
u8 cmode_port9, cmode_port10, cmode_port; u8 cmode_port9, cmode_port10, cmode_port;
int err;
err = mv88e6xxx_port_get_cmode(chip, 9, &cmode_port9); cmode_port9 = chip->ports[9].cmode;
if (err) cmode_port10 = chip->ports[10].cmode;
return err; cmode_port = chip->ports[port].cmode;
err = mv88e6xxx_port_get_cmode(chip, 10, &cmode_port10);
if (err)
return err;
err = mv88e6xxx_port_get_cmode(chip, port, &cmode_port);
if (err)
return err;
switch (port) { switch (port) {
case 2: case 2:
...@@ -365,12 +344,7 @@ static int mv88e6390_serdes_power_sgmii(struct mv88e6xxx_chip *chip, int lane, ...@@ -365,12 +344,7 @@ static int mv88e6390_serdes_power_sgmii(struct mv88e6xxx_chip *chip, int lane,
static int mv88e6390_serdes_power_lane(struct mv88e6xxx_chip *chip, int port, static int mv88e6390_serdes_power_lane(struct mv88e6xxx_chip *chip, int port,
int lane, bool on) int lane, bool on)
{ {
u8 cmode; u8 cmode = chip->ports[port].cmode;
int err;
err = mv88e6xxx_port_get_cmode(chip, port, &cmode);
if (err)
return err;
switch (cmode) { switch (cmode) {
case MV88E6XXX_PORT_STS_CMODE_SGMII: case MV88E6XXX_PORT_STS_CMODE_SGMII:
...@@ -427,16 +401,11 @@ int mv88e6390x_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on) ...@@ -427,16 +401,11 @@ int mv88e6390x_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on)
int mv88e6341_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on) int mv88e6341_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on)
{ {
int err; u8 cmode = chip->ports[port].cmode;
u8 cmode;
if (port != 5) if (port != 5)
return 0; return 0;
err = mv88e6xxx_port_get_cmode(chip, port, &cmode);
if (err)
return err;
if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASE_X || if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASE_X ||
cmode == MV88E6XXX_PORT_STS_CMODE_SGMII || cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX) cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment