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
;
18 case DPMAC_ETH_IF_USXGMII
:
19 *if_mode
= PHY_INTERFACE_MODE_USXGMII
;
21 case DPMAC_ETH_IF_QSGMII
:
22 *if_mode
= PHY_INTERFACE_MODE_QSGMII
;
24 case DPMAC_ETH_IF_SGMII
:
25 *if_mode
= PHY_INTERFACE_MODE_SGMII
;
27 case DPMAC_ETH_IF_XFI
:
28 *if_mode
= PHY_INTERFACE_MODE_10GBASER
;
37 /* Caller must call of_node_put on the returned value */
38 static struct device_node
*dpaa2_mac_get_node(u16 dpmac_id
)
40 struct device_node
*dpmacs
, *dpmac
= NULL
;
44 dpmacs
= of_find_node_by_name(NULL
, "dpmacs");
48 while ((dpmac
= of_get_next_child(dpmacs
, dpmac
)) != NULL
) {
49 err
= of_property_read_u32(dpmac
, "reg", &id
);
61 static int dpaa2_mac_get_if_mode(struct device_node
*node
,
62 struct dpmac_attr attr
)
64 phy_interface_t if_mode
;
67 err
= of_get_phy_mode(node
, &if_mode
);
71 err
= phy_mode(attr
.eth_if
, &if_mode
);
78 static bool dpaa2_mac_phy_mode_mismatch(struct dpaa2_mac
*mac
,
79 phy_interface_t interface
)
82 case PHY_INTERFACE_MODE_10GBASER
:
83 case PHY_INTERFACE_MODE_USXGMII
:
84 case PHY_INTERFACE_MODE_QSGMII
:
85 case PHY_INTERFACE_MODE_SGMII
:
86 case PHY_INTERFACE_MODE_RGMII
:
87 case PHY_INTERFACE_MODE_RGMII_ID
:
88 case PHY_INTERFACE_MODE_RGMII_RXID
:
89 case PHY_INTERFACE_MODE_RGMII_TXID
:
90 return (interface
!= mac
->if_mode
);
96 static void dpaa2_mac_validate(struct phylink_config
*config
,
97 unsigned long *supported
,
98 struct phylink_link_state
*state
)
100 struct dpaa2_mac
*mac
= phylink_to_dpaa2_mac(config
);
101 __ETHTOOL_DECLARE_LINK_MODE_MASK(mask
) = { 0, };
103 if (state
->interface
!= PHY_INTERFACE_MODE_NA
&&
104 dpaa2_mac_phy_mode_mismatch(mac
, state
->interface
)) {
108 phylink_set_port_modes(mask
);
109 phylink_set(mask
, Autoneg
);
110 phylink_set(mask
, Pause
);
111 phylink_set(mask
, Asym_Pause
);
113 switch (state
->interface
) {
114 case PHY_INTERFACE_MODE_NA
:
115 case PHY_INTERFACE_MODE_10GBASER
:
116 case PHY_INTERFACE_MODE_USXGMII
:
117 phylink_set(mask
, 10000baseT_Full
);
118 if (state
->interface
== PHY_INTERFACE_MODE_10GBASER
)
120 phylink_set(mask
, 5000baseT_Full
);
121 phylink_set(mask
, 2500baseT_Full
);
123 case PHY_INTERFACE_MODE_SGMII
:
124 case PHY_INTERFACE_MODE_QSGMII
:
125 case PHY_INTERFACE_MODE_RGMII
:
126 case PHY_INTERFACE_MODE_RGMII_ID
:
127 case PHY_INTERFACE_MODE_RGMII_RXID
:
128 case PHY_INTERFACE_MODE_RGMII_TXID
:
129 phylink_set(mask
, 10baseT_Full
);
130 phylink_set(mask
, 100baseT_Full
);
131 phylink_set(mask
, 1000baseT_Full
);
137 linkmode_and(supported
, supported
, mask
);
138 linkmode_and(state
->advertising
, state
->advertising
, mask
);
143 linkmode_zero(supported
);
146 static void dpaa2_mac_config(struct phylink_config
*config
, unsigned int mode
,
147 const struct phylink_link_state
*state
)
149 struct dpaa2_mac
*mac
= phylink_to_dpaa2_mac(config
);
150 struct dpmac_link_state
*dpmac_state
= &mac
->state
;
153 if (state
->an_enabled
)
154 dpmac_state
->options
|= DPMAC_LINK_OPT_AUTONEG
;
156 dpmac_state
->options
&= ~DPMAC_LINK_OPT_AUTONEG
;
158 err
= dpmac_set_link_state(mac
->mc_io
, 0,
159 mac
->mc_dev
->mc_handle
, dpmac_state
);
161 netdev_err(mac
->net_dev
, "%s: dpmac_set_link_state() = %d\n",
165 static void dpaa2_mac_link_up(struct phylink_config
*config
,
166 struct phy_device
*phy
,
167 unsigned int mode
, phy_interface_t interface
,
168 int speed
, int duplex
,
169 bool tx_pause
, bool rx_pause
)
171 struct dpaa2_mac
*mac
= phylink_to_dpaa2_mac(config
);
172 struct dpmac_link_state
*dpmac_state
= &mac
->state
;
177 if (mac
->if_link_type
== DPMAC_LINK_TYPE_PHY
) {
178 /* If the DPMAC is configured for PHY mode, we need
179 * to pass the link parameters to the MC firmware.
181 dpmac_state
->rate
= speed
;
183 if (duplex
== DUPLEX_HALF
)
184 dpmac_state
->options
|= DPMAC_LINK_OPT_HALF_DUPLEX
;
185 else if (duplex
== DUPLEX_FULL
)
186 dpmac_state
->options
&= ~DPMAC_LINK_OPT_HALF_DUPLEX
;
188 /* This is lossy; the firmware really should take the pause
189 * enablement status rather than pause/asym pause status.
192 dpmac_state
->options
|= DPMAC_LINK_OPT_PAUSE
;
194 dpmac_state
->options
&= ~DPMAC_LINK_OPT_PAUSE
;
196 if (rx_pause
^ tx_pause
)
197 dpmac_state
->options
|= DPMAC_LINK_OPT_ASYM_PAUSE
;
199 dpmac_state
->options
&= ~DPMAC_LINK_OPT_ASYM_PAUSE
;
202 err
= dpmac_set_link_state(mac
->mc_io
, 0,
203 mac
->mc_dev
->mc_handle
, dpmac_state
);
205 netdev_err(mac
->net_dev
, "%s: dpmac_set_link_state() = %d\n",
209 static void dpaa2_mac_link_down(struct phylink_config
*config
,
211 phy_interface_t interface
)
213 struct dpaa2_mac
*mac
= phylink_to_dpaa2_mac(config
);
214 struct dpmac_link_state
*dpmac_state
= &mac
->state
;
218 err
= dpmac_set_link_state(mac
->mc_io
, 0,
219 mac
->mc_dev
->mc_handle
, dpmac_state
);
221 netdev_err(mac
->net_dev
, "dpmac_set_link_state() = %d\n", err
);
224 static const struct phylink_mac_ops dpaa2_mac_phylink_ops
= {
225 .validate
= dpaa2_mac_validate
,
226 .mac_config
= dpaa2_mac_config
,
227 .mac_link_up
= dpaa2_mac_link_up
,
228 .mac_link_down
= dpaa2_mac_link_down
,
231 bool dpaa2_mac_is_type_fixed(struct fsl_mc_device
*dpmac_dev
,
232 struct fsl_mc_io
*mc_io
)
234 struct dpmac_attr attr
;
239 err
= dpmac_open(mc_io
, 0, dpmac_dev
->obj_desc
.id
,
241 if (err
|| !mc_handle
)
244 err
= dpmac_get_attributes(mc_io
, 0, mc_handle
, &attr
);
248 if (attr
.link_type
== DPMAC_LINK_TYPE_FIXED
)
252 dpmac_close(mc_io
, 0, mc_handle
);
257 static int dpaa2_pcs_create(struct dpaa2_mac
*mac
,
258 struct device_node
*dpmac_node
, int id
)
260 struct mdio_device
*mdiodev
;
261 struct device_node
*node
;
263 node
= of_parse_phandle(dpmac_node
, "pcs-handle", 0);
265 /* do not error out on old DTS files */
266 netdev_warn(mac
->net_dev
, "pcs-handle node not found\n");
270 if (!of_device_is_available(node
)) {
271 netdev_err(mac
->net_dev
, "pcs-handle node not available\n");
276 mdiodev
= of_mdio_find_device(node
);
279 return -EPROBE_DEFER
;
281 mac
->pcs
= lynx_pcs_create(mdiodev
);
283 netdev_err(mac
->net_dev
, "lynx_pcs_create() failed\n");
284 put_device(&mdiodev
->dev
);
291 static void dpaa2_pcs_destroy(struct dpaa2_mac
*mac
)
293 struct lynx_pcs
*pcs
= mac
->pcs
;
296 struct device
*dev
= &pcs
->mdio
->dev
;
297 lynx_pcs_destroy(pcs
);
303 int dpaa2_mac_connect(struct dpaa2_mac
*mac
)
305 struct fsl_mc_device
*dpmac_dev
= mac
->mc_dev
;
306 struct net_device
*net_dev
= mac
->net_dev
;
307 struct device_node
*dpmac_node
;
308 struct phylink
*phylink
;
309 struct dpmac_attr attr
;
312 err
= dpmac_open(mac
->mc_io
, 0, dpmac_dev
->obj_desc
.id
,
313 &dpmac_dev
->mc_handle
);
314 if (err
|| !dpmac_dev
->mc_handle
) {
315 netdev_err(net_dev
, "dpmac_open() = %d\n", err
);
319 err
= dpmac_get_attributes(mac
->mc_io
, 0, dpmac_dev
->mc_handle
, &attr
);
321 netdev_err(net_dev
, "dpmac_get_attributes() = %d\n", err
);
322 goto err_close_dpmac
;
325 mac
->if_link_type
= attr
.link_type
;
327 dpmac_node
= dpaa2_mac_get_node(attr
.id
);
329 netdev_err(net_dev
, "No dpmac@%d node found.\n", attr
.id
);
331 goto err_close_dpmac
;
334 err
= dpaa2_mac_get_if_mode(dpmac_node
, attr
);
341 /* The MAC does not have the capability to add RGMII delays so
342 * error out if the interface mode requests them and there is no PHY
345 if (of_phy_is_fixed_link(dpmac_node
) &&
346 (mac
->if_mode
== PHY_INTERFACE_MODE_RGMII_ID
||
347 mac
->if_mode
== PHY_INTERFACE_MODE_RGMII_RXID
||
348 mac
->if_mode
== PHY_INTERFACE_MODE_RGMII_TXID
)) {
349 netdev_err(net_dev
, "RGMII delay not supported\n");
354 if (attr
.link_type
== DPMAC_LINK_TYPE_PHY
&&
355 attr
.eth_if
!= DPMAC_ETH_IF_RGMII
) {
356 err
= dpaa2_pcs_create(mac
, dpmac_node
, attr
.id
);
361 mac
->phylink_config
.dev
= &net_dev
->dev
;
362 mac
->phylink_config
.type
= PHYLINK_NETDEV
;
364 phylink
= phylink_create(&mac
->phylink_config
,
365 of_fwnode_handle(dpmac_node
), mac
->if_mode
,
366 &dpaa2_mac_phylink_ops
);
367 if (IS_ERR(phylink
)) {
368 err
= PTR_ERR(phylink
);
369 goto err_pcs_destroy
;
371 mac
->phylink
= phylink
;
374 phylink_set_pcs(mac
->phylink
, &mac
->pcs
->pcs
);
376 err
= phylink_of_phy_connect(mac
->phylink
, dpmac_node
, 0);
378 netdev_err(net_dev
, "phylink_of_phy_connect() = %d\n", err
);
379 goto err_phylink_destroy
;
382 of_node_put(dpmac_node
);
387 phylink_destroy(mac
->phylink
);
389 dpaa2_pcs_destroy(mac
);
391 of_node_put(dpmac_node
);
393 dpmac_close(mac
->mc_io
, 0, dpmac_dev
->mc_handle
);
397 void dpaa2_mac_disconnect(struct dpaa2_mac
*mac
)
402 phylink_disconnect_phy(mac
->phylink
);
403 phylink_destroy(mac
->phylink
);
404 dpaa2_pcs_destroy(mac
);
406 dpmac_close(mac
->mc_io
, 0, mac
->mc_dev
->mc_handle
);
409 static char dpaa2_mac_ethtool_stats
[][ETH_GSTRING_LEN
] = {
410 [DPMAC_CNT_ING_ALL_FRAME
] = "[mac] rx all frames",
411 [DPMAC_CNT_ING_GOOD_FRAME
] = "[mac] rx frames ok",
412 [DPMAC_CNT_ING_ERR_FRAME
] = "[mac] rx frame errors",
413 [DPMAC_CNT_ING_FRAME_DISCARD
] = "[mac] rx frame discards",
414 [DPMAC_CNT_ING_UCAST_FRAME
] = "[mac] rx u-cast",
415 [DPMAC_CNT_ING_BCAST_FRAME
] = "[mac] rx b-cast",
416 [DPMAC_CNT_ING_MCAST_FRAME
] = "[mac] rx m-cast",
417 [DPMAC_CNT_ING_FRAME_64
] = "[mac] rx 64 bytes",
418 [DPMAC_CNT_ING_FRAME_127
] = "[mac] rx 65-127 bytes",
419 [DPMAC_CNT_ING_FRAME_255
] = "[mac] rx 128-255 bytes",
420 [DPMAC_CNT_ING_FRAME_511
] = "[mac] rx 256-511 bytes",
421 [DPMAC_CNT_ING_FRAME_1023
] = "[mac] rx 512-1023 bytes",
422 [DPMAC_CNT_ING_FRAME_1518
] = "[mac] rx 1024-1518 bytes",
423 [DPMAC_CNT_ING_FRAME_1519_MAX
] = "[mac] rx 1519-max bytes",
424 [DPMAC_CNT_ING_FRAG
] = "[mac] rx frags",
425 [DPMAC_CNT_ING_JABBER
] = "[mac] rx jabber",
426 [DPMAC_CNT_ING_ALIGN_ERR
] = "[mac] rx align errors",
427 [DPMAC_CNT_ING_OVERSIZED
] = "[mac] rx oversized",
428 [DPMAC_CNT_ING_VALID_PAUSE_FRAME
] = "[mac] rx pause",
429 [DPMAC_CNT_ING_BYTE
] = "[mac] rx bytes",
430 [DPMAC_CNT_EGR_GOOD_FRAME
] = "[mac] tx frames ok",
431 [DPMAC_CNT_EGR_UCAST_FRAME
] = "[mac] tx u-cast",
432 [DPMAC_CNT_EGR_MCAST_FRAME
] = "[mac] tx m-cast",
433 [DPMAC_CNT_EGR_BCAST_FRAME
] = "[mac] tx b-cast",
434 [DPMAC_CNT_EGR_ERR_FRAME
] = "[mac] tx frame errors",
435 [DPMAC_CNT_EGR_UNDERSIZED
] = "[mac] tx undersized",
436 [DPMAC_CNT_EGR_VALID_PAUSE_FRAME
] = "[mac] tx b-pause",
437 [DPMAC_CNT_EGR_BYTE
] = "[mac] tx bytes",
440 #define DPAA2_MAC_NUM_STATS ARRAY_SIZE(dpaa2_mac_ethtool_stats)
442 int dpaa2_mac_get_sset_count(void)
444 return DPAA2_MAC_NUM_STATS
;
447 void dpaa2_mac_get_strings(u8
*data
)
452 for (i
= 0; i
< DPAA2_MAC_NUM_STATS
; i
++) {
453 strlcpy(p
, dpaa2_mac_ethtool_stats
[i
], ETH_GSTRING_LEN
);
454 p
+= ETH_GSTRING_LEN
;
458 void dpaa2_mac_get_ethtool_stats(struct dpaa2_mac
*mac
, u64
*data
)
460 struct fsl_mc_device
*dpmac_dev
= mac
->mc_dev
;
464 for (i
= 0; i
< DPAA2_MAC_NUM_STATS
; i
++) {
465 err
= dpmac_get_counter(mac
->mc_io
, 0, dpmac_dev
->mc_handle
,
468 netdev_err_once(mac
->net_dev
,
469 "dpmac_get_counter error %d\n", err
);
470 *(data
+ i
) = U64_MAX
;