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