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 /* We can switch between SGMII and 1000BASE-X at runtime with 83 * pcs-lynx 84 */ 85 case PHY_INTERFACE_MODE_SGMII: 86 case PHY_INTERFACE_MODE_1000BASEX: 87 if (mac->pcs && 88 (mac->if_mode == PHY_INTERFACE_MODE_SGMII || 89 mac->if_mode == PHY_INTERFACE_MODE_1000BASEX)) 90 return false; 91 return interface != mac->if_mode; 92 93 case PHY_INTERFACE_MODE_10GBASER: 94 case PHY_INTERFACE_MODE_USXGMII: 95 case PHY_INTERFACE_MODE_QSGMII: 96 case PHY_INTERFACE_MODE_RGMII: 97 case PHY_INTERFACE_MODE_RGMII_ID: 98 case PHY_INTERFACE_MODE_RGMII_RXID: 99 case PHY_INTERFACE_MODE_RGMII_TXID: 100 return (interface != mac->if_mode); 101 default: 102 return true; 103 } 104 } 105 106 static void dpaa2_mac_validate(struct phylink_config *config, 107 unsigned long *supported, 108 struct phylink_link_state *state) 109 { 110 struct dpaa2_mac *mac = phylink_to_dpaa2_mac(config); 111 __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; 112 113 if (state->interface != PHY_INTERFACE_MODE_NA && 114 dpaa2_mac_phy_mode_mismatch(mac, state->interface)) { 115 goto empty_set; 116 } 117 118 phylink_set_port_modes(mask); 119 phylink_set(mask, Autoneg); 120 phylink_set(mask, Pause); 121 phylink_set(mask, Asym_Pause); 122 123 switch (state->interface) { 124 case PHY_INTERFACE_MODE_NA: 125 case PHY_INTERFACE_MODE_10GBASER: 126 case PHY_INTERFACE_MODE_USXGMII: 127 phylink_set(mask, 10000baseT_Full); 128 if (state->interface == PHY_INTERFACE_MODE_10GBASER) 129 break; 130 phylink_set(mask, 5000baseT_Full); 131 phylink_set(mask, 2500baseT_Full); 132 fallthrough; 133 case PHY_INTERFACE_MODE_SGMII: 134 case PHY_INTERFACE_MODE_QSGMII: 135 case PHY_INTERFACE_MODE_1000BASEX: 136 case PHY_INTERFACE_MODE_RGMII: 137 case PHY_INTERFACE_MODE_RGMII_ID: 138 case PHY_INTERFACE_MODE_RGMII_RXID: 139 case PHY_INTERFACE_MODE_RGMII_TXID: 140 phylink_set(mask, 1000baseX_Full); 141 phylink_set(mask, 1000baseT_Full); 142 if (state->interface == PHY_INTERFACE_MODE_1000BASEX) 143 break; 144 phylink_set(mask, 100baseT_Full); 145 phylink_set(mask, 10baseT_Full); 146 break; 147 default: 148 goto empty_set; 149 } 150 151 linkmode_and(supported, supported, mask); 152 linkmode_and(state->advertising, state->advertising, mask); 153 154 return; 155 156 empty_set: 157 linkmode_zero(supported); 158 } 159 160 static void dpaa2_mac_config(struct phylink_config *config, unsigned int mode, 161 const struct phylink_link_state *state) 162 { 163 struct dpaa2_mac *mac = phylink_to_dpaa2_mac(config); 164 struct dpmac_link_state *dpmac_state = &mac->state; 165 int err; 166 167 if (state->an_enabled) 168 dpmac_state->options |= DPMAC_LINK_OPT_AUTONEG; 169 else 170 dpmac_state->options &= ~DPMAC_LINK_OPT_AUTONEG; 171 172 err = dpmac_set_link_state(mac->mc_io, 0, 173 mac->mc_dev->mc_handle, dpmac_state); 174 if (err) 175 netdev_err(mac->net_dev, "%s: dpmac_set_link_state() = %d\n", 176 __func__, err); 177 } 178 179 static void dpaa2_mac_link_up(struct phylink_config *config, 180 struct phy_device *phy, 181 unsigned int mode, phy_interface_t interface, 182 int speed, int duplex, 183 bool tx_pause, bool rx_pause) 184 { 185 struct dpaa2_mac *mac = phylink_to_dpaa2_mac(config); 186 struct dpmac_link_state *dpmac_state = &mac->state; 187 int err; 188 189 dpmac_state->up = 1; 190 191 dpmac_state->rate = speed; 192 193 if (duplex == DUPLEX_HALF) 194 dpmac_state->options |= DPMAC_LINK_OPT_HALF_DUPLEX; 195 else if (duplex == DUPLEX_FULL) 196 dpmac_state->options &= ~DPMAC_LINK_OPT_HALF_DUPLEX; 197 198 if (rx_pause) 199 dpmac_state->options |= DPMAC_LINK_OPT_PAUSE; 200 else 201 dpmac_state->options &= ~DPMAC_LINK_OPT_PAUSE; 202 203 if (rx_pause ^ tx_pause) 204 dpmac_state->options |= DPMAC_LINK_OPT_ASYM_PAUSE; 205 else 206 dpmac_state->options &= ~DPMAC_LINK_OPT_ASYM_PAUSE; 207 208 err = dpmac_set_link_state(mac->mc_io, 0, 209 mac->mc_dev->mc_handle, dpmac_state); 210 if (err) 211 netdev_err(mac->net_dev, "%s: dpmac_set_link_state() = %d\n", 212 __func__, err); 213 } 214 215 static void dpaa2_mac_link_down(struct phylink_config *config, 216 unsigned int mode, 217 phy_interface_t interface) 218 { 219 struct dpaa2_mac *mac = phylink_to_dpaa2_mac(config); 220 struct dpmac_link_state *dpmac_state = &mac->state; 221 int err; 222 223 dpmac_state->up = 0; 224 err = dpmac_set_link_state(mac->mc_io, 0, 225 mac->mc_dev->mc_handle, dpmac_state); 226 if (err) 227 netdev_err(mac->net_dev, "dpmac_set_link_state() = %d\n", err); 228 } 229 230 static const struct phylink_mac_ops dpaa2_mac_phylink_ops = { 231 .validate = dpaa2_mac_validate, 232 .mac_config = dpaa2_mac_config, 233 .mac_link_up = dpaa2_mac_link_up, 234 .mac_link_down = dpaa2_mac_link_down, 235 }; 236 237 static int dpaa2_pcs_create(struct dpaa2_mac *mac, 238 struct device_node *dpmac_node, int id) 239 { 240 struct mdio_device *mdiodev; 241 struct device_node *node; 242 243 node = of_parse_phandle(dpmac_node, "pcs-handle", 0); 244 if (!node) { 245 /* do not error out on old DTS files */ 246 netdev_warn(mac->net_dev, "pcs-handle node not found\n"); 247 return 0; 248 } 249 250 if (!of_device_is_available(node)) { 251 netdev_err(mac->net_dev, "pcs-handle node not available\n"); 252 of_node_put(node); 253 return -ENODEV; 254 } 255 256 mdiodev = of_mdio_find_device(node); 257 of_node_put(node); 258 if (!mdiodev) 259 return -EPROBE_DEFER; 260 261 mac->pcs = lynx_pcs_create(mdiodev); 262 if (!mac->pcs) { 263 netdev_err(mac->net_dev, "lynx_pcs_create() failed\n"); 264 put_device(&mdiodev->dev); 265 return -ENOMEM; 266 } 267 268 return 0; 269 } 270 271 static void dpaa2_pcs_destroy(struct dpaa2_mac *mac) 272 { 273 struct lynx_pcs *pcs = mac->pcs; 274 275 if (pcs) { 276 struct device *dev = &pcs->mdio->dev; 277 lynx_pcs_destroy(pcs); 278 put_device(dev); 279 mac->pcs = NULL; 280 } 281 } 282 283 int dpaa2_mac_connect(struct dpaa2_mac *mac) 284 { 285 struct net_device *net_dev = mac->net_dev; 286 struct device_node *dpmac_node; 287 struct phylink *phylink; 288 int err; 289 290 mac->if_link_type = mac->attr.link_type; 291 292 dpmac_node = dpaa2_mac_get_node(mac->attr.id); 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 err = -EINVAL; 301 goto err_put_node; 302 } 303 mac->if_mode = err; 304 305 /* The MAC does not have the capability to add RGMII delays so 306 * error out if the interface mode requests them and there is no PHY 307 * to act upon them 308 */ 309 if (of_phy_is_fixed_link(dpmac_node) && 310 (mac->if_mode == PHY_INTERFACE_MODE_RGMII_ID || 311 mac->if_mode == PHY_INTERFACE_MODE_RGMII_RXID || 312 mac->if_mode == PHY_INTERFACE_MODE_RGMII_TXID)) { 313 netdev_err(net_dev, "RGMII delay not supported\n"); 314 err = -EINVAL; 315 goto err_put_node; 316 } 317 318 if ((mac->attr.link_type == DPMAC_LINK_TYPE_PHY && 319 mac->attr.eth_if != DPMAC_ETH_IF_RGMII) || 320 mac->attr.link_type == DPMAC_LINK_TYPE_BACKPLANE) { 321 err = dpaa2_pcs_create(mac, dpmac_node, mac->attr.id); 322 if (err) 323 goto err_put_node; 324 } 325 326 mac->phylink_config.dev = &net_dev->dev; 327 mac->phylink_config.type = PHYLINK_NETDEV; 328 329 phylink = phylink_create(&mac->phylink_config, 330 of_fwnode_handle(dpmac_node), mac->if_mode, 331 &dpaa2_mac_phylink_ops); 332 if (IS_ERR(phylink)) { 333 err = PTR_ERR(phylink); 334 goto err_pcs_destroy; 335 } 336 mac->phylink = phylink; 337 338 if (mac->pcs) 339 phylink_set_pcs(mac->phylink, &mac->pcs->pcs); 340 341 err = phylink_of_phy_connect(mac->phylink, dpmac_node, 0); 342 if (err) { 343 netdev_err(net_dev, "phylink_of_phy_connect() = %d\n", err); 344 goto err_phylink_destroy; 345 } 346 347 of_node_put(dpmac_node); 348 349 return 0; 350 351 err_phylink_destroy: 352 phylink_destroy(mac->phylink); 353 err_pcs_destroy: 354 dpaa2_pcs_destroy(mac); 355 err_put_node: 356 of_node_put(dpmac_node); 357 358 return err; 359 } 360 361 void dpaa2_mac_disconnect(struct dpaa2_mac *mac) 362 { 363 if (!mac->phylink) 364 return; 365 366 phylink_disconnect_phy(mac->phylink); 367 phylink_destroy(mac->phylink); 368 dpaa2_pcs_destroy(mac); 369 } 370 371 int dpaa2_mac_open(struct dpaa2_mac *mac) 372 { 373 struct fsl_mc_device *dpmac_dev = mac->mc_dev; 374 struct net_device *net_dev = mac->net_dev; 375 int err; 376 377 err = dpmac_open(mac->mc_io, 0, dpmac_dev->obj_desc.id, 378 &dpmac_dev->mc_handle); 379 if (err || !dpmac_dev->mc_handle) { 380 netdev_err(net_dev, "dpmac_open() = %d\n", err); 381 return -ENODEV; 382 } 383 384 err = dpmac_get_attributes(mac->mc_io, 0, dpmac_dev->mc_handle, 385 &mac->attr); 386 if (err) { 387 netdev_err(net_dev, "dpmac_get_attributes() = %d\n", err); 388 goto err_close_dpmac; 389 } 390 391 return 0; 392 393 err_close_dpmac: 394 dpmac_close(mac->mc_io, 0, dpmac_dev->mc_handle); 395 return err; 396 } 397 398 void dpaa2_mac_close(struct dpaa2_mac *mac) 399 { 400 struct fsl_mc_device *dpmac_dev = mac->mc_dev; 401 402 dpmac_close(mac->mc_io, 0, dpmac_dev->mc_handle); 403 } 404 405 static char dpaa2_mac_ethtool_stats[][ETH_GSTRING_LEN] = { 406 [DPMAC_CNT_ING_ALL_FRAME] = "[mac] rx all frames", 407 [DPMAC_CNT_ING_GOOD_FRAME] = "[mac] rx frames ok", 408 [DPMAC_CNT_ING_ERR_FRAME] = "[mac] rx frame errors", 409 [DPMAC_CNT_ING_FRAME_DISCARD] = "[mac] rx frame discards", 410 [DPMAC_CNT_ING_UCAST_FRAME] = "[mac] rx u-cast", 411 [DPMAC_CNT_ING_BCAST_FRAME] = "[mac] rx b-cast", 412 [DPMAC_CNT_ING_MCAST_FRAME] = "[mac] rx m-cast", 413 [DPMAC_CNT_ING_FRAME_64] = "[mac] rx 64 bytes", 414 [DPMAC_CNT_ING_FRAME_127] = "[mac] rx 65-127 bytes", 415 [DPMAC_CNT_ING_FRAME_255] = "[mac] rx 128-255 bytes", 416 [DPMAC_CNT_ING_FRAME_511] = "[mac] rx 256-511 bytes", 417 [DPMAC_CNT_ING_FRAME_1023] = "[mac] rx 512-1023 bytes", 418 [DPMAC_CNT_ING_FRAME_1518] = "[mac] rx 1024-1518 bytes", 419 [DPMAC_CNT_ING_FRAME_1519_MAX] = "[mac] rx 1519-max bytes", 420 [DPMAC_CNT_ING_FRAG] = "[mac] rx frags", 421 [DPMAC_CNT_ING_JABBER] = "[mac] rx jabber", 422 [DPMAC_CNT_ING_ALIGN_ERR] = "[mac] rx align errors", 423 [DPMAC_CNT_ING_OVERSIZED] = "[mac] rx oversized", 424 [DPMAC_CNT_ING_VALID_PAUSE_FRAME] = "[mac] rx pause", 425 [DPMAC_CNT_ING_BYTE] = "[mac] rx bytes", 426 [DPMAC_CNT_EGR_GOOD_FRAME] = "[mac] tx frames ok", 427 [DPMAC_CNT_EGR_UCAST_FRAME] = "[mac] tx u-cast", 428 [DPMAC_CNT_EGR_MCAST_FRAME] = "[mac] tx m-cast", 429 [DPMAC_CNT_EGR_BCAST_FRAME] = "[mac] tx b-cast", 430 [DPMAC_CNT_EGR_ERR_FRAME] = "[mac] tx frame errors", 431 [DPMAC_CNT_EGR_UNDERSIZED] = "[mac] tx undersized", 432 [DPMAC_CNT_EGR_VALID_PAUSE_FRAME] = "[mac] tx b-pause", 433 [DPMAC_CNT_EGR_BYTE] = "[mac] tx bytes", 434 }; 435 436 #define DPAA2_MAC_NUM_STATS ARRAY_SIZE(dpaa2_mac_ethtool_stats) 437 438 int dpaa2_mac_get_sset_count(void) 439 { 440 return DPAA2_MAC_NUM_STATS; 441 } 442 443 void dpaa2_mac_get_strings(u8 *data) 444 { 445 u8 *p = data; 446 int i; 447 448 for (i = 0; i < DPAA2_MAC_NUM_STATS; i++) { 449 strlcpy(p, dpaa2_mac_ethtool_stats[i], ETH_GSTRING_LEN); 450 p += ETH_GSTRING_LEN; 451 } 452 } 453 454 void dpaa2_mac_get_ethtool_stats(struct dpaa2_mac *mac, u64 *data) 455 { 456 struct fsl_mc_device *dpmac_dev = mac->mc_dev; 457 int i, err; 458 u64 value; 459 460 for (i = 0; i < DPAA2_MAC_NUM_STATS; i++) { 461 err = dpmac_get_counter(mac->mc_io, 0, dpmac_dev->mc_handle, 462 i, &value); 463 if (err) { 464 netdev_err_once(mac->net_dev, 465 "dpmac_get_counter error %d\n", err); 466 *(data + i) = U64_MAX; 467 continue; 468 } 469 *(data + i) = value; 470 } 471 } 472