phy: generate swphy registers on the fly
authorRussell King <rmk+kernel@arm.linux.org.uk>
Thu, 23 Jun 2016 13:50:20 +0000 (14:50 +0100)
committerDavid S. Miller <davem@davemloft.net>
Mon, 27 Jun 2016 14:40:57 +0000 (10:40 -0400)
Generate software phy registers as and when requested, rather than
duplicating the state in fixed_phy.  This allows us to eliminate
the duplicate storage of of the same data, which is only different
in format.

As fixed_phy_update_regs() no longer updates register state, rename
it to fixed_phy_update().

Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/phy/fixed_phy.c
drivers/net/phy/swphy.c
drivers/net/phy/swphy.h

index d84e30c4682461f3214ed5e04f5c68b25a897289..0dfed86bdb5a953affec4cdacf4d360aaa5aa34c 100644 (file)
@@ -26,8 +26,6 @@
 
 #include "swphy.h"
 
-#define MII_REGS_NUM 29
-
 struct fixed_mdio_bus {
        struct mii_bus *mii_bus;
        struct list_head phys;
@@ -35,7 +33,6 @@ struct fixed_mdio_bus {
 
 struct fixed_phy {
        int addr;
-       u16 regs[MII_REGS_NUM];
        struct phy_device *phydev;
        struct fixed_phy_status status;
        int (*link_update)(struct net_device *, struct fixed_phy_status *);
@@ -48,12 +45,10 @@ static struct fixed_mdio_bus platform_fmb = {
        .phys = LIST_HEAD_INIT(platform_fmb.phys),
 };
 
-static void fixed_phy_update_regs(struct fixed_phy *fp)
+static void fixed_phy_update(struct fixed_phy *fp)
 {
        if (gpio_is_valid(fp->link_gpio))
                fp->status.link = !!gpio_get_value_cansleep(fp->link_gpio);
-
-       swphy_update_regs(fp->regs, &fp->status);
 }
 
 static int fixed_mdio_read(struct mii_bus *bus, int phy_addr, int reg_num)
@@ -61,29 +56,15 @@ static int fixed_mdio_read(struct mii_bus *bus, int phy_addr, int reg_num)
        struct fixed_mdio_bus *fmb = bus->priv;
        struct fixed_phy *fp;
 
-       if (reg_num >= MII_REGS_NUM)
-               return -1;
-
-       /* We do not support emulating Clause 45 over Clause 22 register reads
-        * return an error instead of bogus data.
-        */
-       switch (reg_num) {
-       case MII_MMD_CTRL:
-       case MII_MMD_DATA:
-               return -1;
-       default:
-               break;
-       }
-
        list_for_each_entry(fp, &fmb->phys, node) {
                if (fp->addr == phy_addr) {
                        /* Issue callback if user registered it. */
                        if (fp->link_update) {
                                fp->link_update(fp->phydev->attached_dev,
                                                &fp->status);
-                               fixed_phy_update_regs(fp);
+                               fixed_phy_update(fp);
                        }
-                       return fp->regs[reg_num];
+                       return swphy_read_reg(reg_num, &fp->status);
                }
        }
 
@@ -143,7 +124,7 @@ int fixed_phy_update_state(struct phy_device *phydev,
                        _UPD(pause);
                        _UPD(asym_pause);
 #undef _UPD
-                       fixed_phy_update_regs(fp);
+                       fixed_phy_update(fp);
                        return 0;
                }
        }
@@ -168,8 +149,6 @@ int fixed_phy_add(unsigned int irq, int phy_addr,
        if (!fp)
                return -ENOMEM;
 
-       memset(fp->regs, 0xFF,  sizeof(fp->regs[0]) * MII_REGS_NUM);
-
        if (irq != PHY_POLL)
                fmb->mii_bus->irq[phy_addr] = irq;
 
@@ -184,7 +163,7 @@ int fixed_phy_add(unsigned int irq, int phy_addr,
                        goto err_regs;
        }
 
-       fixed_phy_update_regs(fp);
+       fixed_phy_update(fp);
 
        list_add_tail(&fp->node, &fmb->phys);
 
index 21a9bd8a7830fe71d59aa5a73ad51639dbe98d22..34f58f2349e901aa5d8212c3890d19bea2423b74 100644 (file)
@@ -20,6 +20,8 @@
 
 #include "swphy.h"
 
+#define MII_REGS_NUM 29
+
 struct swmii_regs {
        u16 bmcr;
        u16 bmsr;
@@ -110,14 +112,13 @@ int swphy_validate_state(const struct fixed_phy_status *state)
 EXPORT_SYMBOL_GPL(swphy_validate_state);
 
 /**
- * swphy_update_regs - update MII register array with fixed phy state
- * @regs: array of 32 registers to update
+ * swphy_read_reg - return a MII register from the fixed phy state
+ * @reg: MII register
  * @state: fixed phy status
  *
- * Update the array of MII registers with the fixed phy link, speed,
- * duplex and pause mode settings.
+ * Return the MII @reg register generated from the fixed phy state @state.
  */
-void swphy_update_regs(u16 *regs, const struct fixed_phy_status *state)
+int swphy_read_reg(int reg, const struct fixed_phy_status *state)
 {
        int speed_index, duplex_index;
        u16 bmsr = BMSR_ANEGCAPABLE;
@@ -125,9 +126,12 @@ void swphy_update_regs(u16 *regs, const struct fixed_phy_status *state)
        u16 lpagb = 0;
        u16 lpa = 0;
 
+       if (reg > MII_REGS_NUM)
+               return -1;
+
        speed_index = swphy_decode_speed(state->speed);
        if (WARN_ON(speed_index < 0))
-               return;
+               return 0;
 
        duplex_index = state->duplex ? SWMII_DUPLEX_FULL : SWMII_DUPLEX_HALF;
 
@@ -147,12 +151,29 @@ void swphy_update_regs(u16 *regs, const struct fixed_phy_status *state)
                        lpa |= LPA_PAUSE_ASYM;
        }
 
-       regs[MII_PHYSID1] = 0;
-       regs[MII_PHYSID2] = 0;
+       switch (reg) {
+       case MII_BMCR:
+               return bmcr;
+       case MII_BMSR:
+               return bmsr;
+       case MII_PHYSID1:
+       case MII_PHYSID2:
+               return 0;
+       case MII_LPA:
+               return lpa;
+       case MII_STAT1000:
+               return lpagb;
+
+       /*
+        * We do not support emulating Clause 45 over Clause 22 register
+        * reads.  Return an error instead of bogus data.
+        */
+       case MII_MMD_CTRL:
+       case MII_MMD_DATA:
+               return -1;
 
-       regs[MII_BMSR] = bmsr;
-       regs[MII_BMCR] = bmcr;
-       regs[MII_LPA] = lpa;
-       regs[MII_STAT1000] = lpagb;
+       default:
+               return 0xffff;
+       }
 }
-EXPORT_SYMBOL_GPL(swphy_update_regs);
+EXPORT_SYMBOL_GPL(swphy_read_reg);
index 33d2e061896ee1b3e73b951c9af56316414625ad..2f09ac324e18ea3a9832a9bdc129b890a275a6a5 100644 (file)
@@ -4,6 +4,6 @@
 struct fixed_phy_status;
 
 int swphy_validate_state(const struct fixed_phy_status *state);
-void swphy_update_regs(u16 *regs, const struct fixed_phy_status *state);
+int swphy_read_reg(int reg, const struct fixed_phy_status *state);
 
 #endif