aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarek BehĂșn <marek.behun@nic.cz>2019-08-14 10:40:24 -0400
committerDavid S. Miller <davem@davemloft.net>2019-08-16 16:05:17 -0400
commit927441adea560d59cbbd68b6c26342f44e612271 (patch)
treec620be6d0681c71f874e5c688c360504a08e9550
parent13b18f1d281bc84d3e0024daa706b767b43826a6 (diff)
net: dsa: mv88e6xxx: check for mode change in port_setup_mac
The mv88e6xxx_port_setup_mac checks if the requested MAC settings are different from the current ones, and if not, does nothing (since chaning them requires putting the link down). In this check it only looks if the triplet [link, speed, duplex] is being changed. This patch adds support to also check if the mode parameter (of type phy_interface_t) is requested to be changed. The current mode is computed by the ->port_link_state() method, and if it is different from PHY_INTERFACE_MODE_NA, we check for equality with the requested mode. In the implementations of the mv88e6250_port_link_state() method we set the current mode to PHY_INTERFACE_MODE_NA - so the code does not check for mode change on 6250. In the mv88e6352_port_link_state() method, we use the cached cmode of the port to determine the mode as phy_interface_t (and if it is not enough, eg. for RGMII, we also look at the port control register for RX/TX timings). 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>
-rw-r--r--drivers/net/dsa/mv88e6xxx/chip.c4
-rw-r--r--drivers/net/dsa/mv88e6xxx/port.c38
-rw-r--r--drivers/net/dsa/mv88e6xxx/port.h1
3 files changed, 42 insertions, 1 deletions
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 818a83eb2dcb..9b3ad22a5b98 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -417,7 +417,9 @@ int mv88e6xxx_port_setup_mac(struct mv88e6xxx_chip *chip, int port, int link,
417 */ 417 */
418 if (state.link == link && 418 if (state.link == link &&
419 state.speed == speed && 419 state.speed == speed &&
420 state.duplex == duplex) 420 state.duplex == duplex &&
421 (state.interface == mode ||
422 state.interface == PHY_INTERFACE_MODE_NA))
421 return 0; 423 return 0;
422 424
423 /* Port's MAC control must not be changed unless the link is down */ 425 /* Port's MAC control must not be changed unless the link is down */
diff --git a/drivers/net/dsa/mv88e6xxx/port.c b/drivers/net/dsa/mv88e6xxx/port.c
index 04309ef0a1cc..c95cdb73e5a2 100644
--- a/drivers/net/dsa/mv88e6xxx/port.c
+++ b/drivers/net/dsa/mv88e6xxx/port.c
@@ -590,6 +590,7 @@ int mv88e6250_port_link_state(struct mv88e6xxx_chip *chip, int port,
590 state->link = !!(reg & MV88E6250_PORT_STS_LINK); 590 state->link = !!(reg & MV88E6250_PORT_STS_LINK);
591 state->an_enabled = 1; 591 state->an_enabled = 1;
592 state->an_complete = state->link; 592 state->an_complete = state->link;
593 state->interface = PHY_INTERFACE_MODE_NA;
593 594
594 return 0; 595 return 0;
595} 596}
@@ -600,6 +601,43 @@ int mv88e6352_port_link_state(struct mv88e6xxx_chip *chip, int port,
600 int err; 601 int err;
601 u16 reg; 602 u16 reg;
602 603
604 switch (chip->ports[port].cmode) {
605 case MV88E6XXX_PORT_STS_CMODE_RGMII:
606 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL,
607 &reg);
608 if (err)
609 return err;
610
611 if ((reg & MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK) &&
612 (reg & MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK))
613 state->interface = PHY_INTERFACE_MODE_RGMII_ID;
614 else if (reg & MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK)
615 state->interface = PHY_INTERFACE_MODE_RGMII_RXID;
616 else if (reg & MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK)
617 state->interface = PHY_INTERFACE_MODE_RGMII_TXID;
618 else
619 state->interface = PHY_INTERFACE_MODE_RGMII;
620 break;
621 case MV88E6XXX_PORT_STS_CMODE_1000BASE_X:
622 state->interface = PHY_INTERFACE_MODE_1000BASEX;
623 break;
624 case MV88E6XXX_PORT_STS_CMODE_SGMII:
625 state->interface = PHY_INTERFACE_MODE_SGMII;
626 break;
627 case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
628 state->interface = PHY_INTERFACE_MODE_2500BASEX;
629 break;
630 case MV88E6XXX_PORT_STS_CMODE_XAUI:
631 state->interface = PHY_INTERFACE_MODE_XAUI;
632 break;
633 case MV88E6XXX_PORT_STS_CMODE_RXAUI:
634 state->interface = PHY_INTERFACE_MODE_RXAUI;
635 break;
636 default:
637 /* we do not support other cmode values here */
638 state->interface = PHY_INTERFACE_MODE_NA;
639 }
640
603 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &reg); 641 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &reg);
604 if (err) 642 if (err)
605 return err; 643 return err;
diff --git a/drivers/net/dsa/mv88e6xxx/port.h b/drivers/net/dsa/mv88e6xxx/port.h
index ceec771f8bfc..1abf5ea033e2 100644
--- a/drivers/net/dsa/mv88e6xxx/port.h
+++ b/drivers/net/dsa/mv88e6xxx/port.h
@@ -42,6 +42,7 @@
42#define MV88E6XXX_PORT_STS_TX_PAUSED 0x0020 42#define MV88E6XXX_PORT_STS_TX_PAUSED 0x0020
43#define MV88E6XXX_PORT_STS_FLOW_CTL 0x0010 43#define MV88E6XXX_PORT_STS_FLOW_CTL 0x0010
44#define MV88E6XXX_PORT_STS_CMODE_MASK 0x000f 44#define MV88E6XXX_PORT_STS_CMODE_MASK 0x000f
45#define MV88E6XXX_PORT_STS_CMODE_RGMII 0x0007
45#define MV88E6XXX_PORT_STS_CMODE_100BASE_X 0x0008 46#define MV88E6XXX_PORT_STS_CMODE_100BASE_X 0x0008
46#define MV88E6XXX_PORT_STS_CMODE_1000BASE_X 0x0009 47#define MV88E6XXX_PORT_STS_CMODE_1000BASE_X 0x0009
47#define MV88E6XXX_PORT_STS_CMODE_SGMII 0x000a 48#define MV88E6XXX_PORT_STS_CMODE_SGMII 0x000a