.. | .. |
---|
11 | 11 | #include <linux/device.h> |
---|
12 | 12 | #include <linux/skbuff.h> |
---|
13 | 13 | #include <linux/if_vlan.h> |
---|
14 | | -#include <net/switchdev.h> |
---|
15 | 14 | |
---|
16 | 15 | #include "pci.h" |
---|
17 | 16 | #include "core.h" |
---|
.. | .. |
---|
181 | 180 | if (err) |
---|
182 | 181 | return err; |
---|
183 | 182 | oper_status = mlxsw_reg_paos_oper_status_get(paos_pl); |
---|
184 | | - *p_is_up = oper_status == MLXSW_PORT_ADMIN_STATUS_UP ? true : false; |
---|
| 183 | + *p_is_up = oper_status == MLXSW_PORT_ADMIN_STATUS_UP; |
---|
185 | 184 | return 0; |
---|
186 | 185 | } |
---|
187 | 186 | |
---|
.. | .. |
---|
300 | 299 | u64 len; |
---|
301 | 300 | int err; |
---|
302 | 301 | |
---|
| 302 | + if (skb_cow_head(skb, MLXSW_TXHDR_LEN)) { |
---|
| 303 | + this_cpu_inc(mlxsw_sx_port->pcpu_stats->tx_dropped); |
---|
| 304 | + dev_kfree_skb_any(skb); |
---|
| 305 | + return NETDEV_TX_OK; |
---|
| 306 | + } |
---|
| 307 | + |
---|
| 308 | + memset(skb->cb, 0, sizeof(struct mlxsw_skb_cb)); |
---|
| 309 | + |
---|
303 | 310 | if (mlxsw_core_skb_transmit_busy(mlxsw_sx->core, &tx_info)) |
---|
304 | 311 | return NETDEV_TX_BUSY; |
---|
305 | 312 | |
---|
306 | | - if (unlikely(skb_headroom(skb) < MLXSW_TXHDR_LEN)) { |
---|
307 | | - struct sk_buff *skb_orig = skb; |
---|
308 | | - |
---|
309 | | - skb = skb_realloc_headroom(skb, MLXSW_TXHDR_LEN); |
---|
310 | | - if (!skb) { |
---|
311 | | - this_cpu_inc(mlxsw_sx_port->pcpu_stats->tx_dropped); |
---|
312 | | - dev_kfree_skb_any(skb_orig); |
---|
313 | | - return NETDEV_TX_OK; |
---|
314 | | - } |
---|
315 | | - dev_consume_skb_any(skb_orig); |
---|
316 | | - } |
---|
317 | 313 | mlxsw_sx_txhdr_construct(skb, &tx_info); |
---|
318 | 314 | /* TX header is consumed by HW on the way so we shouldn't count its |
---|
319 | 315 | * bytes as being sent. |
---|
.. | .. |
---|
380 | 376 | stats->tx_dropped = tx_dropped; |
---|
381 | 377 | } |
---|
382 | 378 | |
---|
383 | | -static int mlxsw_sx_port_get_phys_port_name(struct net_device *dev, char *name, |
---|
384 | | - size_t len) |
---|
| 379 | +static struct devlink_port * |
---|
| 380 | +mlxsw_sx_port_get_devlink_port(struct net_device *dev) |
---|
385 | 381 | { |
---|
386 | 382 | struct mlxsw_sx_port *mlxsw_sx_port = netdev_priv(dev); |
---|
| 383 | + struct mlxsw_sx *mlxsw_sx = mlxsw_sx_port->mlxsw_sx; |
---|
387 | 384 | |
---|
388 | | - return mlxsw_core_port_get_phys_port_name(mlxsw_sx_port->mlxsw_sx->core, |
---|
389 | | - mlxsw_sx_port->local_port, |
---|
390 | | - name, len); |
---|
| 385 | + return mlxsw_core_port_devlink_port_get(mlxsw_sx->core, |
---|
| 386 | + mlxsw_sx_port->local_port); |
---|
391 | 387 | } |
---|
392 | 388 | |
---|
393 | 389 | static const struct net_device_ops mlxsw_sx_port_netdev_ops = { |
---|
.. | .. |
---|
396 | 392 | .ndo_start_xmit = mlxsw_sx_port_xmit, |
---|
397 | 393 | .ndo_change_mtu = mlxsw_sx_port_change_mtu, |
---|
398 | 394 | .ndo_get_stats64 = mlxsw_sx_port_get_stats64, |
---|
399 | | - .ndo_get_phys_port_name = mlxsw_sx_port_get_phys_port_name, |
---|
| 395 | + .ndo_get_devlink_port = mlxsw_sx_port_get_devlink_port, |
---|
400 | 396 | }; |
---|
401 | 397 | |
---|
402 | 398 | static void mlxsw_sx_port_get_drvinfo(struct net_device *dev, |
---|
.. | .. |
---|
555 | 551 | |
---|
556 | 552 | static const struct mlxsw_sx_port_link_mode mlxsw_sx_port_link_mode[] = { |
---|
557 | 553 | { |
---|
558 | | - .mask = MLXSW_REG_PTYS_ETH_SPEED_100BASE_T, |
---|
559 | | - .supported = SUPPORTED_100baseT_Full, |
---|
560 | | - .advertised = ADVERTISED_100baseT_Full, |
---|
561 | | - .speed = 100, |
---|
562 | | - }, |
---|
563 | | - { |
---|
564 | | - .mask = MLXSW_REG_PTYS_ETH_SPEED_100BASE_TX, |
---|
565 | | - .speed = 100, |
---|
566 | | - }, |
---|
567 | | - { |
---|
568 | 554 | .mask = MLXSW_REG_PTYS_ETH_SPEED_SGMII | |
---|
569 | 555 | MLXSW_REG_PTYS_ETH_SPEED_1000BASE_KX, |
---|
570 | 556 | .supported = SUPPORTED_1000baseKX_Full, |
---|
571 | 557 | .advertised = ADVERTISED_1000baseKX_Full, |
---|
572 | 558 | .speed = 1000, |
---|
573 | | - }, |
---|
574 | | - { |
---|
575 | | - .mask = MLXSW_REG_PTYS_ETH_SPEED_10GBASE_T, |
---|
576 | | - .supported = SUPPORTED_10000baseT_Full, |
---|
577 | | - .advertised = ADVERTISED_10000baseT_Full, |
---|
578 | | - .speed = 10000, |
---|
579 | 559 | }, |
---|
580 | 560 | { |
---|
581 | 561 | .mask = MLXSW_REG_PTYS_ETH_SPEED_10GBASE_CX4 | |
---|
.. | .. |
---|
592 | 572 | .supported = SUPPORTED_10000baseKR_Full, |
---|
593 | 573 | .advertised = ADVERTISED_10000baseKR_Full, |
---|
594 | 574 | .speed = 10000, |
---|
595 | | - }, |
---|
596 | | - { |
---|
597 | | - .mask = MLXSW_REG_PTYS_ETH_SPEED_20GBASE_KR2, |
---|
598 | | - .supported = SUPPORTED_20000baseKR2_Full, |
---|
599 | | - .advertised = ADVERTISED_20000baseKR2_Full, |
---|
600 | | - .speed = 20000, |
---|
601 | 575 | }, |
---|
602 | 576 | { |
---|
603 | 577 | .mask = MLXSW_REG_PTYS_ETH_SPEED_40GBASE_CR4, |
---|
.. | .. |
---|
634 | 608 | MLXSW_REG_PTYS_ETH_SPEED_50GBASE_CR2 | |
---|
635 | 609 | MLXSW_REG_PTYS_ETH_SPEED_50GBASE_KR2, |
---|
636 | 610 | .speed = 50000, |
---|
637 | | - }, |
---|
638 | | - { |
---|
639 | | - .mask = MLXSW_REG_PTYS_ETH_SPEED_56GBASE_R4, |
---|
640 | | - .supported = SUPPORTED_56000baseKR4_Full, |
---|
641 | | - .advertised = ADVERTISED_56000baseKR4_Full, |
---|
642 | | - .speed = 56000, |
---|
643 | 611 | }, |
---|
644 | 612 | { |
---|
645 | 613 | .mask = MLXSW_REG_PTYS_ETH_SPEED_100GBASE_CR4 | |
---|
.. | .. |
---|
901 | 869 | .set_link_ksettings = mlxsw_sx_port_set_link_ksettings, |
---|
902 | 870 | }; |
---|
903 | 871 | |
---|
904 | | -static int mlxsw_sx_port_attr_get(struct net_device *dev, |
---|
905 | | - struct switchdev_attr *attr) |
---|
906 | | -{ |
---|
907 | | - struct mlxsw_sx_port *mlxsw_sx_port = netdev_priv(dev); |
---|
908 | | - struct mlxsw_sx *mlxsw_sx = mlxsw_sx_port->mlxsw_sx; |
---|
909 | | - |
---|
910 | | - switch (attr->id) { |
---|
911 | | - case SWITCHDEV_ATTR_ID_PORT_PARENT_ID: |
---|
912 | | - attr->u.ppid.id_len = sizeof(mlxsw_sx->hw_id); |
---|
913 | | - memcpy(&attr->u.ppid.id, &mlxsw_sx->hw_id, attr->u.ppid.id_len); |
---|
914 | | - break; |
---|
915 | | - default: |
---|
916 | | - return -EOPNOTSUPP; |
---|
917 | | - } |
---|
918 | | - |
---|
919 | | - return 0; |
---|
920 | | -} |
---|
921 | | - |
---|
922 | | -static const struct switchdev_ops mlxsw_sx_port_switchdev_ops = { |
---|
923 | | - .switchdev_port_attr_get = mlxsw_sx_port_attr_get, |
---|
924 | | -}; |
---|
925 | | - |
---|
926 | 872 | static int mlxsw_sx_hw_id_get(struct mlxsw_sx *mlxsw_sx) |
---|
927 | 873 | { |
---|
928 | 874 | char spad_pl[MLXSW_REG_SPAD_LEN] = {0}; |
---|
.. | .. |
---|
1019 | 965 | if (!dev) |
---|
1020 | 966 | return -ENOMEM; |
---|
1021 | 967 | SET_NETDEV_DEV(dev, mlxsw_sx->bus_info->dev); |
---|
| 968 | + dev_net_set(dev, mlxsw_core_net(mlxsw_sx->core)); |
---|
1022 | 969 | mlxsw_sx_port = netdev_priv(dev); |
---|
1023 | 970 | mlxsw_sx_port->dev = dev; |
---|
1024 | 971 | mlxsw_sx_port->mlxsw_sx = mlxsw_sx; |
---|
.. | .. |
---|
1034 | 981 | |
---|
1035 | 982 | dev->netdev_ops = &mlxsw_sx_port_netdev_ops; |
---|
1036 | 983 | dev->ethtool_ops = &mlxsw_sx_port_ethtool_ops; |
---|
1037 | | - dev->switchdev_ops = &mlxsw_sx_port_switchdev_ops; |
---|
1038 | 984 | |
---|
1039 | 985 | err = mlxsw_sx_port_dev_addr_get(mlxsw_sx_port); |
---|
1040 | 986 | if (err) { |
---|
.. | .. |
---|
1113 | 1059 | } |
---|
1114 | 1060 | |
---|
1115 | 1061 | mlxsw_core_port_eth_set(mlxsw_sx->core, mlxsw_sx_port->local_port, |
---|
1116 | | - mlxsw_sx_port, dev, module + 1, false, 0); |
---|
| 1062 | + mlxsw_sx_port, dev); |
---|
1117 | 1063 | mlxsw_sx->ports[local_port] = mlxsw_sx_port; |
---|
1118 | 1064 | return 0; |
---|
1119 | 1065 | |
---|
.. | .. |
---|
1138 | 1084 | { |
---|
1139 | 1085 | int err; |
---|
1140 | 1086 | |
---|
1141 | | - err = mlxsw_core_port_init(mlxsw_sx->core, local_port); |
---|
| 1087 | + err = mlxsw_core_port_init(mlxsw_sx->core, local_port, |
---|
| 1088 | + module + 1, false, 0, false, 0, |
---|
| 1089 | + mlxsw_sx->hw_id, sizeof(mlxsw_sx->hw_id)); |
---|
1142 | 1090 | if (err) { |
---|
1143 | 1091 | dev_err(mlxsw_sx->bus_info->dev, "Port %d: Failed to init core port\n", |
---|
1144 | 1092 | local_port); |
---|
.. | .. |
---|
1434 | 1382 | return err; |
---|
1435 | 1383 | } |
---|
1436 | 1384 | |
---|
| 1385 | +enum { |
---|
| 1386 | + MLXSW_REG_HTGT_TRAP_GROUP_SX2_RX = 1, |
---|
| 1387 | + MLXSW_REG_HTGT_TRAP_GROUP_SX2_CTRL = 2, |
---|
| 1388 | +}; |
---|
| 1389 | + |
---|
1437 | 1390 | #define MLXSW_SX_RXL(_trap_id) \ |
---|
1438 | 1391 | MLXSW_RXL(mlxsw_sx_rx_listener_func, _trap_id, TRAP_TO_CPU, \ |
---|
1439 | 1392 | false, SX2_RX, FORWARD) |
---|
.. | .. |
---|
1597 | 1550 | } |
---|
1598 | 1551 | |
---|
1599 | 1552 | static int mlxsw_sx_init(struct mlxsw_core *mlxsw_core, |
---|
1600 | | - const struct mlxsw_bus_info *mlxsw_bus_info) |
---|
| 1553 | + const struct mlxsw_bus_info *mlxsw_bus_info, |
---|
| 1554 | + struct netlink_ext_ack *extack) |
---|
1601 | 1555 | { |
---|
1602 | 1556 | struct mlxsw_sx *mlxsw_sx = mlxsw_core_driver_priv(mlxsw_core); |
---|
1603 | 1557 | int err; |
---|