mvebu: add support for SFP
[openwrt/openwrt.git] / target / linux / mvebu / patches-4.4 / 122-phy-separate-swphy-state-validation-from-register-ge.patch
1 From e07630ad84c7dc145863f079f108154fb7c975e7 Mon Sep 17 00:00:00 2001
2 From: Russell King <rmk+kernel@arm.linux.org.uk>
3 Date: Sun, 20 Sep 2015 11:12:15 +0100
4 Subject: [PATCH 711/744] phy: separate swphy state validation from register
5 generation
6
7 Separate out the generation of MII registers from the state validation.
8 This allows us to simplify the error handing in fixed_phy() by allowing
9 earlier error detection.
10
11 Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
12 Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
13 ---
14 drivers/net/phy/fixed_phy.c | 15 +++++++--------
15 drivers/net/phy/swphy.c | 33 ++++++++++++++++++++++++++-------
16 drivers/net/phy/swphy.h | 3 ++-
17 3 files changed, 35 insertions(+), 16 deletions(-)
18
19 --- a/drivers/net/phy/fixed_phy.c
20 +++ b/drivers/net/phy/fixed_phy.c
21 @@ -49,12 +49,12 @@ static struct fixed_mdio_bus platform_fm
22 .phys = LIST_HEAD_INIT(platform_fmb.phys),
23 };
24
25 -static int fixed_phy_update_regs(struct fixed_phy *fp)
26 +static void fixed_phy_update_regs(struct fixed_phy *fp)
27 {
28 if (gpio_is_valid(fp->link_gpio))
29 fp->status.link = !!gpio_get_value_cansleep(fp->link_gpio);
30
31 - return swphy_update_regs(fp->regs, &fp->status);
32 + swphy_update_regs(fp->regs, &fp->status);
33 }
34
35 static int fixed_mdio_read(struct mii_bus *bus, int phy_addr, int reg_num)
36 @@ -161,6 +161,10 @@ int fixed_phy_add(unsigned int irq, int
37 struct fixed_mdio_bus *fmb = &platform_fmb;
38 struct fixed_phy *fp;
39
40 + ret = swphy_validate_state(status);
41 + if (ret < 0)
42 + return ret;
43 +
44 fp = kzalloc(sizeof(*fp), GFP_KERNEL);
45 if (!fp)
46 return -ENOMEM;
47 @@ -180,17 +184,12 @@ int fixed_phy_add(unsigned int irq, int
48 goto err_regs;
49 }
50
51 - ret = fixed_phy_update_regs(fp);
52 - if (ret)
53 - goto err_gpio;
54 + fixed_phy_update_regs(fp);
55
56 list_add_tail(&fp->node, &fmb->phys);
57
58 return 0;
59
60 -err_gpio:
61 - if (gpio_is_valid(fp->link_gpio))
62 - gpio_free(fp->link_gpio);
63 err_regs:
64 kfree(fp);
65 return ret;
66 --- a/drivers/net/phy/swphy.c
67 +++ b/drivers/net/phy/swphy.c
68 @@ -87,6 +87,29 @@ static int swphy_decode_speed(int speed)
69 }
70
71 /**
72 + * swphy_validate_state - validate the software phy status
73 + * @state: software phy status
74 + *
75 + * This checks that we can represent the state stored in @state can be
76 + * represented in the emulated MII registers. Returns 0 if it can,
77 + * otherwise returns -EINVAL.
78 + */
79 +int swphy_validate_state(const struct fixed_phy_status *state)
80 +{
81 + int err;
82 +
83 + if (state->link) {
84 + err = swphy_decode_speed(state->speed);
85 + if (err < 0) {
86 + pr_warn("swphy: unknown speed\n");
87 + return -EINVAL;
88 + }
89 + }
90 + return 0;
91 +}
92 +EXPORT_SYMBOL_GPL(swphy_validate_state);
93 +
94 +/**
95 * swphy_update_regs - update MII register array with fixed phy state
96 * @regs: array of 32 registers to update
97 * @state: fixed phy status
98 @@ -94,7 +117,7 @@ static int swphy_decode_speed(int speed)
99 * Update the array of MII registers with the fixed phy link, speed,
100 * duplex and pause mode settings.
101 */
102 -int swphy_update_regs(u16 *regs, const struct fixed_phy_status *state)
103 +void swphy_update_regs(u16 *regs, const struct fixed_phy_status *state)
104 {
105 int speed_index, duplex_index;
106 u16 bmsr = BMSR_ANEGCAPABLE;
107 @@ -103,10 +126,8 @@ int swphy_update_regs(u16 *regs, const s
108 u16 lpa = 0;
109
110 speed_index = swphy_decode_speed(state->speed);
111 - if (speed_index < 0) {
112 - pr_warn("swphy: unknown speed\n");
113 - return -EINVAL;
114 - }
115 + if (WARN_ON(speed_index < 0))
116 + return;
117
118 duplex_index = state->duplex ? SWMII_DUPLEX_FULL : SWMII_DUPLEX_HALF;
119
120 @@ -133,7 +154,5 @@ int swphy_update_regs(u16 *regs, const s
121 regs[MII_BMCR] = bmcr;
122 regs[MII_LPA] = lpa;
123 regs[MII_STAT1000] = lpagb;
124 -
125 - return 0;
126 }
127 EXPORT_SYMBOL_GPL(swphy_update_regs);
128 --- a/drivers/net/phy/swphy.h
129 +++ b/drivers/net/phy/swphy.h
130 @@ -3,6 +3,7 @@
131
132 struct fixed_phy_status;
133
134 -int swphy_update_regs(u16 *regs, const struct fixed_phy_status *state);
135 +int swphy_validate_state(const struct fixed_phy_status *state);
136 +void swphy_update_regs(u16 *regs, const struct fixed_phy_status *state);
137
138 #endif