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>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Russell King 2016-06-23 14:50:15 +01:00 коммит произвёл David S. Miller
Родитель 0629bf17ea
Коммит 68888ce075
3 изменённых файлов: 35 добавлений и 16 удалений

Просмотреть файл

@ -48,12 +48,12 @@ static struct fixed_mdio_bus platform_fmb = {
.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)
@ -160,6 +160,10 @@ int fixed_phy_add(unsigned int irq, int phy_addr,
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 phy_addr,
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;

Просмотреть файл

@ -86,6 +86,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
@ -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 struct fixed_phy_status *state)
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 struct fixed_phy_status *state)
regs[MII_BMCR] = bmcr;
regs[MII_LPA] = lpa;
regs[MII_STAT1000] = lpagb;
return 0;
}
EXPORT_SYMBOL_GPL(swphy_update_regs);

Просмотреть файл

@ -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