mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-29 22:02:02 +00:00
Merge branch 'lan9303-phylink'
Jerry Ray says: ==================== dsa: lan9303: Move to PHYLINK This patch series moves the lan9303 driver to use the phylink api away from phylib. Migrating to phylink means removing the .adjust_link api. The functionality from the adjust_link is moved to the phylink_mac_link_up api. The code being removed only affected the cpu port. The other ports on the LAN9303 do not need anything from the phylink_mac_link_up api. Patches: 0001 - Whitespace only change aligning the dsa_switch_ops members. No code changes. 0002 - Moves the Turbo bit initialization out of the adjust_link api and places it in a driver initialization execution path. It only needs to be initialized once, it is never changed, and it is not a per-port flag. 0003 - Adds exception handling logic in the extremely unlikely event that the read of the device fails. 0004 - Performance optimization that skips a slow register write if there is no need to perform it. 0005 - Change the way we identify the xMII port as phydev will be NULL when this logic is moved into phylink_mac_link_up. 0006 - Removes adjust_link and begins using the phylink dsa_switch_ops apis. 0007 - Adds XMII port flow control settings in the phylink_mac_link_up() api while cleaning up the ANEG / speed / duplex implementation. --- v6->v7: - Moved the initialization of the Turbo bit into lan9303_setup(). - Added a macro for determining is a port is an XMII port. - Added setting the XMII flow control in the phylink_mac_link_up() API. - removed unnecessary error handling and cleaned up the code flow in phylink_mac_link_up(). v5->v6: - Moved to using port number to identify xMII port for the LAN9303. v4->v5: - Created prep patches to better show how things migrate. - cleaned up comments. v3->v4: - Addressed whitespace issues as a separate patch. - Removed port_max_mtu api patch as it is unrelated to phylink migration. - Reworked the implementation to preserve the adjust_link functionality by including it in the phylink_mac_link_up api. v2->v3: Added back in disabling Turbo Mode on the CPU MII interface. Removed the unnecessary clearing of the phy supported interfaces. v1->v2: corrected the reported mtu size, removing ETH_HLEN and ETH_FCS_LEN ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
147c50ac3a
1 changed files with 114 additions and 55 deletions
|
@ -15,6 +15,9 @@
|
|||
|
||||
#include "lan9303.h"
|
||||
|
||||
/* For the LAN9303 and LAN9354, only port 0 is an XMII port. */
|
||||
#define IS_PORT_XMII(port) ((port) == 0)
|
||||
|
||||
#define LAN9303_NUM_PORTS 3
|
||||
|
||||
/* 13.2 System Control and Status Registers
|
||||
|
@ -50,6 +53,9 @@
|
|||
#define LAN9303_MANUAL_FC_1 0x68
|
||||
#define LAN9303_MANUAL_FC_2 0x69
|
||||
#define LAN9303_MANUAL_FC_0 0x6a
|
||||
# define LAN9303_BP_EN BIT(6)
|
||||
# define LAN9303_RX_FC_EN BIT(2)
|
||||
# define LAN9303_TX_FC_EN BIT(1)
|
||||
#define LAN9303_SWITCH_CSR_DATA 0x6b
|
||||
#define LAN9303_SWITCH_CSR_CMD 0x6c
|
||||
#define LAN9303_SWITCH_CSR_CMD_BUSY BIT(31)
|
||||
|
@ -225,6 +231,13 @@ const struct regmap_access_table lan9303_register_set = {
|
|||
};
|
||||
EXPORT_SYMBOL(lan9303_register_set);
|
||||
|
||||
/* Flow Control registers indexed by port number */
|
||||
static unsigned int flow_ctl_reg[] = {
|
||||
LAN9303_MANUAL_FC_0,
|
||||
LAN9303_MANUAL_FC_1,
|
||||
LAN9303_MANUAL_FC_2
|
||||
};
|
||||
|
||||
static int lan9303_read(struct regmap *regmap, unsigned int offset, u32 *reg)
|
||||
{
|
||||
int ret, i;
|
||||
|
@ -902,6 +915,7 @@ static int lan9303_setup(struct dsa_switch *ds)
|
|||
{
|
||||
struct lan9303 *chip = ds->priv;
|
||||
int ret;
|
||||
u32 reg;
|
||||
|
||||
/* Make sure that port 0 is the cpu port */
|
||||
if (!dsa_is_cpu_port(ds, 0)) {
|
||||
|
@ -909,6 +923,17 @@ static int lan9303_setup(struct dsa_switch *ds)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Virtual Phy: Remove Turbo 200Mbit mode */
|
||||
ret = lan9303_read(chip->regmap, LAN9303_VIRT_SPECIAL_CTRL, ®);
|
||||
if (ret)
|
||||
return (ret);
|
||||
|
||||
/* Clear the TURBO Mode bit if it was set. */
|
||||
if (reg & LAN9303_VIRT_SPECIAL_TURBO) {
|
||||
reg &= ~LAN9303_VIRT_SPECIAL_TURBO;
|
||||
regmap_write(chip->regmap, LAN9303_VIRT_SPECIAL_CTRL, reg);
|
||||
}
|
||||
|
||||
ret = lan9303_setup_tagging(chip);
|
||||
if (ret)
|
||||
dev_err(chip->dev, "failed to setup port tagging %d\n", ret);
|
||||
|
@ -1049,42 +1074,6 @@ static int lan9303_phy_write(struct dsa_switch *ds, int phy, int regnum,
|
|||
return chip->ops->phy_write(chip, phy, regnum, val);
|
||||
}
|
||||
|
||||
static void lan9303_adjust_link(struct dsa_switch *ds, int port,
|
||||
struct phy_device *phydev)
|
||||
{
|
||||
struct lan9303 *chip = ds->priv;
|
||||
int ctl;
|
||||
|
||||
if (!phy_is_pseudo_fixed_link(phydev))
|
||||
return;
|
||||
|
||||
ctl = lan9303_phy_read(ds, port, MII_BMCR);
|
||||
|
||||
ctl &= ~BMCR_ANENABLE;
|
||||
|
||||
if (phydev->speed == SPEED_100)
|
||||
ctl |= BMCR_SPEED100;
|
||||
else if (phydev->speed == SPEED_10)
|
||||
ctl &= ~BMCR_SPEED100;
|
||||
else
|
||||
dev_err(ds->dev, "unsupported speed: %d\n", phydev->speed);
|
||||
|
||||
if (phydev->duplex == DUPLEX_FULL)
|
||||
ctl |= BMCR_FULLDPLX;
|
||||
else
|
||||
ctl &= ~BMCR_FULLDPLX;
|
||||
|
||||
lan9303_phy_write(ds, port, MII_BMCR, ctl);
|
||||
|
||||
if (port == chip->phy_addr_base) {
|
||||
/* Virtual Phy: Remove Turbo 200Mbit mode */
|
||||
lan9303_read(chip->regmap, LAN9303_VIRT_SPECIAL_CTRL, &ctl);
|
||||
|
||||
ctl &= ~LAN9303_VIRT_SPECIAL_TURBO;
|
||||
regmap_write(chip->regmap, LAN9303_VIRT_SPECIAL_CTRL, ctl);
|
||||
}
|
||||
}
|
||||
|
||||
static int lan9303_port_enable(struct dsa_switch *ds, int port,
|
||||
struct phy_device *phy)
|
||||
{
|
||||
|
@ -1281,26 +1270,96 @@ static int lan9303_port_mdb_del(struct dsa_switch *ds, int port,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void lan9303_phylink_get_caps(struct dsa_switch *ds, int port,
|
||||
struct phylink_config *config)
|
||||
{
|
||||
struct lan9303 *chip = ds->priv;
|
||||
|
||||
dev_dbg(chip->dev, "%s(%d) entered.", __func__, port);
|
||||
|
||||
config->mac_capabilities = MAC_10 | MAC_100 | MAC_ASYM_PAUSE |
|
||||
MAC_SYM_PAUSE;
|
||||
|
||||
if (port == 0) {
|
||||
__set_bit(PHY_INTERFACE_MODE_RMII,
|
||||
config->supported_interfaces);
|
||||
__set_bit(PHY_INTERFACE_MODE_MII,
|
||||
config->supported_interfaces);
|
||||
} else {
|
||||
__set_bit(PHY_INTERFACE_MODE_INTERNAL,
|
||||
config->supported_interfaces);
|
||||
/* Compatibility for phylib's default interface type when the
|
||||
* phy-mode property is absent
|
||||
*/
|
||||
__set_bit(PHY_INTERFACE_MODE_GMII,
|
||||
config->supported_interfaces);
|
||||
}
|
||||
|
||||
/* This driver does not make use of the speed, duplex, pause or the
|
||||
* advertisement in its mac_config, so it is safe to mark this driver
|
||||
* as non-legacy.
|
||||
*/
|
||||
config->legacy_pre_march2020 = false;
|
||||
}
|
||||
|
||||
static void lan9303_phylink_mac_link_up(struct dsa_switch *ds, int port,
|
||||
unsigned int mode,
|
||||
phy_interface_t interface,
|
||||
struct phy_device *phydev, int speed,
|
||||
int duplex, bool tx_pause,
|
||||
bool rx_pause)
|
||||
{
|
||||
struct lan9303 *chip = ds->priv;
|
||||
u32 ctl;
|
||||
u32 reg;
|
||||
|
||||
/* On this device, we are only interested in doing something here if
|
||||
* this is the xMII port. All other ports are 10/100 phys using MDIO
|
||||
* to control there link settings.
|
||||
*/
|
||||
if (!IS_PORT_XMII(port))
|
||||
return;
|
||||
|
||||
/* Disable auto-negotiation and force the speed/duplex settings. */
|
||||
ctl = lan9303_phy_read(ds, port, MII_BMCR);
|
||||
ctl &= ~(BMCR_ANENABLE | BMCR_SPEED100 | BMCR_FULLDPLX);
|
||||
if (speed == SPEED_100)
|
||||
ctl |= BMCR_SPEED100;
|
||||
if (duplex == DUPLEX_FULL)
|
||||
ctl |= BMCR_FULLDPLX;
|
||||
lan9303_phy_write(ds, port, MII_BMCR, ctl);
|
||||
|
||||
/* Force the flow control settings. */
|
||||
lan9303_read(chip->regmap, flow_ctl_reg[port], ®);
|
||||
reg &= ~(LAN9303_BP_EN | LAN9303_RX_FC_EN | LAN9303_TX_FC_EN);
|
||||
if (rx_pause)
|
||||
reg |= (LAN9303_RX_FC_EN | LAN9303_BP_EN);
|
||||
if (tx_pause)
|
||||
reg |= LAN9303_TX_FC_EN;
|
||||
regmap_write(chip->regmap, flow_ctl_reg[port], reg);
|
||||
}
|
||||
|
||||
static const struct dsa_switch_ops lan9303_switch_ops = {
|
||||
.get_tag_protocol = lan9303_get_tag_protocol,
|
||||
.setup = lan9303_setup,
|
||||
.get_strings = lan9303_get_strings,
|
||||
.phy_read = lan9303_phy_read,
|
||||
.phy_write = lan9303_phy_write,
|
||||
.adjust_link = lan9303_adjust_link,
|
||||
.get_ethtool_stats = lan9303_get_ethtool_stats,
|
||||
.get_sset_count = lan9303_get_sset_count,
|
||||
.port_enable = lan9303_port_enable,
|
||||
.port_disable = lan9303_port_disable,
|
||||
.port_bridge_join = lan9303_port_bridge_join,
|
||||
.port_bridge_leave = lan9303_port_bridge_leave,
|
||||
.port_stp_state_set = lan9303_port_stp_state_set,
|
||||
.port_fast_age = lan9303_port_fast_age,
|
||||
.port_fdb_add = lan9303_port_fdb_add,
|
||||
.port_fdb_del = lan9303_port_fdb_del,
|
||||
.port_fdb_dump = lan9303_port_fdb_dump,
|
||||
.port_mdb_add = lan9303_port_mdb_add,
|
||||
.port_mdb_del = lan9303_port_mdb_del,
|
||||
.get_tag_protocol = lan9303_get_tag_protocol,
|
||||
.setup = lan9303_setup,
|
||||
.get_strings = lan9303_get_strings,
|
||||
.phy_read = lan9303_phy_read,
|
||||
.phy_write = lan9303_phy_write,
|
||||
.phylink_get_caps = lan9303_phylink_get_caps,
|
||||
.phylink_mac_link_up = lan9303_phylink_mac_link_up,
|
||||
.get_ethtool_stats = lan9303_get_ethtool_stats,
|
||||
.get_sset_count = lan9303_get_sset_count,
|
||||
.port_enable = lan9303_port_enable,
|
||||
.port_disable = lan9303_port_disable,
|
||||
.port_bridge_join = lan9303_port_bridge_join,
|
||||
.port_bridge_leave = lan9303_port_bridge_leave,
|
||||
.port_stp_state_set = lan9303_port_stp_state_set,
|
||||
.port_fast_age = lan9303_port_fast_age,
|
||||
.port_fdb_add = lan9303_port_fdb_add,
|
||||
.port_fdb_del = lan9303_port_fdb_del,
|
||||
.port_fdb_dump = lan9303_port_fdb_dump,
|
||||
.port_mdb_add = lan9303_port_mdb_add,
|
||||
.port_mdb_del = lan9303_port_mdb_del,
|
||||
};
|
||||
|
||||
static int lan9303_register_switch(struct lan9303 *chip)
|
||||
|
|
Loading…
Reference in a new issue