diff options
author | David S. Miller <davem@davemloft.net> | 2018-02-28 11:07:12 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-02-28 11:07:12 -0500 |
commit | 2824db741b650fc22f066924a2bfa3fb47054b6d (patch) | |
tree | b16ee97e936e7db44364d28641871f31db2088ce | |
parent | 44d15d930bb8463d10b05bbed45e881e5055495a (diff) | |
parent | 3bb35261c74e394aa42d0c636d2608093a1e3309 (diff) |
Merge branch 'SFP-updates'
Russell King says:
====================
SFP updates
Included in this series are a further few updates for SFP support:
- Adding support for Fiberstore's non-standard BiDi modules operating
at 1310nm/1550nm wavelengths rather than the 1000BASE-BX standard of
1310nm/1490nm.
- Adding support for negotiating the PHY interface mode with the MAC,
so that modules supporting faster speeds and Gigabit ethernet work
with Gigabit-only MACs.
- Adding support for high power (>1W) SFP modules.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | Documentation/devicetree/bindings/net/sff,sfp.txt | 5 | ||||
-rw-r--r-- | drivers/net/phy/phylink.c | 33 | ||||
-rw-r--r-- | drivers/net/phy/sfp-bus.c | 162 | ||||
-rw-r--r-- | drivers/net/phy/sfp.c | 150 | ||||
-rw-r--r-- | include/linux/sfp.h | 18 |
5 files changed, 243 insertions, 125 deletions
diff --git a/Documentation/devicetree/bindings/net/sff,sfp.txt b/Documentation/devicetree/bindings/net/sff,sfp.txt index f1c441bedf68..929591d52ed6 100644 --- a/Documentation/devicetree/bindings/net/sff,sfp.txt +++ b/Documentation/devicetree/bindings/net/sff,sfp.txt | |||
@@ -33,6 +33,10 @@ Optional Properties: | |||
33 | Select (AKA RS1) output gpio signal (SFP+ only), low: low Tx rate, high: | 33 | Select (AKA RS1) output gpio signal (SFP+ only), low: low Tx rate, high: |
34 | high Tx rate. Must not be present for SFF modules | 34 | high Tx rate. Must not be present for SFF modules |
35 | 35 | ||
36 | - maximum-power-milliwatt : Maximum module power consumption | ||
37 | Specifies the maximum power consumption allowable by a module in the | ||
38 | slot, in milli-Watts. Presently, modules can be up to 1W, 1.5W or 2W. | ||
39 | |||
36 | Example #1: Direct serdes to SFP connection | 40 | Example #1: Direct serdes to SFP connection |
37 | 41 | ||
38 | sfp_eth3: sfp-eth3 { | 42 | sfp_eth3: sfp-eth3 { |
@@ -40,6 +44,7 @@ sfp_eth3: sfp-eth3 { | |||
40 | i2c-bus = <&sfp_1g_i2c>; | 44 | i2c-bus = <&sfp_1g_i2c>; |
41 | los-gpios = <&cpm_gpio2 22 GPIO_ACTIVE_HIGH>; | 45 | los-gpios = <&cpm_gpio2 22 GPIO_ACTIVE_HIGH>; |
42 | mod-def0-gpios = <&cpm_gpio2 21 GPIO_ACTIVE_LOW>; | 46 | mod-def0-gpios = <&cpm_gpio2 21 GPIO_ACTIVE_LOW>; |
47 | maximum-power-milliwatt = <1000>; | ||
43 | pinctrl-names = "default"; | 48 | pinctrl-names = "default"; |
44 | pinctrl-0 = <&cpm_sfp_1g_pins &cps_sfp_1g_pins>; | 49 | pinctrl-0 = <&cpm_sfp_1g_pins &cps_sfp_1g_pins>; |
45 | tx-disable-gpios = <&cps_gpio1 24 GPIO_ACTIVE_HIGH>; | 50 | tx-disable-gpios = <&cps_gpio1 24 GPIO_ACTIVE_HIGH>; |
diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c index 6ac8b29b2dc3..27327c917a59 100644 --- a/drivers/net/phy/phylink.c +++ b/drivers/net/phy/phylink.c | |||
@@ -1584,25 +1584,14 @@ static int phylink_sfp_module_insert(void *upstream, | |||
1584 | bool changed; | 1584 | bool changed; |
1585 | u8 port; | 1585 | u8 port; |
1586 | 1586 | ||
1587 | sfp_parse_support(pl->sfp_bus, id, support); | ||
1588 | port = sfp_parse_port(pl->sfp_bus, id, support); | ||
1589 | iface = sfp_parse_interface(pl->sfp_bus, id); | ||
1590 | |||
1591 | ASSERT_RTNL(); | 1587 | ASSERT_RTNL(); |
1592 | 1588 | ||
1593 | switch (iface) { | 1589 | sfp_parse_support(pl->sfp_bus, id, support); |
1594 | case PHY_INTERFACE_MODE_SGMII: | 1590 | port = sfp_parse_port(pl->sfp_bus, id, support); |
1595 | case PHY_INTERFACE_MODE_1000BASEX: | ||
1596 | case PHY_INTERFACE_MODE_2500BASEX: | ||
1597 | case PHY_INTERFACE_MODE_10GKR: | ||
1598 | break; | ||
1599 | default: | ||
1600 | return -EINVAL; | ||
1601 | } | ||
1602 | 1591 | ||
1603 | memset(&config, 0, sizeof(config)); | 1592 | memset(&config, 0, sizeof(config)); |
1604 | linkmode_copy(config.advertising, support); | 1593 | linkmode_copy(config.advertising, support); |
1605 | config.interface = iface; | 1594 | config.interface = PHY_INTERFACE_MODE_NA; |
1606 | config.speed = SPEED_UNKNOWN; | 1595 | config.speed = SPEED_UNKNOWN; |
1607 | config.duplex = DUPLEX_UNKNOWN; | 1596 | config.duplex = DUPLEX_UNKNOWN; |
1608 | config.pause = MLO_PAUSE_AN; | 1597 | config.pause = MLO_PAUSE_AN; |
@@ -1611,6 +1600,22 @@ static int phylink_sfp_module_insert(void *upstream, | |||
1611 | /* Ignore errors if we're expecting a PHY to attach later */ | 1600 | /* Ignore errors if we're expecting a PHY to attach later */ |
1612 | ret = phylink_validate(pl, support, &config); | 1601 | ret = phylink_validate(pl, support, &config); |
1613 | if (ret) { | 1602 | if (ret) { |
1603 | netdev_err(pl->netdev, "validation with support %*pb failed: %d\n", | ||
1604 | __ETHTOOL_LINK_MODE_MASK_NBITS, support, ret); | ||
1605 | return ret; | ||
1606 | } | ||
1607 | |||
1608 | iface = sfp_select_interface(pl->sfp_bus, id, config.advertising); | ||
1609 | if (iface == PHY_INTERFACE_MODE_NA) { | ||
1610 | netdev_err(pl->netdev, | ||
1611 | "selection of interface failed, advertisment %*pb\n", | ||
1612 | __ETHTOOL_LINK_MODE_MASK_NBITS, config.advertising); | ||
1613 | return -EINVAL; | ||
1614 | } | ||
1615 | |||
1616 | config.interface = iface; | ||
1617 | ret = phylink_validate(pl, support, &config); | ||
1618 | if (ret) { | ||
1614 | netdev_err(pl->netdev, "validation of %s/%s with support %*pb failed: %d\n", | 1619 | netdev_err(pl->netdev, "validation of %s/%s with support %*pb failed: %d\n", |
1615 | phylink_an_mode_str(MLO_AN_INBAND), | 1620 | phylink_an_mode_str(MLO_AN_INBAND), |
1616 | phy_modes(config.interface), | 1621 | phy_modes(config.interface), |
diff --git a/drivers/net/phy/sfp-bus.c b/drivers/net/phy/sfp-bus.c index 8961209ee949..3d4ff5d0d2a6 100644 --- a/drivers/net/phy/sfp-bus.c +++ b/drivers/net/phy/sfp-bus.c | |||
@@ -106,68 +106,6 @@ int sfp_parse_port(struct sfp_bus *bus, const struct sfp_eeprom_id *id, | |||
106 | EXPORT_SYMBOL_GPL(sfp_parse_port); | 106 | EXPORT_SYMBOL_GPL(sfp_parse_port); |
107 | 107 | ||
108 | /** | 108 | /** |
109 | * sfp_parse_interface() - Parse the phy_interface_t | ||
110 | * @bus: a pointer to the &struct sfp_bus structure for the sfp module | ||
111 | * @id: a pointer to the module's &struct sfp_eeprom_id | ||
112 | * | ||
113 | * Derive the phy_interface_t mode for the information found in the | ||
114 | * module's identifying EEPROM. There is no standard or defined way | ||
115 | * to derive this information, so we use some heuristics. | ||
116 | * | ||
117 | * If the encoding is 64b66b, then the module must be >= 10G, so | ||
118 | * return %PHY_INTERFACE_MODE_10GKR. | ||
119 | * | ||
120 | * If it's 8b10b, then it's 1G or slower. If it's definitely a fibre | ||
121 | * module, return %PHY_INTERFACE_MODE_1000BASEX mode, otherwise return | ||
122 | * %PHY_INTERFACE_MODE_SGMII mode. | ||
123 | * | ||
124 | * If the encoding is not known, return %PHY_INTERFACE_MODE_NA. | ||
125 | */ | ||
126 | phy_interface_t sfp_parse_interface(struct sfp_bus *bus, | ||
127 | const struct sfp_eeprom_id *id) | ||
128 | { | ||
129 | phy_interface_t iface; | ||
130 | |||
131 | /* Setting the serdes link mode is guesswork: there's no field in | ||
132 | * the EEPROM which indicates what mode should be used. | ||
133 | * | ||
134 | * If the module wants 64b66b, then it must be >= 10G. | ||
135 | * | ||
136 | * If it's a gigabit-only fiber module, it probably does not have | ||
137 | * a PHY, so switch to 802.3z negotiation mode. Otherwise, switch | ||
138 | * to SGMII mode (which is required to support non-gigabit speeds). | ||
139 | */ | ||
140 | switch (id->base.encoding) { | ||
141 | case SFP_ENCODING_8472_64B66B: | ||
142 | iface = PHY_INTERFACE_MODE_10GKR; | ||
143 | break; | ||
144 | |||
145 | case SFP_ENCODING_8B10B: | ||
146 | if (!id->base.e1000_base_t && | ||
147 | !id->base.e100_base_lx && | ||
148 | !id->base.e100_base_fx) | ||
149 | iface = PHY_INTERFACE_MODE_1000BASEX; | ||
150 | else | ||
151 | iface = PHY_INTERFACE_MODE_SGMII; | ||
152 | break; | ||
153 | |||
154 | default: | ||
155 | if (id->base.e1000_base_cx) { | ||
156 | iface = PHY_INTERFACE_MODE_1000BASEX; | ||
157 | break; | ||
158 | } | ||
159 | |||
160 | iface = PHY_INTERFACE_MODE_NA; | ||
161 | dev_err(bus->sfp_dev, | ||
162 | "SFP module encoding does not support 8b10b nor 64b66b\n"); | ||
163 | break; | ||
164 | } | ||
165 | |||
166 | return iface; | ||
167 | } | ||
168 | EXPORT_SYMBOL_GPL(sfp_parse_interface); | ||
169 | |||
170 | /** | ||
171 | * sfp_parse_support() - Parse the eeprom id for supported link modes | 109 | * sfp_parse_support() - Parse the eeprom id for supported link modes |
172 | * @bus: a pointer to the &struct sfp_bus structure for the sfp module | 110 | * @bus: a pointer to the &struct sfp_bus structure for the sfp module |
173 | * @id: a pointer to the module's &struct sfp_eeprom_id | 111 | * @id: a pointer to the module's &struct sfp_eeprom_id |
@@ -180,10 +118,7 @@ void sfp_parse_support(struct sfp_bus *bus, const struct sfp_eeprom_id *id, | |||
180 | unsigned long *support) | 118 | unsigned long *support) |
181 | { | 119 | { |
182 | unsigned int br_min, br_nom, br_max; | 120 | unsigned int br_min, br_nom, br_max; |
183 | 121 | __ETHTOOL_DECLARE_LINK_MODE_MASK(modes) = { 0, }; | |
184 | phylink_set(support, Autoneg); | ||
185 | phylink_set(support, Pause); | ||
186 | phylink_set(support, Asym_Pause); | ||
187 | 122 | ||
188 | /* Decode the bitrate information to MBd */ | 123 | /* Decode the bitrate information to MBd */ |
189 | br_min = br_nom = br_max = 0; | 124 | br_min = br_nom = br_max = 0; |
@@ -201,20 +136,20 @@ void sfp_parse_support(struct sfp_bus *bus, const struct sfp_eeprom_id *id, | |||
201 | 136 | ||
202 | /* Set ethtool support from the compliance fields. */ | 137 | /* Set ethtool support from the compliance fields. */ |
203 | if (id->base.e10g_base_sr) | 138 | if (id->base.e10g_base_sr) |
204 | phylink_set(support, 10000baseSR_Full); | 139 | phylink_set(modes, 10000baseSR_Full); |
205 | if (id->base.e10g_base_lr) | 140 | if (id->base.e10g_base_lr) |
206 | phylink_set(support, 10000baseLR_Full); | 141 | phylink_set(modes, 10000baseLR_Full); |
207 | if (id->base.e10g_base_lrm) | 142 | if (id->base.e10g_base_lrm) |
208 | phylink_set(support, 10000baseLRM_Full); | 143 | phylink_set(modes, 10000baseLRM_Full); |
209 | if (id->base.e10g_base_er) | 144 | if (id->base.e10g_base_er) |
210 | phylink_set(support, 10000baseER_Full); | 145 | phylink_set(modes, 10000baseER_Full); |
211 | if (id->base.e1000_base_sx || | 146 | if (id->base.e1000_base_sx || |
212 | id->base.e1000_base_lx || | 147 | id->base.e1000_base_lx || |
213 | id->base.e1000_base_cx) | 148 | id->base.e1000_base_cx) |
214 | phylink_set(support, 1000baseX_Full); | 149 | phylink_set(modes, 1000baseX_Full); |
215 | if (id->base.e1000_base_t) { | 150 | if (id->base.e1000_base_t) { |
216 | phylink_set(support, 1000baseT_Half); | 151 | phylink_set(modes, 1000baseT_Half); |
217 | phylink_set(support, 1000baseT_Full); | 152 | phylink_set(modes, 1000baseT_Full); |
218 | } | 153 | } |
219 | 154 | ||
220 | /* 1000Base-PX or 1000Base-BX10 */ | 155 | /* 1000Base-PX or 1000Base-BX10 */ |
@@ -228,20 +163,20 @@ void sfp_parse_support(struct sfp_bus *bus, const struct sfp_eeprom_id *id, | |||
228 | if ((id->base.sfp_ct_passive || id->base.sfp_ct_active) && br_nom) { | 163 | if ((id->base.sfp_ct_passive || id->base.sfp_ct_active) && br_nom) { |
229 | /* This may look odd, but some manufacturers use 12000MBd */ | 164 | /* This may look odd, but some manufacturers use 12000MBd */ |
230 | if (br_min <= 12000 && br_max >= 10300) | 165 | if (br_min <= 12000 && br_max >= 10300) |
231 | phylink_set(support, 10000baseCR_Full); | 166 | phylink_set(modes, 10000baseCR_Full); |
232 | if (br_min <= 3200 && br_max >= 3100) | 167 | if (br_min <= 3200 && br_max >= 3100) |
233 | phylink_set(support, 2500baseX_Full); | 168 | phylink_set(modes, 2500baseX_Full); |
234 | if (br_min <= 1300 && br_max >= 1200) | 169 | if (br_min <= 1300 && br_max >= 1200) |
235 | phylink_set(support, 1000baseX_Full); | 170 | phylink_set(modes, 1000baseX_Full); |
236 | } | 171 | } |
237 | if (id->base.sfp_ct_passive) { | 172 | if (id->base.sfp_ct_passive) { |
238 | if (id->base.passive.sff8431_app_e) | 173 | if (id->base.passive.sff8431_app_e) |
239 | phylink_set(support, 10000baseCR_Full); | 174 | phylink_set(modes, 10000baseCR_Full); |
240 | } | 175 | } |
241 | if (id->base.sfp_ct_active) { | 176 | if (id->base.sfp_ct_active) { |
242 | if (id->base.active.sff8431_app_e || | 177 | if (id->base.active.sff8431_app_e || |
243 | id->base.active.sff8431_lim) { | 178 | id->base.active.sff8431_lim) { |
244 | phylink_set(support, 10000baseCR_Full); | 179 | phylink_set(modes, 10000baseCR_Full); |
245 | } | 180 | } |
246 | } | 181 | } |
247 | 182 | ||
@@ -249,18 +184,18 @@ void sfp_parse_support(struct sfp_bus *bus, const struct sfp_eeprom_id *id, | |||
249 | case 0x00: /* Unspecified */ | 184 | case 0x00: /* Unspecified */ |
250 | break; | 185 | break; |
251 | case 0x02: /* 100Gbase-SR4 or 25Gbase-SR */ | 186 | case 0x02: /* 100Gbase-SR4 or 25Gbase-SR */ |
252 | phylink_set(support, 100000baseSR4_Full); | 187 | phylink_set(modes, 100000baseSR4_Full); |
253 | phylink_set(support, 25000baseSR_Full); | 188 | phylink_set(modes, 25000baseSR_Full); |
254 | break; | 189 | break; |
255 | case 0x03: /* 100Gbase-LR4 or 25Gbase-LR */ | 190 | case 0x03: /* 100Gbase-LR4 or 25Gbase-LR */ |
256 | case 0x04: /* 100Gbase-ER4 or 25Gbase-ER */ | 191 | case 0x04: /* 100Gbase-ER4 or 25Gbase-ER */ |
257 | phylink_set(support, 100000baseLR4_ER4_Full); | 192 | phylink_set(modes, 100000baseLR4_ER4_Full); |
258 | break; | 193 | break; |
259 | case 0x0b: /* 100Gbase-CR4 or 25Gbase-CR CA-L */ | 194 | case 0x0b: /* 100Gbase-CR4 or 25Gbase-CR CA-L */ |
260 | case 0x0c: /* 25Gbase-CR CA-S */ | 195 | case 0x0c: /* 25Gbase-CR CA-S */ |
261 | case 0x0d: /* 25Gbase-CR CA-N */ | 196 | case 0x0d: /* 25Gbase-CR CA-N */ |
262 | phylink_set(support, 100000baseCR4_Full); | 197 | phylink_set(modes, 100000baseCR4_Full); |
263 | phylink_set(support, 25000baseCR_Full); | 198 | phylink_set(modes, 25000baseCR_Full); |
264 | break; | 199 | break; |
265 | default: | 200 | default: |
266 | dev_warn(bus->sfp_dev, | 201 | dev_warn(bus->sfp_dev, |
@@ -274,13 +209,70 @@ void sfp_parse_support(struct sfp_bus *bus, const struct sfp_eeprom_id *id, | |||
274 | id->base.fc_speed_200 || | 209 | id->base.fc_speed_200 || |
275 | id->base.fc_speed_400) { | 210 | id->base.fc_speed_400) { |
276 | if (id->base.br_nominal >= 31) | 211 | if (id->base.br_nominal >= 31) |
277 | phylink_set(support, 2500baseX_Full); | 212 | phylink_set(modes, 2500baseX_Full); |
278 | if (id->base.br_nominal >= 12) | 213 | if (id->base.br_nominal >= 12) |
279 | phylink_set(support, 1000baseX_Full); | 214 | phylink_set(modes, 1000baseX_Full); |
280 | } | 215 | } |
216 | |||
217 | /* If we haven't discovered any modes that this module supports, try | ||
218 | * the encoding and bitrate to determine supported modes. Some BiDi | ||
219 | * modules (eg, 1310nm/1550nm) are not 1000BASE-BX compliant due to | ||
220 | * the differing wavelengths, so do not set any transceiver bits. | ||
221 | */ | ||
222 | if (bitmap_empty(modes, __ETHTOOL_LINK_MODE_MASK_NBITS)) { | ||
223 | /* If the encoding and bit rate allows 1000baseX */ | ||
224 | if (id->base.encoding == SFP_ENCODING_8B10B && br_nom && | ||
225 | br_min <= 1300 && br_max >= 1200) | ||
226 | phylink_set(modes, 1000baseX_Full); | ||
227 | } | ||
228 | |||
229 | bitmap_or(support, support, modes, __ETHTOOL_LINK_MODE_MASK_NBITS); | ||
230 | |||
231 | phylink_set(support, Autoneg); | ||
232 | phylink_set(support, Pause); | ||
233 | phylink_set(support, Asym_Pause); | ||
281 | } | 234 | } |
282 | EXPORT_SYMBOL_GPL(sfp_parse_support); | 235 | EXPORT_SYMBOL_GPL(sfp_parse_support); |
283 | 236 | ||
237 | /** | ||
238 | * sfp_select_interface() - Select appropriate phy_interface_t mode | ||
239 | * @bus: a pointer to the &struct sfp_bus structure for the sfp module | ||
240 | * @id: a pointer to the module's &struct sfp_eeprom_id | ||
241 | * @link_modes: ethtool link modes mask | ||
242 | * | ||
243 | * Derive the phy_interface_t mode for the information found in the | ||
244 | * module's identifying EEPROM and the link modes mask. There is no | ||
245 | * standard or defined way to derive this information, so we decide | ||
246 | * based upon the link mode mask. | ||
247 | */ | ||
248 | phy_interface_t sfp_select_interface(struct sfp_bus *bus, | ||
249 | const struct sfp_eeprom_id *id, | ||
250 | unsigned long *link_modes) | ||
251 | { | ||
252 | if (phylink_test(link_modes, 10000baseCR_Full) || | ||
253 | phylink_test(link_modes, 10000baseSR_Full) || | ||
254 | phylink_test(link_modes, 10000baseLR_Full) || | ||
255 | phylink_test(link_modes, 10000baseLRM_Full) || | ||
256 | phylink_test(link_modes, 10000baseER_Full)) | ||
257 | return PHY_INTERFACE_MODE_10GKR; | ||
258 | |||
259 | if (phylink_test(link_modes, 2500baseX_Full)) | ||
260 | return PHY_INTERFACE_MODE_2500BASEX; | ||
261 | |||
262 | if (id->base.e1000_base_t || | ||
263 | id->base.e100_base_lx || | ||
264 | id->base.e100_base_fx) | ||
265 | return PHY_INTERFACE_MODE_SGMII; | ||
266 | |||
267 | if (phylink_test(link_modes, 1000baseX_Full)) | ||
268 | return PHY_INTERFACE_MODE_1000BASEX; | ||
269 | |||
270 | dev_warn(bus->sfp_dev, "Unable to ascertain link mode\n"); | ||
271 | |||
272 | return PHY_INTERFACE_MODE_NA; | ||
273 | } | ||
274 | EXPORT_SYMBOL_GPL(sfp_select_interface); | ||
275 | |||
284 | static LIST_HEAD(sfp_buses); | 276 | static LIST_HEAD(sfp_buses); |
285 | static DEFINE_MUTEX(sfp_mutex); | 277 | static DEFINE_MUTEX(sfp_mutex); |
286 | 278 | ||
diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c index 6c7d9289078d..83bf4959b043 100644 --- a/drivers/net/phy/sfp.c +++ b/drivers/net/phy/sfp.c | |||
@@ -42,6 +42,7 @@ enum { | |||
42 | 42 | ||
43 | SFP_MOD_EMPTY = 0, | 43 | SFP_MOD_EMPTY = 0, |
44 | SFP_MOD_PROBE, | 44 | SFP_MOD_PROBE, |
45 | SFP_MOD_HPOWER, | ||
45 | SFP_MOD_PRESENT, | 46 | SFP_MOD_PRESENT, |
46 | SFP_MOD_ERROR, | 47 | SFP_MOD_ERROR, |
47 | 48 | ||
@@ -86,6 +87,7 @@ static const enum gpiod_flags gpio_flags[] = { | |||
86 | * access the I2C EEPROM. However, Avago modules require 300ms. | 87 | * access the I2C EEPROM. However, Avago modules require 300ms. |
87 | */ | 88 | */ |
88 | #define T_PROBE_INIT msecs_to_jiffies(300) | 89 | #define T_PROBE_INIT msecs_to_jiffies(300) |
90 | #define T_HPOWER_LEVEL msecs_to_jiffies(300) | ||
89 | #define T_PROBE_RETRY msecs_to_jiffies(100) | 91 | #define T_PROBE_RETRY msecs_to_jiffies(100) |
90 | 92 | ||
91 | /* SFP modules appear to always have their PHY configured for bus address | 93 | /* SFP modules appear to always have their PHY configured for bus address |
@@ -110,10 +112,12 @@ struct sfp { | |||
110 | struct sfp_bus *sfp_bus; | 112 | struct sfp_bus *sfp_bus; |
111 | struct phy_device *mod_phy; | 113 | struct phy_device *mod_phy; |
112 | const struct sff_data *type; | 114 | const struct sff_data *type; |
115 | u32 max_power_mW; | ||
113 | 116 | ||
114 | unsigned int (*get_state)(struct sfp *); | 117 | unsigned int (*get_state)(struct sfp *); |
115 | void (*set_state)(struct sfp *, unsigned int); | 118 | void (*set_state)(struct sfp *, unsigned int); |
116 | int (*read)(struct sfp *, bool, u8, void *, size_t); | 119 | int (*read)(struct sfp *, bool, u8, void *, size_t); |
120 | int (*write)(struct sfp *, bool, u8, void *, size_t); | ||
117 | 121 | ||
118 | struct gpio_desc *gpio[GPIO_MAX]; | 122 | struct gpio_desc *gpio[GPIO_MAX]; |
119 | 123 | ||
@@ -201,10 +205,11 @@ static void sfp_gpio_set_state(struct sfp *sfp, unsigned int state) | |||
201 | } | 205 | } |
202 | } | 206 | } |
203 | 207 | ||
204 | static int sfp__i2c_read(struct i2c_adapter *i2c, u8 bus_addr, u8 dev_addr, | 208 | static int sfp_i2c_read(struct sfp *sfp, bool a2, u8 dev_addr, void *buf, |
205 | void *buf, size_t len) | 209 | size_t len) |
206 | { | 210 | { |
207 | struct i2c_msg msgs[2]; | 211 | struct i2c_msg msgs[2]; |
212 | u8 bus_addr = a2 ? 0x51 : 0x50; | ||
208 | int ret; | 213 | int ret; |
209 | 214 | ||
210 | msgs[0].addr = bus_addr; | 215 | msgs[0].addr = bus_addr; |
@@ -216,17 +221,38 @@ static int sfp__i2c_read(struct i2c_adapter *i2c, u8 bus_addr, u8 dev_addr, | |||
216 | msgs[1].len = len; | 221 | msgs[1].len = len; |
217 | msgs[1].buf = buf; | 222 | msgs[1].buf = buf; |
218 | 223 | ||
219 | ret = i2c_transfer(i2c, msgs, ARRAY_SIZE(msgs)); | 224 | ret = i2c_transfer(sfp->i2c, msgs, ARRAY_SIZE(msgs)); |
220 | if (ret < 0) | 225 | if (ret < 0) |
221 | return ret; | 226 | return ret; |
222 | 227 | ||
223 | return ret == ARRAY_SIZE(msgs) ? len : 0; | 228 | return ret == ARRAY_SIZE(msgs) ? len : 0; |
224 | } | 229 | } |
225 | 230 | ||
226 | static int sfp_i2c_read(struct sfp *sfp, bool a2, u8 addr, void *buf, | 231 | static int sfp_i2c_write(struct sfp *sfp, bool a2, u8 dev_addr, void *buf, |
227 | size_t len) | 232 | size_t len) |
228 | { | 233 | { |
229 | return sfp__i2c_read(sfp->i2c, a2 ? 0x51 : 0x50, addr, buf, len); | 234 | struct i2c_msg msgs[1]; |
235 | u8 bus_addr = a2 ? 0x51 : 0x50; | ||
236 | int ret; | ||
237 | |||
238 | msgs[0].addr = bus_addr; | ||
239 | msgs[0].flags = 0; | ||
240 | msgs[0].len = 1 + len; | ||
241 | msgs[0].buf = kmalloc(1 + len, GFP_KERNEL); | ||
242 | if (!msgs[0].buf) | ||
243 | return -ENOMEM; | ||
244 | |||
245 | msgs[0].buf[0] = dev_addr; | ||
246 | memcpy(&msgs[0].buf[1], buf, len); | ||
247 | |||
248 | ret = i2c_transfer(sfp->i2c, msgs, ARRAY_SIZE(msgs)); | ||
249 | |||
250 | kfree(msgs[0].buf); | ||
251 | |||
252 | if (ret < 0) | ||
253 | return ret; | ||
254 | |||
255 | return ret == ARRAY_SIZE(msgs) ? len : 0; | ||
230 | } | 256 | } |
231 | 257 | ||
232 | static int sfp_i2c_configure(struct sfp *sfp, struct i2c_adapter *i2c) | 258 | static int sfp_i2c_configure(struct sfp *sfp, struct i2c_adapter *i2c) |
@@ -239,6 +265,7 @@ static int sfp_i2c_configure(struct sfp *sfp, struct i2c_adapter *i2c) | |||
239 | 265 | ||
240 | sfp->i2c = i2c; | 266 | sfp->i2c = i2c; |
241 | sfp->read = sfp_i2c_read; | 267 | sfp->read = sfp_i2c_read; |
268 | sfp->write = sfp_i2c_write; | ||
242 | 269 | ||
243 | i2c_mii = mdio_i2c_alloc(sfp->dev, i2c); | 270 | i2c_mii = mdio_i2c_alloc(sfp->dev, i2c); |
244 | if (IS_ERR(i2c_mii)) | 271 | if (IS_ERR(i2c_mii)) |
@@ -274,6 +301,11 @@ static int sfp_read(struct sfp *sfp, bool a2, u8 addr, void *buf, size_t len) | |||
274 | return sfp->read(sfp, a2, addr, buf, len); | 301 | return sfp->read(sfp, a2, addr, buf, len); |
275 | } | 302 | } |
276 | 303 | ||
304 | static int sfp_write(struct sfp *sfp, bool a2, u8 addr, void *buf, size_t len) | ||
305 | { | ||
306 | return sfp->write(sfp, a2, addr, buf, len); | ||
307 | } | ||
308 | |||
277 | static unsigned int sfp_check(void *buf, size_t len) | 309 | static unsigned int sfp_check(void *buf, size_t len) |
278 | { | 310 | { |
279 | u8 *p, check; | 311 | u8 *p, check; |
@@ -462,21 +494,83 @@ static void sfp_sm_mod_init(struct sfp *sfp) | |||
462 | sfp_sm_probe_phy(sfp); | 494 | sfp_sm_probe_phy(sfp); |
463 | } | 495 | } |
464 | 496 | ||
497 | static int sfp_sm_mod_hpower(struct sfp *sfp) | ||
498 | { | ||
499 | u32 power; | ||
500 | u8 val; | ||
501 | int err; | ||
502 | |||
503 | power = 1000; | ||
504 | if (sfp->id.ext.options & cpu_to_be16(SFP_OPTIONS_POWER_DECL)) | ||
505 | power = 1500; | ||
506 | if (sfp->id.ext.options & cpu_to_be16(SFP_OPTIONS_HIGH_POWER_LEVEL)) | ||
507 | power = 2000; | ||
508 | |||
509 | if (sfp->id.ext.sff8472_compliance == SFP_SFF8472_COMPLIANCE_NONE && | ||
510 | (sfp->id.ext.diagmon & (SFP_DIAGMON_DDM | SFP_DIAGMON_ADDRMODE)) != | ||
511 | SFP_DIAGMON_DDM) { | ||
512 | /* The module appears not to implement bus address 0xa2, | ||
513 | * or requires an address change sequence, so assume that | ||
514 | * the module powers up in the indicated power mode. | ||
515 | */ | ||
516 | if (power > sfp->max_power_mW) { | ||
517 | dev_err(sfp->dev, | ||
518 | "Host does not support %u.%uW modules\n", | ||
519 | power / 1000, (power / 100) % 10); | ||
520 | return -EINVAL; | ||
521 | } | ||
522 | return 0; | ||
523 | } | ||
524 | |||
525 | if (power > sfp->max_power_mW) { | ||
526 | dev_warn(sfp->dev, | ||
527 | "Host does not support %u.%uW modules, module left in power mode 1\n", | ||
528 | power / 1000, (power / 100) % 10); | ||
529 | return 0; | ||
530 | } | ||
531 | |||
532 | if (power <= 1000) | ||
533 | return 0; | ||
534 | |||
535 | err = sfp_read(sfp, true, SFP_EXT_STATUS, &val, sizeof(val)); | ||
536 | if (err != sizeof(val)) { | ||
537 | dev_err(sfp->dev, "Failed to read EEPROM: %d\n", err); | ||
538 | err = -EAGAIN; | ||
539 | goto err; | ||
540 | } | ||
541 | |||
542 | val |= BIT(0); | ||
543 | |||
544 | err = sfp_write(sfp, true, SFP_EXT_STATUS, &val, sizeof(val)); | ||
545 | if (err != sizeof(val)) { | ||
546 | dev_err(sfp->dev, "Failed to write EEPROM: %d\n", err); | ||
547 | err = -EAGAIN; | ||
548 | goto err; | ||
549 | } | ||
550 | |||
551 | dev_info(sfp->dev, "Module switched to %u.%uW power level\n", | ||
552 | power / 1000, (power / 100) % 10); | ||
553 | return T_HPOWER_LEVEL; | ||
554 | |||
555 | err: | ||
556 | return err; | ||
557 | } | ||
558 | |||
465 | static int sfp_sm_mod_probe(struct sfp *sfp) | 559 | static int sfp_sm_mod_probe(struct sfp *sfp) |
466 | { | 560 | { |
467 | /* SFP module inserted - read I2C data */ | 561 | /* SFP module inserted - read I2C data */ |
468 | struct sfp_eeprom_id id; | 562 | struct sfp_eeprom_id id; |
469 | u8 check; | 563 | u8 check; |
470 | int err; | 564 | int ret; |
471 | 565 | ||
472 | err = sfp_read(sfp, false, 0, &id, sizeof(id)); | 566 | ret = sfp_read(sfp, false, 0, &id, sizeof(id)); |
473 | if (err < 0) { | 567 | if (ret < 0) { |
474 | dev_err(sfp->dev, "failed to read EEPROM: %d\n", err); | 568 | dev_err(sfp->dev, "failed to read EEPROM: %d\n", ret); |
475 | return -EAGAIN; | 569 | return -EAGAIN; |
476 | } | 570 | } |
477 | 571 | ||
478 | if (err != sizeof(id)) { | 572 | if (ret != sizeof(id)) { |
479 | dev_err(sfp->dev, "EEPROM short read: %d\n", err); | 573 | dev_err(sfp->dev, "EEPROM short read: %d\n", ret); |
480 | return -EAGAIN; | 574 | return -EAGAIN; |
481 | } | 575 | } |
482 | 576 | ||
@@ -521,7 +615,11 @@ static int sfp_sm_mod_probe(struct sfp *sfp) | |||
521 | dev_warn(sfp->dev, | 615 | dev_warn(sfp->dev, |
522 | "module address swap to access page 0xA2 is not supported.\n"); | 616 | "module address swap to access page 0xA2 is not supported.\n"); |
523 | 617 | ||
524 | return sfp_module_insert(sfp->sfp_bus, &sfp->id); | 618 | ret = sfp_module_insert(sfp->sfp_bus, &sfp->id); |
619 | if (ret < 0) | ||
620 | return ret; | ||
621 | |||
622 | return sfp_sm_mod_hpower(sfp); | ||
525 | } | 623 | } |
526 | 624 | ||
527 | static void sfp_sm_mod_remove(struct sfp *sfp) | 625 | static void sfp_sm_mod_remove(struct sfp *sfp) |
@@ -560,17 +658,25 @@ static void sfp_sm_event(struct sfp *sfp, unsigned int event) | |||
560 | if (event == SFP_E_REMOVE) { | 658 | if (event == SFP_E_REMOVE) { |
561 | sfp_sm_ins_next(sfp, SFP_MOD_EMPTY, 0); | 659 | sfp_sm_ins_next(sfp, SFP_MOD_EMPTY, 0); |
562 | } else if (event == SFP_E_TIMEOUT) { | 660 | } else if (event == SFP_E_TIMEOUT) { |
563 | int err = sfp_sm_mod_probe(sfp); | 661 | int val = sfp_sm_mod_probe(sfp); |
564 | 662 | ||
565 | if (err == 0) | 663 | if (val == 0) |
566 | sfp_sm_ins_next(sfp, SFP_MOD_PRESENT, 0); | 664 | sfp_sm_ins_next(sfp, SFP_MOD_PRESENT, 0); |
567 | else if (err == -EAGAIN) | 665 | else if (val > 0) |
568 | sfp_sm_set_timer(sfp, T_PROBE_RETRY); | 666 | sfp_sm_ins_next(sfp, SFP_MOD_HPOWER, val); |
569 | else | 667 | else if (val != -EAGAIN) |
570 | sfp_sm_ins_next(sfp, SFP_MOD_ERROR, 0); | 668 | sfp_sm_ins_next(sfp, SFP_MOD_ERROR, 0); |
669 | else | ||
670 | sfp_sm_set_timer(sfp, T_PROBE_RETRY); | ||
571 | } | 671 | } |
572 | break; | 672 | break; |
573 | 673 | ||
674 | case SFP_MOD_HPOWER: | ||
675 | if (event == SFP_E_TIMEOUT) { | ||
676 | sfp_sm_ins_next(sfp, SFP_MOD_PRESENT, 0); | ||
677 | break; | ||
678 | } | ||
679 | /* fallthrough */ | ||
574 | case SFP_MOD_PRESENT: | 680 | case SFP_MOD_PRESENT: |
575 | case SFP_MOD_ERROR: | 681 | case SFP_MOD_ERROR: |
576 | if (event == SFP_E_REMOVE) { | 682 | if (event == SFP_E_REMOVE) { |
@@ -889,6 +995,14 @@ static int sfp_probe(struct platform_device *pdev) | |||
889 | if (!(sfp->gpio[GPIO_MODDEF0])) | 995 | if (!(sfp->gpio[GPIO_MODDEF0])) |
890 | sfp->get_state = sff_gpio_get_state; | 996 | sfp->get_state = sff_gpio_get_state; |
891 | 997 | ||
998 | device_property_read_u32(&pdev->dev, "maximum-power-milliwatt", | ||
999 | &sfp->max_power_mW); | ||
1000 | if (!sfp->max_power_mW) | ||
1001 | sfp->max_power_mW = 1000; | ||
1002 | |||
1003 | dev_info(sfp->dev, "Host maximum power %u.%uW\n", | ||
1004 | sfp->max_power_mW / 1000, (sfp->max_power_mW / 100) % 10); | ||
1005 | |||
892 | sfp->sfp_bus = sfp_register_socket(sfp->dev, sfp, &sfp_module_ops); | 1006 | sfp->sfp_bus = sfp_register_socket(sfp->dev, sfp, &sfp_module_ops); |
893 | if (!sfp->sfp_bus) | 1007 | if (!sfp->sfp_bus) |
894 | return -ENOMEM; | 1008 | return -ENOMEM; |
diff --git a/include/linux/sfp.h b/include/linux/sfp.h index e724d5a3dd80..ebce9e24906a 100644 --- a/include/linux/sfp.h +++ b/include/linux/sfp.h | |||
@@ -422,10 +422,11 @@ struct sfp_upstream_ops { | |||
422 | #if IS_ENABLED(CONFIG_SFP) | 422 | #if IS_ENABLED(CONFIG_SFP) |
423 | int sfp_parse_port(struct sfp_bus *bus, const struct sfp_eeprom_id *id, | 423 | int sfp_parse_port(struct sfp_bus *bus, const struct sfp_eeprom_id *id, |
424 | unsigned long *support); | 424 | unsigned long *support); |
425 | phy_interface_t sfp_parse_interface(struct sfp_bus *bus, | ||
426 | const struct sfp_eeprom_id *id); | ||
427 | void sfp_parse_support(struct sfp_bus *bus, const struct sfp_eeprom_id *id, | 425 | void sfp_parse_support(struct sfp_bus *bus, const struct sfp_eeprom_id *id, |
428 | unsigned long *support); | 426 | unsigned long *support); |
427 | phy_interface_t sfp_select_interface(struct sfp_bus *bus, | ||
428 | const struct sfp_eeprom_id *id, | ||
429 | unsigned long *link_modes); | ||
429 | 430 | ||
430 | int sfp_get_module_info(struct sfp_bus *bus, struct ethtool_modinfo *modinfo); | 431 | int sfp_get_module_info(struct sfp_bus *bus, struct ethtool_modinfo *modinfo); |
431 | int sfp_get_module_eeprom(struct sfp_bus *bus, struct ethtool_eeprom *ee, | 432 | int sfp_get_module_eeprom(struct sfp_bus *bus, struct ethtool_eeprom *ee, |
@@ -444,18 +445,19 @@ static inline int sfp_parse_port(struct sfp_bus *bus, | |||
444 | return PORT_OTHER; | 445 | return PORT_OTHER; |
445 | } | 446 | } |
446 | 447 | ||
447 | static inline phy_interface_t sfp_parse_interface(struct sfp_bus *bus, | ||
448 | const struct sfp_eeprom_id *id) | ||
449 | { | ||
450 | return PHY_INTERFACE_MODE_NA; | ||
451 | } | ||
452 | |||
453 | static inline void sfp_parse_support(struct sfp_bus *bus, | 448 | static inline void sfp_parse_support(struct sfp_bus *bus, |
454 | const struct sfp_eeprom_id *id, | 449 | const struct sfp_eeprom_id *id, |
455 | unsigned long *support) | 450 | unsigned long *support) |
456 | { | 451 | { |
457 | } | 452 | } |
458 | 453 | ||
454 | static inline phy_interface_t sfp_select_interface(struct sfp_bus *bus, | ||
455 | const struct sfp_eeprom_id *id, | ||
456 | unsigned long *link_modes) | ||
457 | { | ||
458 | return PHY_INTERFACE_MODE_NA; | ||
459 | } | ||
460 | |||
459 | static inline int sfp_get_module_info(struct sfp_bus *bus, | 461 | static inline int sfp_get_module_info(struct sfp_bus *bus, |
460 | struct ethtool_modinfo *modinfo) | 462 | struct ethtool_modinfo *modinfo) |
461 | { | 463 | { |