1 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) 2 /* Copyright 2019 NXP */ 3 4 #include <linux/acpi.h> 5 #include <linux/pcs-lynx.h> 6 #include <linux/property.h> 7 8 #include "dpaa2-eth.h" 9 #include "dpaa2-mac.h" 10 11 #define phylink_to_dpaa2_mac(config) \ 12 container_of((config), struct dpaa2_mac, phylink_config) 13 14 #define DPMAC_PROTOCOL_CHANGE_VER_MAJOR 4 15 #define DPMAC_PROTOCOL_CHANGE_VER_MINOR 8 16 17 #define DPAA2_MAC_FEATURE_PROTOCOL_CHANGE BIT(0) 18 19 static int dpaa2_mac_cmp_ver(struct dpaa2_mac *mac, 20 u16 ver_major, u16 ver_minor) 21 { 22 if (mac->ver_major == ver_major) 23 return mac->ver_minor - ver_minor; 24 return mac->ver_major - ver_major; 25 } 26 27 static void dpaa2_mac_detect_features(struct dpaa2_mac *mac) 28 { 29 mac->features = 0; 30 31 if (dpaa2_mac_cmp_ver(mac, DPMAC_PROTOCOL_CHANGE_VER_MAJOR, 32 DPMAC_PROTOCOL_CHANGE_VER_MINOR) >= 0) 33 mac->features |= DPAA2_MAC_FEATURE_PROTOCOL_CHANGE; 34 } 35 36 static int phy_mode(enum dpmac_eth_if eth_if, phy_interface_t *if_mode) 37 { 38 *if_mode = PHY_INTERFACE_MODE_NA; 39 40 switch (eth_if) { 41 case DPMAC_ETH_IF_RGMII: 42 *if_mode = PHY_INTERFACE_MODE_RGMII; 43 break; 44 case DPMAC_ETH_IF_USXGMII: 45 *if_mode = PHY_INTERFACE_MODE_USXGMII; 46 break; 47 case DPMAC_ETH_IF_QSGMII: 48 *if_mode = PHY_INTERFACE_MODE_QSGMII; 49 break; 50 case DPMAC_ETH_IF_SGMII: 51 *if_mode = PHY_INTERFACE_MODE_SGMII; 52 break; 53 case DPMAC_ETH_IF_XFI: 54 *if_mode = PHY_INTERFACE_MODE_10GBASER; 55 break; 56 default: 57 return -EINVAL; 58 } 59 60 return 0; 61 } 62 63 static struct fwnode_handle *dpaa2_mac_get_node(struct device *dev, 64 u16 dpmac_id) 65 { 66 struct fwnode_handle *fwnode, *parent = NULL, *child = NULL; 67 struct device_node *dpmacs = NULL; 68 int err; 69 u32 id; 70 71 fwnode = dev_fwnode(dev->parent); 72 if (is_of_node(fwnode)) { 73 dpmacs = of_find_node_by_name(NULL, "dpmacs"); 74 if (!dpmacs) 75 return NULL; 76 parent = of_fwnode_handle(dpmacs); 77 } else if (is_acpi_node(fwnode)) { 78 parent = fwnode; 79 } else { 80 /* The root dprc device didn't yet get to finalize it's probe, 81 * thus the fwnode field is not yet set. Defer probe if we are 82 * facing this situation. 83 */ 84 return ERR_PTR(-EPROBE_DEFER); 85 } 86 87 if (!parent) 88 return NULL; 89 90 fwnode_for_each_child_node(parent, child) { 91 err = -EINVAL; 92 if (is_acpi_device_node(child)) 93 err = acpi_get_local_address(ACPI_HANDLE_FWNODE(child), &id); 94 else if (is_of_node(child)) 95 err = of_property_read_u32(to_of_node(child), "reg", &id); 96 if (err) 97 continue; 98 99 if (id == dpmac_id) { 100 of_node_put(dpmacs); 101 return child; 102 } 103 } 104 of_node_put(dpmacs); 105 return NULL; 106 } 107 108 static int dpaa2_mac_get_if_mode(struct fwnode_handle *dpmac_node, 109 struct dpmac_attr attr) 110 { 111 phy_interface_t if_mode; 112 int err; 113 114 err = fwnode_get_phy_mode(dpmac_node); 115 if (err > 0) 116 return err; 117 118 err = phy_mode(attr.eth_if, &if_mode); 119 if (!err) 120 return if_mode; 121 122 return err; 123 } 124 125 static struct phylink_pcs *dpaa2_mac_select_pcs(struct phylink_config *config, 126 phy_interface_t interface) 127 { 128 struct dpaa2_mac *mac = phylink_to_dpaa2_mac(config); 129 130 return mac->pcs; 131 } 132 133 static void dpaa2_mac_config(struct phylink_config *config, unsigned int mode, 134 const struct phylink_link_state *state) 135 { 136 struct dpaa2_mac *mac = phylink_to_dpaa2_mac(config); 137 struct dpmac_link_state *dpmac_state = &mac->state; 138 int err; 139 140 if (state->an_enabled) 141 dpmac_state->options |= DPMAC_LINK_OPT_AUTONEG; 142 else 143 dpmac_state->options &= ~DPMAC_LINK_OPT_AUTONEG; 144 145 err = dpmac_set_link_state(mac->mc_io, 0, 146 mac->mc_dev->mc_handle, dpmac_state); 147 if (err) 148 netdev_err(mac->net_dev, "%s: dpmac_set_link_state() = %d\n", 149 __func__, err); 150 } 151 152 static void dpaa2_mac_link_up(struct phylink_config *config, 153 struct phy_device *phy, 154 unsigned int mode, phy_interface_t interface, 155 int speed, int duplex, 156 bool tx_pause, bool rx_pause) 157 { 158 struct dpaa2_mac *mac = phylink_to_dpaa2_mac(config); 159 struct dpmac_link_state *dpmac_state = &mac->state; 160 int err; 161 162 dpmac_state->up = 1; 163 164 dpmac_state->rate = speed; 165 166 if (duplex == DUPLEX_HALF) 167 dpmac_state->options |= DPMAC_LINK_OPT_HALF_DUPLEX; 168 else if (duplex == DUPLEX_FULL) 169 dpmac_state->options &= ~DPMAC_LINK_OPT_HALF_DUPLEX; 170 171 if (rx_pause) 172 dpmac_state->options |= DPMAC_LINK_OPT_PAUSE; 173 else 174 dpmac_state->options &= ~DPMAC_LINK_OPT_PAUSE; 175 176 if (rx_pause ^ tx_pause) 177 dpmac_state->options |= DPMAC_LINK_OPT_ASYM_PAUSE; 178 else 179 dpmac_state->options &= ~DPMAC_LINK_OPT_ASYM_PAUSE; 180 181 err = dpmac_set_link_state(mac->mc_io, 0, 182 mac->mc_dev->mc_handle, dpmac_state); 183 if (err) 184 netdev_err(mac->net_dev, "%s: dpmac_set_link_state() = %d\n", 185 __func__, err); 186 } 187 188 static void dpaa2_mac_link_down(struct phylink_config *config, 189 unsigned int mode, 190 phy_interface_t interface) 191 { 192 struct dpaa2_mac *mac = phylink_to_dpaa2_mac(config); 193 struct dpmac_link_state *dpmac_state = &mac->state; 194 int err; 195 196 dpmac_state->up = 0; 197 err = dpmac_set_link_state(mac->mc_io, 0, 198 mac->mc_dev->mc_handle, dpmac_state); 199 if (err) 200 netdev_err(mac->net_dev, "dpmac_set_link_state() = %d\n", err); 201 } 202 203 static const struct phylink_mac_ops dpaa2_mac_phylink_ops = { 204 .validate = phylink_generic_validate, 205 .mac_select_pcs = dpaa2_mac_select_pcs, 206 .mac_config = dpaa2_mac_config, 207 .mac_link_up = dpaa2_mac_link_up, 208 .mac_link_down = dpaa2_mac_link_down, 209 }; 210 211 static int dpaa2_pcs_create(struct dpaa2_mac *mac, 212 struct fwnode_handle *dpmac_node, 213 int id) 214 { 215 struct mdio_device *mdiodev; 216 struct fwnode_handle *node; 217 218 node = fwnode_find_reference(dpmac_node, "pcs-handle", 0); 219 if (IS_ERR(node)) { 220 /* do not error out on old DTS files */ 221 netdev_warn(mac->net_dev, "pcs-handle node not found\n"); 222 return 0; 223 } 224 225 if (!fwnode_device_is_available(node)) { 226 netdev_err(mac->net_dev, "pcs-handle node not available\n"); 227 fwnode_handle_put(node); 228 return -ENODEV; 229 } 230 231 mdiodev = fwnode_mdio_find_device(node); 232 fwnode_handle_put(node); 233 if (!mdiodev) 234 return -EPROBE_DEFER; 235 236 mac->pcs = lynx_pcs_create(mdiodev); 237 if (!mac->pcs) { 238 netdev_err(mac->net_dev, "lynx_pcs_create() failed\n"); 239 put_device(&mdiodev->dev); 240 return -ENOMEM; 241 } 242 243 return 0; 244 } 245 246 static void dpaa2_pcs_destroy(struct dpaa2_mac *mac) 247 { 248 struct phylink_pcs *phylink_pcs = mac->pcs; 249 250 if (phylink_pcs) { 251 struct mdio_device *mdio = lynx_get_mdio_device(phylink_pcs); 252 struct device *dev = &mdio->dev; 253 254 lynx_pcs_destroy(phylink_pcs); 255 put_device(dev); 256 mac->pcs = NULL; 257 } 258 } 259 260 static void dpaa2_mac_set_supported_interfaces(struct dpaa2_mac *mac) 261 { 262 /* We support the current interface mode, and if we have a PCS 263 * similar interface modes that do not require the SerDes lane to be 264 * reconfigured. 265 */ 266 __set_bit(mac->if_mode, mac->phylink_config.supported_interfaces); 267 if (mac->pcs) { 268 switch (mac->if_mode) { 269 case PHY_INTERFACE_MODE_1000BASEX: 270 case PHY_INTERFACE_MODE_SGMII: 271 __set_bit(PHY_INTERFACE_MODE_1000BASEX, 272 mac->phylink_config.supported_interfaces); 273 __set_bit(PHY_INTERFACE_MODE_SGMII, 274 mac->phylink_config.supported_interfaces); 275 break; 276 277 default: 278 break; 279 } 280 } 281 } 282 283 int dpaa2_mac_connect(struct dpaa2_mac *mac) 284 { 285 struct net_device *net_dev = mac->net_dev; 286 struct fwnode_handle *dpmac_node; 287 struct phylink *phylink; 288 int err; 289 290 mac->if_link_type = mac->attr.link_type; 291 292 dpmac_node = mac->fw_node; 293 if (!dpmac_node) { 294 netdev_err(net_dev, "No dpmac@%d node found.\n", mac->attr.id); 295 return -ENODEV; 296 } 297 298 err = dpaa2_mac_get_if_mode(dpmac_node, mac->attr); 299 if (err < 0) 300 return -EINVAL; 301 mac->if_mode = err; 302 303 /* The MAC does not have the capability to add RGMII delays so 304 * error out if the interface mode requests them and there is no PHY 305 * to act upon them 306 */ 307 if (of_phy_is_fixed_link(to_of_node(dpmac_node)) && 308 (mac->if_mode == PHY_INTERFACE_MODE_RGMII_ID || 309 mac->if_mode == PHY_INTERFACE_MODE_RGMII_RXID || 310 mac->if_mode == PHY_INTERFACE_MODE_RGMII_TXID)) { 311 netdev_err(net_dev, "RGMII delay not supported\n"); 312 return -EINVAL; 313 } 314 315 if ((mac->attr.link_type == DPMAC_LINK_TYPE_PHY && 316 mac->attr.eth_if != DPMAC_ETH_IF_RGMII) || 317 mac->attr.link_type == DPMAC_LINK_TYPE_BACKPLANE) { 318 err = dpaa2_pcs_create(mac, dpmac_node, mac->attr.id); 319 if (err) 320 return err; 321 } 322 323 memset(&mac->phylink_config, 0, sizeof(mac->phylink_config)); 324 mac->phylink_config.dev = &net_dev->dev; 325 mac->phylink_config.type = PHYLINK_NETDEV; 326 327 mac->phylink_config.mac_capabilities = MAC_SYM_PAUSE | MAC_ASYM_PAUSE | 328 MAC_10FD | MAC_100FD | MAC_1000FD | MAC_2500FD | MAC_5000FD | 329 MAC_10000FD; 330 331 dpaa2_mac_set_supported_interfaces(mac); 332 333 phylink = phylink_create(&mac->phylink_config, 334 dpmac_node, mac->if_mode, 335 &dpaa2_mac_phylink_ops); 336 if (IS_ERR(phylink)) { 337 err = PTR_ERR(phylink); 338 goto err_pcs_destroy; 339 } 340 mac->phylink = phylink; 341 342 err = phylink_fwnode_phy_connect(mac->phylink, dpmac_node, 0); 343 if (err) { 344 netdev_err(net_dev, "phylink_fwnode_phy_connect() = %d\n", err); 345 goto err_phylink_destroy; 346 } 347 348 return 0; 349 350 err_phylink_destroy: 351 phylink_destroy(mac->phylink); 352 err_pcs_destroy: 353 dpaa2_pcs_destroy(mac); 354 355 return err; 356 } 357 358 void dpaa2_mac_disconnect(struct dpaa2_mac *mac) 359 { 360 if (!mac->phylink) 361 return; 362 363 phylink_disconnect_phy(mac->phylink); 364 phylink_destroy(mac->phylink); 365 dpaa2_pcs_destroy(mac); 366 } 367 368 int dpaa2_mac_open(struct dpaa2_mac *mac) 369 { 370 struct fsl_mc_device *dpmac_dev = mac->mc_dev; 371 struct net_device *net_dev = mac->net_dev; 372 struct fwnode_handle *fw_node; 373 int err; 374 375 err = dpmac_open(mac->mc_io, 0, dpmac_dev->obj_desc.id, 376 &dpmac_dev->mc_handle); 377 if (err || !dpmac_dev->mc_handle) { 378 netdev_err(net_dev, "dpmac_open() = %d\n", err); 379 return -ENODEV; 380 } 381 382 err = dpmac_get_attributes(mac->mc_io, 0, dpmac_dev->mc_handle, 383 &mac->attr); 384 if (err) { 385 netdev_err(net_dev, "dpmac_get_attributes() = %d\n", err); 386 goto err_close_dpmac; 387 } 388 389 err = dpmac_get_api_version(mac->mc_io, 0, &mac->ver_major, &mac->ver_minor); 390 if (err) { 391 netdev_err(net_dev, "dpmac_get_api_version() = %d\n", err); 392 goto err_close_dpmac; 393 } 394 395 dpaa2_mac_detect_features(mac); 396 397 /* Find the device node representing the MAC device and link the device 398 * behind the associated netdev to it. 399 */ 400 fw_node = dpaa2_mac_get_node(&mac->mc_dev->dev, mac->attr.id); 401 if (IS_ERR(fw_node)) { 402 err = PTR_ERR(fw_node); 403 goto err_close_dpmac; 404 } 405 406 mac->fw_node = fw_node; 407 net_dev->dev.of_node = to_of_node(mac->fw_node); 408 409 return 0; 410 411 err_close_dpmac: 412 dpmac_close(mac->mc_io, 0, dpmac_dev->mc_handle); 413 return err; 414 } 415 416 void dpaa2_mac_close(struct dpaa2_mac *mac) 417 { 418 struct fsl_mc_device *dpmac_dev = mac->mc_dev; 419 420 dpmac_close(mac->mc_io, 0, dpmac_dev->mc_handle); 421 if (mac->fw_node) 422 fwnode_handle_put(mac->fw_node); 423 } 424 425 static char dpaa2_mac_ethtool_stats[][ETH_GSTRING_LEN] = { 426 [DPMAC_CNT_ING_ALL_FRAME] = "[mac] rx all frames", 427 [DPMAC_CNT_ING_GOOD_FRAME] = "[mac] rx frames ok", 428 [DPMAC_CNT_ING_ERR_FRAME] = "[mac] rx frame errors", 429 [DPMAC_CNT_ING_FRAME_DISCARD] = "[mac] rx frame discards", 430 [DPMAC_CNT_ING_UCAST_FRAME] = "[mac] rx u-cast", 431 [DPMAC_CNT_ING_BCAST_FRAME] = "[mac] rx b-cast", 432 [DPMAC_CNT_ING_MCAST_FRAME] = "[mac] rx m-cast", 433 [DPMAC_CNT_ING_FRAME_64] = "[mac] rx 64 bytes", 434 [DPMAC_CNT_ING_FRAME_127] = "[mac] rx 65-127 bytes", 435 [DPMAC_CNT_ING_FRAME_255] = "[mac] rx 128-255 bytes", 436 [DPMAC_CNT_ING_FRAME_511] = "[mac] rx 256-511 bytes", 437 [DPMAC_CNT_ING_FRAME_1023] = "[mac] rx 512-1023 bytes", 438 [DPMAC_CNT_ING_FRAME_1518] = "[mac] rx 1024-1518 bytes", 439 [DPMAC_CNT_ING_FRAME_1519_MAX] = "[mac] rx 1519-max bytes", 440 [DPMAC_CNT_ING_FRAG] = "[mac] rx frags", 441 [DPMAC_CNT_ING_JABBER] = "[mac] rx jabber", 442 [DPMAC_CNT_ING_ALIGN_ERR] = "[mac] rx align errors", 443 [DPMAC_CNT_ING_OVERSIZED] = "[mac] rx oversized", 444 [DPMAC_CNT_ING_VALID_PAUSE_FRAME] = "[mac] rx pause", 445 [DPMAC_CNT_ING_BYTE] = "[mac] rx bytes", 446 [DPMAC_CNT_EGR_GOOD_FRAME] = "[mac] tx frames ok", 447 [DPMAC_CNT_EGR_UCAST_FRAME] = "[mac] tx u-cast", 448 [DPMAC_CNT_EGR_MCAST_FRAME] = "[mac] tx m-cast", 449 [DPMAC_CNT_EGR_BCAST_FRAME] = "[mac] tx b-cast", 450 [DPMAC_CNT_EGR_ERR_FRAME] = "[mac] tx frame errors", 451 [DPMAC_CNT_EGR_UNDERSIZED] = "[mac] tx undersized", 452 [DPMAC_CNT_EGR_VALID_PAUSE_FRAME] = "[mac] tx b-pause", 453 [DPMAC_CNT_EGR_BYTE] = "[mac] tx bytes", 454 }; 455 456 #define DPAA2_MAC_NUM_STATS ARRAY_SIZE(dpaa2_mac_ethtool_stats) 457 458 int dpaa2_mac_get_sset_count(void) 459 { 460 return DPAA2_MAC_NUM_STATS; 461 } 462 463 void dpaa2_mac_get_strings(u8 *data) 464 { 465 u8 *p = data; 466 int i; 467 468 for (i = 0; i < DPAA2_MAC_NUM_STATS; i++) { 469 strlcpy(p, dpaa2_mac_ethtool_stats[i], ETH_GSTRING_LEN); 470 p += ETH_GSTRING_LEN; 471 } 472 } 473 474 void dpaa2_mac_get_ethtool_stats(struct dpaa2_mac *mac, u64 *data) 475 { 476 struct fsl_mc_device *dpmac_dev = mac->mc_dev; 477 int i, err; 478 u64 value; 479 480 for (i = 0; i < DPAA2_MAC_NUM_STATS; i++) { 481 err = dpmac_get_counter(mac->mc_io, 0, dpmac_dev->mc_handle, 482 i, &value); 483 if (err) { 484 netdev_err_once(mac->net_dev, 485 "dpmac_get_counter error %d\n", err); 486 *(data + i) = U64_MAX; 487 continue; 488 } 489 *(data + i) = value; 490 } 491 } 492