From 4264350acb75430d5021a1d7de56a33faf69a097 Mon Sep 17 00:00:00 2001 From: Ansuel Smith Date: Wed, 2 Feb 2022 01:03:32 +0100 Subject: [PATCH 13/16] net: dsa: qca8k: move page cache to driver priv There can be multiple qca8k switch on the same system. Move the static qca8k_current_page to qca8k_priv and make it specific for each switch. Signed-off-by: Ansuel Smith Reviewed-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/dsa/qca8k.c | 42 ++++++++++++++++++++--------------------- drivers/net/dsa/qca8k.h | 9 +++++++++ 2 files changed, 29 insertions(+), 22 deletions(-) --- a/drivers/net/dsa/qca8k.c +++ b/drivers/net/dsa/qca8k.c @@ -75,12 +75,6 @@ static const struct qca8k_mib_desc ar832 MIB_DESC(1, 0xac, "TXUnicast"), }; -/* The 32bit switch registers are accessed indirectly. To achieve this we need - * to set the page of the register. Track the last page that was set to reduce - * mdio writes - */ -static u16 qca8k_current_page = 0xffff; - static void qca8k_split_addr(u32 regaddr, u16 *r1, u16 *r2, u16 *page) { @@ -134,11 +128,13 @@ qca8k_mii_write32(struct mii_bus *bus, i } static int -qca8k_set_page(struct mii_bus *bus, u16 page) +qca8k_set_page(struct qca8k_priv *priv, u16 page) { + u16 *cached_page = &priv->mdio_cache.page; + struct mii_bus *bus = priv->bus; int ret; - if (page == qca8k_current_page) + if (page == *cached_page) return 0; ret = bus->write(bus, 0x18, 0, page); @@ -148,7 +144,7 @@ qca8k_set_page(struct mii_bus *bus, u16 return ret; } - qca8k_current_page = page; + *cached_page = page; usleep_range(1000, 2000); return 0; } @@ -374,7 +370,7 @@ qca8k_regmap_read(void *ctx, uint32_t re mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); - ret = qca8k_set_page(bus, page); + ret = qca8k_set_page(priv, page); if (ret < 0) goto exit; @@ -400,7 +396,7 @@ qca8k_regmap_write(void *ctx, uint32_t r mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); - ret = qca8k_set_page(bus, page); + ret = qca8k_set_page(priv, page); if (ret < 0) goto exit; @@ -427,7 +423,7 @@ qca8k_regmap_update_bits(void *ctx, uint mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); - ret = qca8k_set_page(bus, page); + ret = qca8k_set_page(priv, page); if (ret < 0) goto exit; @@ -1098,8 +1094,9 @@ qca8k_mdio_busy_wait(struct mii_bus *bus } static int -qca8k_mdio_write(struct mii_bus *bus, int phy, int regnum, u16 data) +qca8k_mdio_write(struct qca8k_priv *priv, int phy, int regnum, u16 data) { + struct mii_bus *bus = priv->bus; u16 r1, r2, page; u32 val; int ret; @@ -1116,7 +1113,7 @@ qca8k_mdio_write(struct mii_bus *bus, in mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); - ret = qca8k_set_page(bus, page); + ret = qca8k_set_page(priv, page); if (ret) goto exit; @@ -1135,8 +1132,9 @@ exit: } static int -qca8k_mdio_read(struct mii_bus *bus, int phy, int regnum) +qca8k_mdio_read(struct qca8k_priv *priv, int phy, int regnum) { + struct mii_bus *bus = priv->bus; u16 r1, r2, page; u32 val; int ret; @@ -1152,7 +1150,7 @@ qca8k_mdio_read(struct mii_bus *bus, int mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); - ret = qca8k_set_page(bus, page); + ret = qca8k_set_page(priv, page); if (ret) goto exit; @@ -1181,7 +1179,6 @@ static int qca8k_internal_mdio_write(struct mii_bus *slave_bus, int phy, int regnum, u16 data) { struct qca8k_priv *priv = slave_bus->priv; - struct mii_bus *bus = priv->bus; int ret; /* Use mdio Ethernet when available, fallback to legacy one on error */ @@ -1189,14 +1186,13 @@ qca8k_internal_mdio_write(struct mii_bus if (!ret) return 0; - return qca8k_mdio_write(bus, phy, regnum, data); + return qca8k_mdio_write(priv, phy, regnum, data); } static int qca8k_internal_mdio_read(struct mii_bus *slave_bus, int phy, int regnum) { struct qca8k_priv *priv = slave_bus->priv; - struct mii_bus *bus = priv->bus; int ret; /* Use mdio Ethernet when available, fallback to legacy one on error */ @@ -1204,7 +1200,7 @@ qca8k_internal_mdio_read(struct mii_bus if (ret >= 0) return ret; - return qca8k_mdio_read(bus, phy, regnum); + return qca8k_mdio_read(priv, phy, regnum); } static int @@ -1225,7 +1221,7 @@ qca8k_phy_write(struct dsa_switch *ds, i if (!ret) return ret; - return qca8k_mdio_write(priv->bus, port, regnum, data); + return qca8k_mdio_write(priv, port, regnum, data); } static int @@ -1246,7 +1242,7 @@ qca8k_phy_read(struct dsa_switch *ds, in if (ret >= 0) return ret; - ret = qca8k_mdio_read(priv->bus, port, regnum); + ret = qca8k_mdio_read(priv, port, regnum); if (ret < 0) return 0xffff; @@ -3060,6 +3056,8 @@ qca8k_sw_probe(struct mdio_device *mdiod return PTR_ERR(priv->regmap); } + priv->mdio_cache.page = 0xffff; + /* Check the detected switch id */ ret = qca8k_read_switch_id(priv); if (ret) --- a/drivers/net/dsa/qca8k.h +++ b/drivers/net/dsa/qca8k.h @@ -363,6 +363,14 @@ struct qca8k_ports_config { u8 rgmii_tx_delay[QCA8K_NUM_CPU_PORTS]; /* 0: CPU port0, 1: CPU port6 */ }; +struct qca8k_mdio_cache { +/* The 32bit switch registers are accessed indirectly. To achieve this we need + * to set the page of the register. Track the last page that was set to reduce + * mdio writes + */ + u16 page; +}; + struct qca8k_priv { u8 switch_id; u8 switch_revision; @@ -383,6 +391,7 @@ struct qca8k_priv { struct net_device *mgmt_master; /* Track if mdio/mib Ethernet is available */ struct qca8k_mgmt_eth_data mgmt_eth_data; struct qca8k_mib_eth_data mib_eth_data; + struct qca8k_mdio_cache mdio_cache; }; struct qca8k_mib_desc {