Skip to content

Commit

Permalink
net: dsa: mv88e6xxx: simplify SERDES code for Topaz and Peridot
Browse files Browse the repository at this point in the history
By adding an additional serdes_get_lane implementation (for Topaz), we
can merge the implementations of other SERDES functions (powering and
IRQs). We can skip checking port numbers, since the serdes_get_lane()
methods inform if there is no lane on a port or if the lane cannot be
used for given cmode.

Signed-off-by: Marek Behún <marek.behun@nic.cz>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Marek Behún authored and David S. Miller committed Aug 28, 2019
1 parent 17deaf5 commit d3cf7d8
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 92 deletions.
18 changes: 10 additions & 8 deletions drivers/net/dsa/mv88e6xxx/chip.c
Original file line number Diff line number Diff line change
Expand Up @@ -2927,7 +2927,8 @@ static const struct mv88e6xxx_ops mv88e6141_ops = {
.reset = mv88e6352_g1_reset,
.vtu_getnext = mv88e6352_g1_vtu_getnext,
.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
.serdes_power = mv88e6341_serdes_power,
.serdes_power = mv88e6390_serdes_power,
.serdes_get_lane = mv88e6341_serdes_get_lane,
.gpio_ops = &mv88e6352_gpio_ops,
.phylink_validate = mv88e6341_phylink_validate,
};
Expand Down Expand Up @@ -3301,10 +3302,10 @@ static const struct mv88e6xxx_ops mv88e6190x_ops = {
.rmu_disable = mv88e6390_g1_rmu_disable,
.vtu_getnext = mv88e6390_g1_vtu_getnext,
.vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
.serdes_power = mv88e6390x_serdes_power,
.serdes_power = mv88e6390_serdes_power,
.serdes_get_lane = mv88e6390x_serdes_get_lane,
.serdes_irq_setup = mv88e6390x_serdes_irq_setup,
.serdes_irq_free = mv88e6390x_serdes_irq_free,
.serdes_irq_setup = mv88e6390_serdes_irq_setup,
.serdes_irq_free = mv88e6390_serdes_irq_free,
.gpio_ops = &mv88e6352_gpio_ops,
.phylink_validate = mv88e6390x_phylink_validate,
};
Expand Down Expand Up @@ -3621,7 +3622,8 @@ static const struct mv88e6xxx_ops mv88e6341_ops = {
.reset = mv88e6352_g1_reset,
.vtu_getnext = mv88e6352_g1_vtu_getnext,
.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
.serdes_power = mv88e6341_serdes_power,
.serdes_power = mv88e6390_serdes_power,
.serdes_get_lane = mv88e6341_serdes_get_lane,
.gpio_ops = &mv88e6352_gpio_ops,
.avb_ops = &mv88e6390_avb_ops,
.ptp_ops = &mv88e6352_ptp_ops,
Expand Down Expand Up @@ -3854,10 +3856,10 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = {
.rmu_disable = mv88e6390_g1_rmu_disable,
.vtu_getnext = mv88e6390_g1_vtu_getnext,
.vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
.serdes_power = mv88e6390x_serdes_power,
.serdes_power = mv88e6390_serdes_power,
.serdes_get_lane = mv88e6390x_serdes_get_lane,
.serdes_irq_setup = mv88e6390x_serdes_irq_setup,
.serdes_irq_free = mv88e6390x_serdes_irq_free,
.serdes_irq_setup = mv88e6390_serdes_irq_setup,
.serdes_irq_free = mv88e6390_serdes_irq_free,
.gpio_ops = &mv88e6352_gpio_ops,
.avb_ops = &mv88e6390_avb_ops,
.ptp_ops = &mv88e6352_ptp_ops,
Expand Down
4 changes: 2 additions & 2 deletions drivers/net/dsa/mv88e6xxx/port.c
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,7 @@ int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
return err;
}

err = mv88e6390x_serdes_power(chip, port, false);
err = mv88e6390_serdes_power(chip, port, false);
if (err)
return err;
}
Expand All @@ -470,7 +470,7 @@ int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
if (err)
return err;

err = mv88e6390x_serdes_power(chip, port, true);
err = mv88e6390_serdes_power(chip, port, true);
if (err)
return err;

Expand Down
105 changes: 28 additions & 77 deletions drivers/net/dsa/mv88e6xxx/serdes.c
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,23 @@ void mv88e6352_serdes_irq_free(struct mv88e6xxx_chip *chip, int port)
chip->ports[port].serdes_irq = 0;
}

int mv88e6341_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane)
{
u8 cmode = chip->ports[port].cmode;

if (port != 5)
return -ENODEV;

if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASE_X ||
cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX) {
*lane = MV88E6341_PORT5_LANE;
return 0;
}

return -ENODEV;
}

int mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane)
{
u8 cmode = chip->ports[port].cmode;
Expand Down Expand Up @@ -467,26 +484,9 @@ static int mv88e6390_serdes_power_sgmii(struct mv88e6xxx_chip *chip, u8 lane,
return err;
}

static int mv88e6390_serdes_power_lane(struct mv88e6xxx_chip *chip, int port,
u8 lane, bool on)
{
u8 cmode = chip->ports[port].cmode;

switch (cmode) {
case MV88E6XXX_PORT_STS_CMODE_SGMII:
case MV88E6XXX_PORT_STS_CMODE_1000BASE_X:
case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
return mv88e6390_serdes_power_sgmii(chip, lane, on);
case MV88E6XXX_PORT_STS_CMODE_XAUI:
case MV88E6XXX_PORT_STS_CMODE_RXAUI:
return mv88e6390_serdes_power_10g(chip, lane, on);
}

return 0;
}

int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on)
{
u8 cmode = chip->ports[port].cmode;
u8 lane;
int err;

Expand All @@ -497,31 +497,14 @@ int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on)
return err;
}

switch (port) {
case 9 ... 10:
return mv88e6390_serdes_power_lane(chip, port, lane, on);
}

return 0;
}

int mv88e6390x_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on)
{
u8 lane;
int err;

err = mv88e6xxx_serdes_get_lane(chip, port, &lane);
if (err) {
if (err == -ENODEV)
err = 0;
return err;
}

switch (port) {
case 2 ... 4:
case 5 ... 7:
case 9 ... 10:
return mv88e6390_serdes_power_lane(chip, port, lane, on);
switch (cmode) {
case MV88E6XXX_PORT_STS_CMODE_SGMII:
case MV88E6XXX_PORT_STS_CMODE_1000BASE_X:
case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
return mv88e6390_serdes_power_sgmii(chip, lane, on);
case MV88E6XXX_PORT_STS_CMODE_XAUI:
case MV88E6XXX_PORT_STS_CMODE_RXAUI:
return mv88e6390_serdes_power_10g(chip, lane, on);
}

return 0;
Expand Down Expand Up @@ -686,7 +669,7 @@ static irqreturn_t mv88e6390_serdes_thread_fn(int irq, void *dev_id)
return ret;
}

int mv88e6390x_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port)
int mv88e6390_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port)
{
int err;
u8 lane;
Expand Down Expand Up @@ -725,15 +708,7 @@ int mv88e6390x_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port)
return mv88e6390_serdes_irq_enable(chip, port, lane);
}

int mv88e6390_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port)
{
if (port < 9)
return 0;

return mv88e6390x_serdes_irq_setup(chip, port);
}

void mv88e6390x_serdes_irq_free(struct mv88e6xxx_chip *chip, int port)
void mv88e6390_serdes_irq_free(struct mv88e6xxx_chip *chip, int port)
{
int err;
u8 lane;
Expand All @@ -757,27 +732,3 @@ void mv88e6390x_serdes_irq_free(struct mv88e6xxx_chip *chip, int port)

chip->ports[port].serdes_irq = 0;
}

void mv88e6390_serdes_irq_free(struct mv88e6xxx_chip *chip, int port)
{
if (port < 9)
return;

mv88e6390x_serdes_irq_free(chip, port);
}

int mv88e6341_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on)
{
u8 cmode = chip->ports[port].cmode;

if (port != 5)
return 0;

if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASE_X ||
cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
return mv88e6390_serdes_power_sgmii(chip, MV88E6341_ADDR_SERDES,
on);

return 0;
}
7 changes: 2 additions & 5 deletions drivers/net/dsa/mv88e6xxx/serdes.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
#define MV88E6352_SERDES_INT_STATUS 0x13


#define MV88E6341_ADDR_SERDES 0x15
#define MV88E6341_PORT5_LANE 0x15

#define MV88E6390_PORT9_LANE0 0x09
#define MV88E6390_PORT9_LANE1 0x12
Expand Down Expand Up @@ -87,16 +87,13 @@ static inline int mv88e6xxx_serdes_get_lane(struct mv88e6xxx_chip *chip,
return chip->info->ops->serdes_get_lane(chip, port, lane);
}

int mv88e6341_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane);
int mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane);
int mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane);
int mv88e6341_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on);
int mv88e6352_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on);
int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on);
int mv88e6390x_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on);
int mv88e6390_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port);
void mv88e6390_serdes_irq_free(struct mv88e6xxx_chip *chip, int port);
int mv88e6390x_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port);
void mv88e6390x_serdes_irq_free(struct mv88e6xxx_chip *chip, int port);
int mv88e6352_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port);
int mv88e6352_serdes_get_strings(struct mv88e6xxx_chip *chip,
int port, uint8_t *data);
Expand Down

0 comments on commit d3cf7d8

Please sign in to comment.