1 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) 2 /* Copyright 2019 NXP */ 3 4 #include "dpaa2-eth.h" 5 #include "dpaa2-mac.h" 6 7 #define phylink_to_dpaa2_mac(config) \ 8 container_of((config), struct dpaa2_mac, phylink_config) 9 10 static int phy_mode(enum dpmac_eth_if eth_if, phy_interface_t *if_mode) 11 { 12 *if_mode = PHY_INTERFACE_MODE_NA; 13 14 switch (eth_if) { 15 case DPMAC_ETH_IF_RGMII: 16 *if_mode = PHY_INTERFACE_MODE_RGMII; 17 break; 18 case DPMAC_ETH_IF_USXGMII: 19 *if_mode = PHY_INTERFACE_MODE_USXGMII; 20 break; 21 case DPMAC_ETH_IF_QSGMII: 22 *if_mode = PHY_INTERFACE_MODE_QSGMII; 23 break; 24 case DPMAC_ETH_IF_SGMII: 25 *if_mode = PHY_INTERFACE_MODE_SGMII; 26 break; 27 case DPMAC_ETH_IF_XFI: 28 *if_mode = PHY_INTERFACE_MODE_10GBASER; 29 break; 30 default: 31 return -EINVAL; 32 } 33 34 return 0; 35 } 36 37 /* Caller must call of_node_put on the returned value */ 38 static struct device_node *dpaa2_mac_get_node(u16 dpmac_id) 39 { 40 struct device_node *dpmacs, *dpmac = NULL; 41 u32 id; 42 int err; 43 44 dpmacs = of_find_node_by_name(NULL, "dpmacs"); 45 if (!dpmacs) 46 return NULL; 47 48 while ((dpmac = of_get_next_child(dpmacs, dpmac)) != NULL) { 49 err = of_property_read_u32(dpmac, "reg", &id); 50 if (err) 51 continue; 52 if (id == dpmac_id) 53 break; 54 } 55 56 of_node_put(dpmacs); 57 58 return dpmac; 59 } 60 61 static int dpaa2_mac_get_if_mode(struct device_node *node, 62 struct dpmac_attr attr) 63 { 64 phy_interface_t if_mode; 65 int err; 66 67 err = of_get_phy_mode(node, &if_mode); 68 if (!err) 69 return if_mode; 70 71 err = phy_mode(attr.eth_if, &if_mode); 72 if (!err) 73 return if_mode; 74 75 return err; 76 } 77 78 static bool dpaa2_mac_phy_mode_mismatch(struct dpaa2_mac *mac, 79 phy_interface_t interface) 80 { 81 switch (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); 91 default: 92 return true; 93 } 94 } 95 96 static void dpaa2_mac_validate(struct phylink_config *config, 97 unsigned long *supported, 98 struct phylink_link_state *state) 99 { 100 struct dpaa2_mac *mac = phylink_to_dpaa2_mac(config); 101 __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; 102 103 if (state->interface != PHY_INTERFACE_MODE_NA && 104 dpaa2_mac_phy_mode_mismatch(mac, state->interface)) { 105 goto empty_set; 106 } 107 108 phylink_set_port_modes(mask); 109 phylink_set(mask, Autoneg); 110 phylink_set(mask, Pause); 111 phylink_set(mask, Asym_Pause); 112 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) 119 break; 120 phylink_set(mask, 5000baseT_Full); 121 phylink_set(mask, 2500baseT_Full); 122 fallthrough; 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); 132 break; 133 default: 134 goto empty_set; 135 } 136 137 linkmode_and(supported, supported, mask); 138 linkmode_and(state->advertising, state->advertising, mask); 139 140 return; 141 142 empty_set: 143 linkmode_zero(supported); 144 } 145 146 static void dpaa2_mac_config(struct phylink_config *config, unsigned int mode, 147 const struct phylink_link_state *state) 148 { 149 struct dpaa2_mac *mac = phylink_to_dpaa2_mac(config); 150 struct dpmac_link_state *dpmac_state = &mac->state; 151 int err; 152 153 if (state->an_enabled) 154 dpmac_state->options |= DPMAC_LINK_OPT_AUTONEG; 155 else 156 dpmac_state->options &= ~DPMAC_LINK_OPT_AUTONEG; 157 158 err = dpmac_set_link_state(mac->mc_io, 0, 159 mac->mc_dev->mc_handle, dpmac_state); 160 if (err) 161 netdev_err(mac->net_dev, "%s: dpmac_set_link_state() = %d\n", 162 __func__, err); 163 } 164 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) 170 { 171 struct dpaa2_mac *mac = phylink_to_dpaa2_mac(config); 172 struct dpmac_link_state *dpmac_state = &mac->state; 173 int err; 174 175 dpmac_state->up = 1; 176 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. 180 */ 181 dpmac_state->rate = speed; 182 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; 187 188 /* This is lossy; the firmware really should take the pause 189 * enablement status rather than pause/asym pause status. 190 */ 191 if (rx_pause) 192 dpmac_state->options |= DPMAC_LINK_OPT_PAUSE; 193 else 194 dpmac_state->options &= ~DPMAC_LINK_OPT_PAUSE; 195 196 if (rx_pause ^ tx_pause) 197 dpmac_state->options |= DPMAC_LINK_OPT_ASYM_PAUSE; 198 else 199 dpmac_state->options &= ~DPMAC_LINK_OPT_ASYM_PAUSE; 200 } 201 202 err = dpmac_set_link_state(mac->mc_io, 0, 203 mac->mc_dev->mc_handle, dpmac_state); 204 if (err) 205 netdev_err(mac->net_dev, "%s: dpmac_set_link_state() = %d\n", 206 __func__, err); 207 } 208 209 static void dpaa2_mac_link_down(struct phylink_config *config, 210 unsigned int mode, 211 phy_interface_t interface) 212 { 213 struct dpaa2_mac *mac = phylink_to_dpaa2_mac(config); 214 struct dpmac_link_state *dpmac_state = &mac->state; 215 int err; 216 217 dpmac_state->up = 0; 218 err = dpmac_set_link_state(mac->mc_io, 0, 219 mac->mc_dev->mc_handle, dpmac_state); 220 if (err) 221 netdev_err(mac->net_dev, "dpmac_set_link_state() = %d\n", err); 222 } 223 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, 229 }; 230 231 bool dpaa2_mac_is_type_fixed(struct fsl_mc_device *dpmac_dev, 232 struct fsl_mc_io *mc_io) 233 { 234 struct dpmac_attr attr; 235 bool fixed = false; 236 u16 mc_handle = 0; 237 int err; 238 239 err = dpmac_open(mc_io, 0, dpmac_dev->obj_desc.id, 240 &mc_handle); 241 if (err || !mc_handle) 242 return false; 243 244 err = dpmac_get_attributes(mc_io, 0, mc_handle, &attr); 245 if (err) 246 goto out; 247 248 if (attr.link_type == DPMAC_LINK_TYPE_FIXED) 249 fixed = true; 250 251 out: 252 dpmac_close(mc_io, 0, mc_handle); 253 254 return fixed; 255 } 256 257 static int dpaa2_pcs_create(struct dpaa2_mac *mac, 258 struct device_node *dpmac_node, int id) 259 { 260 struct mdio_device *mdiodev; 261 struct device_node *node; 262 263 node = of_parse_phandle(dpmac_node, "pcs-handle", 0); 264 if (!node) { 265 /* do not error out on old DTS files */ 266 netdev_warn(mac->net_dev, "pcs-handle node not found\n"); 267 return 0; 268 } 269 270 if (!of_device_is_available(node)) { 271 netdev_err(mac->net_dev, "pcs-handle node not available\n"); 272 of_node_put(node); 273 return -ENODEV; 274 } 275 276 mdiodev = of_mdio_find_device(node); 277 of_node_put(node); 278 if (!mdiodev) 279 return -EPROBE_DEFER; 280 281 mac->pcs = lynx_pcs_create(mdiodev); 282 if (!mac->pcs) { 283 netdev_err(mac->net_dev, "lynx_pcs_create() failed\n"); 284 put_device(&mdiodev->dev); 285 return -ENOMEM; 286 } 287 288 return 0; 289 } 290 291 static void dpaa2_pcs_destroy(struct dpaa2_mac *mac) 292 { 293 struct lynx_pcs *pcs = mac->pcs; 294 295 if (pcs) { 296 struct device *dev = &pcs->mdio->dev; 297 lynx_pcs_destroy(pcs); 298 put_device(dev); 299 mac->pcs = NULL; 300 } 301 } 302 303 int dpaa2_mac_connect(struct dpaa2_mac *mac) 304 { 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; 310 int err; 311 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); 316 return -ENODEV; 317 } 318 319 err = dpmac_get_attributes(mac->mc_io, 0, dpmac_dev->mc_handle, &attr); 320 if (err) { 321 netdev_err(net_dev, "dpmac_get_attributes() = %d\n", err); 322 goto err_close_dpmac; 323 } 324 325 mac->if_link_type = attr.link_type; 326 327 dpmac_node = dpaa2_mac_get_node(attr.id); 328 if (!dpmac_node) { 329 netdev_err(net_dev, "No dpmac@%d node found.\n", attr.id); 330 err = -ENODEV; 331 goto err_close_dpmac; 332 } 333 334 err = dpaa2_mac_get_if_mode(dpmac_node, attr); 335 if (err < 0) { 336 err = -EINVAL; 337 goto err_put_node; 338 } 339 mac->if_mode = err; 340 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 343 * to act upon them 344 */ 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"); 350 err = -EINVAL; 351 goto err_put_node; 352 } 353 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); 357 if (err) 358 goto err_put_node; 359 } 360 361 mac->phylink_config.dev = &net_dev->dev; 362 mac->phylink_config.type = PHYLINK_NETDEV; 363 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; 370 } 371 mac->phylink = phylink; 372 373 if (mac->pcs) 374 phylink_set_pcs(mac->phylink, &mac->pcs->pcs); 375 376 err = phylink_of_phy_connect(mac->phylink, dpmac_node, 0); 377 if (err) { 378 netdev_err(net_dev, "phylink_of_phy_connect() = %d\n", err); 379 goto err_phylink_destroy; 380 } 381 382 of_node_put(dpmac_node); 383 384 return 0; 385 386 err_phylink_destroy: 387 phylink_destroy(mac->phylink); 388 err_pcs_destroy: 389 dpaa2_pcs_destroy(mac); 390 err_put_node: 391 of_node_put(dpmac_node); 392 err_close_dpmac: 393 dpmac_close(mac->mc_io, 0, dpmac_dev->mc_handle); 394 return err; 395 } 396 397 void dpaa2_mac_disconnect(struct dpaa2_mac *mac) 398 { 399 if (!mac->phylink) 400 return; 401 402 phylink_disconnect_phy(mac->phylink); 403 phylink_destroy(mac->phylink); 404 dpaa2_pcs_destroy(mac); 405 406 dpmac_close(mac->mc_io, 0, mac->mc_dev->mc_handle); 407 } 408 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", 438 }; 439 440 #define DPAA2_MAC_NUM_STATS ARRAY_SIZE(dpaa2_mac_ethtool_stats) 441 442 int dpaa2_mac_get_sset_count(void) 443 { 444 return DPAA2_MAC_NUM_STATS; 445 } 446 447 void dpaa2_mac_get_strings(u8 *data) 448 { 449 u8 *p = data; 450 int i; 451 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; 455 } 456 } 457 458 void dpaa2_mac_get_ethtool_stats(struct dpaa2_mac *mac, u64 *data) 459 { 460 struct fsl_mc_device *dpmac_dev = mac->mc_dev; 461 int i, err; 462 u64 value; 463 464 for (i = 0; i < DPAA2_MAC_NUM_STATS; i++) { 465 err = dpmac_get_counter(mac->mc_io, 0, dpmac_dev->mc_handle, 466 i, &value); 467 if (err) { 468 netdev_err_once(mac->net_dev, 469 "dpmac_get_counter error %d\n", err); 470 *(data + i) = U64_MAX; 471 continue; 472 } 473 *(data + i) = value; 474 } 475 } 476