1 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
2 /* Copyright 2019 NXP */
7 #define phylink_to_dpaa2_mac(config) \
8 container_of((config), struct dpaa2_mac, phylink_config)
10 static int phy_mode(enum dpmac_eth_if eth_if, phy_interface_t *if_mode)
12 *if_mode = PHY_INTERFACE_MODE_NA;
15 case DPMAC_ETH_IF_RGMII:
16 *if_mode = PHY_INTERFACE_MODE_RGMII;
25 /* Caller must call of_node_put on the returned value */
26 static struct device_node *dpaa2_mac_get_node(u16 dpmac_id)
28 struct device_node *dpmacs, *dpmac = NULL;
32 dpmacs = of_find_node_by_name(NULL, "dpmacs");
36 while ((dpmac = of_get_next_child(dpmacs, dpmac)) != NULL) {
37 err = of_property_read_u32(dpmac, "reg", &id);
49 static int dpaa2_mac_get_if_mode(struct device_node *node,
50 struct dpmac_attr attr)
52 phy_interface_t if_mode;
55 err = of_get_phy_mode(node, &if_mode);
59 err = phy_mode(attr.eth_if, &if_mode);
66 static bool dpaa2_mac_phy_mode_mismatch(struct dpaa2_mac *mac,
67 phy_interface_t interface)
70 case PHY_INTERFACE_MODE_RGMII:
71 case PHY_INTERFACE_MODE_RGMII_ID:
72 case PHY_INTERFACE_MODE_RGMII_RXID:
73 case PHY_INTERFACE_MODE_RGMII_TXID:
74 return (interface != mac->if_mode);
80 static void dpaa2_mac_validate(struct phylink_config *config,
81 unsigned long *supported,
82 struct phylink_link_state *state)
84 struct dpaa2_mac *mac = phylink_to_dpaa2_mac(config);
85 __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
87 if (state->interface != PHY_INTERFACE_MODE_NA &&
88 dpaa2_mac_phy_mode_mismatch(mac, state->interface)) {
92 phylink_set_port_modes(mask);
93 phylink_set(mask, Autoneg);
94 phylink_set(mask, Pause);
95 phylink_set(mask, Asym_Pause);
97 switch (state->interface) {
98 case PHY_INTERFACE_MODE_RGMII:
99 case PHY_INTERFACE_MODE_RGMII_ID:
100 case PHY_INTERFACE_MODE_RGMII_RXID:
101 case PHY_INTERFACE_MODE_RGMII_TXID:
102 phylink_set(mask, 10baseT_Full);
103 phylink_set(mask, 100baseT_Full);
104 phylink_set(mask, 1000baseT_Full);
110 linkmode_and(supported, supported, mask);
111 linkmode_and(state->advertising, state->advertising, mask);
116 linkmode_zero(supported);
119 static void dpaa2_mac_config(struct phylink_config *config, unsigned int mode,
120 const struct phylink_link_state *state)
122 struct dpaa2_mac *mac = phylink_to_dpaa2_mac(config);
123 struct dpmac_link_state *dpmac_state = &mac->state;
126 if (state->an_enabled)
127 dpmac_state->options |= DPMAC_LINK_OPT_AUTONEG;
129 dpmac_state->options &= ~DPMAC_LINK_OPT_AUTONEG;
131 err = dpmac_set_link_state(mac->mc_io, 0,
132 mac->mc_dev->mc_handle, dpmac_state);
134 netdev_err(mac->net_dev, "%s: dpmac_set_link_state() = %d\n",
138 static void dpaa2_mac_link_up(struct phylink_config *config,
139 struct phy_device *phy,
140 unsigned int mode, phy_interface_t interface,
141 int speed, int duplex,
142 bool tx_pause, bool rx_pause)
144 struct dpaa2_mac *mac = phylink_to_dpaa2_mac(config);
145 struct dpmac_link_state *dpmac_state = &mac->state;
150 if (mac->if_link_type == DPMAC_LINK_TYPE_PHY) {
151 /* If the DPMAC is configured for PHY mode, we need
152 * to pass the link parameters to the MC firmware.
154 dpmac_state->rate = speed;
156 if (duplex == DUPLEX_HALF)
157 dpmac_state->options |= DPMAC_LINK_OPT_HALF_DUPLEX;
158 else if (duplex == DUPLEX_FULL)
159 dpmac_state->options &= ~DPMAC_LINK_OPT_HALF_DUPLEX;
161 /* This is lossy; the firmware really should take the pause
162 * enablement status rather than pause/asym pause status.
165 dpmac_state->options |= DPMAC_LINK_OPT_PAUSE;
167 dpmac_state->options &= ~DPMAC_LINK_OPT_PAUSE;
169 if (rx_pause ^ tx_pause)
170 dpmac_state->options |= DPMAC_LINK_OPT_ASYM_PAUSE;
172 dpmac_state->options &= ~DPMAC_LINK_OPT_ASYM_PAUSE;
175 err = dpmac_set_link_state(mac->mc_io, 0,
176 mac->mc_dev->mc_handle, dpmac_state);
178 netdev_err(mac->net_dev, "%s: dpmac_set_link_state() = %d\n",
182 static void dpaa2_mac_link_down(struct phylink_config *config,
184 phy_interface_t interface)
186 struct dpaa2_mac *mac = phylink_to_dpaa2_mac(config);
187 struct dpmac_link_state *dpmac_state = &mac->state;
191 err = dpmac_set_link_state(mac->mc_io, 0,
192 mac->mc_dev->mc_handle, dpmac_state);
194 netdev_err(mac->net_dev, "dpmac_set_link_state() = %d\n", err);
197 static const struct phylink_mac_ops dpaa2_mac_phylink_ops = {
198 .validate = dpaa2_mac_validate,
199 .mac_config = dpaa2_mac_config,
200 .mac_link_up = dpaa2_mac_link_up,
201 .mac_link_down = dpaa2_mac_link_down,
204 bool dpaa2_mac_is_type_fixed(struct fsl_mc_device *dpmac_dev,
205 struct fsl_mc_io *mc_io)
207 struct dpmac_attr attr;
212 err = dpmac_open(mc_io, 0, dpmac_dev->obj_desc.id,
214 if (err || !mc_handle)
217 err = dpmac_get_attributes(mc_io, 0, mc_handle, &attr);
221 if (attr.link_type == DPMAC_LINK_TYPE_FIXED)
225 dpmac_close(mc_io, 0, mc_handle);
230 int dpaa2_mac_connect(struct dpaa2_mac *mac)
232 struct fsl_mc_device *dpmac_dev = mac->mc_dev;
233 struct net_device *net_dev = mac->net_dev;
234 struct device_node *dpmac_node;
235 struct phylink *phylink;
236 struct dpmac_attr attr;
239 err = dpmac_open(mac->mc_io, 0, dpmac_dev->obj_desc.id,
240 &dpmac_dev->mc_handle);
241 if (err || !dpmac_dev->mc_handle) {
242 netdev_err(net_dev, "dpmac_open() = %d\n", err);
246 err = dpmac_get_attributes(mac->mc_io, 0, dpmac_dev->mc_handle, &attr);
248 netdev_err(net_dev, "dpmac_get_attributes() = %d\n", err);
249 goto err_close_dpmac;
252 mac->if_link_type = attr.link_type;
254 dpmac_node = dpaa2_mac_get_node(attr.id);
256 netdev_err(net_dev, "No dpmac@%d node found.\n", attr.id);
258 goto err_close_dpmac;
261 err = dpaa2_mac_get_if_mode(dpmac_node, attr);
268 /* The MAC does not have the capability to add RGMII delays so
269 * error out if the interface mode requests them and there is no PHY
272 if (of_phy_is_fixed_link(dpmac_node) &&
273 (mac->if_mode == PHY_INTERFACE_MODE_RGMII_ID ||
274 mac->if_mode == PHY_INTERFACE_MODE_RGMII_RXID ||
275 mac->if_mode == PHY_INTERFACE_MODE_RGMII_TXID)) {
276 netdev_err(net_dev, "RGMII delay not supported\n");
281 mac->phylink_config.dev = &net_dev->dev;
282 mac->phylink_config.type = PHYLINK_NETDEV;
284 phylink = phylink_create(&mac->phylink_config,
285 of_fwnode_handle(dpmac_node), mac->if_mode,
286 &dpaa2_mac_phylink_ops);
287 if (IS_ERR(phylink)) {
288 err = PTR_ERR(phylink);
291 mac->phylink = phylink;
293 err = phylink_of_phy_connect(mac->phylink, dpmac_node, 0);
295 netdev_err(net_dev, "phylink_of_phy_connect() = %d\n", err);
296 goto err_phylink_destroy;
299 of_node_put(dpmac_node);
304 phylink_destroy(mac->phylink);
306 of_node_put(dpmac_node);
308 dpmac_close(mac->mc_io, 0, dpmac_dev->mc_handle);
312 void dpaa2_mac_disconnect(struct dpaa2_mac *mac)
317 phylink_disconnect_phy(mac->phylink);
318 phylink_destroy(mac->phylink);
319 dpmac_close(mac->mc_io, 0, mac->mc_dev->mc_handle);
322 static char dpaa2_mac_ethtool_stats[][ETH_GSTRING_LEN] = {
323 [DPMAC_CNT_ING_ALL_FRAME] = "[mac] rx all frames",
324 [DPMAC_CNT_ING_GOOD_FRAME] = "[mac] rx frames ok",
325 [DPMAC_CNT_ING_ERR_FRAME] = "[mac] rx frame errors",
326 [DPMAC_CNT_ING_FRAME_DISCARD] = "[mac] rx frame discards",
327 [DPMAC_CNT_ING_UCAST_FRAME] = "[mac] rx u-cast",
328 [DPMAC_CNT_ING_BCAST_FRAME] = "[mac] rx b-cast",
329 [DPMAC_CNT_ING_MCAST_FRAME] = "[mac] rx m-cast",
330 [DPMAC_CNT_ING_FRAME_64] = "[mac] rx 64 bytes",
331 [DPMAC_CNT_ING_FRAME_127] = "[mac] rx 65-127 bytes",
332 [DPMAC_CNT_ING_FRAME_255] = "[mac] rx 128-255 bytes",
333 [DPMAC_CNT_ING_FRAME_511] = "[mac] rx 256-511 bytes",
334 [DPMAC_CNT_ING_FRAME_1023] = "[mac] rx 512-1023 bytes",
335 [DPMAC_CNT_ING_FRAME_1518] = "[mac] rx 1024-1518 bytes",
336 [DPMAC_CNT_ING_FRAME_1519_MAX] = "[mac] rx 1519-max bytes",
337 [DPMAC_CNT_ING_FRAG] = "[mac] rx frags",
338 [DPMAC_CNT_ING_JABBER] = "[mac] rx jabber",
339 [DPMAC_CNT_ING_ALIGN_ERR] = "[mac] rx align errors",
340 [DPMAC_CNT_ING_OVERSIZED] = "[mac] rx oversized",
341 [DPMAC_CNT_ING_VALID_PAUSE_FRAME] = "[mac] rx pause",
342 [DPMAC_CNT_ING_BYTE] = "[mac] rx bytes",
343 [DPMAC_CNT_EGR_GOOD_FRAME] = "[mac] tx frames ok",
344 [DPMAC_CNT_EGR_UCAST_FRAME] = "[mac] tx u-cast",
345 [DPMAC_CNT_EGR_MCAST_FRAME] = "[mac] tx m-cast",
346 [DPMAC_CNT_EGR_BCAST_FRAME] = "[mac] tx b-cast",
347 [DPMAC_CNT_EGR_ERR_FRAME] = "[mac] tx frame errors",
348 [DPMAC_CNT_EGR_UNDERSIZED] = "[mac] tx undersized",
349 [DPMAC_CNT_EGR_VALID_PAUSE_FRAME] = "[mac] tx b-pause",
350 [DPMAC_CNT_EGR_BYTE] = "[mac] tx bytes",
353 #define DPAA2_MAC_NUM_STATS ARRAY_SIZE(dpaa2_mac_ethtool_stats)
355 int dpaa2_mac_get_sset_count(void)
357 return DPAA2_MAC_NUM_STATS;
360 void dpaa2_mac_get_strings(u8 *data)
365 for (i = 0; i < DPAA2_MAC_NUM_STATS; i++) {
366 strlcpy(p, dpaa2_mac_ethtool_stats[i], ETH_GSTRING_LEN);
367 p += ETH_GSTRING_LEN;
371 void dpaa2_mac_get_ethtool_stats(struct dpaa2_mac *mac, u64 *data)
373 struct fsl_mc_device *dpmac_dev = mac->mc_dev;
377 for (i = 0; i < DPAA2_MAC_NUM_STATS; i++) {
378 err = dpmac_get_counter(mac->mc_io, 0, dpmac_dev->mc_handle,
381 netdev_err_once(mac->net_dev,
382 "dpmac_get_counter error %d\n", err);
383 *(data + i) = U64_MAX;