... | ... | ||
---|---|---|---|
26 | struct, .match_phy_device is extended to provide also the | 26 | struct, .match_phy_device is extended to provide also the |
27 | current phy_driver is trying to match for. This add the | 27 | current phy_driver is trying to match for. This add the |
28 | extra benefits that some other PHY can simplify their | 28 | extra benefits that some other PHY can simplify their |
29 | .match_phy_device OP. | 29 | .match_phy_device OP. |
30 | 30 | ||
31 | Changes v6: | ||
32 | - Out of RFC | ||
33 | - Add Reviewed-by tag from Russell | ||
31 | Changes v5: | 34 | Changes v5: |
32 | - Add Reviewed-by tag from Rob | 35 | - Add Reviewed-by tag from Rob |
33 | - Fix subject in DT patch | 36 | - Fix subject in DT patch |
34 | - Fix wrong Suggested-by tag in patch 1 | 37 | - Fix wrong Suggested-by tag in patch 1 |
35 | - Rework nxp patch to 80 column | 38 | - Rework nxp patch to 80 column |
... | ... | diff view generated by jsdifflib |
1 | Pass PHY driver pointer to .match_phy_device OP in addition to phydev. | 1 | Pass PHY driver pointer to .match_phy_device OP in addition to phydev. |
---|---|---|---|
2 | Having access to the PHY driver struct might be useful to check the | 2 | Having access to the PHY driver struct might be useful to check the |
3 | PHY ID of the driver is being matched for in case the PHY ID scanned in | 3 | PHY ID of the driver is being matched for in case the PHY ID scanned in |
4 | the phydev is not consistent. | 4 | the phydev is not consistent. |
5 | 5 | ||
6 | A scenario for this is a PHY that change PHY ID after a firmware is | 6 | A scenario for this is a PHY that change PHY ID after a firmware is |
7 | loaded, in such case, the PHY ID stored in PHY device struct is not | 7 | loaded, in such case, the PHY ID stored in PHY device struct is not |
8 | valid anymore and PHY will manually scan the ID in the match_phy_device | 8 | valid anymore and PHY will manually scan the ID in the match_phy_device |
9 | function. | 9 | function. |
10 | 10 | ||
11 | Having the PHY driver info is also useful for those PHY driver that | 11 | Having the PHY driver info is also useful for those PHY driver that |
12 | implement multiple simple .match_phy_device OP to match specific MMD PHY | 12 | implement multiple simple .match_phy_device OP to match specific MMD PHY |
13 | ID. With this extra info if the parsing logic is the same, the matching | 13 | ID. With this extra info if the parsing logic is the same, the matching |
14 | function can be generalized by using the phy_id in the PHY driver | 14 | function can be generalized by using the phy_id in the PHY driver |
15 | instead of hardcoding. | 15 | instead of hardcoding. |
16 | 16 | ||
17 | Suggested-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk> | 17 | Suggested-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk> |
18 | Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk> | 18 | Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk> |
19 | Signed-off-by: Christian Marangi <ansuelsmth@gmail.com> | 19 | Signed-off-by: Christian Marangi <ansuelsmth@gmail.com> |
20 | --- | 20 | --- |
21 | drivers/net/phy/bcm87xx.c | 6 ++++-- | 21 | drivers/net/phy/bcm87xx.c | 6 ++++-- |
22 | drivers/net/phy/icplus.c | 6 ++++-- | 22 | drivers/net/phy/icplus.c | 6 ++++-- |
23 | drivers/net/phy/marvell10g.c | 12 ++++++++---- | 23 | drivers/net/phy/marvell10g.c | 12 ++++++++---- |
24 | drivers/net/phy/micrel.c | 6 ++++-- | 24 | drivers/net/phy/micrel.c | 6 ++++-- |
25 | drivers/net/phy/nxp-c45-tja11xx.c | 12 ++++++++---- | 25 | drivers/net/phy/nxp-c45-tja11xx.c | 12 ++++++++---- |
26 | drivers/net/phy/nxp-tja11xx.c | 6 ++++-- | 26 | drivers/net/phy/nxp-tja11xx.c | 6 ++++-- |
27 | drivers/net/phy/phy_device.c | 2 +- | 27 | drivers/net/phy/phy_device.c | 2 +- |
28 | drivers/net/phy/realtek/realtek_main.c | 27 +++++++++++++++++--------- | 28 | drivers/net/phy/realtek/realtek_main.c | 27 +++++++++++++++++--------- |
29 | drivers/net/phy/teranetics.c | 3 ++- | 29 | drivers/net/phy/teranetics.c | 3 ++- |
30 | include/linux/phy.h | 3 ++- | 30 | include/linux/phy.h | 3 ++- |
31 | 10 files changed, 55 insertions(+), 28 deletions(-) | 31 | 10 files changed, 55 insertions(+), 28 deletions(-) |
32 | 32 | ||
33 | diff --git a/drivers/net/phy/bcm87xx.c b/drivers/net/phy/bcm87xx.c | 33 | diff --git a/drivers/net/phy/bcm87xx.c b/drivers/net/phy/bcm87xx.c |
34 | index XXXXXXX..XXXXXXX 100644 | 34 | index XXXXXXX..XXXXXXX 100644 |
35 | --- a/drivers/net/phy/bcm87xx.c | 35 | --- a/drivers/net/phy/bcm87xx.c |
36 | +++ b/drivers/net/phy/bcm87xx.c | 36 | +++ b/drivers/net/phy/bcm87xx.c |
37 | @@ -XXX,XX +XXX,XX @@ static irqreturn_t bcm87xx_handle_interrupt(struct phy_device *phydev) | 37 | @@ -XXX,XX +XXX,XX @@ static irqreturn_t bcm87xx_handle_interrupt(struct phy_device *phydev) |
38 | return IRQ_HANDLED; | 38 | return IRQ_HANDLED; |
39 | } | 39 | } |
40 | 40 | ||
41 | -static int bcm8706_match_phy_device(struct phy_device *phydev) | 41 | -static int bcm8706_match_phy_device(struct phy_device *phydev) |
42 | +static int bcm8706_match_phy_device(struct phy_device *phydev, | 42 | +static int bcm8706_match_phy_device(struct phy_device *phydev, |
43 | + const struct phy_driver *phydrv) | 43 | + const struct phy_driver *phydrv) |
44 | { | 44 | { |
45 | return phydev->c45_ids.device_ids[4] == PHY_ID_BCM8706; | 45 | return phydev->c45_ids.device_ids[4] == PHY_ID_BCM8706; |
46 | } | 46 | } |
47 | 47 | ||
48 | -static int bcm8727_match_phy_device(struct phy_device *phydev) | 48 | -static int bcm8727_match_phy_device(struct phy_device *phydev) |
49 | +static int bcm8727_match_phy_device(struct phy_device *phydev, | 49 | +static int bcm8727_match_phy_device(struct phy_device *phydev, |
50 | + const struct phy_driver *phydrv) | 50 | + const struct phy_driver *phydrv) |
51 | { | 51 | { |
52 | return phydev->c45_ids.device_ids[4] == PHY_ID_BCM8727; | 52 | return phydev->c45_ids.device_ids[4] == PHY_ID_BCM8727; |
53 | } | 53 | } |
54 | diff --git a/drivers/net/phy/icplus.c b/drivers/net/phy/icplus.c | 54 | diff --git a/drivers/net/phy/icplus.c b/drivers/net/phy/icplus.c |
55 | index XXXXXXX..XXXXXXX 100644 | 55 | index XXXXXXX..XXXXXXX 100644 |
56 | --- a/drivers/net/phy/icplus.c | 56 | --- a/drivers/net/phy/icplus.c |
57 | +++ b/drivers/net/phy/icplus.c | 57 | +++ b/drivers/net/phy/icplus.c |
58 | @@ -XXX,XX +XXX,XX @@ static int ip101a_g_match_phy_device(struct phy_device *phydev, bool ip101a) | 58 | @@ -XXX,XX +XXX,XX @@ static int ip101a_g_match_phy_device(struct phy_device *phydev, bool ip101a) |
59 | return ip101a == !ret; | 59 | return ip101a == !ret; |
60 | } | 60 | } |
61 | 61 | ||
62 | -static int ip101a_match_phy_device(struct phy_device *phydev) | 62 | -static int ip101a_match_phy_device(struct phy_device *phydev) |
63 | +static int ip101a_match_phy_device(struct phy_device *phydev, | 63 | +static int ip101a_match_phy_device(struct phy_device *phydev, |
64 | + const struct phy_driver *phydrv) | 64 | + const struct phy_driver *phydrv) |
65 | { | 65 | { |
66 | return ip101a_g_match_phy_device(phydev, true); | 66 | return ip101a_g_match_phy_device(phydev, true); |
67 | } | 67 | } |
68 | 68 | ||
69 | -static int ip101g_match_phy_device(struct phy_device *phydev) | 69 | -static int ip101g_match_phy_device(struct phy_device *phydev) |
70 | +static int ip101g_match_phy_device(struct phy_device *phydev, | 70 | +static int ip101g_match_phy_device(struct phy_device *phydev, |
71 | + const struct phy_driver *phydrv) | 71 | + const struct phy_driver *phydrv) |
72 | { | 72 | { |
73 | return ip101a_g_match_phy_device(phydev, false); | 73 | return ip101a_g_match_phy_device(phydev, false); |
74 | } | 74 | } |
75 | diff --git a/drivers/net/phy/marvell10g.c b/drivers/net/phy/marvell10g.c | 75 | diff --git a/drivers/net/phy/marvell10g.c b/drivers/net/phy/marvell10g.c |
76 | index XXXXXXX..XXXXXXX 100644 | 76 | index XXXXXXX..XXXXXXX 100644 |
77 | --- a/drivers/net/phy/marvell10g.c | 77 | --- a/drivers/net/phy/marvell10g.c |
78 | +++ b/drivers/net/phy/marvell10g.c | 78 | +++ b/drivers/net/phy/marvell10g.c |
79 | @@ -XXX,XX +XXX,XX @@ static int mv3310_get_number_of_ports(struct phy_device *phydev) | 79 | @@ -XXX,XX +XXX,XX @@ static int mv3310_get_number_of_ports(struct phy_device *phydev) |
80 | return ret + 1; | 80 | return ret + 1; |
81 | } | 81 | } |
82 | 82 | ||
83 | -static int mv3310_match_phy_device(struct phy_device *phydev) | 83 | -static int mv3310_match_phy_device(struct phy_device *phydev) |
84 | +static int mv3310_match_phy_device(struct phy_device *phydev, | 84 | +static int mv3310_match_phy_device(struct phy_device *phydev, |
85 | + const struct phy_driver *phydrv) | 85 | + const struct phy_driver *phydrv) |
86 | { | 86 | { |
87 | if ((phydev->c45_ids.device_ids[MDIO_MMD_PMAPMD] & | 87 | if ((phydev->c45_ids.device_ids[MDIO_MMD_PMAPMD] & |
88 | MARVELL_PHY_ID_MASK) != MARVELL_PHY_ID_88X3310) | 88 | MARVELL_PHY_ID_MASK) != MARVELL_PHY_ID_88X3310) |
89 | @@ -XXX,XX +XXX,XX @@ static int mv3310_match_phy_device(struct phy_device *phydev) | 89 | @@ -XXX,XX +XXX,XX @@ static int mv3310_match_phy_device(struct phy_device *phydev) |
90 | return mv3310_get_number_of_ports(phydev) == 1; | 90 | return mv3310_get_number_of_ports(phydev) == 1; |
91 | } | 91 | } |
92 | 92 | ||
93 | -static int mv3340_match_phy_device(struct phy_device *phydev) | 93 | -static int mv3340_match_phy_device(struct phy_device *phydev) |
94 | +static int mv3340_match_phy_device(struct phy_device *phydev, | 94 | +static int mv3340_match_phy_device(struct phy_device *phydev, |
95 | + const struct phy_driver *phydrv) | 95 | + const struct phy_driver *phydrv) |
96 | { | 96 | { |
97 | if ((phydev->c45_ids.device_ids[MDIO_MMD_PMAPMD] & | 97 | if ((phydev->c45_ids.device_ids[MDIO_MMD_PMAPMD] & |
98 | MARVELL_PHY_ID_MASK) != MARVELL_PHY_ID_88X3310) | 98 | MARVELL_PHY_ID_MASK) != MARVELL_PHY_ID_88X3310) |
99 | @@ -XXX,XX +XXX,XX @@ static int mv211x_match_phy_device(struct phy_device *phydev, bool has_5g) | 99 | @@ -XXX,XX +XXX,XX @@ static int mv211x_match_phy_device(struct phy_device *phydev, bool has_5g) |
100 | return !!(val & MDIO_PCS_SPEED_5G) == has_5g; | 100 | return !!(val & MDIO_PCS_SPEED_5G) == has_5g; |
101 | } | 101 | } |
102 | 102 | ||
103 | -static int mv2110_match_phy_device(struct phy_device *phydev) | 103 | -static int mv2110_match_phy_device(struct phy_device *phydev) |
104 | +static int mv2110_match_phy_device(struct phy_device *phydev, | 104 | +static int mv2110_match_phy_device(struct phy_device *phydev, |
105 | + const struct phy_driver *phydrv) | 105 | + const struct phy_driver *phydrv) |
106 | { | 106 | { |
107 | return mv211x_match_phy_device(phydev, true); | 107 | return mv211x_match_phy_device(phydev, true); |
108 | } | 108 | } |
109 | 109 | ||
110 | -static int mv2111_match_phy_device(struct phy_device *phydev) | 110 | -static int mv2111_match_phy_device(struct phy_device *phydev) |
111 | +static int mv2111_match_phy_device(struct phy_device *phydev, | 111 | +static int mv2111_match_phy_device(struct phy_device *phydev, |
112 | + const struct phy_driver *phydrv) | 112 | + const struct phy_driver *phydrv) |
113 | { | 113 | { |
114 | return mv211x_match_phy_device(phydev, false); | 114 | return mv211x_match_phy_device(phydev, false); |
115 | } | 115 | } |
116 | diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c | 116 | diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c |
117 | index XXXXXXX..XXXXXXX 100644 | 117 | index XXXXXXX..XXXXXXX 100644 |
118 | --- a/drivers/net/phy/micrel.c | 118 | --- a/drivers/net/phy/micrel.c |
119 | +++ b/drivers/net/phy/micrel.c | 119 | +++ b/drivers/net/phy/micrel.c |
120 | @@ -XXX,XX +XXX,XX @@ static int ksz8051_ksz8795_match_phy_device(struct phy_device *phydev, | 120 | @@ -XXX,XX +XXX,XX @@ static int ksz8051_ksz8795_match_phy_device(struct phy_device *phydev, |
121 | return !ret; | 121 | return !ret; |
122 | } | 122 | } |
123 | 123 | ||
124 | -static int ksz8051_match_phy_device(struct phy_device *phydev) | 124 | -static int ksz8051_match_phy_device(struct phy_device *phydev) |
125 | +static int ksz8051_match_phy_device(struct phy_device *phydev, | 125 | +static int ksz8051_match_phy_device(struct phy_device *phydev, |
126 | + const struct phy_driver *phydrv) | 126 | + const struct phy_driver *phydrv) |
127 | { | 127 | { |
128 | return ksz8051_ksz8795_match_phy_device(phydev, true); | 128 | return ksz8051_ksz8795_match_phy_device(phydev, true); |
129 | } | 129 | } |
130 | @@ -XXX,XX +XXX,XX @@ static int ksz8061_config_init(struct phy_device *phydev) | 130 | @@ -XXX,XX +XXX,XX @@ static int ksz8061_config_init(struct phy_device *phydev) |
131 | return kszphy_config_init(phydev); | 131 | return kszphy_config_init(phydev); |
132 | } | 132 | } |
133 | 133 | ||
134 | -static int ksz8795_match_phy_device(struct phy_device *phydev) | 134 | -static int ksz8795_match_phy_device(struct phy_device *phydev) |
135 | +static int ksz8795_match_phy_device(struct phy_device *phydev, | 135 | +static int ksz8795_match_phy_device(struct phy_device *phydev, |
136 | + const struct phy_driver *phydrv) | 136 | + const struct phy_driver *phydrv) |
137 | { | 137 | { |
138 | return ksz8051_ksz8795_match_phy_device(phydev, false); | 138 | return ksz8051_ksz8795_match_phy_device(phydev, false); |
139 | } | 139 | } |
140 | diff --git a/drivers/net/phy/nxp-c45-tja11xx.c b/drivers/net/phy/nxp-c45-tja11xx.c | 140 | diff --git a/drivers/net/phy/nxp-c45-tja11xx.c b/drivers/net/phy/nxp-c45-tja11xx.c |
141 | index XXXXXXX..XXXXXXX 100644 | 141 | index XXXXXXX..XXXXXXX 100644 |
142 | --- a/drivers/net/phy/nxp-c45-tja11xx.c | 142 | --- a/drivers/net/phy/nxp-c45-tja11xx.c |
143 | +++ b/drivers/net/phy/nxp-c45-tja11xx.c | 143 | +++ b/drivers/net/phy/nxp-c45-tja11xx.c |
144 | @@ -XXX,XX +XXX,XX @@ static int nxp_c45_macsec_ability(struct phy_device *phydev) | 144 | @@ -XXX,XX +XXX,XX @@ static int nxp_c45_macsec_ability(struct phy_device *phydev) |
145 | return macsec_ability; | 145 | return macsec_ability; |
146 | } | 146 | } |
147 | 147 | ||
148 | -static int tja1103_match_phy_device(struct phy_device *phydev) | 148 | -static int tja1103_match_phy_device(struct phy_device *phydev) |
149 | +static int tja1103_match_phy_device(struct phy_device *phydev, | 149 | +static int tja1103_match_phy_device(struct phy_device *phydev, |
150 | + const struct phy_driver *phydrv) | 150 | + const struct phy_driver *phydrv) |
151 | { | 151 | { |
152 | return phy_id_compare(phydev->phy_id, PHY_ID_TJA_1103, PHY_ID_MASK) && | 152 | return phy_id_compare(phydev->phy_id, PHY_ID_TJA_1103, PHY_ID_MASK) && |
153 | !nxp_c45_macsec_ability(phydev); | 153 | !nxp_c45_macsec_ability(phydev); |
154 | } | 154 | } |
155 | 155 | ||
156 | -static int tja1104_match_phy_device(struct phy_device *phydev) | 156 | -static int tja1104_match_phy_device(struct phy_device *phydev) |
157 | +static int tja1104_match_phy_device(struct phy_device *phydev, | 157 | +static int tja1104_match_phy_device(struct phy_device *phydev, |
158 | + const struct phy_driver *phydrv) | 158 | + const struct phy_driver *phydrv) |
159 | { | 159 | { |
160 | return phy_id_compare(phydev->phy_id, PHY_ID_TJA_1103, PHY_ID_MASK) && | 160 | return phy_id_compare(phydev->phy_id, PHY_ID_TJA_1103, PHY_ID_MASK) && |
161 | nxp_c45_macsec_ability(phydev); | 161 | nxp_c45_macsec_ability(phydev); |
162 | } | 162 | } |
163 | 163 | ||
164 | -static int tja1120_match_phy_device(struct phy_device *phydev) | 164 | -static int tja1120_match_phy_device(struct phy_device *phydev) |
165 | +static int tja1120_match_phy_device(struct phy_device *phydev, | 165 | +static int tja1120_match_phy_device(struct phy_device *phydev, |
166 | + const struct phy_driver *phydrv) | 166 | + const struct phy_driver *phydrv) |
167 | { | 167 | { |
168 | return phy_id_compare(phydev->phy_id, PHY_ID_TJA_1120, PHY_ID_MASK) && | 168 | return phy_id_compare(phydev->phy_id, PHY_ID_TJA_1120, PHY_ID_MASK) && |
169 | !nxp_c45_macsec_ability(phydev); | 169 | !nxp_c45_macsec_ability(phydev); |
170 | } | 170 | } |
171 | 171 | ||
172 | -static int tja1121_match_phy_device(struct phy_device *phydev) | 172 | -static int tja1121_match_phy_device(struct phy_device *phydev) |
173 | +static int tja1121_match_phy_device(struct phy_device *phydev, | 173 | +static int tja1121_match_phy_device(struct phy_device *phydev, |
174 | + const struct phy_driver *phydrv) | 174 | + const struct phy_driver *phydrv) |
175 | { | 175 | { |
176 | return phy_id_compare(phydev->phy_id, PHY_ID_TJA_1120, PHY_ID_MASK) && | 176 | return phy_id_compare(phydev->phy_id, PHY_ID_TJA_1120, PHY_ID_MASK) && |
177 | nxp_c45_macsec_ability(phydev); | 177 | nxp_c45_macsec_ability(phydev); |
178 | diff --git a/drivers/net/phy/nxp-tja11xx.c b/drivers/net/phy/nxp-tja11xx.c | 178 | diff --git a/drivers/net/phy/nxp-tja11xx.c b/drivers/net/phy/nxp-tja11xx.c |
179 | index XXXXXXX..XXXXXXX 100644 | 179 | index XXXXXXX..XXXXXXX 100644 |
180 | --- a/drivers/net/phy/nxp-tja11xx.c | 180 | --- a/drivers/net/phy/nxp-tja11xx.c |
181 | +++ b/drivers/net/phy/nxp-tja11xx.c | 181 | +++ b/drivers/net/phy/nxp-tja11xx.c |
182 | @@ -XXX,XX +XXX,XX @@ static int tja1102_match_phy_device(struct phy_device *phydev, bool port0) | 182 | @@ -XXX,XX +XXX,XX @@ static int tja1102_match_phy_device(struct phy_device *phydev, bool port0) |
183 | return !ret; | 183 | return !ret; |
184 | } | 184 | } |
185 | 185 | ||
186 | -static int tja1102_p0_match_phy_device(struct phy_device *phydev) | 186 | -static int tja1102_p0_match_phy_device(struct phy_device *phydev) |
187 | +static int tja1102_p0_match_phy_device(struct phy_device *phydev, | 187 | +static int tja1102_p0_match_phy_device(struct phy_device *phydev, |
188 | + const struct phy_driver *phydrv) | 188 | + const struct phy_driver *phydrv) |
189 | { | 189 | { |
190 | return tja1102_match_phy_device(phydev, true); | 190 | return tja1102_match_phy_device(phydev, true); |
191 | } | 191 | } |
192 | 192 | ||
193 | -static int tja1102_p1_match_phy_device(struct phy_device *phydev) | 193 | -static int tja1102_p1_match_phy_device(struct phy_device *phydev) |
194 | +static int tja1102_p1_match_phy_device(struct phy_device *phydev, | 194 | +static int tja1102_p1_match_phy_device(struct phy_device *phydev, |
195 | + const struct phy_driver *phydrv) | 195 | + const struct phy_driver *phydrv) |
196 | { | 196 | { |
197 | return tja1102_match_phy_device(phydev, false); | 197 | return tja1102_match_phy_device(phydev, false); |
198 | } | 198 | } |
199 | diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c | 199 | diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c |
200 | index XXXXXXX..XXXXXXX 100644 | 200 | index XXXXXXX..XXXXXXX 100644 |
201 | --- a/drivers/net/phy/phy_device.c | 201 | --- a/drivers/net/phy/phy_device.c |
202 | +++ b/drivers/net/phy/phy_device.c | 202 | +++ b/drivers/net/phy/phy_device.c |
203 | @@ -XXX,XX +XXX,XX @@ static int phy_bus_match(struct device *dev, const struct device_driver *drv) | 203 | @@ -XXX,XX +XXX,XX @@ static int phy_bus_match(struct device *dev, const struct device_driver *drv) |
204 | return 0; | 204 | return 0; |
205 | 205 | ||
206 | if (phydrv->match_phy_device) | 206 | if (phydrv->match_phy_device) |
207 | - return phydrv->match_phy_device(phydev); | 207 | - return phydrv->match_phy_device(phydev); |
208 | + return phydrv->match_phy_device(phydev, phydrv); | 208 | + return phydrv->match_phy_device(phydev, phydrv); |
209 | 209 | ||
210 | if (phydev->is_c45) { | 210 | if (phydev->is_c45) { |
211 | for (i = 1; i < num_ids; i++) { | 211 | for (i = 1; i < num_ids; i++) { |
212 | diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c | 212 | diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c |
213 | index XXXXXXX..XXXXXXX 100644 | 213 | index XXXXXXX..XXXXXXX 100644 |
214 | --- a/drivers/net/phy/realtek/realtek_main.c | 214 | --- a/drivers/net/phy/realtek/realtek_main.c |
215 | +++ b/drivers/net/phy/realtek/realtek_main.c | 215 | +++ b/drivers/net/phy/realtek/realtek_main.c |
216 | @@ -XXX,XX +XXX,XX @@ static bool rtlgen_supports_mmd(struct phy_device *phydev) | 216 | @@ -XXX,XX +XXX,XX @@ static bool rtlgen_supports_mmd(struct phy_device *phydev) |
217 | return val > 0; | 217 | return val > 0; |
218 | } | 218 | } |
219 | 219 | ||
220 | -static int rtlgen_match_phy_device(struct phy_device *phydev) | 220 | -static int rtlgen_match_phy_device(struct phy_device *phydev) |
221 | +static int rtlgen_match_phy_device(struct phy_device *phydev, | 221 | +static int rtlgen_match_phy_device(struct phy_device *phydev, |
222 | + const struct phy_driver *phydrv) | 222 | + const struct phy_driver *phydrv) |
223 | { | 223 | { |
224 | return phydev->phy_id == RTL_GENERIC_PHYID && | 224 | return phydev->phy_id == RTL_GENERIC_PHYID && |
225 | !rtlgen_supports_2_5gbps(phydev); | 225 | !rtlgen_supports_2_5gbps(phydev); |
226 | } | 226 | } |
227 | 227 | ||
228 | -static int rtl8226_match_phy_device(struct phy_device *phydev) | 228 | -static int rtl8226_match_phy_device(struct phy_device *phydev) |
229 | +static int rtl8226_match_phy_device(struct phy_device *phydev, | 229 | +static int rtl8226_match_phy_device(struct phy_device *phydev, |
230 | + const struct phy_driver *phydrv) | 230 | + const struct phy_driver *phydrv) |
231 | { | 231 | { |
232 | return phydev->phy_id == RTL_GENERIC_PHYID && | 232 | return phydev->phy_id == RTL_GENERIC_PHYID && |
233 | rtlgen_supports_2_5gbps(phydev) && | 233 | rtlgen_supports_2_5gbps(phydev) && |
234 | @@ -XXX,XX +XXX,XX @@ static int rtlgen_is_c45_match(struct phy_device *phydev, unsigned int id, | 234 | @@ -XXX,XX +XXX,XX @@ static int rtlgen_is_c45_match(struct phy_device *phydev, unsigned int id, |
235 | return !is_c45 && (id == phydev->phy_id); | 235 | return !is_c45 && (id == phydev->phy_id); |
236 | } | 236 | } |
237 | 237 | ||
238 | -static int rtl8221b_match_phy_device(struct phy_device *phydev) | 238 | -static int rtl8221b_match_phy_device(struct phy_device *phydev) |
239 | +static int rtl8221b_match_phy_device(struct phy_device *phydev, | 239 | +static int rtl8221b_match_phy_device(struct phy_device *phydev, |
240 | + const struct phy_driver *phydrv) | 240 | + const struct phy_driver *phydrv) |
241 | { | 241 | { |
242 | return phydev->phy_id == RTL_8221B && rtlgen_supports_mmd(phydev); | 242 | return phydev->phy_id == RTL_8221B && rtlgen_supports_mmd(phydev); |
243 | } | 243 | } |
244 | 244 | ||
245 | -static int rtl8221b_vb_cg_c22_match_phy_device(struct phy_device *phydev) | 245 | -static int rtl8221b_vb_cg_c22_match_phy_device(struct phy_device *phydev) |
246 | +static int rtl8221b_vb_cg_c22_match_phy_device(struct phy_device *phydev, | 246 | +static int rtl8221b_vb_cg_c22_match_phy_device(struct phy_device *phydev, |
247 | + const struct phy_driver *phydrv) | 247 | + const struct phy_driver *phydrv) |
248 | { | 248 | { |
249 | return rtlgen_is_c45_match(phydev, RTL_8221B_VB_CG, false); | 249 | return rtlgen_is_c45_match(phydev, RTL_8221B_VB_CG, false); |
250 | } | 250 | } |
251 | 251 | ||
252 | -static int rtl8221b_vb_cg_c45_match_phy_device(struct phy_device *phydev) | 252 | -static int rtl8221b_vb_cg_c45_match_phy_device(struct phy_device *phydev) |
253 | +static int rtl8221b_vb_cg_c45_match_phy_device(struct phy_device *phydev, | 253 | +static int rtl8221b_vb_cg_c45_match_phy_device(struct phy_device *phydev, |
254 | + const struct phy_driver *phydrv) | 254 | + const struct phy_driver *phydrv) |
255 | { | 255 | { |
256 | return rtlgen_is_c45_match(phydev, RTL_8221B_VB_CG, true); | 256 | return rtlgen_is_c45_match(phydev, RTL_8221B_VB_CG, true); |
257 | } | 257 | } |
258 | 258 | ||
259 | -static int rtl8221b_vn_cg_c22_match_phy_device(struct phy_device *phydev) | 259 | -static int rtl8221b_vn_cg_c22_match_phy_device(struct phy_device *phydev) |
260 | +static int rtl8221b_vn_cg_c22_match_phy_device(struct phy_device *phydev, | 260 | +static int rtl8221b_vn_cg_c22_match_phy_device(struct phy_device *phydev, |
261 | + const struct phy_driver *phydrv) | 261 | + const struct phy_driver *phydrv) |
262 | { | 262 | { |
263 | return rtlgen_is_c45_match(phydev, RTL_8221B_VN_CG, false); | 263 | return rtlgen_is_c45_match(phydev, RTL_8221B_VN_CG, false); |
264 | } | 264 | } |
265 | 265 | ||
266 | -static int rtl8221b_vn_cg_c45_match_phy_device(struct phy_device *phydev) | 266 | -static int rtl8221b_vn_cg_c45_match_phy_device(struct phy_device *phydev) |
267 | +static int rtl8221b_vn_cg_c45_match_phy_device(struct phy_device *phydev, | 267 | +static int rtl8221b_vn_cg_c45_match_phy_device(struct phy_device *phydev, |
268 | + const struct phy_driver *phydrv) | 268 | + const struct phy_driver *phydrv) |
269 | { | 269 | { |
270 | return rtlgen_is_c45_match(phydev, RTL_8221B_VN_CG, true); | 270 | return rtlgen_is_c45_match(phydev, RTL_8221B_VN_CG, true); |
271 | } | 271 | } |
272 | 272 | ||
273 | -static int rtl_internal_nbaset_match_phy_device(struct phy_device *phydev) | 273 | -static int rtl_internal_nbaset_match_phy_device(struct phy_device *phydev) |
274 | +static int rtl_internal_nbaset_match_phy_device(struct phy_device *phydev, | 274 | +static int rtl_internal_nbaset_match_phy_device(struct phy_device *phydev, |
275 | + const struct phy_driver *phydrv) | 275 | + const struct phy_driver *phydrv) |
276 | { | 276 | { |
277 | if (phydev->is_c45) | 277 | if (phydev->is_c45) |
278 | return false; | 278 | return false; |
279 | @@ -XXX,XX +XXX,XX @@ static int rtl_internal_nbaset_match_phy_device(struct phy_device *phydev) | 279 | @@ -XXX,XX +XXX,XX @@ static int rtl_internal_nbaset_match_phy_device(struct phy_device *phydev) |
280 | return rtlgen_supports_2_5gbps(phydev) && !rtlgen_supports_mmd(phydev); | 280 | return rtlgen_supports_2_5gbps(phydev) && !rtlgen_supports_mmd(phydev); |
281 | } | 281 | } |
282 | 282 | ||
283 | -static int rtl8251b_c45_match_phy_device(struct phy_device *phydev) | 283 | -static int rtl8251b_c45_match_phy_device(struct phy_device *phydev) |
284 | +static int rtl8251b_c45_match_phy_device(struct phy_device *phydev, | 284 | +static int rtl8251b_c45_match_phy_device(struct phy_device *phydev, |
285 | + const struct phy_driver *phydrv) | 285 | + const struct phy_driver *phydrv) |
286 | { | 286 | { |
287 | return rtlgen_is_c45_match(phydev, RTL_8251B, true); | 287 | return rtlgen_is_c45_match(phydev, RTL_8251B, true); |
288 | } | 288 | } |
289 | diff --git a/drivers/net/phy/teranetics.c b/drivers/net/phy/teranetics.c | 289 | diff --git a/drivers/net/phy/teranetics.c b/drivers/net/phy/teranetics.c |
290 | index XXXXXXX..XXXXXXX 100644 | 290 | index XXXXXXX..XXXXXXX 100644 |
291 | --- a/drivers/net/phy/teranetics.c | 291 | --- a/drivers/net/phy/teranetics.c |
292 | +++ b/drivers/net/phy/teranetics.c | 292 | +++ b/drivers/net/phy/teranetics.c |
293 | @@ -XXX,XX +XXX,XX @@ static int teranetics_read_status(struct phy_device *phydev) | 293 | @@ -XXX,XX +XXX,XX @@ static int teranetics_read_status(struct phy_device *phydev) |
294 | return 0; | 294 | return 0; |
295 | } | 295 | } |
296 | 296 | ||
297 | -static int teranetics_match_phy_device(struct phy_device *phydev) | 297 | -static int teranetics_match_phy_device(struct phy_device *phydev) |
298 | +static int teranetics_match_phy_device(struct phy_device *phydev, | 298 | +static int teranetics_match_phy_device(struct phy_device *phydev, |
299 | + const struct phy_driver *phydrv) | 299 | + const struct phy_driver *phydrv) |
300 | { | 300 | { |
301 | return phydev->c45_ids.device_ids[3] == PHY_ID_TN2020; | 301 | return phydev->c45_ids.device_ids[3] == PHY_ID_TN2020; |
302 | } | 302 | } |
303 | diff --git a/include/linux/phy.h b/include/linux/phy.h | 303 | diff --git a/include/linux/phy.h b/include/linux/phy.h |
304 | index XXXXXXX..XXXXXXX 100644 | 304 | index XXXXXXX..XXXXXXX 100644 |
305 | --- a/include/linux/phy.h | 305 | --- a/include/linux/phy.h |
306 | +++ b/include/linux/phy.h | 306 | +++ b/include/linux/phy.h |
307 | @@ -XXX,XX +XXX,XX @@ struct phy_driver { | 307 | @@ -XXX,XX +XXX,XX @@ struct phy_driver { |
308 | * driver for the given phydev. If NULL, matching is based on | 308 | * driver for the given phydev. If NULL, matching is based on |
309 | * phy_id and phy_id_mask. | 309 | * phy_id and phy_id_mask. |
310 | */ | 310 | */ |
311 | - int (*match_phy_device)(struct phy_device *phydev); | 311 | - int (*match_phy_device)(struct phy_device *phydev); |
312 | + int (*match_phy_device)(struct phy_device *phydev, | 312 | + int (*match_phy_device)(struct phy_device *phydev, |
313 | + const struct phy_driver *phydrv); | 313 | + const struct phy_driver *phydrv); |
314 | 314 | ||
315 | /** | 315 | /** |
316 | * @set_wol: Some devices (e.g. qnap TS-119P II) require PHY | 316 | * @set_wol: Some devices (e.g. qnap TS-119P II) require PHY |
317 | -- | 317 | -- |
318 | 2.48.1 | 318 | 2.48.1 | diff view generated by jsdifflib |
1 | Simplify .match_phy_device OP by using a generic function and using the | 1 | Simplify .match_phy_device OP by using a generic function and using the |
---|---|---|---|
2 | new phy_id PHY driver info instead of hardcoding the matching PHY ID. | 2 | new phy_id PHY driver info instead of hardcoding the matching PHY ID. |
3 | 3 | ||
4 | Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk> | 4 | Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk> |
5 | Signed-off-by: Christian Marangi <ansuelsmth@gmail.com> | 5 | Signed-off-by: Christian Marangi <ansuelsmth@gmail.com> |
6 | --- | 6 | --- |
7 | drivers/net/phy/bcm87xx.c | 14 ++++---------- | 7 | drivers/net/phy/bcm87xx.c | 14 ++++---------- |
8 | 1 file changed, 4 insertions(+), 10 deletions(-) | 8 | 1 file changed, 4 insertions(+), 10 deletions(-) |
9 | 9 | ||
10 | diff --git a/drivers/net/phy/bcm87xx.c b/drivers/net/phy/bcm87xx.c | 10 | diff --git a/drivers/net/phy/bcm87xx.c b/drivers/net/phy/bcm87xx.c |
11 | index XXXXXXX..XXXXXXX 100644 | 11 | index XXXXXXX..XXXXXXX 100644 |
12 | --- a/drivers/net/phy/bcm87xx.c | 12 | --- a/drivers/net/phy/bcm87xx.c |
13 | +++ b/drivers/net/phy/bcm87xx.c | 13 | +++ b/drivers/net/phy/bcm87xx.c |
14 | @@ -XXX,XX +XXX,XX @@ static irqreturn_t bcm87xx_handle_interrupt(struct phy_device *phydev) | 14 | @@ -XXX,XX +XXX,XX @@ static irqreturn_t bcm87xx_handle_interrupt(struct phy_device *phydev) |
15 | return IRQ_HANDLED; | 15 | return IRQ_HANDLED; |
16 | } | 16 | } |
17 | 17 | ||
18 | -static int bcm8706_match_phy_device(struct phy_device *phydev, | 18 | -static int bcm8706_match_phy_device(struct phy_device *phydev, |
19 | +static int bcm87xx_match_phy_device(struct phy_device *phydev, | 19 | +static int bcm87xx_match_phy_device(struct phy_device *phydev, |
20 | const struct phy_driver *phydrv) | 20 | const struct phy_driver *phydrv) |
21 | { | 21 | { |
22 | - return phydev->c45_ids.device_ids[4] == PHY_ID_BCM8706; | 22 | - return phydev->c45_ids.device_ids[4] == PHY_ID_BCM8706; |
23 | -} | 23 | -} |
24 | - | 24 | - |
25 | -static int bcm8727_match_phy_device(struct phy_device *phydev, | 25 | -static int bcm8727_match_phy_device(struct phy_device *phydev, |
26 | - const struct phy_driver *phydrv) | 26 | - const struct phy_driver *phydrv) |
27 | -{ | 27 | -{ |
28 | - return phydev->c45_ids.device_ids[4] == PHY_ID_BCM8727; | 28 | - return phydev->c45_ids.device_ids[4] == PHY_ID_BCM8727; |
29 | + return phydev->c45_ids.device_ids[4] == phydrv->phy_id; | 29 | + return phydev->c45_ids.device_ids[4] == phydrv->phy_id; |
30 | } | 30 | } |
31 | 31 | ||
32 | static struct phy_driver bcm87xx_driver[] = { | 32 | static struct phy_driver bcm87xx_driver[] = { |
33 | @@ -XXX,XX +XXX,XX @@ static struct phy_driver bcm87xx_driver[] = { | 33 | @@ -XXX,XX +XXX,XX @@ static struct phy_driver bcm87xx_driver[] = { |
34 | .read_status = bcm87xx_read_status, | 34 | .read_status = bcm87xx_read_status, |
35 | .config_intr = bcm87xx_config_intr, | 35 | .config_intr = bcm87xx_config_intr, |
36 | .handle_interrupt = bcm87xx_handle_interrupt, | 36 | .handle_interrupt = bcm87xx_handle_interrupt, |
37 | - .match_phy_device = bcm8706_match_phy_device, | 37 | - .match_phy_device = bcm8706_match_phy_device, |
38 | + .match_phy_device = bcm87xx_match_phy_device, | 38 | + .match_phy_device = bcm87xx_match_phy_device, |
39 | }, { | 39 | }, { |
40 | .phy_id = PHY_ID_BCM8727, | 40 | .phy_id = PHY_ID_BCM8727, |
41 | .phy_id_mask = 0xffffffff, | 41 | .phy_id_mask = 0xffffffff, |
42 | @@ -XXX,XX +XXX,XX @@ static struct phy_driver bcm87xx_driver[] = { | 42 | @@ -XXX,XX +XXX,XX @@ static struct phy_driver bcm87xx_driver[] = { |
43 | .read_status = bcm87xx_read_status, | 43 | .read_status = bcm87xx_read_status, |
44 | .config_intr = bcm87xx_config_intr, | 44 | .config_intr = bcm87xx_config_intr, |
45 | .handle_interrupt = bcm87xx_handle_interrupt, | 45 | .handle_interrupt = bcm87xx_handle_interrupt, |
46 | - .match_phy_device = bcm8727_match_phy_device, | 46 | - .match_phy_device = bcm8727_match_phy_device, |
47 | + .match_phy_device = bcm87xx_match_phy_device, | 47 | + .match_phy_device = bcm87xx_match_phy_device, |
48 | } }; | 48 | } }; |
49 | 49 | ||
50 | module_phy_driver(bcm87xx_driver); | 50 | module_phy_driver(bcm87xx_driver); |
51 | -- | 51 | -- |
52 | 2.48.1 | 52 | 2.48.1 | diff view generated by jsdifflib |
... | ... | ||
---|---|---|---|
3 | with new variant for macsec and no_macsec PHYs. | 3 | with new variant for macsec and no_macsec PHYs. |
4 | 4 | ||
5 | Also make use of PHY_ID_MATCH_MODEL macro and drop PHY_ID_MASK define to | 5 | Also make use of PHY_ID_MATCH_MODEL macro and drop PHY_ID_MASK define to |
6 | introduce phy_id and phy_id_mask again in phy_driver struct. | 6 | introduce phy_id and phy_id_mask again in phy_driver struct. |
7 | 7 | ||
8 | Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk> | ||
8 | Signed-off-by: Christian Marangi <ansuelsmth@gmail.com> | 9 | Signed-off-by: Christian Marangi <ansuelsmth@gmail.com> |
9 | --- | 10 | --- |
10 | drivers/net/phy/nxp-c45-tja11xx.c | 45 ++++++++++++++----------------- | 11 | drivers/net/phy/nxp-c45-tja11xx.c | 45 ++++++++++++++----------------- |
11 | 1 file changed, 20 insertions(+), 25 deletions(-) | 12 | 1 file changed, 20 insertions(+), 25 deletions(-) |
12 | 13 | ||
... | ... | diff view generated by jsdifflib |
... | ... | ||
---|---|---|---|
7 | 7 | ||
8 | This is useful for custom .match_phy_device function that wants to use | 8 | This is useful for custom .match_phy_device function that wants to use |
9 | the generic logic under some condition. (example a PHY is already setup | 9 | the generic logic under some condition. (example a PHY is already setup |
10 | and provide the correct PHY ID) | 10 | and provide the correct PHY ID) |
11 | 11 | ||
12 | Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk> | ||
12 | Signed-off-by: Christian Marangi <ansuelsmth@gmail.com> | 13 | Signed-off-by: Christian Marangi <ansuelsmth@gmail.com> |
13 | --- | 14 | --- |
14 | drivers/net/phy/phy_device.c | 52 +++++++++++++++++++++++++----------- | 15 | drivers/net/phy/phy_device.c | 52 +++++++++++++++++++++++++----------- |
15 | include/linux/phy.h | 3 +++ | 16 | include/linux/phy.h | 3 +++ |
16 | 2 files changed, 40 insertions(+), 15 deletions(-) | 17 | 2 files changed, 40 insertions(+), 15 deletions(-) |
... | ... | diff view generated by jsdifflib |
1 | Add support for Aeonsemi AS21xxx 10G C45 PHYs. These PHYs integrate | 1 | Add support for Aeonsemi AS21xxx 10G C45 PHYs. These PHYs integrate |
---|---|---|---|
2 | an IPC to setup some configuration and require special handling to | 2 | an IPC to setup some configuration and require special handling to |
3 | sync with the parity bit. The parity bit is a way the IPC use to | 3 | sync with the parity bit. The parity bit is a way the IPC use to |
4 | follow correct order of command sent. | 4 | follow correct order of command sent. |
5 | 5 | ||
6 | Supported PHYs AS21011JB1, AS21011PB1, AS21010JB1, AS21010PB1, | 6 | Supported PHYs AS21011JB1, AS21011PB1, AS21010JB1, AS21010PB1, |
7 | AS21511JB1, AS21511PB1, AS21510JB1, AS21510PB1, AS21210JB1, | 7 | AS21511JB1, AS21511PB1, AS21510JB1, AS21510PB1, AS21210JB1, |
8 | AS21210PB1 that all register with the PHY ID 0x7500 0x7510 | 8 | AS21210PB1 that all register with the PHY ID 0x7500 0x7510 |
9 | before the firmware is loaded. | 9 | before the firmware is loaded. |
10 | 10 | ||
11 | They all support up to 5 LEDs with various HW mode supported. | 11 | They all support up to 5 LEDs with various HW mode supported. |
12 | 12 | ||
13 | While implementing it was found some strange coincidence with using the | 13 | While implementing it was found some strange coincidence with using the |
14 | same logic for implementing C22 in MMD regs in Broadcom PHYs. | 14 | same logic for implementing C22 in MMD regs in Broadcom PHYs. |
15 | 15 | ||
16 | For reference here the AS21xxx PHY name logic: | 16 | For reference here the AS21xxx PHY name logic: |
17 | 17 | ||
18 | AS21x1xxB1 | 18 | AS21x1xxB1 |
19 | ^ ^^ | 19 | ^ ^^ |
20 | | |J: Supports SyncE/PTP | 20 | | |J: Supports SyncE/PTP |
21 | | |P: No SyncE/PTP support | 21 | | |P: No SyncE/PTP support |
22 | | 1: Supports 2nd Serdes | 22 | | 1: Supports 2nd Serdes |
23 | | 2: Not 2nd Serdes support | 23 | | 2: Not 2nd Serdes support |
24 | 0: 10G, 5G, 2.5G | 24 | 0: 10G, 5G, 2.5G |
25 | 5: 5G, 2.5G | 25 | 5: 5G, 2.5G |
26 | 2: 2.5G | 26 | 2: 2.5G |
27 | 27 | ||
28 | Signed-off-by: Christian Marangi <ansuelsmth@gmail.com> | 28 | Signed-off-by: Christian Marangi <ansuelsmth@gmail.com> |
29 | --- | 29 | --- |
30 | MAINTAINERS | 6 + | 30 | MAINTAINERS | 6 + |
31 | drivers/net/phy/Kconfig | 12 + | 31 | drivers/net/phy/Kconfig | 12 + |
32 | drivers/net/phy/Makefile | 1 + | 32 | drivers/net/phy/Makefile | 1 + |
33 | drivers/net/phy/as21xxx.c | 1067 +++++++++++++++++++++++++++++++++++++ | 33 | drivers/net/phy/as21xxx.c | 1067 +++++++++++++++++++++++++++++++++++++ |
34 | 4 files changed, 1086 insertions(+) | 34 | 4 files changed, 1086 insertions(+) |
35 | create mode 100644 drivers/net/phy/as21xxx.c | 35 | create mode 100644 drivers/net/phy/as21xxx.c |
36 | 36 | ||
37 | diff --git a/MAINTAINERS b/MAINTAINERS | 37 | diff --git a/MAINTAINERS b/MAINTAINERS |
38 | index XXXXXXX..XXXXXXX 100644 | 38 | index XXXXXXX..XXXXXXX 100644 |
39 | --- a/MAINTAINERS | 39 | --- a/MAINTAINERS |
40 | +++ b/MAINTAINERS | 40 | +++ b/MAINTAINERS |
41 | @@ -XXX,XX +XXX,XX @@ F: drivers/iio/accel/adxl380.h | 41 | @@ -XXX,XX +XXX,XX @@ F: drivers/iio/accel/adxl380.h |
42 | F: drivers/iio/accel/adxl380_i2c.c | 42 | F: drivers/iio/accel/adxl380_i2c.c |
43 | F: drivers/iio/accel/adxl380_spi.c | 43 | F: drivers/iio/accel/adxl380_spi.c |
44 | 44 | ||
45 | +AEONSEMI PHY DRIVER | 45 | +AEONSEMI PHY DRIVER |
46 | +M: Christian Marangi <ansuelsmth@gmail.com> | 46 | +M: Christian Marangi <ansuelsmth@gmail.com> |
47 | +L: netdev@vger.kernel.org | 47 | +L: netdev@vger.kernel.org |
48 | +S: Maintained | 48 | +S: Maintained |
49 | +F: drivers/net/phy/as21xxx.c | 49 | +F: drivers/net/phy/as21xxx.c |
50 | + | 50 | + |
51 | AF8133J THREE-AXIS MAGNETOMETER DRIVER | 51 | AF8133J THREE-AXIS MAGNETOMETER DRIVER |
52 | M: Ondřej Jirman <megi@xff.cz> | 52 | M: Ondřej Jirman <megi@xff.cz> |
53 | S: Maintained | 53 | S: Maintained |
54 | diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig | 54 | diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig |
55 | index XXXXXXX..XXXXXXX 100644 | 55 | index XXXXXXX..XXXXXXX 100644 |
56 | --- a/drivers/net/phy/Kconfig | 56 | --- a/drivers/net/phy/Kconfig |
57 | +++ b/drivers/net/phy/Kconfig | 57 | +++ b/drivers/net/phy/Kconfig |
58 | @@ -XXX,XX +XXX,XX @@ config AMCC_QT2025_PHY | 58 | @@ -XXX,XX +XXX,XX @@ config AMCC_QT2025_PHY |
59 | help | 59 | help |
60 | Adds support for the Applied Micro Circuits Corporation QT2025 PHY. | 60 | Adds support for the Applied Micro Circuits Corporation QT2025 PHY. |
61 | 61 | ||
62 | +config AS21XXX_PHY | 62 | +config AS21XXX_PHY |
63 | + tristate "Aeonsemi AS21xxx PHYs" | 63 | + tristate "Aeonsemi AS21xxx PHYs" |
64 | + help | 64 | + help |
65 | + Currently supports the Aeonsemi AS21xxx PHY. | 65 | + Currently supports the Aeonsemi AS21xxx PHY. |
66 | + | 66 | + |
67 | + These are C45 PHYs 10G that require all a generic firmware. | 67 | + These are C45 PHYs 10G that require all a generic firmware. |
68 | + | 68 | + |
69 | + Supported PHYs AS21011JB1, AS21011PB1, AS21010JB1, AS21010PB1, | 69 | + Supported PHYs AS21011JB1, AS21011PB1, AS21010JB1, AS21010PB1, |
70 | + AS21511JB1, AS21511PB1, AS21510JB1, AS21510PB1, AS21210JB1, | 70 | + AS21511JB1, AS21511PB1, AS21510JB1, AS21510PB1, AS21210JB1, |
71 | + AS21210PB1 that all register with the PHY ID 0x7500 0x7500 | 71 | + AS21210PB1 that all register with the PHY ID 0x7500 0x7500 |
72 | + before the firmware is loaded. | 72 | + before the firmware is loaded. |
73 | + | 73 | + |
74 | source "drivers/net/phy/aquantia/Kconfig" | 74 | source "drivers/net/phy/aquantia/Kconfig" |
75 | 75 | ||
76 | config AX88796B_PHY | 76 | config AX88796B_PHY |
77 | diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile | 77 | diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile |
78 | index XXXXXXX..XXXXXXX 100644 | 78 | index XXXXXXX..XXXXXXX 100644 |
79 | --- a/drivers/net/phy/Makefile | 79 | --- a/drivers/net/phy/Makefile |
80 | +++ b/drivers/net/phy/Makefile | 80 | +++ b/drivers/net/phy/Makefile |
81 | @@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_AIR_EN8811H_PHY) += air_en8811h.o | 81 | @@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_AIR_EN8811H_PHY) += air_en8811h.o |
82 | obj-$(CONFIG_AMD_PHY) += amd.o | 82 | obj-$(CONFIG_AMD_PHY) += amd.o |
83 | obj-$(CONFIG_AMCC_QT2025_PHY) += qt2025.o | 83 | obj-$(CONFIG_AMCC_QT2025_PHY) += qt2025.o |
84 | obj-$(CONFIG_AQUANTIA_PHY) += aquantia/ | 84 | obj-$(CONFIG_AQUANTIA_PHY) += aquantia/ |
85 | +obj-$(CONFIG_AS21XXX_PHY) += as21xxx.o | 85 | +obj-$(CONFIG_AS21XXX_PHY) += as21xxx.o |
86 | ifdef CONFIG_AX88796B_RUST_PHY | 86 | ifdef CONFIG_AX88796B_RUST_PHY |
87 | obj-$(CONFIG_AX88796B_PHY) += ax88796b_rust.o | 87 | obj-$(CONFIG_AX88796B_PHY) += ax88796b_rust.o |
88 | else | 88 | else |
89 | diff --git a/drivers/net/phy/as21xxx.c b/drivers/net/phy/as21xxx.c | 89 | diff --git a/drivers/net/phy/as21xxx.c b/drivers/net/phy/as21xxx.c |
90 | new file mode 100644 | 90 | new file mode 100644 |
91 | index XXXXXXX..XXXXXXX | 91 | index XXXXXXX..XXXXXXX |
92 | --- /dev/null | 92 | --- /dev/null |
93 | +++ b/drivers/net/phy/as21xxx.c | 93 | +++ b/drivers/net/phy/as21xxx.c |
94 | @@ -XXX,XX +XXX,XX @@ | 94 | @@ -XXX,XX +XXX,XX @@ |
95 | +// SPDX-License-Identifier: GPL-2.0 | 95 | +// SPDX-License-Identifier: GPL-2.0 |
96 | +/* | 96 | +/* |
97 | + * Aeonsemi AS21XXxX PHY Driver | 97 | + * Aeonsemi AS21XXxX PHY Driver |
98 | + * | 98 | + * |
99 | + * Author: Christian Marangi <ansuelsmth@gmail.com> | 99 | + * Author: Christian Marangi <ansuelsmth@gmail.com> |
100 | + */ | 100 | + */ |
101 | + | 101 | + |
102 | +#include <linux/bitfield.h> | 102 | +#include <linux/bitfield.h> |
103 | +#include <linux/firmware.h> | 103 | +#include <linux/firmware.h> |
104 | +#include <linux/module.h> | 104 | +#include <linux/module.h> |
105 | +#include <linux/of.h> | 105 | +#include <linux/of.h> |
106 | +#include <linux/phy.h> | 106 | +#include <linux/phy.h> |
107 | + | 107 | + |
108 | +#define VEND1_GLB_REG_CPU_RESET_ADDR_LO_BASEADDR 0x3 | 108 | +#define VEND1_GLB_REG_CPU_RESET_ADDR_LO_BASEADDR 0x3 |
109 | +#define VEND1_GLB_REG_CPU_RESET_ADDR_HI_BASEADDR 0x4 | 109 | +#define VEND1_GLB_REG_CPU_RESET_ADDR_HI_BASEADDR 0x4 |
110 | + | 110 | + |
111 | +#define VEND1_GLB_REG_CPU_CTRL 0xe | 111 | +#define VEND1_GLB_REG_CPU_CTRL 0xe |
112 | +#define VEND1_GLB_CPU_CTRL_MASK GENMASK(4, 0) | 112 | +#define VEND1_GLB_CPU_CTRL_MASK GENMASK(4, 0) |
113 | +#define VEND1_GLB_CPU_CTRL_LED_POLARITY_MASK GENMASK(12, 8) | 113 | +#define VEND1_GLB_CPU_CTRL_LED_POLARITY_MASK GENMASK(12, 8) |
114 | +#define VEND1_GLB_CPU_CTRL_LED_POLARITY(_n) FIELD_PREP(VEND1_GLB_CPU_CTRL_LED_POLARITY_MASK, \ | 114 | +#define VEND1_GLB_CPU_CTRL_LED_POLARITY(_n) FIELD_PREP(VEND1_GLB_CPU_CTRL_LED_POLARITY_MASK, \ |
115 | + BIT(_n)) | 115 | + BIT(_n)) |
116 | + | 116 | + |
117 | +#define VEND1_FW_START_ADDR 0x100 | 117 | +#define VEND1_FW_START_ADDR 0x100 |
118 | + | 118 | + |
119 | +#define VEND1_GLB_REG_MDIO_INDIRECT_ADDRCMD 0x101 | 119 | +#define VEND1_GLB_REG_MDIO_INDIRECT_ADDRCMD 0x101 |
120 | +#define VEND1_GLB_REG_MDIO_INDIRECT_LOAD 0x102 | 120 | +#define VEND1_GLB_REG_MDIO_INDIRECT_LOAD 0x102 |
121 | + | 121 | + |
122 | +#define VEND1_GLB_REG_MDIO_INDIRECT_STATUS 0x103 | 122 | +#define VEND1_GLB_REG_MDIO_INDIRECT_STATUS 0x103 |
123 | + | 123 | + |
124 | +#define VEND1_PTP_CLK 0x142 | 124 | +#define VEND1_PTP_CLK 0x142 |
125 | +#define VEND1_PTP_CLK_EN BIT(6) | 125 | +#define VEND1_PTP_CLK_EN BIT(6) |
126 | + | 126 | + |
127 | +/* 5 LED at step of 0x20 | 127 | +/* 5 LED at step of 0x20 |
128 | + * FE: Fast-Ethernet (10/100) | 128 | + * FE: Fast-Ethernet (10/100) |
129 | + * GE: Gigabit-Ethernet (1000) | 129 | + * GE: Gigabit-Ethernet (1000) |
130 | + * NG: New-Generation (2500/5000/10000) | 130 | + * NG: New-Generation (2500/5000/10000) |
131 | + */ | 131 | + */ |
132 | +#define VEND1_LED_REG(_n) (0x1800 + ((_n) * 0x10)) | 132 | +#define VEND1_LED_REG(_n) (0x1800 + ((_n) * 0x10)) |
133 | +#define VEND1_LED_REG_A_EVENT GENMASK(15, 11) | 133 | +#define VEND1_LED_REG_A_EVENT GENMASK(15, 11) |
134 | +#define VEND1_LED_CONF 0x1881 | 134 | +#define VEND1_LED_CONF 0x1881 |
135 | +#define VEND1_LED_CONFG_BLINK GENMASK(7, 0) | 135 | +#define VEND1_LED_CONFG_BLINK GENMASK(7, 0) |
136 | + | 136 | + |
137 | +#define VEND1_SPEED_STATUS 0x4002 | 137 | +#define VEND1_SPEED_STATUS 0x4002 |
138 | +#define VEND1_SPEED_MASK GENMASK(7, 0) | 138 | +#define VEND1_SPEED_MASK GENMASK(7, 0) |
139 | +#define VEND1_SPEED_10000 FIELD_PREP_CONST(VEND1_SPEED_MASK, 0x3) | 139 | +#define VEND1_SPEED_10000 FIELD_PREP_CONST(VEND1_SPEED_MASK, 0x3) |
140 | +#define VEND1_SPEED_5000 FIELD_PREP_CONST(VEND1_SPEED_MASK, 0x5) | 140 | +#define VEND1_SPEED_5000 FIELD_PREP_CONST(VEND1_SPEED_MASK, 0x5) |
141 | +#define VEND1_SPEED_2500 FIELD_PREP_CONST(VEND1_SPEED_MASK, 0x9) | 141 | +#define VEND1_SPEED_2500 FIELD_PREP_CONST(VEND1_SPEED_MASK, 0x9) |
142 | +#define VEND1_SPEED_1000 FIELD_PREP_CONST(VEND1_SPEED_MASK, 0x10) | 142 | +#define VEND1_SPEED_1000 FIELD_PREP_CONST(VEND1_SPEED_MASK, 0x10) |
143 | +#define VEND1_SPEED_100 FIELD_PREP_CONST(VEND1_SPEED_MASK, 0x20) | 143 | +#define VEND1_SPEED_100 FIELD_PREP_CONST(VEND1_SPEED_MASK, 0x20) |
144 | +#define VEND1_SPEED_10 FIELD_PREP_CONST(VEND1_SPEED_MASK, 0x0) | 144 | +#define VEND1_SPEED_10 FIELD_PREP_CONST(VEND1_SPEED_MASK, 0x0) |
145 | + | 145 | + |
146 | +#define VEND1_IPC_CMD 0x5801 | 146 | +#define VEND1_IPC_CMD 0x5801 |
147 | +#define AEON_IPC_CMD_PARITY BIT(15) | 147 | +#define AEON_IPC_CMD_PARITY BIT(15) |
148 | +#define AEON_IPC_CMD_SIZE GENMASK(10, 6) | 148 | +#define AEON_IPC_CMD_SIZE GENMASK(10, 6) |
149 | +#define AEON_IPC_CMD_OPCODE GENMASK(5, 0) | 149 | +#define AEON_IPC_CMD_OPCODE GENMASK(5, 0) |
150 | + | 150 | + |
151 | +#define IPC_CMD_NOOP 0x0 /* Do nothing */ | 151 | +#define IPC_CMD_NOOP 0x0 /* Do nothing */ |
152 | +#define IPC_CMD_INFO 0x1 /* Get Firmware Version */ | 152 | +#define IPC_CMD_INFO 0x1 /* Get Firmware Version */ |
153 | +#define IPC_CMD_SYS_CPU 0x2 /* SYS_CPU */ | 153 | +#define IPC_CMD_SYS_CPU 0x2 /* SYS_CPU */ |
154 | +#define IPC_CMD_BULK_DATA 0xa /* Pass bulk data in ipc registers. */ | 154 | +#define IPC_CMD_BULK_DATA 0xa /* Pass bulk data in ipc registers. */ |
155 | +#define IPC_CMD_BULK_WRITE 0xc /* Write bulk data to memory */ | 155 | +#define IPC_CMD_BULK_WRITE 0xc /* Write bulk data to memory */ |
156 | +#define IPC_CMD_CFG_PARAM 0x1a /* Write config parameters to memory */ | 156 | +#define IPC_CMD_CFG_PARAM 0x1a /* Write config parameters to memory */ |
157 | +#define IPC_CMD_NG_TESTMODE 0x1b /* Set NG test mode and tone */ | 157 | +#define IPC_CMD_NG_TESTMODE 0x1b /* Set NG test mode and tone */ |
158 | +#define IPC_CMD_TEMP_MON 0x15 /* Temperature monitoring function */ | 158 | +#define IPC_CMD_TEMP_MON 0x15 /* Temperature monitoring function */ |
159 | +#define IPC_CMD_SET_LED 0x23 /* Set led */ | 159 | +#define IPC_CMD_SET_LED 0x23 /* Set led */ |
160 | + | 160 | + |
161 | +#define VEND1_IPC_STS 0x5802 | 161 | +#define VEND1_IPC_STS 0x5802 |
162 | +#define AEON_IPC_STS_PARITY BIT(15) | 162 | +#define AEON_IPC_STS_PARITY BIT(15) |
163 | +#define AEON_IPC_STS_SIZE GENMASK(14, 10) | 163 | +#define AEON_IPC_STS_SIZE GENMASK(14, 10) |
164 | +#define AEON_IPC_STS_OPCODE GENMASK(9, 4) | 164 | +#define AEON_IPC_STS_OPCODE GENMASK(9, 4) |
165 | +#define AEON_IPC_STS_STATUS GENMASK(3, 0) | 165 | +#define AEON_IPC_STS_STATUS GENMASK(3, 0) |
166 | +#define AEON_IPC_STS_STATUS_RCVD FIELD_PREP_CONST(AEON_IPC_STS_STATUS, 0x1) | 166 | +#define AEON_IPC_STS_STATUS_RCVD FIELD_PREP_CONST(AEON_IPC_STS_STATUS, 0x1) |
167 | +#define AEON_IPC_STS_STATUS_PROCESS FIELD_PREP_CONST(AEON_IPC_STS_STATUS, 0x2) | 167 | +#define AEON_IPC_STS_STATUS_PROCESS FIELD_PREP_CONST(AEON_IPC_STS_STATUS, 0x2) |
168 | +#define AEON_IPC_STS_STATUS_SUCCESS FIELD_PREP_CONST(AEON_IPC_STS_STATUS, 0x4) | 168 | +#define AEON_IPC_STS_STATUS_SUCCESS FIELD_PREP_CONST(AEON_IPC_STS_STATUS, 0x4) |
169 | +#define AEON_IPC_STS_STATUS_ERROR FIELD_PREP_CONST(AEON_IPC_STS_STATUS, 0x8) | 169 | +#define AEON_IPC_STS_STATUS_ERROR FIELD_PREP_CONST(AEON_IPC_STS_STATUS, 0x8) |
170 | +#define AEON_IPC_STS_STATUS_BUSY FIELD_PREP_CONST(AEON_IPC_STS_STATUS, 0xe) | 170 | +#define AEON_IPC_STS_STATUS_BUSY FIELD_PREP_CONST(AEON_IPC_STS_STATUS, 0xe) |
171 | +#define AEON_IPC_STS_STATUS_READY FIELD_PREP_CONST(AEON_IPC_STS_STATUS, 0xf) | 171 | +#define AEON_IPC_STS_STATUS_READY FIELD_PREP_CONST(AEON_IPC_STS_STATUS, 0xf) |
172 | + | 172 | + |
173 | +#define VEND1_IPC_DATA0 0x5808 | 173 | +#define VEND1_IPC_DATA0 0x5808 |
174 | +#define VEND1_IPC_DATA1 0x5809 | 174 | +#define VEND1_IPC_DATA1 0x5809 |
175 | +#define VEND1_IPC_DATA2 0x580a | 175 | +#define VEND1_IPC_DATA2 0x580a |
176 | +#define VEND1_IPC_DATA3 0x580b | 176 | +#define VEND1_IPC_DATA3 0x580b |
177 | +#define VEND1_IPC_DATA4 0x580c | 177 | +#define VEND1_IPC_DATA4 0x580c |
178 | +#define VEND1_IPC_DATA5 0x580d | 178 | +#define VEND1_IPC_DATA5 0x580d |
179 | +#define VEND1_IPC_DATA6 0x580e | 179 | +#define VEND1_IPC_DATA6 0x580e |
180 | +#define VEND1_IPC_DATA7 0x580f | 180 | +#define VEND1_IPC_DATA7 0x580f |
181 | +#define VEND1_IPC_DATA(_n) (VEND1_IPC_DATA0 + (_n)) | 181 | +#define VEND1_IPC_DATA(_n) (VEND1_IPC_DATA0 + (_n)) |
182 | + | 182 | + |
183 | +/* Sub command of CMD_INFO */ | 183 | +/* Sub command of CMD_INFO */ |
184 | +#define IPC_INFO_VERSION 0x1 | 184 | +#define IPC_INFO_VERSION 0x1 |
185 | + | 185 | + |
186 | +/* Sub command of CMD_SYS_CPU */ | 186 | +/* Sub command of CMD_SYS_CPU */ |
187 | +#define IPC_SYS_CPU_REBOOT 0x3 | 187 | +#define IPC_SYS_CPU_REBOOT 0x3 |
188 | +#define IPC_SYS_CPU_IMAGE_OFST 0x4 | 188 | +#define IPC_SYS_CPU_IMAGE_OFST 0x4 |
189 | +#define IPC_SYS_CPU_IMAGE_CHECK 0x5 | 189 | +#define IPC_SYS_CPU_IMAGE_CHECK 0x5 |
190 | +#define IPC_SYS_CPU_PHY_ENABLE 0x6 | 190 | +#define IPC_SYS_CPU_PHY_ENABLE 0x6 |
191 | + | 191 | + |
192 | +/* Sub command of CMD_CFG_PARAM */ | 192 | +/* Sub command of CMD_CFG_PARAM */ |
193 | +#define IPC_CFG_PARAM_DIRECT 0x4 | 193 | +#define IPC_CFG_PARAM_DIRECT 0x4 |
194 | + | 194 | + |
195 | +/* CFG DIRECT sub command */ | 195 | +/* CFG DIRECT sub command */ |
196 | +#define IPC_CFG_PARAM_DIRECT_NG_PHYCTRL 0x1 | 196 | +#define IPC_CFG_PARAM_DIRECT_NG_PHYCTRL 0x1 |
197 | +#define IPC_CFG_PARAM_DIRECT_CU_AN 0x2 | 197 | +#define IPC_CFG_PARAM_DIRECT_CU_AN 0x2 |
198 | +#define IPC_CFG_PARAM_DIRECT_SDS_PCS 0x3 | 198 | +#define IPC_CFG_PARAM_DIRECT_SDS_PCS 0x3 |
199 | +#define IPC_CFG_PARAM_DIRECT_AUTO_EEE 0x4 | 199 | +#define IPC_CFG_PARAM_DIRECT_AUTO_EEE 0x4 |
200 | +#define IPC_CFG_PARAM_DIRECT_SDS_PMA 0x5 | 200 | +#define IPC_CFG_PARAM_DIRECT_SDS_PMA 0x5 |
201 | +#define IPC_CFG_PARAM_DIRECT_DPC_RA 0x6 | 201 | +#define IPC_CFG_PARAM_DIRECT_DPC_RA 0x6 |
202 | +#define IPC_CFG_PARAM_DIRECT_DPC_PKT_CHK 0x7 | 202 | +#define IPC_CFG_PARAM_DIRECT_DPC_PKT_CHK 0x7 |
203 | +#define IPC_CFG_PARAM_DIRECT_DPC_SDS_WAIT_ETH 0x8 | 203 | +#define IPC_CFG_PARAM_DIRECT_DPC_SDS_WAIT_ETH 0x8 |
204 | +#define IPC_CFG_PARAM_DIRECT_WDT 0x9 | 204 | +#define IPC_CFG_PARAM_DIRECT_WDT 0x9 |
205 | +#define IPC_CFG_PARAM_DIRECT_SDS_RESTART_AN 0x10 | 205 | +#define IPC_CFG_PARAM_DIRECT_SDS_RESTART_AN 0x10 |
206 | +#define IPC_CFG_PARAM_DIRECT_TEMP_MON 0x11 | 206 | +#define IPC_CFG_PARAM_DIRECT_TEMP_MON 0x11 |
207 | +#define IPC_CFG_PARAM_DIRECT_WOL 0x12 | 207 | +#define IPC_CFG_PARAM_DIRECT_WOL 0x12 |
208 | + | 208 | + |
209 | +/* Sub command of CMD_TEMP_MON */ | 209 | +/* Sub command of CMD_TEMP_MON */ |
210 | +#define IPC_CMD_TEMP_MON_GET 0x4 | 210 | +#define IPC_CMD_TEMP_MON_GET 0x4 |
211 | + | 211 | + |
212 | +#define AS21XXX_MDIO_AN_C22 0xffe0 | 212 | +#define AS21XXX_MDIO_AN_C22 0xffe0 |
213 | + | 213 | + |
214 | +#define PHY_ID_AS21XXX 0x75009410 | 214 | +#define PHY_ID_AS21XXX 0x75009410 |
215 | +/* AS21xxx ID Legend | 215 | +/* AS21xxx ID Legend |
216 | + * AS21x1xxB1 | 216 | + * AS21x1xxB1 |
217 | + * ^ ^^ | 217 | + * ^ ^^ |
218 | + * | |J: Supports SyncE/PTP | 218 | + * | |J: Supports SyncE/PTP |
219 | + * | |P: No SyncE/PTP support | 219 | + * | |P: No SyncE/PTP support |
220 | + * | 1: Supports 2nd Serdes | 220 | + * | 1: Supports 2nd Serdes |
221 | + * | 2: Not 2nd Serdes support | 221 | + * | 2: Not 2nd Serdes support |
222 | + * 0: 10G, 5G, 2.5G | 222 | + * 0: 10G, 5G, 2.5G |
223 | + * 5: 5G, 2.5G | 223 | + * 5: 5G, 2.5G |
224 | + * 2: 2.5G | 224 | + * 2: 2.5G |
225 | + */ | 225 | + */ |
226 | +#define PHY_ID_AS21011JB1 0x75009402 | 226 | +#define PHY_ID_AS21011JB1 0x75009402 |
227 | +#define PHY_ID_AS21011PB1 0x75009412 | 227 | +#define PHY_ID_AS21011PB1 0x75009412 |
228 | +#define PHY_ID_AS21010JB1 0x75009422 | 228 | +#define PHY_ID_AS21010JB1 0x75009422 |
229 | +#define PHY_ID_AS21010PB1 0x75009432 | 229 | +#define PHY_ID_AS21010PB1 0x75009432 |
230 | +#define PHY_ID_AS21511JB1 0x75009442 | 230 | +#define PHY_ID_AS21511JB1 0x75009442 |
231 | +#define PHY_ID_AS21511PB1 0x75009452 | 231 | +#define PHY_ID_AS21511PB1 0x75009452 |
232 | +#define PHY_ID_AS21510JB1 0x75009462 | 232 | +#define PHY_ID_AS21510JB1 0x75009462 |
233 | +#define PHY_ID_AS21510PB1 0x75009472 | 233 | +#define PHY_ID_AS21510PB1 0x75009472 |
234 | +#define PHY_ID_AS21210JB1 0x75009482 | 234 | +#define PHY_ID_AS21210JB1 0x75009482 |
235 | +#define PHY_ID_AS21210PB1 0x75009492 | 235 | +#define PHY_ID_AS21210PB1 0x75009492 |
236 | +#define PHY_VENDOR_AEONSEMI 0x75009400 | 236 | +#define PHY_VENDOR_AEONSEMI 0x75009400 |
237 | + | 237 | + |
238 | +#define AEON_MAX_LDES 5 | 238 | +#define AEON_MAX_LDES 5 |
239 | +#define AEON_IPC_DELAY 10000 | 239 | +#define AEON_IPC_DELAY 10000 |
240 | +#define AEON_IPC_TIMEOUT (AEON_IPC_DELAY * 100) | 240 | +#define AEON_IPC_TIMEOUT (AEON_IPC_DELAY * 100) |
241 | +#define AEON_IPC_DATA_MAX (8 * sizeof(u16)) | 241 | +#define AEON_IPC_DATA_MAX (8 * sizeof(u16)) |
242 | + | 242 | + |
243 | +#define AEON_BOOT_ADDR 0x1000 | 243 | +#define AEON_BOOT_ADDR 0x1000 |
244 | +#define AEON_CPU_BOOT_ADDR 0x2000 | 244 | +#define AEON_CPU_BOOT_ADDR 0x2000 |
245 | +#define AEON_CPU_CTRL_FW_LOAD (BIT(4) | BIT(2) | BIT(1) | BIT(0)) | 245 | +#define AEON_CPU_CTRL_FW_LOAD (BIT(4) | BIT(2) | BIT(1) | BIT(0)) |
246 | +#define AEON_CPU_CTRL_FW_START BIT(0) | 246 | +#define AEON_CPU_CTRL_FW_START BIT(0) |
247 | + | 247 | + |
248 | +enum as21xxx_led_event { | 248 | +enum as21xxx_led_event { |
249 | + VEND1_LED_REG_A_EVENT_ON_10 = 0x0, | 249 | + VEND1_LED_REG_A_EVENT_ON_10 = 0x0, |
250 | + VEND1_LED_REG_A_EVENT_ON_100, | 250 | + VEND1_LED_REG_A_EVENT_ON_100, |
251 | + VEND1_LED_REG_A_EVENT_ON_1000, | 251 | + VEND1_LED_REG_A_EVENT_ON_1000, |
252 | + VEND1_LED_REG_A_EVENT_ON_2500, | 252 | + VEND1_LED_REG_A_EVENT_ON_2500, |
253 | + VEND1_LED_REG_A_EVENT_ON_5000, | 253 | + VEND1_LED_REG_A_EVENT_ON_5000, |
254 | + VEND1_LED_REG_A_EVENT_ON_10000, | 254 | + VEND1_LED_REG_A_EVENT_ON_10000, |
255 | + VEND1_LED_REG_A_EVENT_ON_FE_GE, | 255 | + VEND1_LED_REG_A_EVENT_ON_FE_GE, |
256 | + VEND1_LED_REG_A_EVENT_ON_NG, | 256 | + VEND1_LED_REG_A_EVENT_ON_NG, |
257 | + VEND1_LED_REG_A_EVENT_ON_FULL_DUPLEX, | 257 | + VEND1_LED_REG_A_EVENT_ON_FULL_DUPLEX, |
258 | + VEND1_LED_REG_A_EVENT_ON_COLLISION, | 258 | + VEND1_LED_REG_A_EVENT_ON_COLLISION, |
259 | + VEND1_LED_REG_A_EVENT_BLINK_TX, | 259 | + VEND1_LED_REG_A_EVENT_BLINK_TX, |
260 | + VEND1_LED_REG_A_EVENT_BLINK_RX, | 260 | + VEND1_LED_REG_A_EVENT_BLINK_RX, |
261 | + VEND1_LED_REG_A_EVENT_BLINK_ACT, | 261 | + VEND1_LED_REG_A_EVENT_BLINK_ACT, |
262 | + VEND1_LED_REG_A_EVENT_ON_LINK, | 262 | + VEND1_LED_REG_A_EVENT_ON_LINK, |
263 | + VEND1_LED_REG_A_EVENT_ON_LINK_BLINK_ACT, | 263 | + VEND1_LED_REG_A_EVENT_ON_LINK_BLINK_ACT, |
264 | + VEND1_LED_REG_A_EVENT_ON_LINK_BLINK_RX, | 264 | + VEND1_LED_REG_A_EVENT_ON_LINK_BLINK_RX, |
265 | + VEND1_LED_REG_A_EVENT_ON_FE_GE_BLINK_ACT, | 265 | + VEND1_LED_REG_A_EVENT_ON_FE_GE_BLINK_ACT, |
266 | + VEND1_LED_REG_A_EVENT_ON_NG_BLINK_ACT, | 266 | + VEND1_LED_REG_A_EVENT_ON_NG_BLINK_ACT, |
267 | + VEND1_LED_REG_A_EVENT_ON_NG_BLINK_FE_GE, | 267 | + VEND1_LED_REG_A_EVENT_ON_NG_BLINK_FE_GE, |
268 | + VEND1_LED_REG_A_EVENT_ON_FD_BLINK_COLLISION, | 268 | + VEND1_LED_REG_A_EVENT_ON_FD_BLINK_COLLISION, |
269 | + VEND1_LED_REG_A_EVENT_ON, | 269 | + VEND1_LED_REG_A_EVENT_ON, |
270 | + VEND1_LED_REG_A_EVENT_OFF, | 270 | + VEND1_LED_REG_A_EVENT_OFF, |
271 | +}; | 271 | +}; |
272 | + | 272 | + |
273 | +struct as21xxx_led_pattern_info { | 273 | +struct as21xxx_led_pattern_info { |
274 | + unsigned int pattern; | 274 | + unsigned int pattern; |
275 | + u16 val; | 275 | + u16 val; |
276 | +}; | 276 | +}; |
277 | + | 277 | + |
278 | +struct as21xxx_priv { | 278 | +struct as21xxx_priv { |
279 | + bool parity_status; | 279 | + bool parity_status; |
280 | + /* Protect concurrent IPC access */ | 280 | + /* Protect concurrent IPC access */ |
281 | + struct mutex ipc_lock; | 281 | + struct mutex ipc_lock; |
282 | +}; | 282 | +}; |
283 | + | 283 | + |
284 | +static struct as21xxx_led_pattern_info as21xxx_led_supported_pattern[] = { | 284 | +static struct as21xxx_led_pattern_info as21xxx_led_supported_pattern[] = { |
285 | + { | 285 | + { |
286 | + .pattern = BIT(TRIGGER_NETDEV_LINK_10), | 286 | + .pattern = BIT(TRIGGER_NETDEV_LINK_10), |
287 | + .val = VEND1_LED_REG_A_EVENT_ON_10 | 287 | + .val = VEND1_LED_REG_A_EVENT_ON_10 |
288 | + }, | 288 | + }, |
289 | + { | 289 | + { |
290 | + .pattern = BIT(TRIGGER_NETDEV_LINK_100), | 290 | + .pattern = BIT(TRIGGER_NETDEV_LINK_100), |
291 | + .val = VEND1_LED_REG_A_EVENT_ON_100 | 291 | + .val = VEND1_LED_REG_A_EVENT_ON_100 |
292 | + }, | 292 | + }, |
293 | + { | 293 | + { |
294 | + .pattern = BIT(TRIGGER_NETDEV_LINK_1000), | 294 | + .pattern = BIT(TRIGGER_NETDEV_LINK_1000), |
295 | + .val = VEND1_LED_REG_A_EVENT_ON_1000 | 295 | + .val = VEND1_LED_REG_A_EVENT_ON_1000 |
296 | + }, | 296 | + }, |
297 | + { | 297 | + { |
298 | + .pattern = BIT(TRIGGER_NETDEV_LINK_2500), | 298 | + .pattern = BIT(TRIGGER_NETDEV_LINK_2500), |
299 | + .val = VEND1_LED_REG_A_EVENT_ON_2500 | 299 | + .val = VEND1_LED_REG_A_EVENT_ON_2500 |
300 | + }, | 300 | + }, |
301 | + { | 301 | + { |
302 | + .pattern = BIT(TRIGGER_NETDEV_LINK_5000), | 302 | + .pattern = BIT(TRIGGER_NETDEV_LINK_5000), |
303 | + .val = VEND1_LED_REG_A_EVENT_ON_5000 | 303 | + .val = VEND1_LED_REG_A_EVENT_ON_5000 |
304 | + }, | 304 | + }, |
305 | + { | 305 | + { |
306 | + .pattern = BIT(TRIGGER_NETDEV_LINK_10000), | 306 | + .pattern = BIT(TRIGGER_NETDEV_LINK_10000), |
307 | + .val = VEND1_LED_REG_A_EVENT_ON_10000 | 307 | + .val = VEND1_LED_REG_A_EVENT_ON_10000 |
308 | + }, | 308 | + }, |
309 | + { | 309 | + { |
310 | + .pattern = BIT(TRIGGER_NETDEV_LINK), | 310 | + .pattern = BIT(TRIGGER_NETDEV_LINK), |
311 | + .val = VEND1_LED_REG_A_EVENT_ON_LINK | 311 | + .val = VEND1_LED_REG_A_EVENT_ON_LINK |
312 | + }, | 312 | + }, |
313 | + { | 313 | + { |
314 | + .pattern = BIT(TRIGGER_NETDEV_LINK_10) | | 314 | + .pattern = BIT(TRIGGER_NETDEV_LINK_10) | |
315 | + BIT(TRIGGER_NETDEV_LINK_100) | | 315 | + BIT(TRIGGER_NETDEV_LINK_100) | |
316 | + BIT(TRIGGER_NETDEV_LINK_1000), | 316 | + BIT(TRIGGER_NETDEV_LINK_1000), |
317 | + .val = VEND1_LED_REG_A_EVENT_ON_FE_GE | 317 | + .val = VEND1_LED_REG_A_EVENT_ON_FE_GE |
318 | + }, | 318 | + }, |
319 | + { | 319 | + { |
320 | + .pattern = BIT(TRIGGER_NETDEV_LINK_2500) | | 320 | + .pattern = BIT(TRIGGER_NETDEV_LINK_2500) | |
321 | + BIT(TRIGGER_NETDEV_LINK_5000) | | 321 | + BIT(TRIGGER_NETDEV_LINK_5000) | |
322 | + BIT(TRIGGER_NETDEV_LINK_10000), | 322 | + BIT(TRIGGER_NETDEV_LINK_10000), |
323 | + .val = VEND1_LED_REG_A_EVENT_ON_NG | 323 | + .val = VEND1_LED_REG_A_EVENT_ON_NG |
324 | + }, | 324 | + }, |
325 | + { | 325 | + { |
326 | + .pattern = BIT(TRIGGER_NETDEV_FULL_DUPLEX), | 326 | + .pattern = BIT(TRIGGER_NETDEV_FULL_DUPLEX), |
327 | + .val = VEND1_LED_REG_A_EVENT_ON_FULL_DUPLEX | 327 | + .val = VEND1_LED_REG_A_EVENT_ON_FULL_DUPLEX |
328 | + }, | 328 | + }, |
329 | + { | 329 | + { |
330 | + .pattern = BIT(TRIGGER_NETDEV_TX), | 330 | + .pattern = BIT(TRIGGER_NETDEV_TX), |
331 | + .val = VEND1_LED_REG_A_EVENT_BLINK_TX | 331 | + .val = VEND1_LED_REG_A_EVENT_BLINK_TX |
332 | + }, | 332 | + }, |
333 | + { | 333 | + { |
334 | + .pattern = BIT(TRIGGER_NETDEV_RX), | 334 | + .pattern = BIT(TRIGGER_NETDEV_RX), |
335 | + .val = VEND1_LED_REG_A_EVENT_BLINK_RX | 335 | + .val = VEND1_LED_REG_A_EVENT_BLINK_RX |
336 | + }, | 336 | + }, |
337 | + { | 337 | + { |
338 | + .pattern = BIT(TRIGGER_NETDEV_TX) | | 338 | + .pattern = BIT(TRIGGER_NETDEV_TX) | |
339 | + BIT(TRIGGER_NETDEV_RX), | 339 | + BIT(TRIGGER_NETDEV_RX), |
340 | + .val = VEND1_LED_REG_A_EVENT_BLINK_ACT | 340 | + .val = VEND1_LED_REG_A_EVENT_BLINK_ACT |
341 | + }, | 341 | + }, |
342 | + { | 342 | + { |
343 | + .pattern = BIT(TRIGGER_NETDEV_LINK_10) | | 343 | + .pattern = BIT(TRIGGER_NETDEV_LINK_10) | |
344 | + BIT(TRIGGER_NETDEV_LINK_100) | | 344 | + BIT(TRIGGER_NETDEV_LINK_100) | |
345 | + BIT(TRIGGER_NETDEV_LINK_1000) | | 345 | + BIT(TRIGGER_NETDEV_LINK_1000) | |
346 | + BIT(TRIGGER_NETDEV_LINK_2500) | | 346 | + BIT(TRIGGER_NETDEV_LINK_2500) | |
347 | + BIT(TRIGGER_NETDEV_LINK_5000) | | 347 | + BIT(TRIGGER_NETDEV_LINK_5000) | |
348 | + BIT(TRIGGER_NETDEV_LINK_10000), | 348 | + BIT(TRIGGER_NETDEV_LINK_10000), |
349 | + .val = VEND1_LED_REG_A_EVENT_ON_LINK | 349 | + .val = VEND1_LED_REG_A_EVENT_ON_LINK |
350 | + }, | 350 | + }, |
351 | + { | 351 | + { |
352 | + .pattern = BIT(TRIGGER_NETDEV_LINK_10) | | 352 | + .pattern = BIT(TRIGGER_NETDEV_LINK_10) | |
353 | + BIT(TRIGGER_NETDEV_LINK_100) | | 353 | + BIT(TRIGGER_NETDEV_LINK_100) | |
354 | + BIT(TRIGGER_NETDEV_LINK_1000) | | 354 | + BIT(TRIGGER_NETDEV_LINK_1000) | |
355 | + BIT(TRIGGER_NETDEV_LINK_2500) | | 355 | + BIT(TRIGGER_NETDEV_LINK_2500) | |
356 | + BIT(TRIGGER_NETDEV_LINK_5000) | | 356 | + BIT(TRIGGER_NETDEV_LINK_5000) | |
357 | + BIT(TRIGGER_NETDEV_LINK_10000) | | 357 | + BIT(TRIGGER_NETDEV_LINK_10000) | |
358 | + BIT(TRIGGER_NETDEV_TX) | | 358 | + BIT(TRIGGER_NETDEV_TX) | |
359 | + BIT(TRIGGER_NETDEV_RX), | 359 | + BIT(TRIGGER_NETDEV_RX), |
360 | + .val = VEND1_LED_REG_A_EVENT_ON_LINK_BLINK_ACT | 360 | + .val = VEND1_LED_REG_A_EVENT_ON_LINK_BLINK_ACT |
361 | + }, | 361 | + }, |
362 | + { | 362 | + { |
363 | + .pattern = BIT(TRIGGER_NETDEV_LINK_10) | | 363 | + .pattern = BIT(TRIGGER_NETDEV_LINK_10) | |
364 | + BIT(TRIGGER_NETDEV_LINK_100) | | 364 | + BIT(TRIGGER_NETDEV_LINK_100) | |
365 | + BIT(TRIGGER_NETDEV_LINK_1000) | | 365 | + BIT(TRIGGER_NETDEV_LINK_1000) | |
366 | + BIT(TRIGGER_NETDEV_LINK_2500) | | 366 | + BIT(TRIGGER_NETDEV_LINK_2500) | |
367 | + BIT(TRIGGER_NETDEV_LINK_5000) | | 367 | + BIT(TRIGGER_NETDEV_LINK_5000) | |
368 | + BIT(TRIGGER_NETDEV_LINK_10000) | | 368 | + BIT(TRIGGER_NETDEV_LINK_10000) | |
369 | + BIT(TRIGGER_NETDEV_RX), | 369 | + BIT(TRIGGER_NETDEV_RX), |
370 | + .val = VEND1_LED_REG_A_EVENT_ON_LINK_BLINK_RX | 370 | + .val = VEND1_LED_REG_A_EVENT_ON_LINK_BLINK_RX |
371 | + }, | 371 | + }, |
372 | + { | 372 | + { |
373 | + .pattern = BIT(TRIGGER_NETDEV_LINK_10) | | 373 | + .pattern = BIT(TRIGGER_NETDEV_LINK_10) | |
374 | + BIT(TRIGGER_NETDEV_LINK_100) | | 374 | + BIT(TRIGGER_NETDEV_LINK_100) | |
375 | + BIT(TRIGGER_NETDEV_LINK_1000) | | 375 | + BIT(TRIGGER_NETDEV_LINK_1000) | |
376 | + BIT(TRIGGER_NETDEV_TX) | | 376 | + BIT(TRIGGER_NETDEV_TX) | |
377 | + BIT(TRIGGER_NETDEV_RX), | 377 | + BIT(TRIGGER_NETDEV_RX), |
378 | + .val = VEND1_LED_REG_A_EVENT_ON_FE_GE_BLINK_ACT | 378 | + .val = VEND1_LED_REG_A_EVENT_ON_FE_GE_BLINK_ACT |
379 | + }, | 379 | + }, |
380 | + { | 380 | + { |
381 | + .pattern = BIT(TRIGGER_NETDEV_LINK_2500) | | 381 | + .pattern = BIT(TRIGGER_NETDEV_LINK_2500) | |
382 | + BIT(TRIGGER_NETDEV_LINK_5000) | | 382 | + BIT(TRIGGER_NETDEV_LINK_5000) | |
383 | + BIT(TRIGGER_NETDEV_LINK_10000) | | 383 | + BIT(TRIGGER_NETDEV_LINK_10000) | |
384 | + BIT(TRIGGER_NETDEV_TX) | | 384 | + BIT(TRIGGER_NETDEV_TX) | |
385 | + BIT(TRIGGER_NETDEV_RX), | 385 | + BIT(TRIGGER_NETDEV_RX), |
386 | + .val = VEND1_LED_REG_A_EVENT_ON_NG_BLINK_ACT | 386 | + .val = VEND1_LED_REG_A_EVENT_ON_NG_BLINK_ACT |
387 | + } | 387 | + } |
388 | +}; | 388 | +}; |
389 | + | 389 | + |
390 | +static int aeon_firmware_boot(struct phy_device *phydev, const u8 *data, | 390 | +static int aeon_firmware_boot(struct phy_device *phydev, const u8 *data, |
391 | + size_t size) | 391 | + size_t size) |
392 | +{ | 392 | +{ |
393 | + int i, ret; | 393 | + int i, ret; |
394 | + u16 val; | 394 | + u16 val; |
395 | + | 395 | + |
396 | + ret = phy_modify_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLB_REG_CPU_CTRL, | 396 | + ret = phy_modify_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLB_REG_CPU_CTRL, |
397 | + VEND1_GLB_CPU_CTRL_MASK, AEON_CPU_CTRL_FW_LOAD); | 397 | + VEND1_GLB_CPU_CTRL_MASK, AEON_CPU_CTRL_FW_LOAD); |
398 | + if (ret) | 398 | + if (ret) |
399 | + return ret; | 399 | + return ret; |
400 | + | 400 | + |
401 | + ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_FW_START_ADDR, | 401 | + ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_FW_START_ADDR, |
402 | + AEON_BOOT_ADDR); | 402 | + AEON_BOOT_ADDR); |
403 | + if (ret) | 403 | + if (ret) |
404 | + return ret; | 404 | + return ret; |
405 | + | 405 | + |
406 | + ret = phy_modify_mmd(phydev, MDIO_MMD_VEND1, | 406 | + ret = phy_modify_mmd(phydev, MDIO_MMD_VEND1, |
407 | + VEND1_GLB_REG_MDIO_INDIRECT_ADDRCMD, | 407 | + VEND1_GLB_REG_MDIO_INDIRECT_ADDRCMD, |
408 | + 0x3ffc, 0xc000); | 408 | + 0x3ffc, 0xc000); |
409 | + if (ret) | 409 | + if (ret) |
410 | + return ret; | 410 | + return ret; |
411 | + | 411 | + |
412 | + val = phy_read_mmd(phydev, MDIO_MMD_VEND1, | 412 | + val = phy_read_mmd(phydev, MDIO_MMD_VEND1, |
413 | + VEND1_GLB_REG_MDIO_INDIRECT_STATUS); | 413 | + VEND1_GLB_REG_MDIO_INDIRECT_STATUS); |
414 | + if (val > 1) { | 414 | + if (val > 1) { |
415 | + phydev_err(phydev, "wrong origin mdio_indirect_status: %x\n", val); | 415 | + phydev_err(phydev, "wrong origin mdio_indirect_status: %x\n", val); |
416 | + return -EINVAL; | 416 | + return -EINVAL; |
417 | + } | 417 | + } |
418 | + | 418 | + |
419 | + /* Firmware is always aligned to u16 */ | 419 | + /* Firmware is always aligned to u16 */ |
420 | + for (i = 0; i < size; i += 2) { | 420 | + for (i = 0; i < size; i += 2) { |
421 | + val = data[i + 1] << 8 | data[i]; | 421 | + val = data[i + 1] << 8 | data[i]; |
422 | + | 422 | + |
423 | + ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, | 423 | + ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, |
424 | + VEND1_GLB_REG_MDIO_INDIRECT_LOAD, val); | 424 | + VEND1_GLB_REG_MDIO_INDIRECT_LOAD, val); |
425 | + if (ret) | 425 | + if (ret) |
426 | + return ret; | 426 | + return ret; |
427 | + } | 427 | + } |
428 | + | 428 | + |
429 | + ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, | 429 | + ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, |
430 | + VEND1_GLB_REG_CPU_RESET_ADDR_LO_BASEADDR, | 430 | + VEND1_GLB_REG_CPU_RESET_ADDR_LO_BASEADDR, |
431 | + lower_16_bits(AEON_CPU_BOOT_ADDR)); | 431 | + lower_16_bits(AEON_CPU_BOOT_ADDR)); |
432 | + if (ret) | 432 | + if (ret) |
433 | + return ret; | 433 | + return ret; |
434 | + | 434 | + |
435 | + ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, | 435 | + ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, |
436 | + VEND1_GLB_REG_CPU_RESET_ADDR_HI_BASEADDR, | 436 | + VEND1_GLB_REG_CPU_RESET_ADDR_HI_BASEADDR, |
437 | + upper_16_bits(AEON_CPU_BOOT_ADDR)); | 437 | + upper_16_bits(AEON_CPU_BOOT_ADDR)); |
438 | + if (ret) | 438 | + if (ret) |
439 | + return ret; | 439 | + return ret; |
440 | + | 440 | + |
441 | + return phy_modify_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLB_REG_CPU_CTRL, | 441 | + return phy_modify_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLB_REG_CPU_CTRL, |
442 | + VEND1_GLB_CPU_CTRL_MASK, AEON_CPU_CTRL_FW_START); | 442 | + VEND1_GLB_CPU_CTRL_MASK, AEON_CPU_CTRL_FW_START); |
443 | +} | 443 | +} |
444 | + | 444 | + |
445 | +static int aeon_firmware_load(struct phy_device *phydev) | 445 | +static int aeon_firmware_load(struct phy_device *phydev) |
446 | +{ | 446 | +{ |
447 | + struct device *dev = &phydev->mdio.dev; | 447 | + struct device *dev = &phydev->mdio.dev; |
448 | + const struct firmware *fw; | 448 | + const struct firmware *fw; |
449 | + const char *fw_name; | 449 | + const char *fw_name; |
450 | + int ret; | 450 | + int ret; |
451 | + | 451 | + |
452 | + ret = of_property_read_string(dev->of_node, "firmware-name", | 452 | + ret = of_property_read_string(dev->of_node, "firmware-name", |
453 | + &fw_name); | 453 | + &fw_name); |
454 | + if (ret) | 454 | + if (ret) |
455 | + return ret; | 455 | + return ret; |
456 | + | 456 | + |
457 | + ret = request_firmware(&fw, fw_name, dev); | 457 | + ret = request_firmware(&fw, fw_name, dev); |
458 | + if (ret) { | 458 | + if (ret) { |
459 | + phydev_err(phydev, "failed to find FW file %s (%d)\n", | 459 | + phydev_err(phydev, "failed to find FW file %s (%d)\n", |
460 | + fw_name, ret); | 460 | + fw_name, ret); |
461 | + return ret; | 461 | + return ret; |
462 | + } | 462 | + } |
463 | + | 463 | + |
464 | + ret = aeon_firmware_boot(phydev, fw->data, fw->size); | 464 | + ret = aeon_firmware_boot(phydev, fw->data, fw->size); |
465 | + | 465 | + |
466 | + release_firmware(fw); | 466 | + release_firmware(fw); |
467 | + | 467 | + |
468 | + return ret; | 468 | + return ret; |
469 | +} | 469 | +} |
470 | + | 470 | + |
471 | +static int aeon_ipcs_wait_cmd(struct phy_device *phydev, bool parity_status) | 471 | +static int aeon_ipcs_wait_cmd(struct phy_device *phydev, bool parity_status) |
472 | +{ | 472 | +{ |
473 | + u16 val; | 473 | + u16 val; |
474 | + | 474 | + |
475 | + /* Exit condition logic: | 475 | + /* Exit condition logic: |
476 | + * - Wait for parity bit equal | 476 | + * - Wait for parity bit equal |
477 | + * - Wait for status success, error OR ready | 477 | + * - Wait for status success, error OR ready |
478 | + */ | 478 | + */ |
479 | + return phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1, VEND1_IPC_STS, val, | 479 | + return phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1, VEND1_IPC_STS, val, |
480 | + FIELD_GET(AEON_IPC_STS_PARITY, val) == parity_status && | 480 | + FIELD_GET(AEON_IPC_STS_PARITY, val) == parity_status && |
481 | + (val & AEON_IPC_STS_STATUS) != AEON_IPC_STS_STATUS_RCVD && | 481 | + (val & AEON_IPC_STS_STATUS) != AEON_IPC_STS_STATUS_RCVD && |
482 | + (val & AEON_IPC_STS_STATUS) != AEON_IPC_STS_STATUS_PROCESS && | 482 | + (val & AEON_IPC_STS_STATUS) != AEON_IPC_STS_STATUS_PROCESS && |
483 | + (val & AEON_IPC_STS_STATUS) != AEON_IPC_STS_STATUS_BUSY, | 483 | + (val & AEON_IPC_STS_STATUS) != AEON_IPC_STS_STATUS_BUSY, |
484 | + AEON_IPC_DELAY, AEON_IPC_TIMEOUT, false); | 484 | + AEON_IPC_DELAY, AEON_IPC_TIMEOUT, false); |
485 | +} | 485 | +} |
486 | + | 486 | + |
487 | +static int aeon_ipc_send_cmd(struct phy_device *phydev, | 487 | +static int aeon_ipc_send_cmd(struct phy_device *phydev, |
488 | + struct as21xxx_priv *priv, | 488 | + struct as21xxx_priv *priv, |
489 | + u16 cmd, u16 *ret_sts) | 489 | + u16 cmd, u16 *ret_sts) |
490 | +{ | 490 | +{ |
491 | + bool curr_parity; | 491 | + bool curr_parity; |
492 | + int ret; | 492 | + int ret; |
493 | + | 493 | + |
494 | + /* The IPC sync by using a single parity bit. | 494 | + /* The IPC sync by using a single parity bit. |
495 | + * Each CMD have alternately this bit set or clear | 495 | + * Each CMD have alternately this bit set or clear |
496 | + * to understand correct flow and packet order. | 496 | + * to understand correct flow and packet order. |
497 | + */ | 497 | + */ |
498 | + curr_parity = priv->parity_status; | 498 | + curr_parity = priv->parity_status; |
499 | + if (priv->parity_status) | 499 | + if (priv->parity_status) |
500 | + cmd |= AEON_IPC_CMD_PARITY; | 500 | + cmd |= AEON_IPC_CMD_PARITY; |
501 | + | 501 | + |
502 | + /* Always update parity for next packet */ | 502 | + /* Always update parity for next packet */ |
503 | + priv->parity_status = !priv->parity_status; | 503 | + priv->parity_status = !priv->parity_status; |
504 | + | 504 | + |
505 | + ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_IPC_CMD, cmd); | 505 | + ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_IPC_CMD, cmd); |
506 | + if (ret) | 506 | + if (ret) |
507 | + return ret; | 507 | + return ret; |
508 | + | 508 | + |
509 | + /* Wait for packet to be processed */ | 509 | + /* Wait for packet to be processed */ |
510 | + usleep_range(AEON_IPC_DELAY, AEON_IPC_DELAY + 5000); | 510 | + usleep_range(AEON_IPC_DELAY, AEON_IPC_DELAY + 5000); |
511 | + | 511 | + |
512 | + /* With no ret_sts, ignore waiting for packet completion | 512 | + /* With no ret_sts, ignore waiting for packet completion |
513 | + * (ipc parity bit sync) | 513 | + * (ipc parity bit sync) |
514 | + */ | 514 | + */ |
515 | + if (!ret_sts) | 515 | + if (!ret_sts) |
516 | + return 0; | 516 | + return 0; |
517 | + | 517 | + |
518 | + ret = aeon_ipcs_wait_cmd(phydev, curr_parity); | 518 | + ret = aeon_ipcs_wait_cmd(phydev, curr_parity); |
519 | + if (ret) | 519 | + if (ret) |
520 | + return ret; | 520 | + return ret; |
521 | + | 521 | + |
522 | + ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_IPC_STS); | 522 | + ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_IPC_STS); |
523 | + if (ret < 0) | 523 | + if (ret < 0) |
524 | + return ret; | 524 | + return ret; |
525 | + | 525 | + |
526 | + *ret_sts = ret; | 526 | + *ret_sts = ret; |
527 | + if ((*ret_sts & AEON_IPC_STS_STATUS) != AEON_IPC_STS_STATUS_SUCCESS) | 527 | + if ((*ret_sts & AEON_IPC_STS_STATUS) != AEON_IPC_STS_STATUS_SUCCESS) |
528 | + return -EINVAL; | 528 | + return -EINVAL; |
529 | + | 529 | + |
530 | + return 0; | 530 | + return 0; |
531 | +} | 531 | +} |
532 | + | 532 | + |
533 | +static int aeon_ipc_send_msg(struct phy_device *phydev, | 533 | +static int aeon_ipc_send_msg(struct phy_device *phydev, |
534 | + u16 opcode, u16 *data, unsigned int data_len, | 534 | + u16 opcode, u16 *data, unsigned int data_len, |
535 | + u16 *ret_sts) | 535 | + u16 *ret_sts) |
536 | +{ | 536 | +{ |
537 | + struct as21xxx_priv *priv = phydev->priv; | 537 | + struct as21xxx_priv *priv = phydev->priv; |
538 | + u16 cmd; | 538 | + u16 cmd; |
539 | + int ret; | 539 | + int ret; |
540 | + int i; | 540 | + int i; |
541 | + | 541 | + |
542 | + /* IPC have a max of 8 register to transfer data, | 542 | + /* IPC have a max of 8 register to transfer data, |
543 | + * make sure we never exceed this. | 543 | + * make sure we never exceed this. |
544 | + */ | 544 | + */ |
545 | + if (data_len > AEON_IPC_DATA_MAX) | 545 | + if (data_len > AEON_IPC_DATA_MAX) |
546 | + return -EINVAL; | 546 | + return -EINVAL; |
547 | + | 547 | + |
548 | + mutex_lock(&priv->ipc_lock); | 548 | + mutex_lock(&priv->ipc_lock); |
549 | + | 549 | + |
550 | + for (i = 0; i < data_len / sizeof(u16); i++) | 550 | + for (i = 0; i < data_len / sizeof(u16); i++) |
551 | + phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_IPC_DATA(i), | 551 | + phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_IPC_DATA(i), |
552 | + data[i]); | 552 | + data[i]); |
553 | + | 553 | + |
554 | + cmd = FIELD_PREP(AEON_IPC_CMD_SIZE, data_len) | | 554 | + cmd = FIELD_PREP(AEON_IPC_CMD_SIZE, data_len) | |
555 | + FIELD_PREP(AEON_IPC_CMD_OPCODE, opcode); | 555 | + FIELD_PREP(AEON_IPC_CMD_OPCODE, opcode); |
556 | + ret = aeon_ipc_send_cmd(phydev, priv, cmd, ret_sts); | 556 | + ret = aeon_ipc_send_cmd(phydev, priv, cmd, ret_sts); |
557 | + if (ret) | 557 | + if (ret) |
558 | + phydev_err(phydev, "failed to send ipc msg for %x: %d\n", | 558 | + phydev_err(phydev, "failed to send ipc msg for %x: %d\n", |
559 | + opcode, ret); | 559 | + opcode, ret); |
560 | + | 560 | + |
561 | + mutex_unlock(&priv->ipc_lock); | 561 | + mutex_unlock(&priv->ipc_lock); |
562 | + | 562 | + |
563 | + return ret; | 563 | + return ret; |
564 | +} | 564 | +} |
565 | + | 565 | + |
566 | +static int aeon_ipc_rcv_msg(struct phy_device *phydev, | 566 | +static int aeon_ipc_rcv_msg(struct phy_device *phydev, |
567 | + u16 ret_sts, u16 *data) | 567 | + u16 ret_sts, u16 *data) |
568 | +{ | 568 | +{ |
569 | + struct as21xxx_priv *priv = phydev->priv; | 569 | + struct as21xxx_priv *priv = phydev->priv; |
570 | + unsigned int size; | 570 | + unsigned int size; |
571 | + int ret; | 571 | + int ret; |
572 | + int i; | 572 | + int i; |
573 | + | 573 | + |
574 | + if ((ret_sts & AEON_IPC_STS_STATUS) == AEON_IPC_STS_STATUS_ERROR) | 574 | + if ((ret_sts & AEON_IPC_STS_STATUS) == AEON_IPC_STS_STATUS_ERROR) |
575 | + return -EINVAL; | 575 | + return -EINVAL; |
576 | + | 576 | + |
577 | + /* Prevent IPC from stack smashing the kernel */ | 577 | + /* Prevent IPC from stack smashing the kernel */ |
578 | + size = FIELD_GET(AEON_IPC_STS_SIZE, ret_sts); | 578 | + size = FIELD_GET(AEON_IPC_STS_SIZE, ret_sts); |
579 | + if (size > AEON_IPC_DATA_MAX) | 579 | + if (size > AEON_IPC_DATA_MAX) |
580 | + return -EINVAL; | 580 | + return -EINVAL; |
581 | + | 581 | + |
582 | + mutex_lock(&priv->ipc_lock); | 582 | + mutex_lock(&priv->ipc_lock); |
583 | + | 583 | + |
584 | + for (i = 0; i < DIV_ROUND_UP(size, sizeof(u16)); i++) { | 584 | + for (i = 0; i < DIV_ROUND_UP(size, sizeof(u16)); i++) { |
585 | + ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_IPC_DATA(i)); | 585 | + ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_IPC_DATA(i)); |
586 | + if (ret < 0) { | 586 | + if (ret < 0) { |
587 | + size = ret; | 587 | + size = ret; |
588 | + goto out; | 588 | + goto out; |
589 | + } | 589 | + } |
590 | + | 590 | + |
591 | + data[i] = ret; | 591 | + data[i] = ret; |
592 | + } | 592 | + } |
593 | + | 593 | + |
594 | +out: | 594 | +out: |
595 | + mutex_unlock(&priv->ipc_lock); | 595 | + mutex_unlock(&priv->ipc_lock); |
596 | + | 596 | + |
597 | + return size; | 597 | + return size; |
598 | +} | 598 | +} |
599 | + | 599 | + |
600 | +static int aeon_ipc_noop(struct phy_device *phydev, | 600 | +static int aeon_ipc_noop(struct phy_device *phydev, |
601 | + struct as21xxx_priv *priv, u16 *ret_sts) | 601 | + struct as21xxx_priv *priv, u16 *ret_sts) |
602 | +{ | 602 | +{ |
603 | + u16 cmd; | 603 | + u16 cmd; |
604 | + | 604 | + |
605 | + cmd = FIELD_PREP(AEON_IPC_CMD_SIZE, 0) | | 605 | + cmd = FIELD_PREP(AEON_IPC_CMD_SIZE, 0) | |
606 | + FIELD_PREP(AEON_IPC_CMD_OPCODE, IPC_CMD_NOOP); | 606 | + FIELD_PREP(AEON_IPC_CMD_OPCODE, IPC_CMD_NOOP); |
607 | + | 607 | + |
608 | + return aeon_ipc_send_cmd(phydev, priv, cmd, ret_sts); | 608 | + return aeon_ipc_send_cmd(phydev, priv, cmd, ret_sts); |
609 | +} | 609 | +} |
610 | + | 610 | + |
611 | +/* Logic to sync parity bit with IPC. | 611 | +/* Logic to sync parity bit with IPC. |
612 | + * We send 2 NOP cmd with same partity and we wait for IPC | 612 | + * We send 2 NOP cmd with same partity and we wait for IPC |
613 | + * to handle the packet only for the second one. This way | 613 | + * to handle the packet only for the second one. This way |
614 | + * we make sure we are sync for every next cmd. | 614 | + * we make sure we are sync for every next cmd. |
615 | + */ | 615 | + */ |
616 | +static int aeon_ipc_sync_parity(struct phy_device *phydev, | 616 | +static int aeon_ipc_sync_parity(struct phy_device *phydev, |
617 | + struct as21xxx_priv *priv) | 617 | + struct as21xxx_priv *priv) |
618 | +{ | 618 | +{ |
619 | + u16 ret_sts; | 619 | + u16 ret_sts; |
620 | + int ret; | 620 | + int ret; |
621 | + | 621 | + |
622 | + mutex_lock(&priv->ipc_lock); | 622 | + mutex_lock(&priv->ipc_lock); |
623 | + | 623 | + |
624 | + /* Send NOP with no parity */ | 624 | + /* Send NOP with no parity */ |
625 | + aeon_ipc_noop(phydev, priv, NULL); | 625 | + aeon_ipc_noop(phydev, priv, NULL); |
626 | + | 626 | + |
627 | + /* Reset packet parity */ | 627 | + /* Reset packet parity */ |
628 | + priv->parity_status = false; | 628 | + priv->parity_status = false; |
629 | + | 629 | + |
630 | + /* Send second NOP with no parity */ | 630 | + /* Send second NOP with no parity */ |
631 | + ret = aeon_ipc_noop(phydev, priv, &ret_sts); | 631 | + ret = aeon_ipc_noop(phydev, priv, &ret_sts); |
632 | + | 632 | + |
633 | + mutex_unlock(&priv->ipc_lock); | 633 | + mutex_unlock(&priv->ipc_lock); |
634 | + | 634 | + |
635 | + /* We expect to return -EINVAL */ | 635 | + /* We expect to return -EINVAL */ |
636 | + if (ret != -EINVAL) | 636 | + if (ret != -EINVAL) |
637 | + return ret; | 637 | + return ret; |
638 | + | 638 | + |
639 | + if ((ret_sts & AEON_IPC_STS_STATUS) != AEON_IPC_STS_STATUS_READY) { | 639 | + if ((ret_sts & AEON_IPC_STS_STATUS) != AEON_IPC_STS_STATUS_READY) { |
640 | + phydev_err(phydev, "Invalid IPC status on sync parity: %x\n", | 640 | + phydev_err(phydev, "Invalid IPC status on sync parity: %x\n", |
641 | + ret_sts); | 641 | + ret_sts); |
642 | + return -EINVAL; | 642 | + return -EINVAL; |
643 | + } | 643 | + } |
644 | + | 644 | + |
645 | + return 0; | 645 | + return 0; |
646 | +} | 646 | +} |
647 | + | 647 | + |
648 | +static int aeon_ipc_get_fw_version(struct phy_device *phydev) | 648 | +static int aeon_ipc_get_fw_version(struct phy_device *phydev) |
649 | +{ | 649 | +{ |
650 | + u16 ret_data[8], data[1]; | 650 | + u16 ret_data[8], data[1]; |
651 | + u16 ret_sts; | 651 | + u16 ret_sts; |
652 | + int ret; | 652 | + int ret; |
653 | + | 653 | + |
654 | + data[0] = IPC_INFO_VERSION; | 654 | + data[0] = IPC_INFO_VERSION; |
655 | + ret = aeon_ipc_send_msg(phydev, IPC_CMD_INFO, data, | 655 | + ret = aeon_ipc_send_msg(phydev, IPC_CMD_INFO, data, |
656 | + sizeof(data), &ret_sts); | 656 | + sizeof(data), &ret_sts); |
657 | + if (ret) | 657 | + if (ret) |
658 | + return ret; | 658 | + return ret; |
659 | + | 659 | + |
660 | + ret = aeon_ipc_rcv_msg(phydev, ret_sts, ret_data); | 660 | + ret = aeon_ipc_rcv_msg(phydev, ret_sts, ret_data); |
661 | + if (ret < 0) | 661 | + if (ret < 0) |
662 | + return ret; | 662 | + return ret; |
663 | + | 663 | + |
664 | + phydev_info(phydev, "Firmware Version: %s\n", (char *)ret_data); | 664 | + phydev_info(phydev, "Firmware Version: %s\n", (char *)ret_data); |
665 | + | 665 | + |
666 | + return 0; | 666 | + return 0; |
667 | +} | 667 | +} |
668 | + | 668 | + |
669 | +static int aeon_dpc_ra_enable(struct phy_device *phydev) | 669 | +static int aeon_dpc_ra_enable(struct phy_device *phydev) |
670 | +{ | 670 | +{ |
671 | + u16 data[2]; | 671 | + u16 data[2]; |
672 | + u16 ret_sts; | 672 | + u16 ret_sts; |
673 | + | 673 | + |
674 | + data[0] = IPC_CFG_PARAM_DIRECT; | 674 | + data[0] = IPC_CFG_PARAM_DIRECT; |
675 | + data[1] = IPC_CFG_PARAM_DIRECT_DPC_RA; | 675 | + data[1] = IPC_CFG_PARAM_DIRECT_DPC_RA; |
676 | + | 676 | + |
677 | + return aeon_ipc_send_msg(phydev, IPC_CMD_CFG_PARAM, data, | 677 | + return aeon_ipc_send_msg(phydev, IPC_CMD_CFG_PARAM, data, |
678 | + sizeof(data), &ret_sts); | 678 | + sizeof(data), &ret_sts); |
679 | +} | 679 | +} |
680 | + | 680 | + |
681 | +static int as21xxx_probe(struct phy_device *phydev) | 681 | +static int as21xxx_probe(struct phy_device *phydev) |
682 | +{ | 682 | +{ |
683 | + struct as21xxx_priv *priv; | 683 | + struct as21xxx_priv *priv; |
684 | + int ret; | 684 | + int ret; |
685 | + | 685 | + |
686 | + priv = devm_kzalloc(&phydev->mdio.dev, | 686 | + priv = devm_kzalloc(&phydev->mdio.dev, |
687 | + sizeof(*priv), GFP_KERNEL); | 687 | + sizeof(*priv), GFP_KERNEL); |
688 | + if (!priv) | 688 | + if (!priv) |
689 | + return -ENOMEM; | 689 | + return -ENOMEM; |
690 | + phydev->priv = priv; | 690 | + phydev->priv = priv; |
691 | + | 691 | + |
692 | + ret = devm_mutex_init(&phydev->mdio.dev, | 692 | + ret = devm_mutex_init(&phydev->mdio.dev, |
693 | + &priv->ipc_lock); | 693 | + &priv->ipc_lock); |
694 | + if (ret) | 694 | + if (ret) |
695 | + return ret; | 695 | + return ret; |
696 | + | 696 | + |
697 | + ret = aeon_ipc_sync_parity(phydev, priv); | 697 | + ret = aeon_ipc_sync_parity(phydev, priv); |
698 | + if (ret) | 698 | + if (ret) |
699 | + return ret; | 699 | + return ret; |
700 | + | 700 | + |
701 | + ret = aeon_ipc_get_fw_version(phydev); | 701 | + ret = aeon_ipc_get_fw_version(phydev); |
702 | + if (ret) | 702 | + if (ret) |
703 | + return ret; | 703 | + return ret; |
704 | + | 704 | + |
705 | + /* Enable PTP clk if not already Enabled */ | 705 | + /* Enable PTP clk if not already Enabled */ |
706 | + ret = phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_PTP_CLK, | 706 | + ret = phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_PTP_CLK, |
707 | + VEND1_PTP_CLK_EN); | 707 | + VEND1_PTP_CLK_EN); |
708 | + if (ret) | 708 | + if (ret) |
709 | + return ret; | 709 | + return ret; |
710 | + | 710 | + |
711 | + return aeon_dpc_ra_enable(phydev); | 711 | + return aeon_dpc_ra_enable(phydev); |
712 | +} | 712 | +} |
713 | + | 713 | + |
714 | +static int as21xxx_read_link(struct phy_device *phydev, int *bmcr) | 714 | +static int as21xxx_read_link(struct phy_device *phydev, int *bmcr) |
715 | +{ | 715 | +{ |
716 | + int status; | 716 | + int status; |
717 | + | 717 | + |
718 | + /* Normal C22 BMCR report inconsistent data, use | 718 | + /* Normal C22 BMCR report inconsistent data, use |
719 | + * the mapped C22 in C45 to have more consistent link info. | 719 | + * the mapped C22 in C45 to have more consistent link info. |
720 | + */ | 720 | + */ |
721 | + *bmcr = phy_read_mmd(phydev, MDIO_MMD_AN, | 721 | + *bmcr = phy_read_mmd(phydev, MDIO_MMD_AN, |
722 | + AS21XXX_MDIO_AN_C22 + MII_BMCR); | 722 | + AS21XXX_MDIO_AN_C22 + MII_BMCR); |
723 | + if (*bmcr < 0) | 723 | + if (*bmcr < 0) |
724 | + return *bmcr; | 724 | + return *bmcr; |
725 | + | 725 | + |
726 | + /* Autoneg is being started, therefore disregard current | 726 | + /* Autoneg is being started, therefore disregard current |
727 | + * link status and report link as down. | 727 | + * link status and report link as down. |
728 | + */ | 728 | + */ |
729 | + if (*bmcr & BMCR_ANRESTART) { | 729 | + if (*bmcr & BMCR_ANRESTART) { |
730 | + phydev->link = 0; | 730 | + phydev->link = 0; |
731 | + return 0; | 731 | + return 0; |
732 | + } | 732 | + } |
733 | + | 733 | + |
734 | + status = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_STAT1); | 734 | + status = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_STAT1); |
735 | + if (status < 0) | 735 | + if (status < 0) |
736 | + return status; | 736 | + return status; |
737 | + | 737 | + |
738 | + phydev->link = !!(status & MDIO_STAT1_LSTATUS); | 738 | + phydev->link = !!(status & MDIO_STAT1_LSTATUS); |
739 | + | 739 | + |
740 | + return 0; | 740 | + return 0; |
741 | +} | 741 | +} |
742 | + | 742 | + |
743 | +static int as21xxx_read_c22_lpa(struct phy_device *phydev) | 743 | +static int as21xxx_read_c22_lpa(struct phy_device *phydev) |
744 | +{ | 744 | +{ |
745 | + int lpagb; | 745 | + int lpagb; |
746 | + | 746 | + |
747 | + /* MII_STAT1000 are only filled in the mapped C22 | 747 | + /* MII_STAT1000 are only filled in the mapped C22 |
748 | + * in C45, use that to fill lpagb values and check. | 748 | + * in C45, use that to fill lpagb values and check. |
749 | + */ | 749 | + */ |
750 | + lpagb = phy_read_mmd(phydev, MDIO_MMD_AN, | 750 | + lpagb = phy_read_mmd(phydev, MDIO_MMD_AN, |
751 | + AS21XXX_MDIO_AN_C22 + MII_STAT1000); | 751 | + AS21XXX_MDIO_AN_C22 + MII_STAT1000); |
752 | + if (lpagb < 0) | 752 | + if (lpagb < 0) |
753 | + return lpagb; | 753 | + return lpagb; |
754 | + | 754 | + |
755 | + if (lpagb & LPA_1000MSFAIL) { | 755 | + if (lpagb & LPA_1000MSFAIL) { |
756 | + int adv = phy_read_mmd(phydev, MDIO_MMD_AN, | 756 | + int adv = phy_read_mmd(phydev, MDIO_MMD_AN, |
757 | + AS21XXX_MDIO_AN_C22 + MII_CTRL1000); | 757 | + AS21XXX_MDIO_AN_C22 + MII_CTRL1000); |
758 | + | 758 | + |
759 | + if (adv < 0) | 759 | + if (adv < 0) |
760 | + return adv; | 760 | + return adv; |
761 | + | 761 | + |
762 | + if (adv & CTL1000_ENABLE_MASTER) | 762 | + if (adv & CTL1000_ENABLE_MASTER) |
763 | + phydev_err(phydev, "Master/Slave resolution failed, maybe conflicting manual settings?\n"); | 763 | + phydev_err(phydev, "Master/Slave resolution failed, maybe conflicting manual settings?\n"); |
764 | + else | 764 | + else |
765 | + phydev_err(phydev, "Master/Slave resolution failed\n"); | 765 | + phydev_err(phydev, "Master/Slave resolution failed\n"); |
766 | + return -ENOLINK; | 766 | + return -ENOLINK; |
767 | + } | 767 | + } |
768 | + | 768 | + |
769 | + mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, | 769 | + mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, |
770 | + lpagb); | 770 | + lpagb); |
771 | + | 771 | + |
772 | + return 0; | 772 | + return 0; |
773 | +} | 773 | +} |
774 | + | 774 | + |
775 | +static int as21xxx_read_status(struct phy_device *phydev) | 775 | +static int as21xxx_read_status(struct phy_device *phydev) |
776 | +{ | 776 | +{ |
777 | + int bmcr, old_link = phydev->link; | 777 | + int bmcr, old_link = phydev->link; |
778 | + int ret; | 778 | + int ret; |
779 | + | 779 | + |
780 | + ret = as21xxx_read_link(phydev, &bmcr); | 780 | + ret = as21xxx_read_link(phydev, &bmcr); |
781 | + if (ret) | 781 | + if (ret) |
782 | + return ret; | 782 | + return ret; |
783 | + | 783 | + |
784 | + /* why bother the PHY if nothing can have changed */ | 784 | + /* why bother the PHY if nothing can have changed */ |
785 | + if (phydev->autoneg == AUTONEG_ENABLE && old_link && phydev->link) | 785 | + if (phydev->autoneg == AUTONEG_ENABLE && old_link && phydev->link) |
786 | + return 0; | 786 | + return 0; |
787 | + | 787 | + |
788 | + phydev->speed = SPEED_UNKNOWN; | 788 | + phydev->speed = SPEED_UNKNOWN; |
789 | + phydev->duplex = DUPLEX_UNKNOWN; | 789 | + phydev->duplex = DUPLEX_UNKNOWN; |
790 | + phydev->pause = 0; | 790 | + phydev->pause = 0; |
791 | + phydev->asym_pause = 0; | 791 | + phydev->asym_pause = 0; |
792 | + | 792 | + |
793 | + if (phydev->autoneg == AUTONEG_ENABLE) { | 793 | + if (phydev->autoneg == AUTONEG_ENABLE) { |
794 | + ret = genphy_c45_read_lpa(phydev); | 794 | + ret = genphy_c45_read_lpa(phydev); |
795 | + if (ret) | 795 | + if (ret) |
796 | + return ret; | 796 | + return ret; |
797 | + | 797 | + |
798 | + ret = as21xxx_read_c22_lpa(phydev); | 798 | + ret = as21xxx_read_c22_lpa(phydev); |
799 | + if (ret) | 799 | + if (ret) |
800 | + return ret; | 800 | + return ret; |
801 | + | 801 | + |
802 | + phy_resolve_aneg_linkmode(phydev); | 802 | + phy_resolve_aneg_linkmode(phydev); |
803 | + } else { | 803 | + } else { |
804 | + int speed; | 804 | + int speed; |
805 | + | 805 | + |
806 | + linkmode_zero(phydev->lp_advertising); | 806 | + linkmode_zero(phydev->lp_advertising); |
807 | + | 807 | + |
808 | + speed = phy_read_mmd(phydev, MDIO_MMD_VEND1, | 808 | + speed = phy_read_mmd(phydev, MDIO_MMD_VEND1, |
809 | + VEND1_SPEED_STATUS); | 809 | + VEND1_SPEED_STATUS); |
810 | + if (speed < 0) | 810 | + if (speed < 0) |
811 | + return speed; | 811 | + return speed; |
812 | + | 812 | + |
813 | + switch (speed & VEND1_SPEED_STATUS) { | 813 | + switch (speed & VEND1_SPEED_STATUS) { |
814 | + case VEND1_SPEED_10000: | 814 | + case VEND1_SPEED_10000: |
815 | + phydev->speed = SPEED_10000; | 815 | + phydev->speed = SPEED_10000; |
816 | + phydev->duplex = DUPLEX_FULL; | 816 | + phydev->duplex = DUPLEX_FULL; |
817 | + break; | 817 | + break; |
818 | + case VEND1_SPEED_5000: | 818 | + case VEND1_SPEED_5000: |
819 | + phydev->speed = SPEED_5000; | 819 | + phydev->speed = SPEED_5000; |
820 | + phydev->duplex = DUPLEX_FULL; | 820 | + phydev->duplex = DUPLEX_FULL; |
821 | + break; | 821 | + break; |
822 | + case VEND1_SPEED_2500: | 822 | + case VEND1_SPEED_2500: |
823 | + phydev->speed = SPEED_2500; | 823 | + phydev->speed = SPEED_2500; |
824 | + phydev->duplex = DUPLEX_FULL; | 824 | + phydev->duplex = DUPLEX_FULL; |
825 | + break; | 825 | + break; |
826 | + case VEND1_SPEED_1000: | 826 | + case VEND1_SPEED_1000: |
827 | + phydev->speed = SPEED_1000; | 827 | + phydev->speed = SPEED_1000; |
828 | + if (bmcr & BMCR_FULLDPLX) | 828 | + if (bmcr & BMCR_FULLDPLX) |
829 | + phydev->duplex = DUPLEX_FULL; | 829 | + phydev->duplex = DUPLEX_FULL; |
830 | + else | 830 | + else |
831 | + phydev->duplex = DUPLEX_HALF; | 831 | + phydev->duplex = DUPLEX_HALF; |
832 | + break; | 832 | + break; |
833 | + case VEND1_SPEED_100: | 833 | + case VEND1_SPEED_100: |
834 | + phydev->speed = SPEED_100; | 834 | + phydev->speed = SPEED_100; |
835 | + phydev->duplex = DUPLEX_FULL; | 835 | + phydev->duplex = DUPLEX_FULL; |
836 | + break; | 836 | + break; |
837 | + case VEND1_SPEED_10: | 837 | + case VEND1_SPEED_10: |
838 | + phydev->speed = SPEED_10; | 838 | + phydev->speed = SPEED_10; |
839 | + phydev->duplex = DUPLEX_FULL; | 839 | + phydev->duplex = DUPLEX_FULL; |
840 | + break; | 840 | + break; |
841 | + default: | 841 | + default: |
842 | + return -EINVAL; | 842 | + return -EINVAL; |
843 | + } | 843 | + } |
844 | + } | 844 | + } |
845 | + | 845 | + |
846 | + return 0; | 846 | + return 0; |
847 | +} | 847 | +} |
848 | + | 848 | + |
849 | +static int as21xxx_led_brightness_set(struct phy_device *phydev, | 849 | +static int as21xxx_led_brightness_set(struct phy_device *phydev, |
850 | + u8 index, enum led_brightness value) | 850 | + u8 index, enum led_brightness value) |
851 | +{ | 851 | +{ |
852 | + u16 val = VEND1_LED_REG_A_EVENT_OFF; | 852 | + u16 val = VEND1_LED_REG_A_EVENT_OFF; |
853 | + | 853 | + |
854 | + if (index > AEON_MAX_LDES) | 854 | + if (index > AEON_MAX_LDES) |
855 | + return -EINVAL; | 855 | + return -EINVAL; |
856 | + | 856 | + |
857 | + if (value) | 857 | + if (value) |
858 | + val = VEND1_LED_REG_A_EVENT_ON; | 858 | + val = VEND1_LED_REG_A_EVENT_ON; |
859 | + | 859 | + |
860 | + return phy_modify_mmd(phydev, MDIO_MMD_VEND1, | 860 | + return phy_modify_mmd(phydev, MDIO_MMD_VEND1, |
861 | + VEND1_LED_REG(index), | 861 | + VEND1_LED_REG(index), |
862 | + VEND1_LED_REG_A_EVENT, | 862 | + VEND1_LED_REG_A_EVENT, |
863 | + FIELD_PREP(VEND1_LED_REG_A_EVENT, val)); | 863 | + FIELD_PREP(VEND1_LED_REG_A_EVENT, val)); |
864 | +} | 864 | +} |
865 | + | 865 | + |
866 | +static int as21xxx_led_hw_is_supported(struct phy_device *phydev, u8 index, | 866 | +static int as21xxx_led_hw_is_supported(struct phy_device *phydev, u8 index, |
867 | + unsigned long rules) | 867 | + unsigned long rules) |
868 | +{ | 868 | +{ |
869 | + int i; | 869 | + int i; |
870 | + | 870 | + |
871 | + if (index > AEON_MAX_LDES) | 871 | + if (index > AEON_MAX_LDES) |
872 | + return -EINVAL; | 872 | + return -EINVAL; |
873 | + | 873 | + |
874 | + for (i = 0; i < ARRAY_SIZE(as21xxx_led_supported_pattern); i++) | 874 | + for (i = 0; i < ARRAY_SIZE(as21xxx_led_supported_pattern); i++) |
875 | + if (rules == as21xxx_led_supported_pattern[i].pattern) | 875 | + if (rules == as21xxx_led_supported_pattern[i].pattern) |
876 | + return 0; | 876 | + return 0; |
877 | + | 877 | + |
878 | + return -EOPNOTSUPP; | 878 | + return -EOPNOTSUPP; |
879 | +} | 879 | +} |
880 | + | 880 | + |
881 | +static int as21xxx_led_hw_control_get(struct phy_device *phydev, u8 index, | 881 | +static int as21xxx_led_hw_control_get(struct phy_device *phydev, u8 index, |
882 | + unsigned long *rules) | 882 | + unsigned long *rules) |
883 | +{ | 883 | +{ |
884 | + int i, val; | 884 | + int i, val; |
885 | + | 885 | + |
886 | + if (index > AEON_MAX_LDES) | 886 | + if (index > AEON_MAX_LDES) |
887 | + return -EINVAL; | 887 | + return -EINVAL; |
888 | + | 888 | + |
889 | + val = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_LED_REG(index)); | 889 | + val = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_LED_REG(index)); |
890 | + if (val < 0) | 890 | + if (val < 0) |
891 | + return val; | 891 | + return val; |
892 | + | 892 | + |
893 | + val = FIELD_GET(VEND1_LED_REG_A_EVENT, val); | 893 | + val = FIELD_GET(VEND1_LED_REG_A_EVENT, val); |
894 | + for (i = 0; i < ARRAY_SIZE(as21xxx_led_supported_pattern); i++) | 894 | + for (i = 0; i < ARRAY_SIZE(as21xxx_led_supported_pattern); i++) |
895 | + if (val == as21xxx_led_supported_pattern[i].val) { | 895 | + if (val == as21xxx_led_supported_pattern[i].val) { |
896 | + *rules = as21xxx_led_supported_pattern[i].pattern; | 896 | + *rules = as21xxx_led_supported_pattern[i].pattern; |
897 | + return 0; | 897 | + return 0; |
898 | + } | 898 | + } |
899 | + | 899 | + |
900 | + /* Should be impossible */ | 900 | + /* Should be impossible */ |
901 | + return -EINVAL; | 901 | + return -EINVAL; |
902 | +} | 902 | +} |
903 | + | 903 | + |
904 | +static int as21xxx_led_hw_control_set(struct phy_device *phydev, u8 index, | 904 | +static int as21xxx_led_hw_control_set(struct phy_device *phydev, u8 index, |
905 | + unsigned long rules) | 905 | + unsigned long rules) |
906 | +{ | 906 | +{ |
907 | + u16 val = 0; | 907 | + u16 val = 0; |
908 | + int i; | 908 | + int i; |
909 | + | 909 | + |
910 | + if (index > AEON_MAX_LDES) | 910 | + if (index > AEON_MAX_LDES) |
911 | + return -EINVAL; | 911 | + return -EINVAL; |
912 | + | 912 | + |
913 | + for (i = 0; i < ARRAY_SIZE(as21xxx_led_supported_pattern); i++) | 913 | + for (i = 0; i < ARRAY_SIZE(as21xxx_led_supported_pattern); i++) |
914 | + if (rules == as21xxx_led_supported_pattern[i].pattern) { | 914 | + if (rules == as21xxx_led_supported_pattern[i].pattern) { |
915 | + val = as21xxx_led_supported_pattern[i].val; | 915 | + val = as21xxx_led_supported_pattern[i].val; |
916 | + break; | 916 | + break; |
917 | + } | 917 | + } |
918 | + | 918 | + |
919 | + return phy_modify_mmd(phydev, MDIO_MMD_VEND1, | 919 | + return phy_modify_mmd(phydev, MDIO_MMD_VEND1, |
920 | + VEND1_LED_REG(index), | 920 | + VEND1_LED_REG(index), |
921 | + VEND1_LED_REG_A_EVENT, | 921 | + VEND1_LED_REG_A_EVENT, |
922 | + FIELD_PREP(VEND1_LED_REG_A_EVENT, val)); | 922 | + FIELD_PREP(VEND1_LED_REG_A_EVENT, val)); |
923 | +} | 923 | +} |
924 | + | 924 | + |
925 | +static int as21xxx_led_polarity_set(struct phy_device *phydev, int index, | 925 | +static int as21xxx_led_polarity_set(struct phy_device *phydev, int index, |
926 | + unsigned long modes) | 926 | + unsigned long modes) |
927 | +{ | 927 | +{ |
928 | + bool led_active_low = false; | 928 | + bool led_active_low = false; |
929 | + u16 mask, val = 0; | 929 | + u16 mask, val = 0; |
930 | + u32 mode; | 930 | + u32 mode; |
931 | + | 931 | + |
932 | + if (index > AEON_MAX_LDES) | 932 | + if (index > AEON_MAX_LDES) |
933 | + return -EINVAL; | 933 | + return -EINVAL; |
934 | + | 934 | + |
935 | + for_each_set_bit(mode, &modes, __PHY_LED_MODES_NUM) { | 935 | + for_each_set_bit(mode, &modes, __PHY_LED_MODES_NUM) { |
936 | + switch (mode) { | 936 | + switch (mode) { |
937 | + case PHY_LED_ACTIVE_LOW: | 937 | + case PHY_LED_ACTIVE_LOW: |
938 | + led_active_low = true; | 938 | + led_active_low = true; |
939 | + break; | 939 | + break; |
940 | + case PHY_LED_ACTIVE_HIGH: /* default mode */ | 940 | + case PHY_LED_ACTIVE_HIGH: /* default mode */ |
941 | + led_active_low = false; | 941 | + led_active_low = false; |
942 | + break; | 942 | + break; |
943 | + default: | 943 | + default: |
944 | + return -EINVAL; | 944 | + return -EINVAL; |
945 | + } | 945 | + } |
946 | + } | 946 | + } |
947 | + | 947 | + |
948 | + mask = VEND1_GLB_CPU_CTRL_LED_POLARITY(index); | 948 | + mask = VEND1_GLB_CPU_CTRL_LED_POLARITY(index); |
949 | + if (led_active_low) | 949 | + if (led_active_low) |
950 | + val = VEND1_GLB_CPU_CTRL_LED_POLARITY(index); | 950 | + val = VEND1_GLB_CPU_CTRL_LED_POLARITY(index); |
951 | + | 951 | + |
952 | + return phy_modify_mmd(phydev, MDIO_MMD_VEND1, | 952 | + return phy_modify_mmd(phydev, MDIO_MMD_VEND1, |
953 | + VEND1_GLB_REG_CPU_CTRL, | 953 | + VEND1_GLB_REG_CPU_CTRL, |
954 | + mask, val); | 954 | + mask, val); |
955 | +} | 955 | +} |
956 | + | 956 | + |
957 | +static int as21xxx_match_phy_device(struct phy_device *phydev, | 957 | +static int as21xxx_match_phy_device(struct phy_device *phydev, |
958 | + const struct phy_driver *phydrv) | 958 | + const struct phy_driver *phydrv) |
959 | +{ | 959 | +{ |
960 | + struct as21xxx_priv *priv; | 960 | + struct as21xxx_priv *priv; |
961 | + u16 ret_sts; | 961 | + u16 ret_sts; |
962 | + u32 phy_id; | 962 | + u32 phy_id; |
963 | + int ret; | 963 | + int ret; |
964 | + | 964 | + |
965 | + /* Skip PHY that are not AS21xxx or already have firmware loaded */ | 965 | + /* Skip PHY that are not AS21xxx or already have firmware loaded */ |
966 | + if (phydev->c45_ids.device_ids[MDIO_MMD_PCS] != PHY_ID_AS21XXX) | 966 | + if (phydev->c45_ids.device_ids[MDIO_MMD_PCS] != PHY_ID_AS21XXX) |
967 | + return genphy_match_phy_device(phydev, phydrv); | 967 | + return genphy_match_phy_device(phydev, phydrv); |
968 | + | 968 | + |
969 | + /* Read PHY ID to handle firmware just loaded */ | 969 | + /* Read PHY ID to handle firmware just loaded */ |
970 | + ret = phy_read_mmd(phydev, MDIO_MMD_PCS, MII_PHYSID1); | 970 | + ret = phy_read_mmd(phydev, MDIO_MMD_PCS, MII_PHYSID1); |
971 | + if (ret < 0) | 971 | + if (ret < 0) |
972 | + return ret; | 972 | + return ret; |
973 | + phy_id = ret << 16; | 973 | + phy_id = ret << 16; |
974 | + | 974 | + |
975 | + ret = phy_read_mmd(phydev, MDIO_MMD_PCS, MII_PHYSID2); | 975 | + ret = phy_read_mmd(phydev, MDIO_MMD_PCS, MII_PHYSID2); |
976 | + if (ret < 0) | 976 | + if (ret < 0) |
977 | + return ret; | 977 | + return ret; |
978 | + phy_id |= ret; | 978 | + phy_id |= ret; |
979 | + | 979 | + |
980 | + /* With PHY ID not the generic AS21xxx one assume | 980 | + /* With PHY ID not the generic AS21xxx one assume |
981 | + * the firmware just loaded | 981 | + * the firmware just loaded |
982 | + */ | 982 | + */ |
983 | + if (phy_id != PHY_ID_AS21XXX) | 983 | + if (phy_id != PHY_ID_AS21XXX) |
984 | + return phy_id == phydrv->phy_id; | 984 | + return phy_id == phydrv->phy_id; |
985 | + | 985 | + |
986 | + /* Allocate temp priv and load the firmware */ | 986 | + /* Allocate temp priv and load the firmware */ |
987 | + priv = kzalloc(sizeof(*priv), GFP_KERNEL); | 987 | + priv = kzalloc(sizeof(*priv), GFP_KERNEL); |
988 | + if (!priv) | 988 | + if (!priv) |
989 | + return -ENOMEM; | 989 | + return -ENOMEM; |
990 | + | 990 | + |
991 | + mutex_init(&priv->ipc_lock); | 991 | + mutex_init(&priv->ipc_lock); |
992 | + | 992 | + |
993 | + ret = aeon_firmware_load(phydev); | 993 | + ret = aeon_firmware_load(phydev); |
994 | + if (ret) | 994 | + if (ret) |
995 | + goto out; | 995 | + goto out; |
996 | + | 996 | + |
997 | + /* Sync parity... */ | 997 | + /* Sync parity... */ |
998 | + ret = aeon_ipc_sync_parity(phydev, priv); | 998 | + ret = aeon_ipc_sync_parity(phydev, priv); |
999 | + if (ret) | 999 | + if (ret) |
1000 | + goto out; | 1000 | + goto out; |
1001 | + | 1001 | + |
1002 | + /* ...and send a third NOOP cmd to wait for firmware finish loading */ | 1002 | + /* ...and send a third NOOP cmd to wait for firmware finish loading */ |
1003 | + ret = aeon_ipc_noop(phydev, priv, &ret_sts); | 1003 | + ret = aeon_ipc_noop(phydev, priv, &ret_sts); |
1004 | + if (ret) | 1004 | + if (ret) |
1005 | + goto out; | 1005 | + goto out; |
1006 | + | 1006 | + |
1007 | +out: | 1007 | +out: |
1008 | + mutex_destroy(&priv->ipc_lock); | 1008 | + mutex_destroy(&priv->ipc_lock); |
1009 | + kfree(priv); | 1009 | + kfree(priv); |
1010 | + | 1010 | + |
1011 | + /* Return not maching anyway as PHY ID will change after | 1011 | + /* Return not maching anyway as PHY ID will change after |
1012 | + * firmware is loaded. This relies on the driver probe | 1012 | + * firmware is loaded. This relies on the driver probe |
1013 | + * order where the first PHY driver probed is the | 1013 | + * order where the first PHY driver probed is the |
1014 | + * generic one. | 1014 | + * generic one. |
1015 | + */ | 1015 | + */ |
1016 | + return ret; | 1016 | + return ret; |
1017 | +} | 1017 | +} |
1018 | + | 1018 | + |
1019 | +static struct phy_driver as21xxx_drivers[] = { | 1019 | +static struct phy_driver as21xxx_drivers[] = { |
1020 | + { | 1020 | + { |
1021 | + /* PHY expose in C45 as 0x7500 0x9410 | 1021 | + /* PHY expose in C45 as 0x7500 0x9410 |
1022 | + * before firmware is loaded. | 1022 | + * before firmware is loaded. |
1023 | + * This driver entry must be attempted first to load | 1023 | + * This driver entry must be attempted first to load |
1024 | + * the firmware and thus update the ID registers. | 1024 | + * the firmware and thus update the ID registers. |
1025 | + */ | 1025 | + */ |
1026 | + PHY_ID_MATCH_EXACT(PHY_ID_AS21XXX), | 1026 | + PHY_ID_MATCH_EXACT(PHY_ID_AS21XXX), |
1027 | + .name = "Aeonsemi AS21xxx", | 1027 | + .name = "Aeonsemi AS21xxx", |
1028 | + .match_phy_device = as21xxx_match_phy_device, | 1028 | + .match_phy_device = as21xxx_match_phy_device, |
1029 | + }, | 1029 | + }, |
1030 | + { | 1030 | + { |
1031 | + PHY_ID_MATCH_EXACT(PHY_ID_AS21011JB1), | 1031 | + PHY_ID_MATCH_EXACT(PHY_ID_AS21011JB1), |
1032 | + .name = "Aeonsemi AS21011JB1", | 1032 | + .name = "Aeonsemi AS21011JB1", |
1033 | + .probe = as21xxx_probe, | 1033 | + .probe = as21xxx_probe, |
1034 | + .match_phy_device = as21xxx_match_phy_device, | 1034 | + .match_phy_device = as21xxx_match_phy_device, |
1035 | + .read_status = as21xxx_read_status, | 1035 | + .read_status = as21xxx_read_status, |
1036 | + .led_brightness_set = as21xxx_led_brightness_set, | 1036 | + .led_brightness_set = as21xxx_led_brightness_set, |
1037 | + .led_hw_is_supported = as21xxx_led_hw_is_supported, | 1037 | + .led_hw_is_supported = as21xxx_led_hw_is_supported, |
1038 | + .led_hw_control_set = as21xxx_led_hw_control_set, | 1038 | + .led_hw_control_set = as21xxx_led_hw_control_set, |
1039 | + .led_hw_control_get = as21xxx_led_hw_control_get, | 1039 | + .led_hw_control_get = as21xxx_led_hw_control_get, |
1040 | + .led_polarity_set = as21xxx_led_polarity_set, | 1040 | + .led_polarity_set = as21xxx_led_polarity_set, |
1041 | + }, | 1041 | + }, |
1042 | + { | 1042 | + { |
1043 | + PHY_ID_MATCH_EXACT(PHY_ID_AS21011PB1), | 1043 | + PHY_ID_MATCH_EXACT(PHY_ID_AS21011PB1), |
1044 | + .name = "Aeonsemi AS21011PB1", | 1044 | + .name = "Aeonsemi AS21011PB1", |
1045 | + .probe = as21xxx_probe, | 1045 | + .probe = as21xxx_probe, |
1046 | + .match_phy_device = as21xxx_match_phy_device, | 1046 | + .match_phy_device = as21xxx_match_phy_device, |
1047 | + .read_status = as21xxx_read_status, | 1047 | + .read_status = as21xxx_read_status, |
1048 | + .led_brightness_set = as21xxx_led_brightness_set, | 1048 | + .led_brightness_set = as21xxx_led_brightness_set, |
1049 | + .led_hw_is_supported = as21xxx_led_hw_is_supported, | 1049 | + .led_hw_is_supported = as21xxx_led_hw_is_supported, |
1050 | + .led_hw_control_set = as21xxx_led_hw_control_set, | 1050 | + .led_hw_control_set = as21xxx_led_hw_control_set, |
1051 | + .led_hw_control_get = as21xxx_led_hw_control_get, | 1051 | + .led_hw_control_get = as21xxx_led_hw_control_get, |
1052 | + .led_polarity_set = as21xxx_led_polarity_set, | 1052 | + .led_polarity_set = as21xxx_led_polarity_set, |
1053 | + }, | 1053 | + }, |
1054 | + { | 1054 | + { |
1055 | + PHY_ID_MATCH_EXACT(PHY_ID_AS21010PB1), | 1055 | + PHY_ID_MATCH_EXACT(PHY_ID_AS21010PB1), |
1056 | + .name = "Aeonsemi AS21010PB1", | 1056 | + .name = "Aeonsemi AS21010PB1", |
1057 | + .probe = as21xxx_probe, | 1057 | + .probe = as21xxx_probe, |
1058 | + .match_phy_device = as21xxx_match_phy_device, | 1058 | + .match_phy_device = as21xxx_match_phy_device, |
1059 | + .read_status = as21xxx_read_status, | 1059 | + .read_status = as21xxx_read_status, |
1060 | + .led_brightness_set = as21xxx_led_brightness_set, | 1060 | + .led_brightness_set = as21xxx_led_brightness_set, |
1061 | + .led_hw_is_supported = as21xxx_led_hw_is_supported, | 1061 | + .led_hw_is_supported = as21xxx_led_hw_is_supported, |
1062 | + .led_hw_control_set = as21xxx_led_hw_control_set, | 1062 | + .led_hw_control_set = as21xxx_led_hw_control_set, |
1063 | + .led_hw_control_get = as21xxx_led_hw_control_get, | 1063 | + .led_hw_control_get = as21xxx_led_hw_control_get, |
1064 | + .led_polarity_set = as21xxx_led_polarity_set, | 1064 | + .led_polarity_set = as21xxx_led_polarity_set, |
1065 | + }, | 1065 | + }, |
1066 | + { | 1066 | + { |
1067 | + PHY_ID_MATCH_EXACT(PHY_ID_AS21010JB1), | 1067 | + PHY_ID_MATCH_EXACT(PHY_ID_AS21010JB1), |
1068 | + .name = "Aeonsemi AS21010JB1", | 1068 | + .name = "Aeonsemi AS21010JB1", |
1069 | + .probe = as21xxx_probe, | 1069 | + .probe = as21xxx_probe, |
1070 | + .match_phy_device = as21xxx_match_phy_device, | 1070 | + .match_phy_device = as21xxx_match_phy_device, |
1071 | + .read_status = as21xxx_read_status, | 1071 | + .read_status = as21xxx_read_status, |
1072 | + .led_brightness_set = as21xxx_led_brightness_set, | 1072 | + .led_brightness_set = as21xxx_led_brightness_set, |
1073 | + .led_hw_is_supported = as21xxx_led_hw_is_supported, | 1073 | + .led_hw_is_supported = as21xxx_led_hw_is_supported, |
1074 | + .led_hw_control_set = as21xxx_led_hw_control_set, | 1074 | + .led_hw_control_set = as21xxx_led_hw_control_set, |
1075 | + .led_hw_control_get = as21xxx_led_hw_control_get, | 1075 | + .led_hw_control_get = as21xxx_led_hw_control_get, |
1076 | + .led_polarity_set = as21xxx_led_polarity_set, | 1076 | + .led_polarity_set = as21xxx_led_polarity_set, |
1077 | + }, | 1077 | + }, |
1078 | + { | 1078 | + { |
1079 | + PHY_ID_MATCH_EXACT(PHY_ID_AS21210PB1), | 1079 | + PHY_ID_MATCH_EXACT(PHY_ID_AS21210PB1), |
1080 | + .name = "Aeonsemi AS21210PB1", | 1080 | + .name = "Aeonsemi AS21210PB1", |
1081 | + .probe = as21xxx_probe, | 1081 | + .probe = as21xxx_probe, |
1082 | + .match_phy_device = as21xxx_match_phy_device, | 1082 | + .match_phy_device = as21xxx_match_phy_device, |
1083 | + .read_status = as21xxx_read_status, | 1083 | + .read_status = as21xxx_read_status, |
1084 | + .led_brightness_set = as21xxx_led_brightness_set, | 1084 | + .led_brightness_set = as21xxx_led_brightness_set, |
1085 | + .led_hw_is_supported = as21xxx_led_hw_is_supported, | 1085 | + .led_hw_is_supported = as21xxx_led_hw_is_supported, |
1086 | + .led_hw_control_set = as21xxx_led_hw_control_set, | 1086 | + .led_hw_control_set = as21xxx_led_hw_control_set, |
1087 | + .led_hw_control_get = as21xxx_led_hw_control_get, | 1087 | + .led_hw_control_get = as21xxx_led_hw_control_get, |
1088 | + .led_polarity_set = as21xxx_led_polarity_set, | 1088 | + .led_polarity_set = as21xxx_led_polarity_set, |
1089 | + }, | 1089 | + }, |
1090 | + { | 1090 | + { |
1091 | + PHY_ID_MATCH_EXACT(PHY_ID_AS21510JB1), | 1091 | + PHY_ID_MATCH_EXACT(PHY_ID_AS21510JB1), |
1092 | + .name = "Aeonsemi AS21510JB1", | 1092 | + .name = "Aeonsemi AS21510JB1", |
1093 | + .probe = as21xxx_probe, | 1093 | + .probe = as21xxx_probe, |
1094 | + .match_phy_device = as21xxx_match_phy_device, | 1094 | + .match_phy_device = as21xxx_match_phy_device, |
1095 | + .read_status = as21xxx_read_status, | 1095 | + .read_status = as21xxx_read_status, |
1096 | + .led_brightness_set = as21xxx_led_brightness_set, | 1096 | + .led_brightness_set = as21xxx_led_brightness_set, |
1097 | + .led_hw_is_supported = as21xxx_led_hw_is_supported, | 1097 | + .led_hw_is_supported = as21xxx_led_hw_is_supported, |
1098 | + .led_hw_control_set = as21xxx_led_hw_control_set, | 1098 | + .led_hw_control_set = as21xxx_led_hw_control_set, |
1099 | + .led_hw_control_get = as21xxx_led_hw_control_get, | 1099 | + .led_hw_control_get = as21xxx_led_hw_control_get, |
1100 | + .led_polarity_set = as21xxx_led_polarity_set, | 1100 | + .led_polarity_set = as21xxx_led_polarity_set, |
1101 | + }, | 1101 | + }, |
1102 | + { | 1102 | + { |
1103 | + PHY_ID_MATCH_EXACT(PHY_ID_AS21510PB1), | 1103 | + PHY_ID_MATCH_EXACT(PHY_ID_AS21510PB1), |
1104 | + .name = "Aeonsemi AS21510PB1", | 1104 | + .name = "Aeonsemi AS21510PB1", |
1105 | + .probe = as21xxx_probe, | 1105 | + .probe = as21xxx_probe, |
1106 | + .match_phy_device = as21xxx_match_phy_device, | 1106 | + .match_phy_device = as21xxx_match_phy_device, |
1107 | + .read_status = as21xxx_read_status, | 1107 | + .read_status = as21xxx_read_status, |
1108 | + .led_brightness_set = as21xxx_led_brightness_set, | 1108 | + .led_brightness_set = as21xxx_led_brightness_set, |
1109 | + .led_hw_is_supported = as21xxx_led_hw_is_supported, | 1109 | + .led_hw_is_supported = as21xxx_led_hw_is_supported, |
1110 | + .led_hw_control_set = as21xxx_led_hw_control_set, | 1110 | + .led_hw_control_set = as21xxx_led_hw_control_set, |
1111 | + .led_hw_control_get = as21xxx_led_hw_control_get, | 1111 | + .led_hw_control_get = as21xxx_led_hw_control_get, |
1112 | + .led_polarity_set = as21xxx_led_polarity_set, | 1112 | + .led_polarity_set = as21xxx_led_polarity_set, |
1113 | + }, | 1113 | + }, |
1114 | + { | 1114 | + { |
1115 | + PHY_ID_MATCH_EXACT(PHY_ID_AS21511JB1), | 1115 | + PHY_ID_MATCH_EXACT(PHY_ID_AS21511JB1), |
1116 | + .name = "Aeonsemi AS21511JB1", | 1116 | + .name = "Aeonsemi AS21511JB1", |
1117 | + .probe = as21xxx_probe, | 1117 | + .probe = as21xxx_probe, |
1118 | + .match_phy_device = as21xxx_match_phy_device, | 1118 | + .match_phy_device = as21xxx_match_phy_device, |
1119 | + .read_status = as21xxx_read_status, | 1119 | + .read_status = as21xxx_read_status, |
1120 | + .led_brightness_set = as21xxx_led_brightness_set, | 1120 | + .led_brightness_set = as21xxx_led_brightness_set, |
1121 | + .led_hw_is_supported = as21xxx_led_hw_is_supported, | 1121 | + .led_hw_is_supported = as21xxx_led_hw_is_supported, |
1122 | + .led_hw_control_set = as21xxx_led_hw_control_set, | 1122 | + .led_hw_control_set = as21xxx_led_hw_control_set, |
1123 | + .led_hw_control_get = as21xxx_led_hw_control_get, | 1123 | + .led_hw_control_get = as21xxx_led_hw_control_get, |
1124 | + .led_polarity_set = as21xxx_led_polarity_set, | 1124 | + .led_polarity_set = as21xxx_led_polarity_set, |
1125 | + }, | 1125 | + }, |
1126 | + { | 1126 | + { |
1127 | + PHY_ID_MATCH_EXACT(PHY_ID_AS21210JB1), | 1127 | + PHY_ID_MATCH_EXACT(PHY_ID_AS21210JB1), |
1128 | + .name = "Aeonsemi AS21210JB1", | 1128 | + .name = "Aeonsemi AS21210JB1", |
1129 | + .probe = as21xxx_probe, | 1129 | + .probe = as21xxx_probe, |
1130 | + .match_phy_device = as21xxx_match_phy_device, | 1130 | + .match_phy_device = as21xxx_match_phy_device, |
1131 | + .read_status = as21xxx_read_status, | 1131 | + .read_status = as21xxx_read_status, |
1132 | + .led_brightness_set = as21xxx_led_brightness_set, | 1132 | + .led_brightness_set = as21xxx_led_brightness_set, |
1133 | + .led_hw_is_supported = as21xxx_led_hw_is_supported, | 1133 | + .led_hw_is_supported = as21xxx_led_hw_is_supported, |
1134 | + .led_hw_control_set = as21xxx_led_hw_control_set, | 1134 | + .led_hw_control_set = as21xxx_led_hw_control_set, |
1135 | + .led_hw_control_get = as21xxx_led_hw_control_get, | 1135 | + .led_hw_control_get = as21xxx_led_hw_control_get, |
1136 | + .led_polarity_set = as21xxx_led_polarity_set, | 1136 | + .led_polarity_set = as21xxx_led_polarity_set, |
1137 | + }, | 1137 | + }, |
1138 | + { | 1138 | + { |
1139 | + PHY_ID_MATCH_EXACT(PHY_ID_AS21511PB1), | 1139 | + PHY_ID_MATCH_EXACT(PHY_ID_AS21511PB1), |
1140 | + .name = "Aeonsemi AS21511PB1", | 1140 | + .name = "Aeonsemi AS21511PB1", |
1141 | + .probe = as21xxx_probe, | 1141 | + .probe = as21xxx_probe, |
1142 | + .match_phy_device = as21xxx_match_phy_device, | 1142 | + .match_phy_device = as21xxx_match_phy_device, |
1143 | + .read_status = as21xxx_read_status, | 1143 | + .read_status = as21xxx_read_status, |
1144 | + .led_brightness_set = as21xxx_led_brightness_set, | 1144 | + .led_brightness_set = as21xxx_led_brightness_set, |
1145 | + .led_hw_is_supported = as21xxx_led_hw_is_supported, | 1145 | + .led_hw_is_supported = as21xxx_led_hw_is_supported, |
1146 | + .led_hw_control_set = as21xxx_led_hw_control_set, | 1146 | + .led_hw_control_set = as21xxx_led_hw_control_set, |
1147 | + .led_hw_control_get = as21xxx_led_hw_control_get, | 1147 | + .led_hw_control_get = as21xxx_led_hw_control_get, |
1148 | + .led_polarity_set = as21xxx_led_polarity_set, | 1148 | + .led_polarity_set = as21xxx_led_polarity_set, |
1149 | + }, | 1149 | + }, |
1150 | +}; | 1150 | +}; |
1151 | +module_phy_driver(as21xxx_drivers); | 1151 | +module_phy_driver(as21xxx_drivers); |
1152 | + | 1152 | + |
1153 | +static struct mdio_device_id __maybe_unused as21xxx_tbl[] = { | 1153 | +static struct mdio_device_id __maybe_unused as21xxx_tbl[] = { |
1154 | + { PHY_ID_MATCH_VENDOR(PHY_VENDOR_AEONSEMI) }, | 1154 | + { PHY_ID_MATCH_VENDOR(PHY_VENDOR_AEONSEMI) }, |
1155 | + { } | 1155 | + { } |
1156 | +}; | 1156 | +}; |
1157 | +MODULE_DEVICE_TABLE(mdio, as21xxx_tbl); | 1157 | +MODULE_DEVICE_TABLE(mdio, as21xxx_tbl); |
1158 | + | 1158 | + |
1159 | +MODULE_DESCRIPTION("Aeonsemi AS21xxx PHY driver"); | 1159 | +MODULE_DESCRIPTION("Aeonsemi AS21xxx PHY driver"); |
1160 | +MODULE_AUTHOR("Christian Marangi <ansuelsmth@gmail.com>"); | 1160 | +MODULE_AUTHOR("Christian Marangi <ansuelsmth@gmail.com>"); |
1161 | +MODULE_LICENSE("GPL"); | 1161 | +MODULE_LICENSE("GPL"); |
1162 | -- | 1162 | -- |
1163 | 2.48.1 | 1163 | 2.48.1 |
1164 | 1164 | diff view generated by jsdifflib |
1 | Add Aeonsemi PHYs and the requirement of a firmware to correctly work. | 1 | Add Aeonsemi PHYs and the requirement of a firmware to correctly work. |
---|---|---|---|
2 | Also document the max number of LEDs supported and what PHY ID expose | 2 | Also document the max number of LEDs supported and what PHY ID expose |
3 | when no firmware is loaded. | 3 | when no firmware is loaded. |
4 | 4 | ||
5 | Supported PHYs AS21011JB1, AS21011PB1, AS21010JB1, AS21010PB1, | 5 | Supported PHYs AS21011JB1, AS21011PB1, AS21010JB1, AS21010PB1, |
6 | AS21511JB1, AS21511PB1, AS21510JB1, AS21510PB1, AS21210JB1, | 6 | AS21511JB1, AS21511PB1, AS21510JB1, AS21510PB1, AS21210JB1, |
7 | AS21210PB1 that all register with the PHY ID 0x7500 0x9410 on C45 | 7 | AS21210PB1 that all register with the PHY ID 0x7500 0x9410 on C45 |
8 | registers before the firmware is loaded. | 8 | registers before the firmware is loaded. |
9 | 9 | ||
10 | Reviewed-by: Rob Herring (Arm) <robh@kernel.org> | 10 | Reviewed-by: Rob Herring (Arm) <robh@kernel.org> |
11 | Signed-off-by: Christian Marangi <ansuelsmth@gmail.com> | 11 | Signed-off-by: Christian Marangi <ansuelsmth@gmail.com> |
12 | --- | 12 | --- |
13 | .../bindings/net/aeonsemi,as21xxx.yaml | 122 ++++++++++++++++++ | 13 | .../bindings/net/aeonsemi,as21xxx.yaml | 122 ++++++++++++++++++ |
14 | MAINTAINERS | 1 + | 14 | MAINTAINERS | 1 + |
15 | 2 files changed, 123 insertions(+) | 15 | 2 files changed, 123 insertions(+) |
16 | create mode 100644 Documentation/devicetree/bindings/net/aeonsemi,as21xxx.yaml | 16 | create mode 100644 Documentation/devicetree/bindings/net/aeonsemi,as21xxx.yaml |
17 | 17 | ||
18 | diff --git a/Documentation/devicetree/bindings/net/aeonsemi,as21xxx.yaml b/Documentation/devicetree/bindings/net/aeonsemi,as21xxx.yaml | 18 | diff --git a/Documentation/devicetree/bindings/net/aeonsemi,as21xxx.yaml b/Documentation/devicetree/bindings/net/aeonsemi,as21xxx.yaml |
19 | new file mode 100644 | 19 | new file mode 100644 |
20 | index XXXXXXX..XXXXXXX | 20 | index XXXXXXX..XXXXXXX |
21 | --- /dev/null | 21 | --- /dev/null |
22 | +++ b/Documentation/devicetree/bindings/net/aeonsemi,as21xxx.yaml | 22 | +++ b/Documentation/devicetree/bindings/net/aeonsemi,as21xxx.yaml |
23 | @@ -XXX,XX +XXX,XX @@ | 23 | @@ -XXX,XX +XXX,XX @@ |
24 | +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) | 24 | +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) |
25 | +%YAML 1.2 | 25 | +%YAML 1.2 |
26 | +--- | 26 | +--- |
27 | +$id: http://devicetree.org/schemas/net/aeonsemi,as21xxx.yaml# | 27 | +$id: http://devicetree.org/schemas/net/aeonsemi,as21xxx.yaml# |
28 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | 28 | +$schema: http://devicetree.org/meta-schemas/core.yaml# |
29 | + | 29 | + |
30 | +title: Aeonsemi AS21XXX Ethernet PHY | 30 | +title: Aeonsemi AS21XXX Ethernet PHY |
31 | + | 31 | + |
32 | +maintainers: | 32 | +maintainers: |
33 | + - Christian Marangi <ansuelsmth@gmail.com> | 33 | + - Christian Marangi <ansuelsmth@gmail.com> |
34 | + | 34 | + |
35 | +description: | | 35 | +description: | |
36 | + Aeonsemi AS21xxx Ethernet PHYs requires a firmware to be loaded to actually | 36 | + Aeonsemi AS21xxx Ethernet PHYs requires a firmware to be loaded to actually |
37 | + work. The same firmware is compatible with various PHYs of the same family. | 37 | + work. The same firmware is compatible with various PHYs of the same family. |
38 | + | 38 | + |
39 | + A PHY with not firmware loaded will be exposed on the MDIO bus with ID | 39 | + A PHY with not firmware loaded will be exposed on the MDIO bus with ID |
40 | + 0x7500 0x7500 or 0x7500 0x9410 on C45 registers. | 40 | + 0x7500 0x7500 or 0x7500 0x9410 on C45 registers. |
41 | + | 41 | + |
42 | + This can be done and is implemented by OEM in 2 different way: | 42 | + This can be done and is implemented by OEM in 2 different way: |
43 | + - Attached SPI flash directly to the PHY with the firmware. The PHY | 43 | + - Attached SPI flash directly to the PHY with the firmware. The PHY |
44 | + will self load the firmware in the presence of this configuration. | 44 | + will self load the firmware in the presence of this configuration. |
45 | + - Manually provided firmware loaded from a file in the filesystem. | 45 | + - Manually provided firmware loaded from a file in the filesystem. |
46 | + | 46 | + |
47 | + Each PHY can support up to 5 LEDs. | 47 | + Each PHY can support up to 5 LEDs. |
48 | + | 48 | + |
49 | + AS2xxx PHY Name logic: | 49 | + AS2xxx PHY Name logic: |
50 | + | 50 | + |
51 | + AS21x1xxB1 | 51 | + AS21x1xxB1 |
52 | + ^ ^^ | 52 | + ^ ^^ |
53 | + | |J: Supports SyncE/PTP | 53 | + | |J: Supports SyncE/PTP |
54 | + | |P: No SyncE/PTP support | 54 | + | |P: No SyncE/PTP support |
55 | + | 1: Supports 2nd Serdes | 55 | + | 1: Supports 2nd Serdes |
56 | + | 2: Not 2nd Serdes support | 56 | + | 2: Not 2nd Serdes support |
57 | + 0: 10G, 5G, 2.5G | 57 | + 0: 10G, 5G, 2.5G |
58 | + 5: 5G, 2.5G | 58 | + 5: 5G, 2.5G |
59 | + 2: 2.5G | 59 | + 2: 2.5G |
60 | + | 60 | + |
61 | +allOf: | 61 | +allOf: |
62 | + - $ref: ethernet-phy.yaml# | 62 | + - $ref: ethernet-phy.yaml# |
63 | + | 63 | + |
64 | +select: | 64 | +select: |
65 | + properties: | 65 | + properties: |
66 | + compatible: | 66 | + compatible: |
67 | + contains: | 67 | + contains: |
68 | + enum: | 68 | + enum: |
69 | + - ethernet-phy-id7500.9410 | 69 | + - ethernet-phy-id7500.9410 |
70 | + - ethernet-phy-id7500.9402 | 70 | + - ethernet-phy-id7500.9402 |
71 | + - ethernet-phy-id7500.9412 | 71 | + - ethernet-phy-id7500.9412 |
72 | + - ethernet-phy-id7500.9422 | 72 | + - ethernet-phy-id7500.9422 |
73 | + - ethernet-phy-id7500.9432 | 73 | + - ethernet-phy-id7500.9432 |
74 | + - ethernet-phy-id7500.9442 | 74 | + - ethernet-phy-id7500.9442 |
75 | + - ethernet-phy-id7500.9452 | 75 | + - ethernet-phy-id7500.9452 |
76 | + - ethernet-phy-id7500.9462 | 76 | + - ethernet-phy-id7500.9462 |
77 | + - ethernet-phy-id7500.9472 | 77 | + - ethernet-phy-id7500.9472 |
78 | + - ethernet-phy-id7500.9482 | 78 | + - ethernet-phy-id7500.9482 |
79 | + - ethernet-phy-id7500.9492 | 79 | + - ethernet-phy-id7500.9492 |
80 | + required: | 80 | + required: |
81 | + - compatible | 81 | + - compatible |
82 | + | 82 | + |
83 | +properties: | 83 | +properties: |
84 | + reg: | 84 | + reg: |
85 | + maxItems: 1 | 85 | + maxItems: 1 |
86 | + | 86 | + |
87 | + firmware-name: | 87 | + firmware-name: |
88 | + description: specify the name of PHY firmware to load | 88 | + description: specify the name of PHY firmware to load |
89 | + maxItems: 1 | 89 | + maxItems: 1 |
90 | + | 90 | + |
91 | +required: | 91 | +required: |
92 | + - compatible | 92 | + - compatible |
93 | + - reg | 93 | + - reg |
94 | + | 94 | + |
95 | +if: | 95 | +if: |
96 | + properties: | 96 | + properties: |
97 | + compatible: | 97 | + compatible: |
98 | + contains: | 98 | + contains: |
99 | + const: ethernet-phy-id7500.9410 | 99 | + const: ethernet-phy-id7500.9410 |
100 | +then: | 100 | +then: |
101 | + required: | 101 | + required: |
102 | + - firmware-name | 102 | + - firmware-name |
103 | +else: | 103 | +else: |
104 | + properties: | 104 | + properties: |
105 | + firmware-name: false | 105 | + firmware-name: false |
106 | + | 106 | + |
107 | +unevaluatedProperties: false | 107 | +unevaluatedProperties: false |
108 | + | 108 | + |
109 | +examples: | 109 | +examples: |
110 | + - | | 110 | + - | |
111 | + #include <dt-bindings/leds/common.h> | 111 | + #include <dt-bindings/leds/common.h> |
112 | + | 112 | + |
113 | + mdio { | 113 | + mdio { |
114 | + #address-cells = <1>; | 114 | + #address-cells = <1>; |
115 | + #size-cells = <0>; | 115 | + #size-cells = <0>; |
116 | + | 116 | + |
117 | + ethernet-phy@1f { | 117 | + ethernet-phy@1f { |
118 | + compatible = "ethernet-phy-id7500.9410", | 118 | + compatible = "ethernet-phy-id7500.9410", |
119 | + "ethernet-phy-ieee802.3-c45"; | 119 | + "ethernet-phy-ieee802.3-c45"; |
120 | + | 120 | + |
121 | + reg = <31>; | 121 | + reg = <31>; |
122 | + firmware-name = "as21x1x_fw.bin"; | 122 | + firmware-name = "as21x1x_fw.bin"; |
123 | + | 123 | + |
124 | + leds { | 124 | + leds { |
125 | + #address-cells = <1>; | 125 | + #address-cells = <1>; |
126 | + #size-cells = <0>; | 126 | + #size-cells = <0>; |
127 | + | 127 | + |
128 | + led@0 { | 128 | + led@0 { |
129 | + reg = <0>; | 129 | + reg = <0>; |
130 | + color = <LED_COLOR_ID_GREEN>; | 130 | + color = <LED_COLOR_ID_GREEN>; |
131 | + function = LED_FUNCTION_LAN; | 131 | + function = LED_FUNCTION_LAN; |
132 | + function-enumerator = <0>; | 132 | + function-enumerator = <0>; |
133 | + default-state = "keep"; | 133 | + default-state = "keep"; |
134 | + }; | 134 | + }; |
135 | + | 135 | + |
136 | + led@1 { | 136 | + led@1 { |
137 | + reg = <1>; | 137 | + reg = <1>; |
138 | + color = <LED_COLOR_ID_GREEN>; | 138 | + color = <LED_COLOR_ID_GREEN>; |
139 | + function = LED_FUNCTION_LAN; | 139 | + function = LED_FUNCTION_LAN; |
140 | + function-enumerator = <1>; | 140 | + function-enumerator = <1>; |
141 | + default-state = "keep"; | 141 | + default-state = "keep"; |
142 | + }; | 142 | + }; |
143 | + }; | 143 | + }; |
144 | + }; | 144 | + }; |
145 | + }; | 145 | + }; |
146 | diff --git a/MAINTAINERS b/MAINTAINERS | 146 | diff --git a/MAINTAINERS b/MAINTAINERS |
147 | index XXXXXXX..XXXXXXX 100644 | 147 | index XXXXXXX..XXXXXXX 100644 |
148 | --- a/MAINTAINERS | 148 | --- a/MAINTAINERS |
149 | +++ b/MAINTAINERS | 149 | +++ b/MAINTAINERS |
150 | @@ -XXX,XX +XXX,XX @@ AEONSEMI PHY DRIVER | 150 | @@ -XXX,XX +XXX,XX @@ AEONSEMI PHY DRIVER |
151 | M: Christian Marangi <ansuelsmth@gmail.com> | 151 | M: Christian Marangi <ansuelsmth@gmail.com> |
152 | L: netdev@vger.kernel.org | 152 | L: netdev@vger.kernel.org |
153 | S: Maintained | 153 | S: Maintained |
154 | +F: Documentation/devicetree/bindings/net/aeonsemi,as21xxx.yaml | 154 | +F: Documentation/devicetree/bindings/net/aeonsemi,as21xxx.yaml |
155 | F: drivers/net/phy/as21xxx.c | 155 | F: drivers/net/phy/as21xxx.c |
156 | 156 | ||
157 | AF8133J THREE-AXIS MAGNETOMETER DRIVER | 157 | AF8133J THREE-AXIS MAGNETOMETER DRIVER |
158 | -- | 158 | -- |
159 | 2.48.1 | 159 | 2.48.1 | diff view generated by jsdifflib |