net: dpaa2-mac: use resolved link config in mac_link_up()
authorRussell King <rmk+kernel@armlinux.org.uk>
Wed, 26 Feb 2020 10:24:01 +0000 (10:24 +0000)
committerDavid S. Miller <davem@davemloft.net>
Thu, 27 Feb 2020 20:02:14 +0000 (12:02 -0800)
Convert the DPAA2 ethernet driver to use the finalised link parameters
in mac_link_up() rather than the parameters in mac_config(), which are
more suited to the needs of the DPAA2 MC firmware than those available
via mac_config().

Tested-by: Ioana Ciornei <ioana.ciornei@nxp.com>
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c
drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.h

index 3a75c5b58f95452a1bd2b69cee88b432438691dc..3ee236c5fc37ca8ad4d699c7d6a0cc2ed64decae 100644 (file)
@@ -123,35 +123,16 @@ static void dpaa2_mac_config(struct phylink_config *config, unsigned int mode,
        struct dpmac_link_state *dpmac_state = &mac->state;
        int err;
 
-       if (state->speed != SPEED_UNKNOWN)
-               dpmac_state->rate = state->speed;
-
-       if (state->duplex != DUPLEX_UNKNOWN) {
-               if (!state->duplex)
-                       dpmac_state->options |= DPMAC_LINK_OPT_HALF_DUPLEX;
-               else
-                       dpmac_state->options &= ~DPMAC_LINK_OPT_HALF_DUPLEX;
-       }
-
        if (state->an_enabled)
                dpmac_state->options |= DPMAC_LINK_OPT_AUTONEG;
        else
                dpmac_state->options &= ~DPMAC_LINK_OPT_AUTONEG;
 
-       if (state->pause & MLO_PAUSE_RX)
-               dpmac_state->options |= DPMAC_LINK_OPT_PAUSE;
-       else
-               dpmac_state->options &= ~DPMAC_LINK_OPT_PAUSE;
-
-       if (!!(state->pause & MLO_PAUSE_RX) ^ !!(state->pause & MLO_PAUSE_TX))
-               dpmac_state->options |= DPMAC_LINK_OPT_ASYM_PAUSE;
-       else
-               dpmac_state->options &= ~DPMAC_LINK_OPT_ASYM_PAUSE;
-
        err = dpmac_set_link_state(mac->mc_io, 0,
                                   mac->mc_dev->mc_handle, dpmac_state);
        if (err)
-               netdev_err(mac->net_dev, "dpmac_set_link_state() = %d\n", err);
+               netdev_err(mac->net_dev, "%s: dpmac_set_link_state() = %d\n",
+                          __func__, err);
 }
 
 static void dpaa2_mac_link_up(struct phylink_config *config,
@@ -165,10 +146,37 @@ static void dpaa2_mac_link_up(struct phylink_config *config,
        int err;
 
        dpmac_state->up = 1;
+
+       if (mac->if_link_type == DPMAC_LINK_TYPE_PHY) {
+               /* If the DPMAC is configured for PHY mode, we need
+                * to pass the link parameters to the MC firmware.
+                */
+               dpmac_state->rate = speed;
+
+               if (duplex == DUPLEX_HALF)
+                       dpmac_state->options |= DPMAC_LINK_OPT_HALF_DUPLEX;
+               else if (duplex == DUPLEX_FULL)
+                       dpmac_state->options &= ~DPMAC_LINK_OPT_HALF_DUPLEX;
+
+               /* This is lossy; the firmware really should take the pause
+                * enablement status rather than pause/asym pause status.
+                */
+               if (rx_pause)
+                       dpmac_state->options |= DPMAC_LINK_OPT_PAUSE;
+               else
+                       dpmac_state->options &= ~DPMAC_LINK_OPT_PAUSE;
+
+               if (rx_pause ^ tx_pause)
+                       dpmac_state->options |= DPMAC_LINK_OPT_ASYM_PAUSE;
+               else
+                       dpmac_state->options &= ~DPMAC_LINK_OPT_ASYM_PAUSE;
+       }
+
        err = dpmac_set_link_state(mac->mc_io, 0,
                                   mac->mc_dev->mc_handle, dpmac_state);
        if (err)
-               netdev_err(mac->net_dev, "dpmac_set_link_state() = %d\n", err);
+               netdev_err(mac->net_dev, "%s: dpmac_set_link_state() = %d\n",
+                          __func__, err);
 }
 
 static void dpaa2_mac_link_down(struct phylink_config *config,
@@ -241,6 +249,8 @@ int dpaa2_mac_connect(struct dpaa2_mac *mac)
                goto err_close_dpmac;
        }
 
+       mac->if_link_type = attr.link_type;
+
        dpmac_node = dpaa2_mac_get_node(attr.id);
        if (!dpmac_node) {
                netdev_err(net_dev, "No dpmac@%d node found.\n", attr.id);
index 4da8079b91558cbac0fca11df714a2dc4b224206..2130d9c7d40eade205fbd91fcb0bbf2218b8d485 100644 (file)
@@ -20,6 +20,7 @@ struct dpaa2_mac {
        struct phylink_config phylink_config;
        struct phylink *phylink;
        phy_interface_t if_mode;
+       enum dpmac_link_type if_link_type;
 };
 
 bool dpaa2_mac_is_type_fixed(struct fsl_mc_device *dpmac_dev,