1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright 2019-2021 NXP 4 */ 5 6#include <net/dsa.h> 7#include <dm/lists.h> 8#include <dm/device_compat.h> 9#include <dm/device-internal.h> 10#include <dm/uclass-internal.h> 11#include <linux/bitmap.h> 12#include <miiphy.h> 13 14#define DSA_PORT_CHILD_DRV_NAME "dsa-port" 15 16/* per-device internal state structure */ 17struct dsa_priv { 18 struct phy_device *cpu_port_fixed_phy; 19 struct udevice *master_dev; 20 int num_ports; 21 u32 cpu_port; 22 int headroom; 23 int tailroom; 24}; 25 26/* external API */ 27int dsa_set_tagging(struct udevice *dev, ushort headroom, ushort tailroom) 28{ 29 struct dsa_priv *priv; 30 31 if (!dev) 32 return -EINVAL; 33 34 if (headroom + tailroom > DSA_MAX_OVR) 35 return -EINVAL; 36 37 priv = dev_get_uclass_priv(dev); 38 39 if (headroom > 0) 40 priv->headroom = headroom; 41 if (tailroom > 0) 42 priv->tailroom = tailroom; 43 44 return 0; 45} 46 47ofnode dsa_port_get_ofnode(struct udevice *dev, int port) 48{ 49 struct dsa_pdata *pdata = dev_get_uclass_plat(dev); 50 struct dsa_port_pdata *port_pdata; 51 struct udevice *pdev; 52 53 if (port == pdata->cpu_port) 54 return pdata->cpu_port_node; 55 56 for (device_find_first_child(dev, &pdev); 57 pdev; 58 device_find_next_child(&pdev)) { 59 port_pdata = dev_get_parent_plat(pdev); 60 if (port_pdata->index == port) 61 return dev_ofnode(pdev); 62 } 63 64 return ofnode_null(); 65} 66 67/* returns the DSA master Ethernet device */ 68struct udevice *dsa_get_master(struct udevice *dev) 69{ 70 struct dsa_priv *priv; 71 72 if (!dev) 73 return NULL; 74 75 priv = dev_get_uclass_priv(dev); 76 77 return priv->master_dev; 78} 79 80/* 81 * Start the desired port, the CPU port and the master Eth interface. 82 * TODO: if cascaded we may need to _start ports in other switches too 83 */ 84static int dsa_port_start(struct udevice *pdev) 85{ 86 struct udevice *dev = dev_get_parent(pdev); 87 struct dsa_priv *priv = dev_get_uclass_priv(dev); 88 struct udevice *master = dsa_get_master(dev); 89 struct dsa_ops *ops = dsa_get_ops(dev); 90 int err; 91 92 if (ops->port_enable) { 93 struct dsa_port_pdata *port_pdata; 94 95 port_pdata = dev_get_parent_plat(pdev); 96 err = ops->port_enable(dev, port_pdata->index, 97 port_pdata->phy); 98 if (err) 99 return err; 100 101 err = ops->port_enable(dev, priv->cpu_port, 102 priv->cpu_port_fixed_phy); 103 if (err) 104 return err; 105 } 106 107 return eth_get_ops(master)->start(master); 108} 109 110/* Stop the desired port, the CPU port and the master Eth interface */ 111static void dsa_port_stop(struct udevice *pdev) 112{ 113 struct udevice *dev = dev_get_parent(pdev); 114 struct dsa_priv *priv = dev_get_uclass_priv(dev); 115 struct udevice *master = dsa_get_master(dev); 116 struct dsa_ops *ops = dsa_get_ops(dev); 117 118 if (ops->port_disable) { 119 struct dsa_port_pdata *port_pdata; 120 121 port_pdata = dev_get_parent_plat(pdev); 122 ops->port_disable(dev, port_pdata->index, port_pdata->phy); 123 ops->port_disable(dev, priv->cpu_port, priv->cpu_port_fixed_phy); 124 } 125 126 eth_get_ops(master)->stop(master); 127} 128 129/* 130 * Insert a DSA tag and call master Ethernet send on the resulting packet 131 * We copy the frame to a stack buffer where we have reserved headroom and 132 * tailroom space. Headroom and tailroom are set to 0. 133 */ 134static int dsa_port_send(struct udevice *pdev, void *packet, int length) 135{ 136 struct udevice *dev = dev_get_parent(pdev); 137 struct dsa_priv *priv = dev_get_uclass_priv(dev); 138 int head = priv->headroom, tail = priv->tailroom; 139 struct udevice *master = dsa_get_master(dev); 140 struct dsa_ops *ops = dsa_get_ops(dev); 141 uchar dsa_packet_tmp[PKTSIZE_ALIGN]; 142 struct dsa_port_pdata *port_pdata; 143 int err; 144 145 if (ops->xmit) { 146 if (length + head + tail > PKTSIZE_ALIGN) 147 return -EINVAL; 148 149 memset(dsa_packet_tmp, 0, head); 150 memset(dsa_packet_tmp + head + length, 0, tail); 151 memcpy(dsa_packet_tmp + head, packet, length); 152 length += head + tail; 153 /* copy back to preserve original buffer alignment */ 154 memcpy(packet, dsa_packet_tmp, length); 155 156 port_pdata = dev_get_parent_plat(pdev); 157 err = ops->xmit(dev, port_pdata->index, packet, length); 158 if (err) 159 return err; 160 } 161 162 return eth_get_ops(master)->send(master, packet, length); 163} 164 165/* Receive a frame from master Ethernet, process it and pass it on */ 166static int dsa_port_recv(struct udevice *pdev, int flags, uchar **packetp) 167{ 168 struct udevice *dev = dev_get_parent(pdev); 169 struct dsa_priv *priv = dev_get_uclass_priv(dev); 170 int head = priv->headroom, tail = priv->tailroom; 171 struct udevice *master = dsa_get_master(dev); 172 struct dsa_ops *ops = dsa_get_ops(dev); 173 struct dsa_port_pdata *port_pdata; 174 int length, port_index, err; 175 176 length = eth_get_ops(master)->recv(master, flags, packetp); 177 if (length <= 0 || !ops->rcv) 178 return length; 179 180 /* 181 * If we receive frames from a different port or frames that DSA driver 182 * doesn't like we discard them here. 183 * In case of discard we return with no frame and expect to be called 184 * again instead of looping here, so upper layer can deal with timeouts. 185 */ 186 port_pdata = dev_get_parent_plat(pdev); 187 err = ops->rcv(dev, &port_index, *packetp, length); 188 if (err || port_index != port_pdata->index || (length <= head + tail)) { 189 if (eth_get_ops(master)->free_pkt) 190 eth_get_ops(master)->free_pkt(master, *packetp, length); 191 return -EAGAIN; 192 } 193 194 /* 195 * We move the pointer over headroom here to avoid a copy. If free_pkt 196 * gets called we move the pointer back before calling master free_pkt. 197 */ 198 *packetp += head; 199 200 return length - head - tail; 201} 202 203static int dsa_port_free_pkt(struct udevice *pdev, uchar *packet, int length) 204{ 205 struct udevice *dev = dev_get_parent(pdev); 206 struct udevice *master = dsa_get_master(dev); 207 struct dsa_priv *priv; 208 209 priv = dev_get_uclass_priv(dev); 210 if (eth_get_ops(master)->free_pkt) { 211 /* return the original pointer and length to master Eth */ 212 packet -= priv->headroom; 213 length += priv->headroom - priv->tailroom; 214 215 return eth_get_ops(master)->free_pkt(master, packet, length); 216 } 217 218 return 0; 219} 220 221static int dsa_port_of_to_pdata(struct udevice *pdev) 222{ 223 struct dsa_port_pdata *port_pdata; 224 struct eth_pdata *eth_pdata; 225 const char *label; 226 u32 index; 227 int err; 228 229 if (!pdev) 230 return -ENODEV; 231 232 err = ofnode_read_u32(dev_ofnode(pdev), "reg", &index); 233 if (err) 234 return err; 235 236 port_pdata = dev_get_parent_plat(pdev); 237 port_pdata->index = index; 238 239 label = ofnode_read_string(dev_ofnode(pdev), "label"); 240 if (label) 241 strlcpy(port_pdata->name, label, DSA_PORT_NAME_LENGTH); 242 243 eth_pdata = dev_get_plat(pdev); 244 eth_pdata->priv_pdata = port_pdata; 245 246 dev_dbg(pdev, "port %d node %s\n", port_pdata->index, 247 ofnode_get_name(dev_ofnode(pdev))); 248 249 return 0; 250} 251 252static const struct eth_ops dsa_port_ops = { 253 .start = dsa_port_start, 254 .send = dsa_port_send, 255 .recv = dsa_port_recv, 256 .stop = dsa_port_stop, 257 .free_pkt = dsa_port_free_pkt, 258}; 259 260/* 261 * Inherit port's hwaddr from the DSA master, unless the port already has a 262 * unique MAC address specified in the environment. 263 */ 264static void dsa_port_set_hwaddr(struct udevice *pdev, struct udevice *master) 265{ 266 struct eth_pdata *eth_pdata, *master_pdata; 267 unsigned char env_enetaddr[ARP_HLEN]; 268 269 eth_env_get_enetaddr_by_index("eth", dev_seq(pdev), env_enetaddr); 270 if (!is_zero_ethaddr(env_enetaddr)) { 271 /* individual port mac addrs require master to be promisc */ 272 struct eth_ops *eth_ops = eth_get_ops(master); 273 274 if (eth_ops->set_promisc) 275 eth_ops->set_promisc(master, true); 276 277 return; 278 } 279 280 master_pdata = dev_get_plat(master); 281 eth_pdata = dev_get_plat(pdev); 282 memcpy(eth_pdata->enetaddr, master_pdata->enetaddr, ARP_HLEN); 283 eth_env_set_enetaddr_by_index("eth", dev_seq(pdev), 284 master_pdata->enetaddr); 285} 286 287static int dsa_port_probe(struct udevice *pdev) 288{ 289 struct udevice *dev = dev_get_parent(pdev); 290 struct dsa_ops *ops = dsa_get_ops(dev); 291 struct dsa_port_pdata *port_pdata; 292 struct udevice *master; 293 int err; 294 295 port_pdata = dev_get_parent_plat(pdev); 296 297 port_pdata->phy = dm_eth_phy_connect(pdev); 298 if (!port_pdata->phy) 299 return -ENODEV; 300 301 master = dsa_get_master(dev); 302 if (!master) 303 return -ENODEV; 304 305 /* 306 * Probe the master device. We depend on the master device for proper 307 * operation and we also need it for MAC inheritance below. 308 * 309 * TODO: we assume the master device is always there and doesn't get 310 * removed during runtime. 311 */ 312 err = device_probe(master); 313 if (err) 314 return err; 315 316 dsa_port_set_hwaddr(pdev, master); 317 318 if (ops->port_probe) { 319 err = ops->port_probe(dev, port_pdata->index, 320 port_pdata->phy); 321 if (err) 322 return err; 323 } 324 325 return 0; 326} 327 328static int dsa_port_remove(struct udevice *pdev) 329{ 330 struct dsa_port_pdata *port_pdata = dev_get_parent_plat(pdev); 331 332 port_pdata->phy = NULL; 333 334 return 0; 335} 336 337U_BOOT_DRIVER(dsa_port) = { 338 .name = DSA_PORT_CHILD_DRV_NAME, 339 .id = UCLASS_ETH, 340 .ops = &dsa_port_ops, 341 .probe = dsa_port_probe, 342 .remove = dsa_port_remove, 343 .of_to_plat = dsa_port_of_to_pdata, 344 .plat_auto = sizeof(struct eth_pdata), 345}; 346 347static int dsa_sanitize_ops(struct udevice *dev) 348{ 349 struct dsa_ops *ops = dsa_get_ops(dev); 350 351 if ((!ops->xmit || !ops->rcv) && 352 (!ops->port_enable && !ops->port_disable)) { 353 dev_err(dev, "Packets cannot be steered to ports\n"); 354 return -EINVAL; 355 } 356 357 return 0; 358} 359 360/* 361 * This function mostly deals with pulling information out of the device tree 362 * into the pdata structure. 363 * It goes through the list of switch ports, registers an eth device for each 364 * front panel port and identifies the cpu port connected to master eth device. 365 * TODO: support cascaded switches 366 */ 367static int dsa_post_bind(struct udevice *dev) 368{ 369 struct dsa_pdata *pdata = dev_get_uclass_plat(dev); 370 ofnode node = dev_ofnode(dev), pnode; 371 int i, err, first_err = 0; 372 373 if (!ofnode_valid(node)) 374 return -ENODEV; 375 376 err = dsa_sanitize_ops(dev); 377 if (err) 378 return err; 379 380 pdata->master_node = ofnode_null(); 381 382 node = ofnode_find_subnode(node, "ports"); 383 if (!ofnode_valid(node)) 384 node = ofnode_find_subnode(dev_ofnode(dev), "ethernet-ports"); 385 if (!ofnode_valid(node)) { 386 dev_err(dev, "ports node is missing under DSA device!\n"); 387 return -EINVAL; 388 } 389 390 pdata->num_ports = ofnode_get_child_count(node); 391 if (pdata->num_ports <= 0 || pdata->num_ports > DSA_MAX_PORTS) { 392 dev_err(dev, "invalid number of ports (%d)\n", 393 pdata->num_ports); 394 return -EINVAL; 395 } 396 397 /* look for the CPU port */ 398 ofnode_for_each_subnode(pnode, node) { 399 u32 ethernet; 400 401 if (ofnode_read_u32(pnode, "ethernet", ðernet)) 402 continue; 403 404 pdata->master_node = ofnode_get_by_phandle(ethernet); 405 pdata->cpu_port_node = pnode; 406 break; 407 } 408 409 if (!ofnode_valid(pdata->master_node)) { 410 dev_err(dev, "master eth node missing!\n"); 411 return -EINVAL; 412 } 413 414 if (ofnode_read_u32(pnode, "reg", &pdata->cpu_port)) { 415 dev_err(dev, "CPU port node not valid!\n"); 416 return -EINVAL; 417 } 418 419 dev_dbg(dev, "master node %s on port %d\n", 420 ofnode_get_name(pdata->master_node), pdata->cpu_port); 421 422 for (i = 0; i < pdata->num_ports; i++) { 423 char name[DSA_PORT_NAME_LENGTH]; 424 struct udevice *pdev; 425 426 /* 427 * If this is the CPU port don't register it as an ETH device, 428 * we skip it on purpose since I/O to/from it from the CPU 429 * isn't useful. 430 */ 431 if (i == pdata->cpu_port) 432 continue; 433 434 /* 435 * Set up default port names. If present, DT port labels 436 * will override the default port names. 437 */ 438 snprintf(name, DSA_PORT_NAME_LENGTH, "%s@%d", dev->name, i); 439 440 ofnode_for_each_subnode(pnode, node) { 441 u32 reg; 442 443 if (ofnode_read_u32(pnode, "reg", ®)) 444 continue; 445 446 if (reg == i) 447 break; 448 } 449 450 /* 451 * skip registration if port id not found or if the port 452 * is explicitly disabled in DT 453 */ 454 if (!ofnode_valid(pnode) || !ofnode_is_enabled(pnode)) 455 continue; 456 457 err = device_bind_driver_to_node(dev, DSA_PORT_CHILD_DRV_NAME, 458 name, pnode, &pdev); 459 if (pdev) { 460 struct dsa_port_pdata *port_pdata; 461 462 port_pdata = dev_get_parent_plat(pdev); 463 strlcpy(port_pdata->name, name, DSA_PORT_NAME_LENGTH); 464 pdev->name = port_pdata->name; 465 } 466 467 /* try to bind all ports but keep 1st error */ 468 if (err && !first_err) 469 first_err = err; 470 } 471 472 if (first_err) 473 return first_err; 474 475 dev_dbg(dev, "DSA ports successfully bound\n"); 476 477 return 0; 478} 479 480/** 481 * Initialize the uclass per device internal state structure (priv). 482 * TODO: pick up references to other switch devices here, if we're cascaded. 483 */ 484static int dsa_pre_probe(struct udevice *dev) 485{ 486 struct dsa_pdata *pdata = dev_get_uclass_plat(dev); 487 struct dsa_priv *priv = dev_get_uclass_priv(dev); 488 int err; 489 490 priv->num_ports = pdata->num_ports; 491 priv->cpu_port = pdata->cpu_port; 492 priv->cpu_port_fixed_phy = fixed_phy_create(pdata->cpu_port_node); 493 if (!priv->cpu_port_fixed_phy) { 494 dev_err(dev, "Failed to register fixed-link for CPU port\n"); 495 return -ENODEV; 496 } 497 498 err = uclass_get_device_by_ofnode(UCLASS_ETH, pdata->master_node, 499 &priv->master_dev); 500 if (err) 501 return err; 502 503 return 0; 504} 505 506static int dsa_post_probe(struct udevice *dev) 507{ 508 struct dsa_priv *priv = dev_get_uclass_priv(dev); 509 struct dsa_ops *ops = dsa_get_ops(dev); 510 int err; 511 512 /* Simulate a probing event for the CPU port */ 513 if (ops->port_probe) { 514 err = ops->port_probe(dev, priv->cpu_port, 515 priv->cpu_port_fixed_phy); 516 if (err) 517 return err; 518 } 519 520 return 0; 521} 522 523UCLASS_DRIVER(dsa) = { 524 .id = UCLASS_DSA, 525 .name = "dsa", 526 .post_bind = dsa_post_bind, 527 .pre_probe = dsa_pre_probe, 528 .post_probe = dsa_post_probe, 529 .per_device_auto = sizeof(struct dsa_priv), 530 .per_device_plat_auto = sizeof(struct dsa_pdata), 531 .per_child_plat_auto = sizeof(struct dsa_port_pdata), 532 .flags = DM_UC_FLAG_SEQ_ALIAS, 533}; 534