diff options
42 files changed, 356 insertions, 498 deletions
@@ -3233,6 +3233,10 @@ N: Rui Prior E: rprior@inescn.pt D: ATM device driver for NICStAR based cards +N: Roopa Prabhu +E: roopa@nvidia.com +D: Bridge co-maintainer, vxlan and networking contributor + N: Stefan Probst E: sp@caldera.de D: The Linux Support Team Erlangen, 1993-97 diff --git a/MAINTAINERS b/MAINTAINERS index c3fce4416723..03f6db69a8ca 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8593,12 +8593,14 @@ F: Documentation/networking/devlink/etas_es58x.rst F: drivers/net/can/usb/etas_es58x/ ETHERNET BRIDGE -M: Roopa Prabhu <roopa@nvidia.com> M: Nikolay Aleksandrov <razor@blackwall.org> +M: Ido Schimmel <idosch@nvidia.com> L: bridge@lists.linux.dev L: netdev@vger.kernel.org S: Maintained W: http://www.linuxfoundation.org/en/Net:Bridge +F: include/linux/if_bridge.h +F: include/uapi/linux/if_bridge.h F: include/linux/netfilter_bridge/ F: net/bridge/ diff --git a/arch/parisc/include/uapi/asm/socket.h b/arch/parisc/include/uapi/asm/socket.h index aa9cd4b951fe..96831c988606 100644 --- a/arch/parisc/include/uapi/asm/socket.h +++ b/arch/parisc/include/uapi/asm/socket.h @@ -132,16 +132,16 @@ #define SO_PASSPIDFD 0x404A #define SO_PEERPIDFD 0x404B -#define SO_DEVMEM_LINEAR 78 -#define SCM_DEVMEM_LINEAR SO_DEVMEM_LINEAR -#define SO_DEVMEM_DMABUF 79 -#define SCM_DEVMEM_DMABUF SO_DEVMEM_DMABUF -#define SO_DEVMEM_DONTNEED 80 - #define SCM_TS_OPT_ID 0x404C #define SO_RCVPRIORITY 0x404D +#define SO_DEVMEM_LINEAR 0x404E +#define SCM_DEVMEM_LINEAR SO_DEVMEM_LINEAR +#define SO_DEVMEM_DMABUF 0x404F +#define SCM_DEVMEM_DMABUF SO_DEVMEM_DMABUF +#define SO_DEVMEM_DONTNEED 0x4050 + #if !defined(__KERNEL__) #if __BITS_PER_LONG == 64 diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index e7f576d52311..950d8e4d86f8 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -323,9 +323,9 @@ static bool bond_sk_check(struct bonding *bond) } } -static bool bond_xdp_check(struct bonding *bond) +bool bond_xdp_check(struct bonding *bond, int mode) { - switch (BOND_MODE(bond)) { + switch (mode) { case BOND_MODE_ROUNDROBIN: case BOND_MODE_ACTIVEBACKUP: return true; @@ -1928,7 +1928,7 @@ void bond_xdp_set_features(struct net_device *bond_dev) ASSERT_RTNL(); - if (!bond_xdp_check(bond) || !bond_has_slaves(bond)) { + if (!bond_xdp_check(bond, BOND_MODE(bond)) || !bond_has_slaves(bond)) { xdp_clear_features_flag(bond_dev); return; } @@ -5693,7 +5693,7 @@ static int bond_xdp_set(struct net_device *dev, struct bpf_prog *prog, ASSERT_RTNL(); - if (!bond_xdp_check(bond)) { + if (!bond_xdp_check(bond, BOND_MODE(bond))) { BOND_NL_ERR(dev, extack, "No native XDP support for the current bonding mode"); return -EOPNOTSUPP; diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c index d1b095af253b..91893c29b899 100644 --- a/drivers/net/bonding/bond_options.c +++ b/drivers/net/bonding/bond_options.c @@ -868,6 +868,9 @@ static bool bond_set_xfrm_features(struct bonding *bond) static int bond_option_mode_set(struct bonding *bond, const struct bond_opt_value *newval) { + if (bond->xdp_prog && !bond_xdp_check(bond, newval->value)) + return -EOPNOTSUPP; + if (!bond_mode_uses_arp(newval->value)) { if (bond->params.arp_interval) { netdev_dbg(bond->dev, "%s mode is incompatible with arp monitoring, start mii monitoring\n", diff --git a/drivers/net/dsa/microchip/ksz8.c b/drivers/net/dsa/microchip/ksz8.c index da7110d67558..be433b4e2b1c 100644 --- a/drivers/net/dsa/microchip/ksz8.c +++ b/drivers/net/dsa/microchip/ksz8.c @@ -1625,7 +1625,6 @@ void ksz8_port_setup(struct ksz_device *dev, int port, bool cpu_port) const u16 *regs = dev->info->regs; struct dsa_switch *ds = dev->ds; const u32 *masks; - int queues; u8 member; masks = dev->info->masks; @@ -1633,15 +1632,7 @@ void ksz8_port_setup(struct ksz_device *dev, int port, bool cpu_port) /* enable broadcast storm limit */ ksz_port_cfg(dev, port, P_BCAST_STORM_CTRL, PORT_BROADCAST_STORM, true); - /* For KSZ88x3 enable only one queue by default, otherwise we won't - * be able to get rid of PCP prios on Port 2. - */ - if (ksz_is_ksz88x3(dev)) - queues = 1; - else - queues = dev->info->num_tx_queues; - - ksz8_port_queue_split(dev, port, queues); + ksz8_port_queue_split(dev, port, dev->info->num_tx_queues); /* replace priority */ ksz_port_cfg(dev, port, P_802_1P_CTRL, diff --git a/drivers/net/dsa/microchip/ksz_dcb.c b/drivers/net/dsa/microchip/ksz_dcb.c index 30b4a6186e38..c3b501997ac9 100644 --- a/drivers/net/dsa/microchip/ksz_dcb.c +++ b/drivers/net/dsa/microchip/ksz_dcb.c @@ -10,7 +10,12 @@ #include "ksz_dcb.h" #include "ksz8.h" -#define KSZ8_REG_PORT_1_CTRL_0 0x10 +/* Port X Control 0 register. + * The datasheet specifies: Port 1 - 0x10, Port 2 - 0x20, Port 3 - 0x30. + * However, the driver uses get_port_addr(), which maps Port 1 to offset 0. + * Therefore, we define the base offset as 0x00 here to align with that logic. + */ +#define KSZ8_REG_PORT_1_CTRL_0 0x00 #define KSZ8_PORT_DIFFSERV_ENABLE BIT(6) #define KSZ8_PORT_802_1P_ENABLE BIT(5) #define KSZ8_PORT_BASED_PRIO_M GENMASK(4, 3) @@ -182,49 +187,6 @@ int ksz_port_get_default_prio(struct dsa_switch *ds, int port) } /** - * ksz88x3_port_set_default_prio_quirks - Quirks for default priority - * @dev: Pointer to the KSZ switch device structure - * @port: Port number for which to set the default priority - * @prio: Priority value to set - * - * This function implements quirks for setting the default priority on KSZ88x3 - * devices. On Port 2, no other priority providers are working - * except of PCP. So, configuring default priority on Port 2 is not possible. - * On Port 1, it is not possible to configure port priority if PCP - * apptrust on Port 2 is disabled. Since we disable multiple queues on the - * switch to disable PCP on Port 2, we need to ensure that the default priority - * configuration on Port 1 is in agreement with the configuration on Port 2. - * - * Return: 0 on success, or a negative error code on failure - */ -static int ksz88x3_port_set_default_prio_quirks(struct ksz_device *dev, int port, - u8 prio) -{ - if (!prio) - return 0; - - if (port == KSZ_PORT_2) { - dev_err(dev->dev, "Port priority configuration is not working on Port 2\n"); - return -EINVAL; - } else if (port == KSZ_PORT_1) { - u8 port2_data; - int ret; - - ret = ksz_pread8(dev, KSZ_PORT_2, KSZ8_REG_PORT_1_CTRL_0, - &port2_data); - if (ret) - return ret; - - if (!(port2_data & KSZ8_PORT_802_1P_ENABLE)) { - dev_err(dev->dev, "Not possible to configure port priority on Port 1 if PCP apptrust on Port 2 is disabled\n"); - return -EINVAL; - } - } - - return 0; -} - -/** * ksz_port_set_default_prio - Sets the default priority for a port on a KSZ * switch * @ds: Pointer to the DSA switch structure @@ -239,18 +201,12 @@ static int ksz88x3_port_set_default_prio_quirks(struct ksz_device *dev, int port int ksz_port_set_default_prio(struct dsa_switch *ds, int port, u8 prio) { struct ksz_device *dev = ds->priv; - int reg, shift, ret; + int reg, shift; u8 mask; if (prio >= dev->info->num_ipms) return -EINVAL; - if (ksz_is_ksz88x3(dev)) { - ret = ksz88x3_port_set_default_prio_quirks(dev, port, prio); - if (ret) - return ret; - } - ksz_get_default_port_prio_reg(dev, ®, &mask, &shift); return ksz_prmw8(dev, port, reg, mask, (prio << shift) & mask); @@ -519,155 +475,6 @@ err_sel_not_vaild: } /** - * ksz88x3_port1_apptrust_quirk - Quirk for apptrust configuration on Port 1 - * of KSZ88x3 devices - * @dev: Pointer to the KSZ switch device structure - * @port: Port number for which to set the apptrust selectors - * @reg: Register address for the apptrust configuration - * @port1_data: Data to set for the apptrust configuration - * - * This function implements a quirk for apptrust configuration on Port 1 of - * KSZ88x3 devices. It ensures that apptrust configuration on Port 1 is not - * possible if PCP apptrust on Port 2 is disabled. This is because the Port 2 - * seems to be permanently hardwired to PCP classification, so we need to - * do Port 1 configuration always in agreement with Port 2 configuration. - * - * Return: 0 on success, or a negative error code on failure - */ -static int ksz88x3_port1_apptrust_quirk(struct ksz_device *dev, int port, - int reg, u8 port1_data) -{ - u8 port2_data; - int ret; - - /* If no apptrust is requested for Port 1, no need to care about Port 2 - * configuration. - */ - if (!(port1_data & (KSZ8_PORT_802_1P_ENABLE | KSZ8_PORT_DIFFSERV_ENABLE))) - return 0; - - /* We got request to enable any apptrust on Port 1. To make it possible, - * we need to enable multiple queues on the switch. If we enable - * multiqueue support, PCP classification on Port 2 will be - * automatically activated by HW. - */ - ret = ksz_pread8(dev, KSZ_PORT_2, reg, &port2_data); - if (ret) - return ret; - - /* If KSZ8_PORT_802_1P_ENABLE bit is set on Port 2, the driver showed - * the interest in PCP classification on Port 2. In this case, - * multiqueue support is enabled and we can enable any apptrust on - * Port 1. - * If KSZ8_PORT_802_1P_ENABLE bit is not set on Port 2, the PCP - * classification on Port 2 is still active, but the driver disabled - * multiqueue support and made frame prioritization inactive for - * all ports. In this case, we can't enable any apptrust on Port 1. - */ - if (!(port2_data & KSZ8_PORT_802_1P_ENABLE)) { - dev_err(dev->dev, "Not possible to enable any apptrust on Port 1 if PCP apptrust on Port 2 is disabled\n"); - return -EINVAL; - } - - return 0; -} - -/** - * ksz88x3_port2_apptrust_quirk - Quirk for apptrust configuration on Port 2 - * of KSZ88x3 devices - * @dev: Pointer to the KSZ switch device structure - * @port: Port number for which to set the apptrust selectors - * @reg: Register address for the apptrust configuration - * @port2_data: Data to set for the apptrust configuration - * - * This function implements a quirk for apptrust configuration on Port 2 of - * KSZ88x3 devices. It ensures that DSCP apptrust is not working on Port 2 and - * that it is not possible to disable PCP on Port 2. The only way to disable PCP - * on Port 2 is to disable multiple queues on the switch. - * - * Return: 0 on success, or a negative error code on failure - */ -static int ksz88x3_port2_apptrust_quirk(struct ksz_device *dev, int port, - int reg, u8 port2_data) -{ - struct dsa_switch *ds = dev->ds; - u8 port1_data; - int ret; - - /* First validate Port 2 configuration. DiffServ/DSCP is not working - * on this port. - */ - if (port2_data & KSZ8_PORT_DIFFSERV_ENABLE) { - dev_err(dev->dev, "DSCP apptrust is not working on Port 2\n"); - return -EINVAL; - } - - /* If PCP support is requested, we need to enable all queues on the - * switch to make PCP priority working on Port 2. - */ - if (port2_data & KSZ8_PORT_802_1P_ENABLE) - return ksz8_all_queues_split(dev, dev->info->num_tx_queues); - - /* We got request to disable PCP priority on Port 2. - * Now, we need to compare Port 2 configuration with Port 1 - * configuration. - */ - ret = ksz_pread8(dev, KSZ_PORT_1, reg, &port1_data); - if (ret) - return ret; - - /* If Port 1 has any apptrust enabled, we can't disable multiple queues - * on the switch, so we can't disable PCP on Port 2. - */ - if (port1_data & (KSZ8_PORT_802_1P_ENABLE | KSZ8_PORT_DIFFSERV_ENABLE)) { - dev_err(dev->dev, "Not possible to disable PCP on Port 2 if any apptrust is enabled on Port 1\n"); - return -EINVAL; - } - - /* Now we need to ensure that default priority on Port 1 is set to 0 - * otherwise we can't disable multiqueue support on the switch. - */ - ret = ksz_port_get_default_prio(ds, KSZ_PORT_1); - if (ret < 0) { - return ret; - } else if (ret) { - dev_err(dev->dev, "Not possible to disable PCP on Port 2 if non zero default priority is set on Port 1\n"); - return -EINVAL; - } - - /* Port 1 has no apptrust or default priority set and we got request to - * disable PCP on Port 2. We can disable multiqueue support to disable - * PCP on Port 2. - */ - return ksz8_all_queues_split(dev, 1); -} - -/** - * ksz88x3_port_apptrust_quirk - Quirk for apptrust configuration on KSZ88x3 - * devices - * @dev: Pointer to the KSZ switch device structure - * @port: Port number for which to set the apptrust selectors - * @reg: Register address for the apptrust configuration - * @data: Data to set for the apptrust configuration - * - * This function implements a quirk for apptrust configuration on KSZ88x3 - * devices. It ensures that apptrust configuration on Port 1 and - * Port 2 is done in agreement with each other. - * - * Return: 0 on success, or a negative error code on failure - */ -static int ksz88x3_port_apptrust_quirk(struct ksz_device *dev, int port, - int reg, u8 data) -{ - if (port == KSZ_PORT_1) - return ksz88x3_port1_apptrust_quirk(dev, port, reg, data); - else if (port == KSZ_PORT_2) - return ksz88x3_port2_apptrust_quirk(dev, port, reg, data); - - return 0; -} - -/** * ksz_port_set_apptrust - Sets the apptrust selectors for a port on a KSZ * switch * @ds: Pointer to the DSA switch structure @@ -707,12 +514,6 @@ int ksz_port_set_apptrust(struct dsa_switch *ds, int port, } } - if (ksz_is_ksz88x3(dev)) { - ret = ksz88x3_port_apptrust_quirk(dev, port, reg, data); - if (ret) - return ret; - } - return ksz_prmw8(dev, port, reg, mask, data); } @@ -799,21 +600,5 @@ int ksz_dcb_init_port(struct ksz_device *dev, int port) */ int ksz_dcb_init(struct ksz_device *dev) { - int ret; - - ret = ksz_init_global_dscp_map(dev); - if (ret) - return ret; - - /* Enable 802.1p priority control on Port 2 during switch initialization. - * This setup is critical for the apptrust functionality on Port 1, which - * relies on the priority settings of Port 2. Note: Port 1 is naturally - * configured before Port 2, necessitating this configuration order. - */ - if (ksz_is_ksz88x3(dev)) - return ksz_prmw8(dev, KSZ_PORT_2, KSZ8_REG_PORT_1_CTRL_0, - KSZ8_PORT_802_1P_ENABLE, - KSZ8_PORT_802_1P_ENABLE); - - return 0; + return ksz_init_global_dscp_map(dev); } diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index 5db96ca52505..901929f96b38 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c @@ -3674,6 +3674,21 @@ static int mv88e6xxx_stats_setup(struct mv88e6xxx_chip *chip) return mv88e6xxx_g1_stats_clear(chip); } +static int mv88e6320_setup_errata(struct mv88e6xxx_chip *chip) +{ + u16 dummy; + int err; + + /* Workaround for erratum + * 3.3 RGMII timing may be out of spec when transmit delay is enabled + */ + err = mv88e6xxx_port_hidden_write(chip, 0, 0xf, 0x7, 0xe000); + if (err) + return err; + + return mv88e6xxx_port_hidden_read(chip, 0, 0xf, 0x7, &dummy); +} + /* Check if the errata has already been applied. */ static bool mv88e6390_setup_errata_applied(struct mv88e6xxx_chip *chip) { @@ -5130,6 +5145,7 @@ static const struct mv88e6xxx_ops mv88e6290_ops = { static const struct mv88e6xxx_ops mv88e6320_ops = { /* MV88E6XXX_FAMILY_6320 */ + .setup_errata = mv88e6320_setup_errata, .ieee_pri_map = mv88e6085_g1_ieee_pri_map, .ip_pri_map = mv88e6085_g1_ip_pri_map, .irl_init_all = mv88e6352_g2_irl_init_all, @@ -5145,6 +5161,7 @@ static const struct mv88e6xxx_ops mv88e6320_ops = { .port_set_rgmii_delay = mv88e6320_port_set_rgmii_delay, .port_set_speed_duplex = mv88e6185_port_set_speed_duplex, .port_tag_remap = mv88e6095_port_tag_remap, + .port_set_policy = mv88e6352_port_set_policy, .port_set_frame_mode = mv88e6351_port_set_frame_mode, .port_set_ucast_flood = mv88e6352_port_set_ucast_flood, .port_set_mcast_flood = mv88e6352_port_set_mcast_flood, @@ -5169,8 +5186,10 @@ static const struct mv88e6xxx_ops mv88e6320_ops = { .hardware_reset_pre = mv88e6xxx_g2_eeprom_wait, .hardware_reset_post = mv88e6xxx_g2_eeprom_wait, .reset = mv88e6352_g1_reset, - .vtu_getnext = mv88e6185_g1_vtu_getnext, - .vtu_loadpurge = mv88e6185_g1_vtu_loadpurge, + .vtu_getnext = mv88e6352_g1_vtu_getnext, + .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge, + .stu_getnext = mv88e6352_g1_stu_getnext, + .stu_loadpurge = mv88e6352_g1_stu_loadpurge, .gpio_ops = &mv88e6352_gpio_ops, .avb_ops = &mv88e6352_avb_ops, .ptp_ops = &mv88e6352_ptp_ops, @@ -5179,6 +5198,7 @@ static const struct mv88e6xxx_ops mv88e6320_ops = { static const struct mv88e6xxx_ops mv88e6321_ops = { /* MV88E6XXX_FAMILY_6320 */ + .setup_errata = mv88e6320_setup_errata, .ieee_pri_map = mv88e6085_g1_ieee_pri_map, .ip_pri_map = mv88e6085_g1_ip_pri_map, .irl_init_all = mv88e6352_g2_irl_init_all, @@ -5194,6 +5214,7 @@ static const struct mv88e6xxx_ops mv88e6321_ops = { .port_set_rgmii_delay = mv88e6320_port_set_rgmii_delay, .port_set_speed_duplex = mv88e6185_port_set_speed_duplex, .port_tag_remap = mv88e6095_port_tag_remap, + .port_set_policy = mv88e6352_port_set_policy, .port_set_frame_mode = mv88e6351_port_set_frame_mode, .port_set_ucast_flood = mv88e6352_port_set_ucast_flood, .port_set_mcast_flood = mv88e6352_port_set_mcast_flood, @@ -5217,8 +5238,10 @@ static const struct mv88e6xxx_ops mv88e6321_ops = { .hardware_reset_pre = mv88e6xxx_g2_eeprom_wait, .hardware_reset_post = mv88e6xxx_g2_eeprom_wait, .reset = mv88e6352_g1_reset, - .vtu_getnext = mv88e6185_g1_vtu_getnext, - .vtu_loadpurge = mv88e6185_g1_vtu_loadpurge, + .vtu_getnext = mv88e6352_g1_vtu_getnext, + .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge, + .stu_getnext = mv88e6352_g1_stu_getnext, + .stu_loadpurge = mv88e6352_g1_stu_loadpurge, .gpio_ops = &mv88e6352_gpio_ops, .avb_ops = &mv88e6352_avb_ops, .ptp_ops = &mv88e6352_ptp_ops, @@ -5818,7 +5841,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .global1_addr = 0x1b, .global2_addr = 0x1c, .age_time_coeff = 3750, - .atu_move_port_mask = 0x1f, + .atu_move_port_mask = 0xf, .g1_irqs = 9, .g2_irqs = 10, .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_BANK1, @@ -6236,9 +6259,11 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .num_databases = 4096, .num_macs = 8192, .num_ports = 7, - .num_internal_phys = 5, + .num_internal_phys = 2, + .internal_phys_offset = 3, .num_gpio = 15, .max_vid = 4095, + .max_sid = 63, .port_base_addr = 0x10, .phy_base_addr = 0x0, .global1_addr = 0x1b, @@ -6262,9 +6287,11 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .num_databases = 4096, .num_macs = 8192, .num_ports = 7, - .num_internal_phys = 5, + .num_internal_phys = 2, + .internal_phys_offset = 3, .num_gpio = 15, .max_vid = 4095, + .max_sid = 63, .port_base_addr = 0x10, .phy_base_addr = 0x0, .global1_addr = 0x1b, @@ -6274,6 +6301,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .g2_irqs = 10, .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_BANK1, .atu_move_port_mask = 0xf, + .pvt = true, .multi_chip = true, .edsa_support = MV88E6XXX_EDSA_SUPPORTED, .ptp_support = true, @@ -6296,7 +6324,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .global1_addr = 0x1b, .global2_addr = 0x1c, .age_time_coeff = 3750, - .atu_move_port_mask = 0x1f, + .atu_move_port_mask = 0xf, .g1_irqs = 9, .g2_irqs = 10, .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_BANK1, diff --git a/drivers/net/dsa/sja1105/sja1105_ethtool.c b/drivers/net/dsa/sja1105/sja1105_ethtool.c index 2ea64b1d026d..84d7d3f66bd0 100644 --- a/drivers/net/dsa/sja1105/sja1105_ethtool.c +++ b/drivers/net/dsa/sja1105/sja1105_ethtool.c @@ -571,6 +571,9 @@ void sja1105_get_ethtool_stats(struct dsa_switch *ds, int port, u64 *data) max_ctr = __MAX_SJA1105PQRS_PORT_COUNTER; for (i = 0; i < max_ctr; i++) { + if (!strlen(sja1105_port_counters[i].name)) + continue; + rc = sja1105_port_counter_read(priv, port, i, &data[k++]); if (rc) { dev_err(ds->dev, @@ -596,8 +599,12 @@ void sja1105_get_strings(struct dsa_switch *ds, int port, else max_ctr = __MAX_SJA1105PQRS_PORT_COUNTER; - for (i = 0; i < max_ctr; i++) + for (i = 0; i < max_ctr; i++) { + if (!strlen(sja1105_port_counters[i].name)) + continue; + ethtool_puts(&data, sja1105_port_counters[i].name); + } } int sja1105_get_sset_count(struct dsa_switch *ds, int port, int sset) diff --git a/drivers/net/dsa/sja1105/sja1105_ptp.c b/drivers/net/dsa/sja1105/sja1105_ptp.c index a1f4ca6ad888..08b45fdd1d24 100644 --- a/drivers/net/dsa/sja1105/sja1105_ptp.c +++ b/drivers/net/dsa/sja1105/sja1105_ptp.c @@ -61,17 +61,21 @@ enum sja1105_ptp_clk_mode { int sja1105_hwtstamp_set(struct dsa_switch *ds, int port, struct ifreq *ifr) { struct sja1105_private *priv = ds->priv; + unsigned long hwts_tx_en, hwts_rx_en; struct hwtstamp_config config; if (copy_from_user(&config, ifr->ifr_data, sizeof(config))) return -EFAULT; + hwts_tx_en = priv->hwts_tx_en; + hwts_rx_en = priv->hwts_rx_en; + switch (config.tx_type) { case HWTSTAMP_TX_OFF: - priv->hwts_tx_en &= ~BIT(port); + hwts_tx_en &= ~BIT(port); break; case HWTSTAMP_TX_ON: - priv->hwts_tx_en |= BIT(port); + hwts_tx_en |= BIT(port); break; default: return -ERANGE; @@ -79,15 +83,21 @@ int sja1105_hwtstamp_set(struct dsa_switch *ds, int port, struct ifreq *ifr) switch (config.rx_filter) { case HWTSTAMP_FILTER_NONE: - priv->hwts_rx_en &= ~BIT(port); + hwts_rx_en &= ~BIT(port); break; - default: - priv->hwts_rx_en |= BIT(port); + case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: + hwts_rx_en |= BIT(port); break; + default: + return -ERANGE; } if (copy_to_user(ifr->ifr_data, &config, sizeof(config))) return -EFAULT; + + priv->hwts_tx_en = hwts_tx_en; + priv->hwts_rx_en = hwts_rx_en; + return 0; } diff --git a/drivers/net/dsa/sja1105/sja1105_static_config.c b/drivers/net/dsa/sja1105/sja1105_static_config.c index 3d790f8c6f4d..ffece8a400a6 100644 --- a/drivers/net/dsa/sja1105/sja1105_static_config.c +++ b/drivers/net/dsa/sja1105/sja1105_static_config.c @@ -1917,8 +1917,10 @@ int sja1105_table_delete_entry(struct sja1105_table *table, int i) if (i > table->entry_count) return -ERANGE; - memmove(entries + i * entry_size, entries + (i + 1) * entry_size, - (table->entry_count - i) * entry_size); + if (i + 1 < table->entry_count) { + memmove(entries + i * entry_size, entries + (i + 1) * entry_size, + (table->entry_count - i - 1) * entry_size); + } table->entry_count--; diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 08a41e9c25ff..934ba9425857 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -489,6 +489,17 @@ static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev) txr = &bp->tx_ring[bp->tx_ring_map[i]]; prod = txr->tx_prod; +#if (MAX_SKB_FRAGS > TX_MAX_FRAGS) + if (skb_shinfo(skb)->nr_frags > TX_MAX_FRAGS) { + netdev_warn_once(dev, "SKB has too many (%d) fragments, max supported is %d. SKB will be linearized.\n", + skb_shinfo(skb)->nr_frags, TX_MAX_FRAGS); + if (skb_linearize(skb)) { + dev_kfree_skb_any(skb); + dev_core_stats_tx_dropped_inc(dev); + return NETDEV_TX_OK; + } + } +#endif free_size = bnxt_tx_avail(bp, txr); if (unlikely(free_size < skb_shinfo(skb)->nr_frags + 2)) { /* We must have raced with NAPI cleanup */ @@ -568,7 +579,7 @@ static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev) TX_BD_FLAGS_LHINT_512_AND_SMALLER | TX_BD_FLAGS_COAL_NOW | TX_BD_FLAGS_PACKET_END | - (2 << TX_BD_FLAGS_BD_CNT_SHIFT)); + TX_BD_CNT(2)); if (skb->ip_summed == CHECKSUM_PARTIAL) tx_push1->tx_bd_hsize_lflags = @@ -643,7 +654,7 @@ normal_tx: dma_unmap_addr_set(tx_buf, mapping, mapping); flags = (len << TX_BD_LEN_SHIFT) | TX_BD_TYPE_LONG_TX_BD | - ((last_frag + 2) << TX_BD_FLAGS_BD_CNT_SHIFT); + TX_BD_CNT(last_frag + 2); txbd->tx_bd_haddr = cpu_to_le64(mapping); txbd->tx_bd_opaque = SET_TX_OPAQUE(bp, txr, prod, 2 + last_frag); @@ -15901,7 +15912,7 @@ static int bnxt_queue_start(struct net_device *dev, void *qmem, int idx) napi_enable(&bnapi->napi); bnxt_db_nq_arm(bp, &cpr->cp_db, cpr->cp_raw_cons); - for (i = 0; i <= bp->nr_vnics; i++) { + for (i = 0; i < bp->nr_vnics; i++) { |