1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-or-later 2 /* 3 * Copyright 2008 - 2015 Freescale Semiconductor Inc. 4 */ 5 6 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 7 8 #include <linux/init.h> 9 #include <linux/module.h> 10 #include <linux/of_address.h> 11 #include <linux/of_platform.h> 12 #include <linux/of_net.h> 13 #include <linux/of_mdio.h> 14 #include <linux/device.h> 15 #include <linux/phy.h> 16 #include <linux/netdevice.h> 17 #include <linux/phy_fixed.h> 18 #include <linux/etherdevice.h> 19 #include <linux/libfdt_env.h> 20 21 #include "mac.h" 22 #include "fman_mac.h" 23 #include "fman_dtsec.h" 24 #include "fman_tgec.h" 25 #include "fman_memac.h" 26 27 MODULE_LICENSE("Dual BSD/GPL"); 28 MODULE_DESCRIPTION("FSL FMan MAC API based driver"); 29 30 struct mac_priv_s { 31 u8 cell_index; 32 struct fman *fman; 33 /* List of multicast addresses */ 34 struct list_head mc_addr_list; 35 struct platform_device *eth_dev; 36 u16 speed; 37 }; 38 39 struct mac_address { 40 u8 addr[ETH_ALEN]; 41 struct list_head list; 42 }; 43 44 static void mac_exception(struct mac_device *mac_dev, 45 enum fman_mac_exceptions ex) 46 { 47 if (ex == FM_MAC_EX_10G_RX_FIFO_OVFL) { 48 /* don't flag RX FIFO after the first */ 49 mac_dev->set_exception(mac_dev->fman_mac, 50 FM_MAC_EX_10G_RX_FIFO_OVFL, false); 51 dev_err(mac_dev->dev, "10G MAC got RX FIFO Error = %x\n", ex); 52 } 53 54 dev_dbg(mac_dev->dev, "%s:%s() -> %d\n", KBUILD_BASENAME ".c", 55 __func__, ex); 56 } 57 58 int fman_set_multi(struct net_device *net_dev, struct mac_device *mac_dev) 59 { 60 struct mac_priv_s *priv; 61 struct mac_address *old_addr, *tmp; 62 struct netdev_hw_addr *ha; 63 int err; 64 enet_addr_t *addr; 65 66 priv = mac_dev->priv; 67 68 /* Clear previous address list */ 69 list_for_each_entry_safe(old_addr, tmp, &priv->mc_addr_list, list) { 70 addr = (enet_addr_t *)old_addr->addr; 71 err = mac_dev->remove_hash_mac_addr(mac_dev->fman_mac, addr); 72 if (err < 0) 73 return err; 74 75 list_del(&old_addr->list); 76 kfree(old_addr); 77 } 78 79 /* Add all the addresses from the new list */ 80 netdev_for_each_mc_addr(ha, net_dev) { 81 addr = (enet_addr_t *)ha->addr; 82 err = mac_dev->add_hash_mac_addr(mac_dev->fman_mac, addr); 83 if (err < 0) 84 return err; 85 86 tmp = kmalloc(sizeof(*tmp), GFP_ATOMIC); 87 if (!tmp) 88 return -ENOMEM; 89 90 ether_addr_copy(tmp->addr, ha->addr); 91 list_add(&tmp->list, &priv->mc_addr_list); 92 } 93 return 0; 94 } 95 96 /** 97 * fman_set_mac_active_pause 98 * @mac_dev: A pointer to the MAC device 99 * @rx: Pause frame setting for RX 100 * @tx: Pause frame setting for TX 101 * 102 * Set the MAC RX/TX PAUSE frames settings 103 * 104 * Avoid redundant calls to FMD, if the MAC driver already contains the desired 105 * active PAUSE settings. Otherwise, the new active settings should be reflected 106 * in FMan. 107 * 108 * Return: 0 on success; Error code otherwise. 109 */ 110 int fman_set_mac_active_pause(struct mac_device *mac_dev, bool rx, bool tx) 111 { 112 struct fman_mac *fman_mac = mac_dev->fman_mac; 113 int err = 0; 114 115 if (rx != mac_dev->rx_pause_active) { 116 err = mac_dev->set_rx_pause(fman_mac, rx); 117 if (likely(err == 0)) 118 mac_dev->rx_pause_active = rx; 119 } 120 121 if (tx != mac_dev->tx_pause_active) { 122 u16 pause_time = (tx ? FSL_FM_PAUSE_TIME_ENABLE : 123 FSL_FM_PAUSE_TIME_DISABLE); 124 125 err = mac_dev->set_tx_pause(fman_mac, 0, pause_time, 0); 126 127 if (likely(err == 0)) 128 mac_dev->tx_pause_active = tx; 129 } 130 131 return err; 132 } 133 EXPORT_SYMBOL(fman_set_mac_active_pause); 134 135 /** 136 * fman_get_pause_cfg 137 * @mac_dev: A pointer to the MAC device 138 * @rx_pause: Return value for RX setting 139 * @tx_pause: Return value for TX setting 140 * 141 * Determine the MAC RX/TX PAUSE frames settings based on PHY 142 * autonegotiation or values set by eththool. 143 * 144 * Return: Pointer to FMan device. 145 */ 146 void fman_get_pause_cfg(struct mac_device *mac_dev, bool *rx_pause, 147 bool *tx_pause) 148 { 149 struct phy_device *phy_dev = mac_dev->phy_dev; 150 u16 lcl_adv, rmt_adv; 151 u8 flowctrl; 152 153 *rx_pause = *tx_pause = false; 154 155 if (!phy_dev->duplex) 156 return; 157 158 /* If PAUSE autonegotiation is disabled, the TX/RX PAUSE settings 159 * are those set by ethtool. 160 */ 161 if (!mac_dev->autoneg_pause) { 162 *rx_pause = mac_dev->rx_pause_req; 163 *tx_pause = mac_dev->tx_pause_req; 164 return; 165 } 166 167 /* Else if PAUSE autonegotiation is enabled, the TX/RX PAUSE 168 * settings depend on the result of the link negotiation. 169 */ 170 171 /* get local capabilities */ 172 lcl_adv = linkmode_adv_to_lcl_adv_t(phy_dev->advertising); 173 174 /* get link partner capabilities */ 175 rmt_adv = 0; 176 if (phy_dev->pause) 177 rmt_adv |= LPA_PAUSE_CAP; 178 if (phy_dev->asym_pause) 179 rmt_adv |= LPA_PAUSE_ASYM; 180 181 /* Calculate TX/RX settings based on local and peer advertised 182 * symmetric/asymmetric PAUSE capabilities. 183 */ 184 flowctrl = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv); 185 if (flowctrl & FLOW_CTRL_RX) 186 *rx_pause = true; 187 if (flowctrl & FLOW_CTRL_TX) 188 *tx_pause = true; 189 } 190 EXPORT_SYMBOL(fman_get_pause_cfg); 191 192 #define DTSEC_SUPPORTED \ 193 (SUPPORTED_10baseT_Half \ 194 | SUPPORTED_10baseT_Full \ 195 | SUPPORTED_100baseT_Half \ 196 | SUPPORTED_100baseT_Full \ 197 | SUPPORTED_Autoneg \ 198 | SUPPORTED_Pause \ 199 | SUPPORTED_Asym_Pause \ 200 | SUPPORTED_FIBRE \ 201 | SUPPORTED_MII) 202 203 static DEFINE_MUTEX(eth_lock); 204 205 static const u16 phy2speed[] = { 206 [PHY_INTERFACE_MODE_MII] = SPEED_100, 207 [PHY_INTERFACE_MODE_GMII] = SPEED_1000, 208 [PHY_INTERFACE_MODE_SGMII] = SPEED_1000, 209 [PHY_INTERFACE_MODE_TBI] = SPEED_1000, 210 [PHY_INTERFACE_MODE_RMII] = SPEED_100, 211 [PHY_INTERFACE_MODE_RGMII] = SPEED_1000, 212 [PHY_INTERFACE_MODE_RGMII_ID] = SPEED_1000, 213 [PHY_INTERFACE_MODE_RGMII_RXID] = SPEED_1000, 214 [PHY_INTERFACE_MODE_RGMII_TXID] = SPEED_1000, 215 [PHY_INTERFACE_MODE_RTBI] = SPEED_1000, 216 [PHY_INTERFACE_MODE_QSGMII] = SPEED_1000, 217 [PHY_INTERFACE_MODE_XGMII] = SPEED_10000 218 }; 219 220 static struct platform_device *dpaa_eth_add_device(int fman_id, 221 struct mac_device *mac_dev) 222 { 223 struct platform_device *pdev; 224 struct dpaa_eth_data data; 225 struct mac_priv_s *priv; 226 static int dpaa_eth_dev_cnt; 227 int ret; 228 229 priv = mac_dev->priv; 230 231 data.mac_dev = mac_dev; 232 data.mac_hw_id = priv->cell_index; 233 data.fman_hw_id = fman_id; 234 235 mutex_lock(ð_lock); 236 pdev = platform_device_alloc("dpaa-ethernet", dpaa_eth_dev_cnt); 237 if (!pdev) { 238 ret = -ENOMEM; 239 goto no_mem; 240 } 241 242 pdev->dev.parent = mac_dev->dev; 243 244 ret = platform_device_add_data(pdev, &data, sizeof(data)); 245 if (ret) 246 goto err; 247 248 ret = platform_device_add(pdev); 249 if (ret) 250 goto err; 251 252 dpaa_eth_dev_cnt++; 253 mutex_unlock(ð_lock); 254 255 return pdev; 256 257 err: 258 platform_device_put(pdev); 259 no_mem: 260 mutex_unlock(ð_lock); 261 262 return ERR_PTR(ret); 263 } 264 265 static const struct of_device_id mac_match[] = { 266 { .compatible = "fsl,fman-dtsec", .data = dtsec_initialization }, 267 { .compatible = "fsl,fman-xgec", .data = tgec_initialization }, 268 { .compatible = "fsl,fman-memac", .data = memac_initialization }, 269 {} 270 }; 271 MODULE_DEVICE_TABLE(of, mac_match); 272 273 static int mac_probe(struct platform_device *_of_dev) 274 { 275 int err, i, nph; 276 int (*init)(struct mac_device *mac_dev, struct device_node *mac_node, 277 struct fman_mac_params *params); 278 struct device *dev; 279 struct device_node *mac_node, *dev_node; 280 struct mac_device *mac_dev; 281 struct platform_device *of_dev; 282 struct resource *res; 283 struct mac_priv_s *priv; 284 struct fman_mac_params params; 285 u32 val; 286 u8 fman_id; 287 phy_interface_t phy_if; 288 289 dev = &_of_dev->dev; 290 mac_node = dev->of_node; 291 init = of_device_get_match_data(dev); 292 293 mac_dev = devm_kzalloc(dev, sizeof(*mac_dev), GFP_KERNEL); 294 if (!mac_dev) 295 return -ENOMEM; 296 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 297 if (!priv) 298 return -ENOMEM; 299 300 /* Save private information */ 301 mac_dev->priv = priv; 302 mac_dev->dev = dev; 303 304 INIT_LIST_HEAD(&priv->mc_addr_list); 305 306 /* Get the FM node */ 307 dev_node = of_get_parent(mac_node); 308 if (!dev_node) { 309 dev_err(dev, "of_get_parent(%pOF) failed\n", 310 mac_node); 311 return -EINVAL; 312 } 313 314 of_dev = of_find_device_by_node(dev_node); 315 if (!of_dev) { 316 dev_err(dev, "of_find_device_by_node(%pOF) failed\n", dev_node); 317 err = -EINVAL; 318 goto _return_of_node_put; 319 } 320 321 /* Get the FMan cell-index */ 322 err = of_property_read_u32(dev_node, "cell-index", &val); 323 if (err) { 324 dev_err(dev, "failed to read cell-index for %pOF\n", dev_node); 325 err = -EINVAL; 326 goto _return_of_node_put; 327 } 328 /* cell-index 0 => FMan id 1 */ 329 fman_id = (u8)(val + 1); 330 331 priv->fman = fman_bind(&of_dev->dev); 332 if (!priv->fman) { 333 dev_err(dev, "fman_bind(%pOF) failed\n", dev_node); 334 err = -ENODEV; 335 goto _return_of_node_put; 336 } 337 338 of_node_put(dev_node); 339 340 /* Get the address of the memory mapped registers */ 341 res = platform_get_mem_or_io(_of_dev, 0); 342 if (!res) { 343 dev_err(dev, "could not get registers\n"); 344 return -EINVAL; 345 } 346 347 err = devm_request_resource(dev, fman_get_mem_region(priv->fman), res); 348 if (err) { 349 dev_err_probe(dev, err, "could not request resource\n"); 350 return err; 351 } 352 353 mac_dev->vaddr = devm_ioremap(dev, res->start, resource_size(res)); 354 if (!mac_dev->vaddr) { 355 dev_err(dev, "devm_ioremap() failed\n"); 356 return -EIO; 357 } 358 mac_dev->vaddr_end = mac_dev->vaddr + resource_size(res); 359 360 if (!of_device_is_available(mac_node)) 361 return -ENODEV; 362 363 /* Get the cell-index */ 364 err = of_property_read_u32(mac_node, "cell-index", &val); 365 if (err) { 366 dev_err(dev, "failed to read cell-index for %pOF\n", mac_node); 367 return -EINVAL; 368 } 369 priv->cell_index = (u8)val; 370 371 /* Get the MAC address */ 372 err = of_get_mac_address(mac_node, mac_dev->addr); 373 if (err) 374 dev_warn(dev, "of_get_mac_address(%pOF) failed\n", mac_node); 375 376 /* Get the port handles */ 377 nph = of_count_phandle_with_args(mac_node, "fsl,fman-ports", NULL); 378 if (unlikely(nph < 0)) { 379 dev_err(dev, "of_count_phandle_with_args(%pOF, fsl,fman-ports) failed\n", 380 mac_node); 381 return nph; 382 } 383 384 if (nph != ARRAY_SIZE(mac_dev->port)) { 385 dev_err(dev, "Not supported number of fman-ports handles of mac node %pOF from device tree\n", 386 mac_node); 387 return -EINVAL; 388 } 389 390 for (i = 0; i < ARRAY_SIZE(mac_dev->port); i++) { 391 /* Find the port node */ 392 dev_node = of_parse_phandle(mac_node, "fsl,fman-ports", i); 393 if (!dev_node) { 394 dev_err(dev, "of_parse_phandle(%pOF, fsl,fman-ports) failed\n", 395 mac_node); 396 return -EINVAL; 397 } 398 399 of_dev = of_find_device_by_node(dev_node); 400 if (!of_dev) { 401 dev_err(dev, "of_find_device_by_node(%pOF) failed\n", 402 dev_node); 403 err = -EINVAL; 404 goto _return_of_node_put; 405 } 406 407 mac_dev->port[i] = fman_port_bind(&of_dev->dev); 408 if (!mac_dev->port[i]) { 409 dev_err(dev, "dev_get_drvdata(%pOF) failed\n", 410 dev_node); 411 err = -EINVAL; 412 goto _return_of_node_put; 413 } 414 of_node_put(dev_node); 415 } 416 417 /* Get the PHY connection type */ 418 err = of_get_phy_mode(mac_node, &phy_if); 419 if (err) { 420 dev_warn(dev, 421 "of_get_phy_mode() for %pOF failed. Defaulting to SGMII\n", 422 mac_node); 423 phy_if = PHY_INTERFACE_MODE_SGMII; 424 } 425 mac_dev->phy_if = phy_if; 426 427 priv->speed = phy2speed[mac_dev->phy_if]; 428 params.max_speed = priv->speed; 429 mac_dev->if_support = DTSEC_SUPPORTED; 430 /* We don't support half-duplex in SGMII mode */ 431 if (mac_dev->phy_if == PHY_INTERFACE_MODE_SGMII) 432 mac_dev->if_support &= ~(SUPPORTED_10baseT_Half | 433 SUPPORTED_100baseT_Half); 434 435 /* Gigabit support (no half-duplex) */ 436 if (params.max_speed == 1000) 437 mac_dev->if_support |= SUPPORTED_1000baseT_Full; 438 439 /* The 10G interface only supports one mode */ 440 if (mac_dev->phy_if == PHY_INTERFACE_MODE_XGMII) 441 mac_dev->if_support = SUPPORTED_10000baseT_Full; 442 443 /* Get the rest of the PHY information */ 444 mac_dev->phy_node = of_parse_phandle(mac_node, "phy-handle", 0); 445 446 params.basex_if = false; 447 params.mac_id = priv->cell_index; 448 params.fm = (void *)priv->fman; 449 params.exception_cb = mac_exception; 450 params.event_cb = mac_exception; 451 452 err = init(mac_dev, mac_node, ¶ms); 453 if (err < 0) { 454 dev_err(dev, "mac_dev->init() = %d\n", err); 455 of_node_put(mac_dev->phy_node); 456 return err; 457 } 458 459 /* pause frame autonegotiation enabled */ 460 mac_dev->autoneg_pause = true; 461 462 /* By intializing the values to false, force FMD to enable PAUSE frames 463 * on RX and TX 464 */ 465 mac_dev->rx_pause_req = true; 466 mac_dev->tx_pause_req = true; 467 mac_dev->rx_pause_active = false; 468 mac_dev->tx_pause_active = false; 469 err = fman_set_mac_active_pause(mac_dev, true, true); 470 if (err < 0) 471 dev_err(dev, "fman_set_mac_active_pause() = %d\n", err); 472 473 if (!is_zero_ether_addr(mac_dev->addr)) 474 dev_info(dev, "FMan MAC address: %pM\n", mac_dev->addr); 475 476 priv->eth_dev = dpaa_eth_add_device(fman_id, mac_dev); 477 if (IS_ERR(priv->eth_dev)) { 478 dev_err(dev, "failed to add Ethernet platform device for MAC %d\n", 479 priv->cell_index); 480 priv->eth_dev = NULL; 481 } 482 483 return err; 484 485 _return_of_node_put: 486 of_node_put(dev_node); 487 return err; 488 } 489 490 static struct platform_driver mac_driver = { 491 .driver = { 492 .name = KBUILD_MODNAME, 493 .of_match_table = mac_match, 494 }, 495 .probe = mac_probe, 496 }; 497 498 builtin_platform_driver(mac_driver); 499