171947923SIoana Ciornei // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) 271947923SIoana Ciornei /* Copyright 2019 NXP */ 371947923SIoana Ciornei 471947923SIoana Ciornei #include "dpaa2-eth.h" 571947923SIoana Ciornei #include "dpaa2-mac.h" 671947923SIoana Ciornei 771947923SIoana Ciornei #define phylink_to_dpaa2_mac(config) \ 871947923SIoana Ciornei container_of((config), struct dpaa2_mac, phylink_config) 971947923SIoana Ciornei 10226df3efSIoana Ciornei static int phy_mode(enum dpmac_eth_if eth_if, phy_interface_t *if_mode) 1171947923SIoana Ciornei { 12226df3efSIoana Ciornei *if_mode = PHY_INTERFACE_MODE_NA; 13226df3efSIoana Ciornei 1471947923SIoana Ciornei switch (eth_if) { 1571947923SIoana Ciornei case DPMAC_ETH_IF_RGMII: 16226df3efSIoana Ciornei *if_mode = PHY_INTERFACE_MODE_RGMII; 17226df3efSIoana Ciornei break; 1871947923SIoana Ciornei default: 1971947923SIoana Ciornei return -EINVAL; 2071947923SIoana Ciornei } 21226df3efSIoana Ciornei 22226df3efSIoana Ciornei return 0; 2371947923SIoana Ciornei } 2471947923SIoana Ciornei 2571947923SIoana Ciornei /* Caller must call of_node_put on the returned value */ 2671947923SIoana Ciornei static struct device_node *dpaa2_mac_get_node(u16 dpmac_id) 2771947923SIoana Ciornei { 2871947923SIoana Ciornei struct device_node *dpmacs, *dpmac = NULL; 2971947923SIoana Ciornei u32 id; 3071947923SIoana Ciornei int err; 3171947923SIoana Ciornei 3271947923SIoana Ciornei dpmacs = of_find_node_by_name(NULL, "dpmacs"); 3371947923SIoana Ciornei if (!dpmacs) 3471947923SIoana Ciornei return NULL; 3571947923SIoana Ciornei 3671947923SIoana Ciornei while ((dpmac = of_get_next_child(dpmacs, dpmac)) != NULL) { 3771947923SIoana Ciornei err = of_property_read_u32(dpmac, "reg", &id); 3871947923SIoana Ciornei if (err) 3971947923SIoana Ciornei continue; 4071947923SIoana Ciornei if (id == dpmac_id) 4171947923SIoana Ciornei break; 4271947923SIoana Ciornei } 4371947923SIoana Ciornei 4471947923SIoana Ciornei of_node_put(dpmacs); 4571947923SIoana Ciornei 4671947923SIoana Ciornei return dpmac; 4771947923SIoana Ciornei } 4871947923SIoana Ciornei 4971947923SIoana Ciornei static int dpaa2_mac_get_if_mode(struct device_node *node, 5071947923SIoana Ciornei struct dpmac_attr attr) 5171947923SIoana Ciornei { 520c65b2b9SAndrew Lunn phy_interface_t if_mode; 530c65b2b9SAndrew Lunn int err; 5471947923SIoana Ciornei 550c65b2b9SAndrew Lunn err = of_get_phy_mode(node, &if_mode); 560c65b2b9SAndrew Lunn if (!err) 5771947923SIoana Ciornei return if_mode; 5871947923SIoana Ciornei 59226df3efSIoana Ciornei err = phy_mode(attr.eth_if, &if_mode); 60226df3efSIoana Ciornei if (!err) 6171947923SIoana Ciornei return if_mode; 6271947923SIoana Ciornei 63226df3efSIoana Ciornei return err; 6471947923SIoana Ciornei } 6571947923SIoana Ciornei 6671947923SIoana Ciornei static bool dpaa2_mac_phy_mode_mismatch(struct dpaa2_mac *mac, 6771947923SIoana Ciornei phy_interface_t interface) 6871947923SIoana Ciornei { 6971947923SIoana Ciornei switch (interface) { 7071947923SIoana Ciornei case PHY_INTERFACE_MODE_RGMII: 7171947923SIoana Ciornei case PHY_INTERFACE_MODE_RGMII_ID: 7271947923SIoana Ciornei case PHY_INTERFACE_MODE_RGMII_RXID: 7371947923SIoana Ciornei case PHY_INTERFACE_MODE_RGMII_TXID: 7471947923SIoana Ciornei return (interface != mac->if_mode); 7571947923SIoana Ciornei default: 7671947923SIoana Ciornei return true; 7771947923SIoana Ciornei } 7871947923SIoana Ciornei } 7971947923SIoana Ciornei 8071947923SIoana Ciornei static void dpaa2_mac_validate(struct phylink_config *config, 8171947923SIoana Ciornei unsigned long *supported, 8271947923SIoana Ciornei struct phylink_link_state *state) 8371947923SIoana Ciornei { 8471947923SIoana Ciornei struct dpaa2_mac *mac = phylink_to_dpaa2_mac(config); 8571947923SIoana Ciornei __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; 8671947923SIoana Ciornei 8771947923SIoana Ciornei if (state->interface != PHY_INTERFACE_MODE_NA && 8871947923SIoana Ciornei dpaa2_mac_phy_mode_mismatch(mac, state->interface)) { 8971947923SIoana Ciornei goto empty_set; 9071947923SIoana Ciornei } 9171947923SIoana Ciornei 9271947923SIoana Ciornei phylink_set_port_modes(mask); 9371947923SIoana Ciornei phylink_set(mask, Autoneg); 9471947923SIoana Ciornei phylink_set(mask, Pause); 9571947923SIoana Ciornei phylink_set(mask, Asym_Pause); 9671947923SIoana Ciornei 9771947923SIoana Ciornei switch (state->interface) { 9871947923SIoana Ciornei case PHY_INTERFACE_MODE_RGMII: 9971947923SIoana Ciornei case PHY_INTERFACE_MODE_RGMII_ID: 10071947923SIoana Ciornei case PHY_INTERFACE_MODE_RGMII_RXID: 10171947923SIoana Ciornei case PHY_INTERFACE_MODE_RGMII_TXID: 10271947923SIoana Ciornei phylink_set(mask, 10baseT_Full); 10371947923SIoana Ciornei phylink_set(mask, 100baseT_Full); 10471947923SIoana Ciornei phylink_set(mask, 1000baseT_Full); 10571947923SIoana Ciornei break; 10671947923SIoana Ciornei default: 10771947923SIoana Ciornei goto empty_set; 10871947923SIoana Ciornei } 10971947923SIoana Ciornei 11071947923SIoana Ciornei linkmode_and(supported, supported, mask); 11171947923SIoana Ciornei linkmode_and(state->advertising, state->advertising, mask); 11271947923SIoana Ciornei 11371947923SIoana Ciornei return; 11471947923SIoana Ciornei 11571947923SIoana Ciornei empty_set: 11671947923SIoana Ciornei linkmode_zero(supported); 11771947923SIoana Ciornei } 11871947923SIoana Ciornei 11971947923SIoana Ciornei static void dpaa2_mac_config(struct phylink_config *config, unsigned int mode, 12071947923SIoana Ciornei const struct phylink_link_state *state) 12171947923SIoana Ciornei { 12271947923SIoana Ciornei struct dpaa2_mac *mac = phylink_to_dpaa2_mac(config); 12371947923SIoana Ciornei struct dpmac_link_state *dpmac_state = &mac->state; 12471947923SIoana Ciornei int err; 12571947923SIoana Ciornei 12671947923SIoana Ciornei if (state->an_enabled) 12771947923SIoana Ciornei dpmac_state->options |= DPMAC_LINK_OPT_AUTONEG; 12871947923SIoana Ciornei else 12971947923SIoana Ciornei dpmac_state->options &= ~DPMAC_LINK_OPT_AUTONEG; 13071947923SIoana Ciornei 13171947923SIoana Ciornei err = dpmac_set_link_state(mac->mc_io, 0, 13271947923SIoana Ciornei mac->mc_dev->mc_handle, dpmac_state); 13371947923SIoana Ciornei if (err) 134*37556a4aSRussell King netdev_err(mac->net_dev, "%s: dpmac_set_link_state() = %d\n", 135*37556a4aSRussell King __func__, err); 13671947923SIoana Ciornei } 13771947923SIoana Ciornei 13891a208f2SRussell King static void dpaa2_mac_link_up(struct phylink_config *config, 13991a208f2SRussell King struct phy_device *phy, 14091a208f2SRussell King unsigned int mode, phy_interface_t interface, 14191a208f2SRussell King int speed, int duplex, 14291a208f2SRussell King bool tx_pause, bool rx_pause) 14371947923SIoana Ciornei { 14471947923SIoana Ciornei struct dpaa2_mac *mac = phylink_to_dpaa2_mac(config); 14571947923SIoana Ciornei struct dpmac_link_state *dpmac_state = &mac->state; 14671947923SIoana Ciornei int err; 14771947923SIoana Ciornei 14871947923SIoana Ciornei dpmac_state->up = 1; 149*37556a4aSRussell King 150*37556a4aSRussell King if (mac->if_link_type == DPMAC_LINK_TYPE_PHY) { 151*37556a4aSRussell King /* If the DPMAC is configured for PHY mode, we need 152*37556a4aSRussell King * to pass the link parameters to the MC firmware. 153*37556a4aSRussell King */ 154*37556a4aSRussell King dpmac_state->rate = speed; 155*37556a4aSRussell King 156*37556a4aSRussell King if (duplex == DUPLEX_HALF) 157*37556a4aSRussell King dpmac_state->options |= DPMAC_LINK_OPT_HALF_DUPLEX; 158*37556a4aSRussell King else if (duplex == DUPLEX_FULL) 159*37556a4aSRussell King dpmac_state->options &= ~DPMAC_LINK_OPT_HALF_DUPLEX; 160*37556a4aSRussell King 161*37556a4aSRussell King /* This is lossy; the firmware really should take the pause 162*37556a4aSRussell King * enablement status rather than pause/asym pause status. 163*37556a4aSRussell King */ 164*37556a4aSRussell King if (rx_pause) 165*37556a4aSRussell King dpmac_state->options |= DPMAC_LINK_OPT_PAUSE; 166*37556a4aSRussell King else 167*37556a4aSRussell King dpmac_state->options &= ~DPMAC_LINK_OPT_PAUSE; 168*37556a4aSRussell King 169*37556a4aSRussell King if (rx_pause ^ tx_pause) 170*37556a4aSRussell King dpmac_state->options |= DPMAC_LINK_OPT_ASYM_PAUSE; 171*37556a4aSRussell King else 172*37556a4aSRussell King dpmac_state->options &= ~DPMAC_LINK_OPT_ASYM_PAUSE; 173*37556a4aSRussell King } 174*37556a4aSRussell King 17571947923SIoana Ciornei err = dpmac_set_link_state(mac->mc_io, 0, 17671947923SIoana Ciornei mac->mc_dev->mc_handle, dpmac_state); 17771947923SIoana Ciornei if (err) 178*37556a4aSRussell King netdev_err(mac->net_dev, "%s: dpmac_set_link_state() = %d\n", 179*37556a4aSRussell King __func__, err); 18071947923SIoana Ciornei } 18171947923SIoana Ciornei 18271947923SIoana Ciornei static void dpaa2_mac_link_down(struct phylink_config *config, 18371947923SIoana Ciornei unsigned int mode, 18471947923SIoana Ciornei phy_interface_t interface) 18571947923SIoana Ciornei { 18671947923SIoana Ciornei struct dpaa2_mac *mac = phylink_to_dpaa2_mac(config); 18771947923SIoana Ciornei struct dpmac_link_state *dpmac_state = &mac->state; 18871947923SIoana Ciornei int err; 18971947923SIoana Ciornei 19071947923SIoana Ciornei dpmac_state->up = 0; 19171947923SIoana Ciornei err = dpmac_set_link_state(mac->mc_io, 0, 19271947923SIoana Ciornei mac->mc_dev->mc_handle, dpmac_state); 19371947923SIoana Ciornei if (err) 19471947923SIoana Ciornei netdev_err(mac->net_dev, "dpmac_set_link_state() = %d\n", err); 19571947923SIoana Ciornei } 19671947923SIoana Ciornei 19771947923SIoana Ciornei static const struct phylink_mac_ops dpaa2_mac_phylink_ops = { 19871947923SIoana Ciornei .validate = dpaa2_mac_validate, 19971947923SIoana Ciornei .mac_config = dpaa2_mac_config, 20071947923SIoana Ciornei .mac_link_up = dpaa2_mac_link_up, 20171947923SIoana Ciornei .mac_link_down = dpaa2_mac_link_down, 20271947923SIoana Ciornei }; 20371947923SIoana Ciornei 20471947923SIoana Ciornei bool dpaa2_mac_is_type_fixed(struct fsl_mc_device *dpmac_dev, 20571947923SIoana Ciornei struct fsl_mc_io *mc_io) 20671947923SIoana Ciornei { 20771947923SIoana Ciornei struct dpmac_attr attr; 20871947923SIoana Ciornei bool fixed = false; 20971947923SIoana Ciornei u16 mc_handle = 0; 21071947923SIoana Ciornei int err; 21171947923SIoana Ciornei 21271947923SIoana Ciornei err = dpmac_open(mc_io, 0, dpmac_dev->obj_desc.id, 21371947923SIoana Ciornei &mc_handle); 21471947923SIoana Ciornei if (err || !mc_handle) 21571947923SIoana Ciornei return false; 21671947923SIoana Ciornei 21771947923SIoana Ciornei err = dpmac_get_attributes(mc_io, 0, mc_handle, &attr); 21871947923SIoana Ciornei if (err) 21971947923SIoana Ciornei goto out; 22071947923SIoana Ciornei 22171947923SIoana Ciornei if (attr.link_type == DPMAC_LINK_TYPE_FIXED) 22271947923SIoana Ciornei fixed = true; 22371947923SIoana Ciornei 22471947923SIoana Ciornei out: 22571947923SIoana Ciornei dpmac_close(mc_io, 0, mc_handle); 22671947923SIoana Ciornei 22771947923SIoana Ciornei return fixed; 22871947923SIoana Ciornei } 22971947923SIoana Ciornei 23071947923SIoana Ciornei int dpaa2_mac_connect(struct dpaa2_mac *mac) 23171947923SIoana Ciornei { 23271947923SIoana Ciornei struct fsl_mc_device *dpmac_dev = mac->mc_dev; 23371947923SIoana Ciornei struct net_device *net_dev = mac->net_dev; 23471947923SIoana Ciornei struct device_node *dpmac_node; 23571947923SIoana Ciornei struct phylink *phylink; 23671947923SIoana Ciornei struct dpmac_attr attr; 23771947923SIoana Ciornei int err; 23871947923SIoana Ciornei 23971947923SIoana Ciornei err = dpmac_open(mac->mc_io, 0, dpmac_dev->obj_desc.id, 24071947923SIoana Ciornei &dpmac_dev->mc_handle); 24171947923SIoana Ciornei if (err || !dpmac_dev->mc_handle) { 24271947923SIoana Ciornei netdev_err(net_dev, "dpmac_open() = %d\n", err); 24371947923SIoana Ciornei return -ENODEV; 24471947923SIoana Ciornei } 24571947923SIoana Ciornei 24671947923SIoana Ciornei err = dpmac_get_attributes(mac->mc_io, 0, dpmac_dev->mc_handle, &attr); 24771947923SIoana Ciornei if (err) { 24871947923SIoana Ciornei netdev_err(net_dev, "dpmac_get_attributes() = %d\n", err); 24971947923SIoana Ciornei goto err_close_dpmac; 25071947923SIoana Ciornei } 25171947923SIoana Ciornei 252*37556a4aSRussell King mac->if_link_type = attr.link_type; 253*37556a4aSRussell King 25471947923SIoana Ciornei dpmac_node = dpaa2_mac_get_node(attr.id); 25571947923SIoana Ciornei if (!dpmac_node) { 25671947923SIoana Ciornei netdev_err(net_dev, "No dpmac@%d node found.\n", attr.id); 25771947923SIoana Ciornei err = -ENODEV; 25871947923SIoana Ciornei goto err_close_dpmac; 25971947923SIoana Ciornei } 26071947923SIoana Ciornei 26171947923SIoana Ciornei err = dpaa2_mac_get_if_mode(dpmac_node, attr); 26271947923SIoana Ciornei if (err < 0) { 26371947923SIoana Ciornei err = -EINVAL; 26471947923SIoana Ciornei goto err_put_node; 26571947923SIoana Ciornei } 26671947923SIoana Ciornei mac->if_mode = err; 26771947923SIoana Ciornei 26871947923SIoana Ciornei /* The MAC does not have the capability to add RGMII delays so 26971947923SIoana Ciornei * error out if the interface mode requests them and there is no PHY 27071947923SIoana Ciornei * to act upon them 27171947923SIoana Ciornei */ 27271947923SIoana Ciornei if (of_phy_is_fixed_link(dpmac_node) && 27371947923SIoana Ciornei (mac->if_mode == PHY_INTERFACE_MODE_RGMII_ID || 27471947923SIoana Ciornei mac->if_mode == PHY_INTERFACE_MODE_RGMII_RXID || 27571947923SIoana Ciornei mac->if_mode == PHY_INTERFACE_MODE_RGMII_TXID)) { 27671947923SIoana Ciornei netdev_err(net_dev, "RGMII delay not supported\n"); 27771947923SIoana Ciornei err = -EINVAL; 27871947923SIoana Ciornei goto err_put_node; 27971947923SIoana Ciornei } 28071947923SIoana Ciornei 28171947923SIoana Ciornei mac->phylink_config.dev = &net_dev->dev; 28271947923SIoana Ciornei mac->phylink_config.type = PHYLINK_NETDEV; 28371947923SIoana Ciornei 28471947923SIoana Ciornei phylink = phylink_create(&mac->phylink_config, 28571947923SIoana Ciornei of_fwnode_handle(dpmac_node), mac->if_mode, 28671947923SIoana Ciornei &dpaa2_mac_phylink_ops); 28771947923SIoana Ciornei if (IS_ERR(phylink)) { 28871947923SIoana Ciornei err = PTR_ERR(phylink); 28971947923SIoana Ciornei goto err_put_node; 29071947923SIoana Ciornei } 29171947923SIoana Ciornei mac->phylink = phylink; 29271947923SIoana Ciornei 29371947923SIoana Ciornei err = phylink_of_phy_connect(mac->phylink, dpmac_node, 0); 29471947923SIoana Ciornei if (err) { 29571947923SIoana Ciornei netdev_err(net_dev, "phylink_of_phy_connect() = %d\n", err); 29671947923SIoana Ciornei goto err_phylink_destroy; 29771947923SIoana Ciornei } 29871947923SIoana Ciornei 29971947923SIoana Ciornei of_node_put(dpmac_node); 30071947923SIoana Ciornei 30171947923SIoana Ciornei return 0; 30271947923SIoana Ciornei 30371947923SIoana Ciornei err_phylink_destroy: 30471947923SIoana Ciornei phylink_destroy(mac->phylink); 30571947923SIoana Ciornei err_put_node: 30671947923SIoana Ciornei of_node_put(dpmac_node); 30771947923SIoana Ciornei err_close_dpmac: 30871947923SIoana Ciornei dpmac_close(mac->mc_io, 0, dpmac_dev->mc_handle); 30971947923SIoana Ciornei return err; 31071947923SIoana Ciornei } 31171947923SIoana Ciornei 31271947923SIoana Ciornei void dpaa2_mac_disconnect(struct dpaa2_mac *mac) 31371947923SIoana Ciornei { 31471947923SIoana Ciornei if (!mac->phylink) 31571947923SIoana Ciornei return; 31671947923SIoana Ciornei 31771947923SIoana Ciornei phylink_disconnect_phy(mac->phylink); 31871947923SIoana Ciornei phylink_destroy(mac->phylink); 31971947923SIoana Ciornei dpmac_close(mac->mc_io, 0, mac->mc_dev->mc_handle); 32071947923SIoana Ciornei } 321991df1fbSIoana Ciornei 322991df1fbSIoana Ciornei static char dpaa2_mac_ethtool_stats[][ETH_GSTRING_LEN] = { 323991df1fbSIoana Ciornei [DPMAC_CNT_ING_ALL_FRAME] = "[mac] rx all frames", 324991df1fbSIoana Ciornei [DPMAC_CNT_ING_GOOD_FRAME] = "[mac] rx frames ok", 325991df1fbSIoana Ciornei [DPMAC_CNT_ING_ERR_FRAME] = "[mac] rx frame errors", 326991df1fbSIoana Ciornei [DPMAC_CNT_ING_FRAME_DISCARD] = "[mac] rx frame discards", 327991df1fbSIoana Ciornei [DPMAC_CNT_ING_UCAST_FRAME] = "[mac] rx u-cast", 328991df1fbSIoana Ciornei [DPMAC_CNT_ING_BCAST_FRAME] = "[mac] rx b-cast", 329991df1fbSIoana Ciornei [DPMAC_CNT_ING_MCAST_FRAME] = "[mac] rx m-cast", 330991df1fbSIoana Ciornei [DPMAC_CNT_ING_FRAME_64] = "[mac] rx 64 bytes", 331991df1fbSIoana Ciornei [DPMAC_CNT_ING_FRAME_127] = "[mac] rx 65-127 bytes", 332991df1fbSIoana Ciornei [DPMAC_CNT_ING_FRAME_255] = "[mac] rx 128-255 bytes", 333991df1fbSIoana Ciornei [DPMAC_CNT_ING_FRAME_511] = "[mac] rx 256-511 bytes", 334991df1fbSIoana Ciornei [DPMAC_CNT_ING_FRAME_1023] = "[mac] rx 512-1023 bytes", 335991df1fbSIoana Ciornei [DPMAC_CNT_ING_FRAME_1518] = "[mac] rx 1024-1518 bytes", 336991df1fbSIoana Ciornei [DPMAC_CNT_ING_FRAME_1519_MAX] = "[mac] rx 1519-max bytes", 337991df1fbSIoana Ciornei [DPMAC_CNT_ING_FRAG] = "[mac] rx frags", 338991df1fbSIoana Ciornei [DPMAC_CNT_ING_JABBER] = "[mac] rx jabber", 339991df1fbSIoana Ciornei [DPMAC_CNT_ING_ALIGN_ERR] = "[mac] rx align errors", 340991df1fbSIoana Ciornei [DPMAC_CNT_ING_OVERSIZED] = "[mac] rx oversized", 341991df1fbSIoana Ciornei [DPMAC_CNT_ING_VALID_PAUSE_FRAME] = "[mac] rx pause", 342991df1fbSIoana Ciornei [DPMAC_CNT_ING_BYTE] = "[mac] rx bytes", 343991df1fbSIoana Ciornei [DPMAC_CNT_EGR_GOOD_FRAME] = "[mac] tx frames ok", 344991df1fbSIoana Ciornei [DPMAC_CNT_EGR_UCAST_FRAME] = "[mac] tx u-cast", 345991df1fbSIoana Ciornei [DPMAC_CNT_EGR_MCAST_FRAME] = "[mac] tx m-cast", 346991df1fbSIoana Ciornei [DPMAC_CNT_EGR_BCAST_FRAME] = "[mac] tx b-cast", 347991df1fbSIoana Ciornei [DPMAC_CNT_EGR_ERR_FRAME] = "[mac] tx frame errors", 348991df1fbSIoana Ciornei [DPMAC_CNT_EGR_UNDERSIZED] = "[mac] tx undersized", 349991df1fbSIoana Ciornei [DPMAC_CNT_EGR_VALID_PAUSE_FRAME] = "[mac] tx b-pause", 350991df1fbSIoana Ciornei [DPMAC_CNT_EGR_BYTE] = "[mac] tx bytes", 351991df1fbSIoana Ciornei }; 352991df1fbSIoana Ciornei 353991df1fbSIoana Ciornei #define DPAA2_MAC_NUM_STATS ARRAY_SIZE(dpaa2_mac_ethtool_stats) 354991df1fbSIoana Ciornei 355991df1fbSIoana Ciornei int dpaa2_mac_get_sset_count(void) 356991df1fbSIoana Ciornei { 357991df1fbSIoana Ciornei return DPAA2_MAC_NUM_STATS; 358991df1fbSIoana Ciornei } 359991df1fbSIoana Ciornei 360991df1fbSIoana Ciornei void dpaa2_mac_get_strings(u8 *data) 361991df1fbSIoana Ciornei { 362991df1fbSIoana Ciornei u8 *p = data; 363991df1fbSIoana Ciornei int i; 364991df1fbSIoana Ciornei 365991df1fbSIoana Ciornei for (i = 0; i < DPAA2_MAC_NUM_STATS; i++) { 366991df1fbSIoana Ciornei strlcpy(p, dpaa2_mac_ethtool_stats[i], ETH_GSTRING_LEN); 367991df1fbSIoana Ciornei p += ETH_GSTRING_LEN; 368991df1fbSIoana Ciornei } 369991df1fbSIoana Ciornei } 370991df1fbSIoana Ciornei 371991df1fbSIoana Ciornei void dpaa2_mac_get_ethtool_stats(struct dpaa2_mac *mac, u64 *data) 372991df1fbSIoana Ciornei { 373991df1fbSIoana Ciornei struct fsl_mc_device *dpmac_dev = mac->mc_dev; 374991df1fbSIoana Ciornei int i, err; 375991df1fbSIoana Ciornei u64 value; 376991df1fbSIoana Ciornei 377991df1fbSIoana Ciornei for (i = 0; i < DPAA2_MAC_NUM_STATS; i++) { 378991df1fbSIoana Ciornei err = dpmac_get_counter(mac->mc_io, 0, dpmac_dev->mc_handle, 379991df1fbSIoana Ciornei i, &value); 380991df1fbSIoana Ciornei if (err) { 381991df1fbSIoana Ciornei netdev_err_once(mac->net_dev, 382991df1fbSIoana Ciornei "dpmac_get_counter error %d\n", err); 383991df1fbSIoana Ciornei *(data + i) = U64_MAX; 384991df1fbSIoana Ciornei continue; 385991df1fbSIoana Ciornei } 386991df1fbSIoana Ciornei *(data + i) = value; 387991df1fbSIoana Ciornei } 388991df1fbSIoana Ciornei } 389