xref: /openbmc/linux/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c (revision 37556a4ac48369cd87c6635c2fe42bff51b71723)
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