123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- From affa013f494486079c3c5ad2d00cebc41a3d7445 Mon Sep 17 00:00:00 2001
- From: Sean Anderson <[email protected]>
- Date: Mon, 17 Oct 2022 16:22:36 -0400
- Subject: [PATCH 01/21] net: fman: memac: Add serdes support
- This adds support for using a serdes which has to be configured. This is
- primarly in preparation for phylink conversion, which will then change the
- serdes mode dynamically.
- Signed-off-by: Sean Anderson <[email protected]>
- Signed-off-by: David S. Miller <[email protected]>
- ---
- .../net/ethernet/freescale/fman/fman_memac.c | 49 ++++++++++++++++++-
- 1 file changed, 47 insertions(+), 2 deletions(-)
- --- a/drivers/net/ethernet/freescale/fman/fman_memac.c
- +++ b/drivers/net/ethernet/freescale/fman/fman_memac.c
- @@ -13,6 +13,7 @@
- #include <linux/io.h>
- #include <linux/phy.h>
- #include <linux/phy_fixed.h>
- +#include <linux/phy/phy.h>
- #include <linux/of_mdio.h>
-
- /* PCS registers */
- @@ -324,6 +325,7 @@ struct fman_mac {
- void *fm;
- struct fman_rev_info fm_rev_info;
- bool basex_if;
- + struct phy *serdes;
- struct phy_device *pcsphy;
- bool allmulti_enabled;
- };
- @@ -1203,17 +1205,56 @@ int memac_initialization(struct mac_devi
- }
- }
-
- + memac->serdes = devm_of_phy_get(mac_dev->dev, mac_node, "serdes");
- + err = PTR_ERR(memac->serdes);
- + if (err == -ENODEV || err == -ENOSYS) {
- + dev_dbg(mac_dev->dev, "could not get (optional) serdes\n");
- + memac->serdes = NULL;
- + } else if (IS_ERR(memac->serdes)) {
- + dev_err_probe(mac_dev->dev, err, "could not get serdes\n");
- + goto _return_fm_mac_free;
- + } else {
- + err = phy_init(memac->serdes);
- + if (err) {
- + dev_err_probe(mac_dev->dev, err,
- + "could not initialize serdes\n");
- + goto _return_fm_mac_free;
- + }
- +
- + err = phy_power_on(memac->serdes);
- + if (err) {
- + dev_err_probe(mac_dev->dev, err,
- + "could not power on serdes\n");
- + goto _return_phy_exit;
- + }
- +
- + if (memac->phy_if == PHY_INTERFACE_MODE_SGMII ||
- + memac->phy_if == PHY_INTERFACE_MODE_1000BASEX ||
- + memac->phy_if == PHY_INTERFACE_MODE_2500BASEX ||
- + memac->phy_if == PHY_INTERFACE_MODE_QSGMII ||
- + memac->phy_if == PHY_INTERFACE_MODE_XGMII) {
- + err = phy_set_mode_ext(memac->serdes, PHY_MODE_ETHERNET,
- + memac->phy_if);
- + if (err) {
- + dev_err_probe(mac_dev->dev, err,
- + "could not set serdes mode to %s\n",
- + phy_modes(memac->phy_if));
- + goto _return_phy_power_off;
- + }
- + }
- + }
- +
- if (!mac_dev->phy_node && of_phy_is_fixed_link(mac_node)) {
- struct phy_device *phy;
-
- err = of_phy_register_fixed_link(mac_node);
- if (err)
- - goto _return_fm_mac_free;
- + goto _return_phy_power_off;
-
- fixed_link = kzalloc(sizeof(*fixed_link), GFP_KERNEL);
- if (!fixed_link) {
- err = -ENOMEM;
- - goto _return_fm_mac_free;
- + goto _return_phy_power_off;
- }
-
- mac_dev->phy_node = of_node_get(mac_node);
- @@ -1242,6 +1283,10 @@ int memac_initialization(struct mac_devi
-
- goto _return;
-
- +_return_phy_power_off:
- + phy_power_off(memac->serdes);
- +_return_phy_exit:
- + phy_exit(memac->serdes);
- _return_fixed_link_free:
- kfree(fixed_link);
- _return_fm_mac_free:
|