|
13 | 13 | #include <linux/io.h> |
14 | 14 | #include <linux/phy.h> |
15 | 15 | #include <linux/phy_fixed.h> |
| 16 | +#include <linux/phy/phy.h> |
16 | 17 | #include <linux/of_mdio.h> |
17 | 18 |
|
18 | 19 | /* PCS registers */ |
@@ -324,6 +325,7 @@ struct fman_mac { |
324 | 325 | void *fm; |
325 | 326 | struct fman_rev_info fm_rev_info; |
326 | 327 | bool basex_if; |
| 328 | + struct phy *serdes; |
327 | 329 | struct phy_device *pcsphy; |
328 | 330 | bool allmulti_enabled; |
329 | 331 | }; |
@@ -1203,17 +1205,56 @@ int memac_initialization(struct mac_device *mac_dev, |
1203 | 1205 | } |
1204 | 1206 | } |
1205 | 1207 |
|
| 1208 | + memac->serdes = devm_of_phy_get(mac_dev->dev, mac_node, "serdes"); |
| 1209 | + err = PTR_ERR(memac->serdes); |
| 1210 | + if (err == -ENODEV || err == -ENOSYS) { |
| 1211 | + dev_dbg(mac_dev->dev, "could not get (optional) serdes\n"); |
| 1212 | + memac->serdes = NULL; |
| 1213 | + } else if (IS_ERR(memac->serdes)) { |
| 1214 | + dev_err_probe(mac_dev->dev, err, "could not get serdes\n"); |
| 1215 | + goto _return_fm_mac_free; |
| 1216 | + } else { |
| 1217 | + err = phy_init(memac->serdes); |
| 1218 | + if (err) { |
| 1219 | + dev_err_probe(mac_dev->dev, err, |
| 1220 | + "could not initialize serdes\n"); |
| 1221 | + goto _return_fm_mac_free; |
| 1222 | + } |
| 1223 | + |
| 1224 | + err = phy_power_on(memac->serdes); |
| 1225 | + if (err) { |
| 1226 | + dev_err_probe(mac_dev->dev, err, |
| 1227 | + "could not power on serdes\n"); |
| 1228 | + goto _return_phy_exit; |
| 1229 | + } |
| 1230 | + |
| 1231 | + if (memac->phy_if == PHY_INTERFACE_MODE_SGMII || |
| 1232 | + memac->phy_if == PHY_INTERFACE_MODE_1000BASEX || |
| 1233 | + memac->phy_if == PHY_INTERFACE_MODE_2500BASEX || |
| 1234 | + memac->phy_if == PHY_INTERFACE_MODE_QSGMII || |
| 1235 | + memac->phy_if == PHY_INTERFACE_MODE_XGMII) { |
| 1236 | + err = phy_set_mode_ext(memac->serdes, PHY_MODE_ETHERNET, |
| 1237 | + memac->phy_if); |
| 1238 | + if (err) { |
| 1239 | + dev_err_probe(mac_dev->dev, err, |
| 1240 | + "could not set serdes mode to %s\n", |
| 1241 | + phy_modes(memac->phy_if)); |
| 1242 | + goto _return_phy_power_off; |
| 1243 | + } |
| 1244 | + } |
| 1245 | + } |
| 1246 | + |
1206 | 1247 | if (!mac_dev->phy_node && of_phy_is_fixed_link(mac_node)) { |
1207 | 1248 | struct phy_device *phy; |
1208 | 1249 |
|
1209 | 1250 | err = of_phy_register_fixed_link(mac_node); |
1210 | 1251 | if (err) |
1211 | | - goto _return_fm_mac_free; |
| 1252 | + goto _return_phy_power_off; |
1212 | 1253 |
|
1213 | 1254 | fixed_link = kzalloc(sizeof(*fixed_link), GFP_KERNEL); |
1214 | 1255 | if (!fixed_link) { |
1215 | 1256 | err = -ENOMEM; |
1216 | | - goto _return_fm_mac_free; |
| 1257 | + goto _return_phy_power_off; |
1217 | 1258 | } |
1218 | 1259 |
|
1219 | 1260 | mac_dev->phy_node = of_node_get(mac_node); |
@@ -1242,6 +1283,10 @@ int memac_initialization(struct mac_device *mac_dev, |
1242 | 1283 |
|
1243 | 1284 | goto _return; |
1244 | 1285 |
|
| 1286 | +_return_phy_power_off: |
| 1287 | + phy_power_off(memac->serdes); |
| 1288 | +_return_phy_exit: |
| 1289 | + phy_exit(memac->serdes); |
1245 | 1290 | _return_fixed_link_free: |
1246 | 1291 | kfree(fixed_link); |
1247 | 1292 | _return_fm_mac_free: |
|
0 commit comments