Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Marek Behún and committed by
David S. Miller
927441ad 13b18f1d

+42 -1
+3 -1
drivers/net/dsa/mv88e6xxx/chip.c
··· 417 417 */ 418 418 if (state.link == link && 419 419 state.speed == speed && 420 - state.duplex == duplex) 420 + state.duplex == duplex && 421 + (state.interface == mode || 422 + state.interface == PHY_INTERFACE_MODE_NA)) 421 423 return 0; 422 424 423 425 /* Port's MAC control must not be changed unless the link is down */
+38
drivers/net/dsa/mv88e6xxx/port.c
··· 590 590 state->link = !!(reg & MV88E6250_PORT_STS_LINK); 591 591 state->an_enabled = 1; 592 592 state->an_complete = state->link; 593 + state->interface = PHY_INTERFACE_MODE_NA; 593 594 594 595 return 0; 595 596 } ··· 600 599 { 601 600 int err; 602 601 u16 reg; 602 + 603 + switch (chip->ports[port].cmode) { 604 + case MV88E6XXX_PORT_STS_CMODE_RGMII: 605 + err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL, 606 + &reg); 607 + if (err) 608 + return err; 609 + 610 + if ((reg & MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK) && 611 + (reg & MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK)) 612 + state->interface = PHY_INTERFACE_MODE_RGMII_ID; 613 + else if (reg & MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK) 614 + state->interface = PHY_INTERFACE_MODE_RGMII_RXID; 615 + else if (reg & MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK) 616 + state->interface = PHY_INTERFACE_MODE_RGMII_TXID; 617 + else 618 + state->interface = PHY_INTERFACE_MODE_RGMII; 619 + break; 620 + case MV88E6XXX_PORT_STS_CMODE_1000BASE_X: 621 + state->interface = PHY_INTERFACE_MODE_1000BASEX; 622 + break; 623 + case MV88E6XXX_PORT_STS_CMODE_SGMII: 624 + state->interface = PHY_INTERFACE_MODE_SGMII; 625 + break; 626 + case MV88E6XXX_PORT_STS_CMODE_2500BASEX: 627 + state->interface = PHY_INTERFACE_MODE_2500BASEX; 628 + break; 629 + case MV88E6XXX_PORT_STS_CMODE_XAUI: 630 + state->interface = PHY_INTERFACE_MODE_XAUI; 631 + break; 632 + case MV88E6XXX_PORT_STS_CMODE_RXAUI: 633 + state->interface = PHY_INTERFACE_MODE_RXAUI; 634 + break; 635 + default: 636 + /* we do not support other cmode values here */ 637 + state->interface = PHY_INTERFACE_MODE_NA; 638 + } 603 639 604 640 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &reg); 605 641 if (err)
+1
drivers/net/dsa/mv88e6xxx/port.h
··· 42 42 #define MV88E6XXX_PORT_STS_TX_PAUSED 0x0020 43 43 #define MV88E6XXX_PORT_STS_FLOW_CTL 0x0010 44 44 #define MV88E6XXX_PORT_STS_CMODE_MASK 0x000f 45 + #define MV88E6XXX_PORT_STS_CMODE_RGMII 0x0007 45 46 #define MV88E6XXX_PORT_STS_CMODE_100BASE_X 0x0008 46 47 #define MV88E6XXX_PORT_STS_CMODE_1000BASE_X 0x0009 47 48 #define MV88E6XXX_PORT_STS_CMODE_SGMII 0x000a