diff options
Diffstat (limited to 'target/linux/mvebu/patches-4.4/122-phy-separate-swphy-state-validation-from-register-ge.patch')
-rw-r--r-- | target/linux/mvebu/patches-4.4/122-phy-separate-swphy-state-validation-from-register-ge.patch | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/target/linux/mvebu/patches-4.4/122-phy-separate-swphy-state-validation-from-register-ge.patch b/target/linux/mvebu/patches-4.4/122-phy-separate-swphy-state-validation-from-register-ge.patch new file mode 100644 index 0000000000..4b332cc8b7 --- /dev/null +++ b/target/linux/mvebu/patches-4.4/122-phy-separate-swphy-state-validation-from-register-ge.patch @@ -0,0 +1,138 @@ +From e07630ad84c7dc145863f079f108154fb7c975e7 Mon Sep 17 00:00:00 2001 +From: Russell King <rmk+kernel@arm.linux.org.uk> +Date: Sun, 20 Sep 2015 11:12:15 +0100 +Subject: [PATCH 711/744] phy: separate swphy state validation from register + generation + +Separate out the generation of MII registers from the state validation. +This allows us to simplify the error handing in fixed_phy() by allowing +earlier error detection. + +Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> +Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> +--- + drivers/net/phy/fixed_phy.c | 15 +++++++-------- + drivers/net/phy/swphy.c | 33 ++++++++++++++++++++++++++------- + drivers/net/phy/swphy.h | 3 ++- + 3 files changed, 35 insertions(+), 16 deletions(-) + +--- a/drivers/net/phy/fixed_phy.c ++++ b/drivers/net/phy/fixed_phy.c +@@ -49,12 +49,12 @@ static struct fixed_mdio_bus platform_fm + .phys = LIST_HEAD_INIT(platform_fmb.phys), + }; + +-static int fixed_phy_update_regs(struct fixed_phy *fp) ++static void fixed_phy_update_regs(struct fixed_phy *fp) + { + if (gpio_is_valid(fp->link_gpio)) + fp->status.link = !!gpio_get_value_cansleep(fp->link_gpio); + +- return swphy_update_regs(fp->regs, &fp->status); ++ swphy_update_regs(fp->regs, &fp->status); + } + + static int fixed_mdio_read(struct mii_bus *bus, int phy_addr, int reg_num) +@@ -161,6 +161,10 @@ int fixed_phy_add(unsigned int irq, int + struct fixed_mdio_bus *fmb = &platform_fmb; + struct fixed_phy *fp; + ++ ret = swphy_validate_state(status); ++ if (ret < 0) ++ return ret; ++ + fp = kzalloc(sizeof(*fp), GFP_KERNEL); + if (!fp) + return -ENOMEM; +@@ -180,17 +184,12 @@ int fixed_phy_add(unsigned int irq, int + goto err_regs; + } + +- ret = fixed_phy_update_regs(fp); +- if (ret) +- goto err_gpio; ++ fixed_phy_update_regs(fp); + + list_add_tail(&fp->node, &fmb->phys); + + return 0; + +-err_gpio: +- if (gpio_is_valid(fp->link_gpio)) +- gpio_free(fp->link_gpio); + err_regs: + kfree(fp); + return ret; +--- a/drivers/net/phy/swphy.c ++++ b/drivers/net/phy/swphy.c +@@ -87,6 +87,29 @@ static int swphy_decode_speed(int speed) + } + + /** ++ * swphy_validate_state - validate the software phy status ++ * @state: software phy status ++ * ++ * This checks that we can represent the state stored in @state can be ++ * represented in the emulated MII registers. Returns 0 if it can, ++ * otherwise returns -EINVAL. ++ */ ++int swphy_validate_state(const struct fixed_phy_status *state) ++{ ++ int err; ++ ++ if (state->link) { ++ err = swphy_decode_speed(state->speed); ++ if (err < 0) { ++ pr_warn("swphy: unknown speed\n"); ++ return -EINVAL; ++ } ++ } ++ return 0; ++} ++EXPORT_SYMBOL_GPL(swphy_validate_state); ++ ++/** + * swphy_update_regs - update MII register array with fixed phy state + * @regs: array of 32 registers to update + * @state: fixed phy status +@@ -94,7 +117,7 @@ static int swphy_decode_speed(int speed) + * Update the array of MII registers with the fixed phy link, speed, + * duplex and pause mode settings. + */ +-int swphy_update_regs(u16 *regs, const struct fixed_phy_status *state) ++void swphy_update_regs(u16 *regs, const struct fixed_phy_status *state) + { + int speed_index, duplex_index; + u16 bmsr = BMSR_ANEGCAPABLE; +@@ -103,10 +126,8 @@ int swphy_update_regs(u16 *regs, const s + u16 lpa = 0; + + speed_index = swphy_decode_speed(state->speed); +- if (speed_index < 0) { +- pr_warn("swphy: unknown speed\n"); +- return -EINVAL; +- } ++ if (WARN_ON(speed_index < 0)) ++ return; + + duplex_index = state->duplex ? SWMII_DUPLEX_FULL : SWMII_DUPLEX_HALF; + +@@ -133,7 +154,5 @@ int swphy_update_regs(u16 *regs, const s + regs[MII_BMCR] = bmcr; + regs[MII_LPA] = lpa; + regs[MII_STAT1000] = lpagb; +- +- return 0; + } + EXPORT_SYMBOL_GPL(swphy_update_regs); +--- a/drivers/net/phy/swphy.h ++++ b/drivers/net/phy/swphy.h +@@ -3,6 +3,7 @@ + + struct fixed_phy_status; + +-int swphy_update_regs(u16 *regs, const struct fixed_phy_status *state); ++int swphy_validate_state(const struct fixed_phy_status *state); ++void swphy_update_regs(u16 *regs, const struct fixed_phy_status *state); + + #endif |