|
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