mirror of
https://kernel.googlesource.com/pub/scm/linux/kernel/git/stable/linux-stable.git
synced 2025-09-27 17:32:00 +10:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
Merge in late fixes to prepare for the 6.15 net-next PR. No conflicts, adjacent changes: drivers/net/ethernet/broadcom/bnxt/bnxt.c919f9f497d
("eth: bnxt: fix out-of-range access of vnic_info array")fe96d717d3
("bnxt_en: Extend queue stop/start for TX rings") Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
023b1e9d26
4
CREDITS
4
CREDITS
@ -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
|
||||
|
@ -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/
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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",
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
@ -181,49 +186,6 @@ int ksz_port_get_default_prio(struct dsa_switch *ds, int port)
|
||||
return (data & mask) >> shift;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
@ -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);
|
||||
@ -518,155 +474,6 @@ err_sel_not_vaild:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
@ -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);
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
|
||||
hwts_rx_en |= BIT(port);
|
||||
break;
|
||||
default:
|
||||
priv->hwts_rx_en |= BIT(port);
|
||||
break;
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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--;
|
||||
|
||||
|
@ -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++) {
|
||||
vnic = &bp->vnic_info[i];
|
||||
|
||||
rc = bnxt_hwrm_vnic_set_rss_p5(bp, vnic, true);
|
||||
@ -15935,7 +15946,7 @@ static int bnxt_queue_stop(struct net_device *dev, void *qmem, int idx)
|
||||
struct bnxt_napi *bnapi;
|
||||
int i;
|
||||
|
||||
for (i = 0; i <= bp->nr_vnics; i++) {
|
||||
for (i = 0; i < bp->nr_vnics; i++) {
|
||||
vnic = &bp->vnic_info[i];
|
||||
vnic->mru = 0;
|
||||
bnxt_hwrm_vnic_update(bp, vnic,
|
||||
|
@ -82,6 +82,12 @@ struct tx_bd {
|
||||
#define TX_OPAQUE_PROD(bp, opq) ((TX_OPAQUE_IDX(opq) + TX_OPAQUE_BDS(opq)) &\
|
||||
(bp)->tx_ring_mask)
|
||||
|
||||
#define TX_BD_CNT(n) (((n) << TX_BD_FLAGS_BD_CNT_SHIFT) & TX_BD_FLAGS_BD_CNT)
|
||||
|
||||
#define TX_MAX_BD_CNT 32
|
||||
|
||||
#define TX_MAX_FRAGS (TX_MAX_BD_CNT - 2)
|
||||
|
||||
struct tx_bd_ext {
|
||||
__le32 tx_bd_hsize_lflags;
|
||||
#define TX_BD_FLAGS_TCP_UDP_CHKSUM (1 << 0)
|
||||
|
@ -49,8 +49,7 @@ struct bnxt_sw_tx_bd *bnxt_xmit_bd(struct bnxt *bp,
|
||||
tx_buf->page = virt_to_head_page(xdp->data);
|
||||
|
||||
txbd = &txr->tx_desc_ring[TX_RING(bp, prod)][TX_IDX(prod)];
|
||||
flags = (len << TX_BD_LEN_SHIFT) |
|
||||
((num_frags + 1) << TX_BD_FLAGS_BD_CNT_SHIFT) |
|
||||
flags = (len << TX_BD_LEN_SHIFT) | TX_BD_CNT(num_frags + 1) |
|
||||
bnxt_lhint_arr[len >> 9];
|
||||
txbd->tx_bd_len_flags_type = cpu_to_le32(flags);
|
||||
txbd->tx_bd_opaque = SET_TX_OPAQUE(bp, txr, prod, 1 + num_frags);
|
||||
|
@ -114,7 +114,8 @@ void gve_rx_stop_ring_dqo(struct gve_priv *priv, int idx)
|
||||
if (!gve_rx_was_added_to_block(priv, idx))
|
||||
return;
|
||||
|
||||
page_pool_disable_direct_recycling(rx->dqo.page_pool);
|
||||
if (rx->dqo.page_pool)
|
||||
page_pool_disable_direct_recycling(rx->dqo.page_pool);
|
||||
gve_remove_napi(priv, ntfy_idx);
|
||||
gve_rx_remove_from_block(priv, idx);
|
||||
gve_rx_reset_ring_dqo(priv, idx);
|
||||
|
@ -4829,6 +4829,18 @@ static void vnic_add_client_data(struct ibmvnic_adapter *adapter,
|
||||
strscpy(vlcd->name, adapter->netdev->name, len);
|
||||
}
|
||||
|
||||
static void ibmvnic_print_hex_dump(struct net_device *dev, void *buf,
|
||||
size_t len)
|
||||
{
|
||||
unsigned char hex_str[16 * 3];
|
||||
|
||||
for (size_t i = 0; i < len; i += 16) {
|
||||
hex_dump_to_buffer((unsigned char *)buf + i, len - i, 16, 8,
|
||||
hex_str, sizeof(hex_str), false);
|
||||
netdev_dbg(dev, "%s\n", hex_str);
|
||||
}
|
||||
}
|
||||
|
||||
static int send_login(struct ibmvnic_adapter *adapter)
|
||||
{
|
||||
struct ibmvnic_login_rsp_buffer *login_rsp_buffer;
|
||||
@ -4939,10 +4951,8 @@ static int send_login(struct ibmvnic_adapter *adapter)
|
||||
vnic_add_client_data(adapter, vlcd);
|
||||
|
||||
netdev_dbg(adapter->netdev, "Login Buffer:\n");
|
||||
for (i = 0; i < (adapter->login_buf_sz - 1) / 8 + 1; i++) {
|
||||
netdev_dbg(adapter->netdev, "%016lx\n",
|
||||
((unsigned long *)(adapter->login_buf))[i]);
|
||||
}
|
||||
ibmvnic_print_hex_dump(adapter->netdev, adapter->login_buf,
|
||||
adapter->login_buf_sz);
|
||||
|
||||
memset(&crq, 0, sizeof(crq));
|
||||
crq.login.first = IBMVNIC_CRQ_CMD;
|
||||
@ -5319,15 +5329,13 @@ static void handle_query_ip_offload_rsp(struct ibmvnic_adapter *adapter)
|
||||
{
|
||||
struct device *dev = &adapter->vdev->dev;
|
||||
struct ibmvnic_query_ip_offload_buffer *buf = &adapter->ip_offload_buf;
|
||||
int i;
|
||||
|
||||
dma_unmap_single(dev, adapter->ip_offload_tok,
|
||||
sizeof(adapter->ip_offload_buf), DMA_FROM_DEVICE);
|
||||
|
||||
netdev_dbg(adapter->netdev, "Query IP Offload Buffer:\n");
|
||||
for (i = 0; i < (sizeof(adapter->ip_offload_buf) - 1) / 8 + 1; i++)
|
||||
netdev_dbg(adapter->netdev, "%016lx\n",
|
||||
((unsigned long *)(buf))[i]);
|
||||
ibmvnic_print_hex_dump(adapter->netdev, buf,
|
||||
sizeof(adapter->ip_offload_buf));
|
||||
|
||||
netdev_dbg(adapter->netdev, "ipv4_chksum = %d\n", buf->ipv4_chksum);
|
||||
netdev_dbg(adapter->netdev, "ipv6_chksum = %d\n", buf->ipv6_chksum);
|
||||
@ -5558,10 +5566,8 @@ static int handle_login_rsp(union ibmvnic_crq *login_rsp_crq,
|
||||
netdev->mtu = adapter->req_mtu - ETH_HLEN;
|
||||
|
||||
netdev_dbg(adapter->netdev, "Login Response Buffer:\n");
|
||||
for (i = 0; i < (adapter->login_rsp_buf_sz - 1) / 8 + 1; i++) {
|
||||
netdev_dbg(adapter->netdev, "%016lx\n",
|
||||
((unsigned long *)(adapter->login_rsp_buf))[i]);
|
||||
}
|
||||
ibmvnic_print_hex_dump(netdev, adapter->login_rsp_buf,
|
||||
adapter->login_rsp_buf_sz);
|
||||
|
||||
/* Sanity checks */
|
||||
if (login->num_txcomp_subcrqs != login_rsp->num_txsubm_subcrqs ||
|
||||
|
@ -25,10 +25,10 @@ struct ice_health_status {
|
||||
* The below lookup requires to be sorted by code.
|
||||
*/
|
||||
|
||||
static const char *const ice_common_port_solutions =
|
||||
static const char ice_common_port_solutions[] =
|
||||
"Check your cable connection. Change or replace the module or cable. Manually set speed and duplex.";
|
||||
static const char *const ice_port_number_label = "Port Number";
|
||||
static const char *const ice_update_nvm_solution = "Update to the latest NVM image.";
|
||||
static const char ice_port_number_label[] = "Port Number";
|
||||
static const char ice_update_nvm_solution[] = "Update to the latest NVM image.";
|
||||
|
||||
static const struct ice_health_status ice_health_status_lookup[] = {
|
||||
{ICE_AQC_HEALTH_STATUS_ERR_UNKNOWN_MOD_STRICT, "An unsupported module was detected.",
|
||||
|
@ -2157,7 +2157,8 @@ ice_parse_common_caps(struct ice_hw *hw, struct ice_hw_common_caps *caps,
|
||||
caps->nvm_unified_update);
|
||||
break;
|
||||
case ICE_AQC_CAPS_RDMA:
|
||||
caps->rdma = (number == 1);
|
||||
if (IS_ENABLED(CONFIG_INFINIBAND_IRDMA))
|
||||
caps->rdma = (number == 1);
|
||||
ice_debug(hw, ICE_DBG_INIT, "%s: rdma = %d\n", prefix, caps->rdma);
|
||||
break;
|
||||
case ICE_AQC_CAPS_MAX_MTU:
|
||||
|
@ -1778,6 +1778,7 @@ static int ice_ptp_write_perout(struct ice_hw *hw, unsigned int chan,
|
||||
8 + chan + (tmr_idx * 4));
|
||||
|
||||
wr32(hw, GLGEN_GPIO_CTL(gpio_pin), val);
|
||||
ice_flush(hw);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1838,9 +1839,10 @@ static int ice_ptp_cfg_perout(struct ice_pf *pf, struct ptp_perout_request *rq,
|
||||
div64_u64_rem(start, period, &phase);
|
||||
|
||||
/* If we have only phase or start time is in the past, start the timer
|
||||
* at the next multiple of period, maintaining phase.
|
||||
* at the next multiple of period, maintaining phase at least 0.5 second
|
||||
* from now, so we have time to write it to HW.
|
||||
*/
|
||||
clk = ice_ptp_read_src_clk_reg(pf, NULL);
|
||||
clk = ice_ptp_read_src_clk_reg(pf, NULL) + NSEC_PER_MSEC * 500;
|
||||
if (rq->flags & PTP_PEROUT_PHASE || start <= clk - prop_delay_ns)
|
||||
start = div64_u64(clk + period - 1, period) * period + phase;
|
||||
|
||||
|
@ -565,7 +565,7 @@ bool ice_vc_isvalid_vsi_id(struct ice_vf *vf, u16 vsi_id)
|
||||
*
|
||||
* check for the valid queue ID
|
||||
*/
|
||||
static bool ice_vc_isvalid_q_id(struct ice_vsi *vsi, u8 qid)
|
||||
static bool ice_vc_isvalid_q_id(struct ice_vsi *vsi, u16 qid)
|
||||
{
|
||||
/* allocated Tx and Rx queues should be always equal for VF VSI */
|
||||
return qid < vsi->alloc_txq;
|
||||
@ -1865,15 +1865,33 @@ static int ice_vc_cfg_q_bw(struct ice_vf *vf, u8 *msg)
|
||||
|
||||
for (i = 0; i < qbw->num_queues; i++) {
|
||||
if (qbw->cfg[i].shaper.peak != 0 && vf->max_tx_rate != 0 &&
|
||||
qbw->cfg[i].shaper.peak > vf->max_tx_rate)
|
||||
qbw->cfg[i].shaper.peak > vf->max_tx_rate) {
|
||||
dev_warn(ice_pf_to_dev(vf->pf), "The maximum queue %d rate limit configuration may not take effect because the maximum TX rate for VF-%d is %d\n",
|
||||
qbw->cfg[i].queue_id, vf->vf_id,
|
||||
vf->max_tx_rate);
|
||||
v_ret = VIRTCHNL_STATUS_ERR_PARAM;
|
||||
goto err;
|
||||
}
|
||||
if (qbw->cfg[i].shaper.committed != 0 && vf->min_tx_rate != 0 &&
|
||||
qbw->cfg[i].shaper.committed < vf->min_tx_rate)
|
||||
qbw->cfg[i].shaper.committed < vf->min_tx_rate) {
|
||||
dev_warn(ice_pf_to_dev(vf->pf), "The minimum queue %d rate limit configuration may not take effect because the minimum TX rate for VF-%d is %d\n",
|
||||
qbw->cfg[i].queue_id, vf->vf_id,
|
||||
vf->max_tx_rate);
|
||||
vf->min_tx_rate);
|
||||
v_ret = VIRTCHNL_STATUS_ERR_PARAM;
|
||||
goto err;
|
||||
}
|
||||
if (qbw->cfg[i].queue_id > vf->num_vf_qs) {
|
||||
dev_warn(ice_pf_to_dev(vf->pf), "VF-%d trying to configure invalid queue_id\n",
|
||||
vf->vf_id);
|
||||
v_ret = VIRTCHNL_STATUS_ERR_PARAM;
|
||||
goto err;
|
||||
}
|
||||
if (qbw->cfg[i].tc >= ICE_MAX_TRAFFIC_CLASS) {
|
||||
dev_warn(ice_pf_to_dev(vf->pf), "VF-%d trying to configure a traffic class higher than allowed\n",
|
||||
vf->vf_id);
|
||||
v_ret = VIRTCHNL_STATUS_ERR_PARAM;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < qbw->num_queues; i++) {
|
||||
@ -1903,13 +1921,21 @@ err:
|
||||
*/
|
||||
static int ice_vc_cfg_q_quanta(struct ice_vf *vf, u8 *msg)
|
||||
{
|
||||
u16 quanta_prof_id, quanta_size, start_qid, num_queues, end_qid, i;
|
||||
enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS;
|
||||
u16 quanta_prof_id, quanta_size, start_qid, end_qid, i;
|
||||
struct virtchnl_quanta_cfg *qquanta =
|
||||
(struct virtchnl_quanta_cfg *)msg;
|
||||
struct ice_vsi *vsi;
|
||||
int ret;
|
||||
|
||||
start_qid = qquanta->queue_select.start_queue_id;
|
||||
num_queues = qquanta->queue_select.num_queues;
|
||||
|
||||
if (check_add_overflow(start_qid, num_queues, &end_qid)) {
|
||||
v_ret = VIRTCHNL_STATUS_ERR_PARAM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) {
|
||||
v_ret = VIRTCHNL_STATUS_ERR_PARAM;
|
||||
goto err;
|
||||
@ -1921,8 +1947,6 @@ static int ice_vc_cfg_q_quanta(struct ice_vf *vf, u8 *msg)
|
||||
goto err;
|
||||
}
|
||||
|
||||
end_qid = qquanta->queue_select.start_queue_id +
|
||||
qquanta->queue_select.num_queues;
|
||||
if (end_qid > ICE_MAX_RSS_QS_PER_VF ||
|
||||
end_qid > min_t(u16, vsi->alloc_txq, vsi->alloc_rxq)) {
|
||||
dev_err(ice_pf_to_dev(vf->pf), "VF-%d trying to configure more than allocated number of queues: %d\n",
|
||||
@ -1951,7 +1975,6 @@ static int ice_vc_cfg_q_quanta(struct ice_vf *vf, u8 *msg)
|
||||
goto err;
|
||||
}
|
||||
|
||||
start_qid = qquanta->queue_select.start_queue_id;
|
||||
for (i = start_qid; i < end_qid; i++)
|
||||
vsi->tx_rings[i]->quanta_prof_id = quanta_prof_id;
|
||||
|
||||
|
@ -832,21 +832,27 @@ ice_vc_fdir_parse_raw(struct ice_vf *vf,
|
||||
struct virtchnl_proto_hdrs *proto,
|
||||
struct virtchnl_fdir_fltr_conf *conf)
|
||||
{
|
||||
u8 *pkt_buf, *msk_buf __free(kfree);
|
||||
u8 *pkt_buf, *msk_buf __free(kfree) = NULL;
|
||||
struct ice_parser_result rslt;
|
||||
struct ice_pf *pf = vf->pf;
|
||||
u16 pkt_len, udp_port = 0;
|
||||
struct ice_parser *psr;
|
||||
int status = -ENOMEM;
|
||||
struct ice_hw *hw;
|
||||
u16 udp_port = 0;
|
||||
|
||||
pkt_buf = kzalloc(proto->raw.pkt_len, GFP_KERNEL);
|
||||
msk_buf = kzalloc(proto->raw.pkt_len, GFP_KERNEL);
|
||||
pkt_len = proto->raw.pkt_len;
|
||||
|
||||
if (!pkt_len || pkt_len > VIRTCHNL_MAX_SIZE_RAW_PACKET)
|
||||
return -EINVAL;
|
||||
|
||||
pkt_buf = kzalloc(pkt_len, GFP_KERNEL);
|
||||
msk_buf = kzalloc(pkt_len, GFP_KERNEL);
|
||||
|
||||
if (!pkt_buf || !msk_buf)
|
||||
goto err_mem_alloc;
|
||||
|
||||
memcpy(pkt_buf, proto->raw.spec, proto->raw.pkt_len);
|
||||
memcpy(msk_buf, proto->raw.mask, proto->raw.pkt_len);
|
||||
memcpy(pkt_buf, proto->raw.spec, pkt_len);
|
||||
memcpy(msk_buf, proto->raw.mask, pkt_len);
|
||||
|
||||
hw = &pf->hw;
|
||||
|
||||
@ -862,7 +868,7 @@ ice_vc_fdir_parse_raw(struct ice_vf *vf,
|
||||
if (ice_get_open_tunnel_port(hw, &udp_port, TNL_VXLAN))
|
||||
ice_parser_vxlan_tunnel_set(psr, udp_port, true);
|
||||
|
||||
status = ice_parser_run(psr, pkt_buf, proto->raw.pkt_len, &rslt);
|
||||
status = ice_parser_run(psr, pkt_buf, pkt_len, &rslt);
|
||||
if (status)
|
||||
goto err_parser_destroy;
|
||||
|
||||
@ -876,7 +882,7 @@ ice_vc_fdir_parse_raw(struct ice_vf *vf,
|
||||
}
|
||||
|
||||
status = ice_parser_profile_init(&rslt, pkt_buf, msk_buf,
|
||||
proto->raw.pkt_len, ICE_BLK_FD,
|
||||
pkt_len, ICE_BLK_FD,
|
||||
conf->prof);
|
||||
if (status)
|
||||
goto err_parser_profile_init;
|
||||
@ -885,7 +891,7 @@ ice_vc_fdir_parse_raw(struct ice_vf *vf,
|
||||
ice_parser_profile_dump(hw, conf->prof);
|
||||
|
||||
/* Store raw flow info into @conf */
|
||||
conf->pkt_len = proto->raw.pkt_len;
|
||||
conf->pkt_len = pkt_len;
|
||||
conf->pkt_buf = pkt_buf;
|
||||
conf->parser_ena = true;
|
||||
|
||||
|
@ -928,15 +928,19 @@ static int idpf_stop(struct net_device *netdev)
|
||||
static void idpf_decfg_netdev(struct idpf_vport *vport)
|
||||
{
|
||||
struct idpf_adapter *adapter = vport->adapter;
|
||||
u16 idx = vport->idx;
|
||||
|
||||
kfree(vport->rx_ptype_lkup);
|
||||
vport->rx_ptype_lkup = NULL;
|
||||
|
||||
unregister_netdev(vport->netdev);
|
||||
free_netdev(vport->netdev);
|
||||
if (test_and_clear_bit(IDPF_VPORT_REG_NETDEV,
|
||||
adapter->vport_config[idx]->flags)) {
|
||||
unregister_netdev(vport->netdev);
|
||||
free_netdev(vport->netdev);
|
||||
}
|
||||
vport->netdev = NULL;
|
||||
|
||||
adapter->netdevs[vport->idx] = NULL;
|
||||
adapter->netdevs[idx] = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1537,13 +1541,22 @@ void idpf_init_task(struct work_struct *work)
|
||||
}
|
||||
|
||||
for (index = 0; index < adapter->max_vports; index++) {
|
||||
if (adapter->netdevs[index] &&
|
||||
!test_bit(IDPF_VPORT_REG_NETDEV,
|
||||
adapter->vport_config[index]->flags)) {
|
||||
register_netdev(adapter->netdevs[index]);
|
||||
set_bit(IDPF_VPORT_REG_NETDEV,
|
||||
adapter->vport_config[index]->flags);
|
||||
struct net_device *netdev = adapter->netdevs[index];
|
||||
struct idpf_vport_config *vport_config;
|
||||
|
||||
vport_config = adapter->vport_config[index];
|
||||
|
||||
if (!netdev ||
|
||||
test_bit(IDPF_VPORT_REG_NETDEV, vport_config->flags))
|
||||
continue;
|
||||
|
||||
err = register_netdev(netdev);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "failed to register netdev for vport %d: %pe\n",
|
||||
index, ERR_PTR(err));
|
||||
continue;
|
||||
}
|
||||
set_bit(IDPF_VPORT_REG_NETDEV, vport_config->flags);
|
||||
}
|
||||
|
||||
/* As all the required vports are created, clear the reset flag
|
||||
|
@ -884,8 +884,10 @@ static int flow_type_to_traffic_type(u32 flow_type)
|
||||
case ESP_V6_FLOW:
|
||||
return MLX5_TT_IPV6_IPSEC_ESP;
|
||||
case IPV4_FLOW:
|
||||
case IP_USER_FLOW:
|
||||
return MLX5_TT_IPV4;
|
||||
case IPV6_FLOW:
|
||||
case IPV6_USER_FLOW:
|
||||
return MLX5_TT_IPV6;
|
||||
default:
|
||||
return -EINVAL;
|
||||
|
@ -1031,6 +1031,10 @@ static void mlx5_do_bond(struct mlx5_lag *ldev)
|
||||
if (err) {
|
||||
if (shared_fdb || roce_lag)
|
||||
mlx5_lag_add_devices(ldev);
|
||||
if (shared_fdb) {
|
||||
mlx5_ldev_for_each(i, 0, ldev)
|
||||
mlx5_eswitch_reload_ib_reps(ldev->pf[i].dev->priv.eswitch);
|
||||
}
|
||||
|
||||
return;
|
||||
} else if (roce_lag) {
|
||||
|
@ -1210,24 +1210,24 @@ static int mlx5_function_enable(struct mlx5_core_dev *dev, bool boot, u64 timeou
|
||||
dev->caps.embedded_cpu = mlx5_read_embedded_cpu(dev);
|
||||
mlx5_cmd_set_state(dev, MLX5_CMDIF_STATE_UP);
|
||||
|
||||
mlx5_start_health_poll(dev);
|
||||
|
||||
err = mlx5_core_enable_hca(dev, 0);
|
||||
if (err) {
|
||||
mlx5_core_err(dev, "enable hca failed\n");
|
||||
goto stop_health_poll;
|
||||
goto err_cmd_cleanup;
|
||||
}
|
||||
|
||||
mlx5_start_health_poll(dev);
|
||||
|
||||
err = mlx5_core_set_issi(dev);
|
||||
if (err) {
|
||||
mlx5_core_err(dev, "failed to set issi\n");
|
||||
goto err_disable_hca;
|
||||
goto stop_health_poll;
|
||||
}
|
||||
|
||||
err = mlx5_satisfy_startup_pages(dev, 1);
|
||||
if (err) {
|
||||
mlx5_core_err(dev, "failed to allocate boot pages\n");
|
||||
goto err_disable_hca;
|
||||
goto stop_health_poll;
|
||||
}
|
||||
|
||||
err = mlx5_tout_query_dtor(dev);
|
||||
@ -1240,10 +1240,9 @@ static int mlx5_function_enable(struct mlx5_core_dev *dev, bool boot, u64 timeou
|
||||
|
||||
reclaim_boot_pages:
|
||||
mlx5_reclaim_startup_pages(dev);
|
||||
err_disable_hca:
|
||||
mlx5_core_disable_hca(dev, 0);
|
||||
stop_health_poll:
|
||||
mlx5_stop_health_poll(dev, boot);
|
||||
mlx5_core_disable_hca(dev, 0);
|
||||
err_cmd_cleanup:
|
||||
mlx5_cmd_set_state(dev, MLX5_CMDIF_STATE_DOWN);
|
||||
mlx5_cmd_disable(dev);
|
||||
@ -1254,8 +1253,8 @@ err_cmd_cleanup:
|
||||
static void mlx5_function_disable(struct mlx5_core_dev *dev, bool boot)
|
||||
{
|
||||
mlx5_reclaim_startup_pages(dev);
|
||||
mlx5_core_disable_hca(dev, 0);
|
||||
mlx5_stop_health_poll(dev, boot);
|
||||
mlx5_core_disable_hca(dev, 0);
|
||||
mlx5_cmd_set_state(dev, MLX5_CMDIF_STATE_DOWN);
|
||||
mlx5_cmd_disable(dev);
|
||||
}
|
||||
|
@ -212,7 +212,22 @@ static const u8 mlxsw_sp4_acl_bf_crc6_tab[256] = {
|
||||
* This array defines key offsets for easy access when copying key blocks from
|
||||
* entry key to Bloom filter chunk.
|
||||
*/
|
||||
static const u8 chunk_key_offsets[MLXSW_BLOOM_KEY_CHUNKS] = {2, 20, 38};
|
||||
static char *
|
||||
mlxsw_sp_acl_bf_enc_key_get(struct mlxsw_sp_acl_atcam_entry *aentry,
|
||||
u8 chunk_index)
|
||||
{
|
||||
switch (chunk_index) {
|
||||
case 0:
|
||||
return &aentry->ht_key.enc_key[2];
|
||||
case 1:
|
||||
return &aentry->ht_key.enc_key[20];
|
||||
case 2:
|
||||
return &aentry->ht_key.enc_key[38];
|
||||
default:
|
||||
WARN_ON_ONCE(1);
|
||||
return &aentry->ht_key.enc_key[0];
|
||||
}
|
||||
}
|
||||
|
||||
static u16 mlxsw_sp2_acl_bf_crc16_byte(u16 crc, u8 c)
|
||||
{
|
||||
@ -235,9 +250,10 @@ __mlxsw_sp_acl_bf_key_encode(struct mlxsw_sp_acl_atcam_region *aregion,
|
||||
u8 key_offset, u8 chunk_key_len, u8 chunk_len)
|
||||
{
|
||||
struct mlxsw_afk_key_info *key_info = aregion->region->key_info;
|
||||
u8 chunk_index, chunk_count, block_count;
|
||||
u8 chunk_index, chunk_count;
|
||||
char *chunk = output;
|
||||
__be16 erp_region_id;
|
||||
u32 block_count;
|
||||
|
||||
block_count = mlxsw_afk_key_info_blocks_count_get(key_info);
|
||||
chunk_count = 1 + ((block_count - 1) >> 2);
|
||||
@ -245,12 +261,13 @@ __mlxsw_sp_acl_bf_key_encode(struct mlxsw_sp_acl_atcam_region *aregion,
|
||||
(aregion->region->id << 4));
|
||||
for (chunk_index = max_chunks - chunk_count; chunk_index < max_chunks;
|
||||
chunk_index++) {
|
||||
char *enc_key;
|
||||
|
||||
memset(chunk, 0, pad_bytes);
|
||||
memcpy(chunk + pad_bytes, &erp_region_id,
|
||||
sizeof(erp_region_id));
|
||||
memcpy(chunk + key_offset,
|
||||
&aentry->ht_key.enc_key[chunk_key_offsets[chunk_index]],
|
||||
chunk_key_len);
|
||||
enc_key = mlxsw_sp_acl_bf_enc_key_get(aentry, chunk_index);
|
||||
memcpy(chunk + key_offset, enc_key, chunk_key_len);
|
||||
chunk += chunk_len;
|
||||
}
|
||||
*len = chunk_count * chunk_len;
|
||||
|
@ -3688,7 +3688,6 @@ static int stmmac_request_irq_multi_msi(struct net_device *dev)
|
||||
{
|
||||
struct stmmac_priv *priv = netdev_priv(dev);
|
||||
enum request_irq_err irq_err;
|
||||
cpumask_t cpu_mask;
|
||||
int irq_idx = 0;
|
||||
char *int_name;
|
||||
int ret;
|
||||
@ -3817,9 +3816,8 @@ static int stmmac_request_irq_multi_msi(struct net_device *dev)
|
||||
irq_idx = i;
|
||||
goto irq_error;
|
||||
}
|
||||
cpumask_clear(&cpu_mask);
|
||||
cpumask_set_cpu(i % num_online_cpus(), &cpu_mask);
|
||||
irq_set_affinity_hint(priv->rx_irq[i], &cpu_mask);
|
||||
irq_set_affinity_hint(priv->rx_irq[i],
|
||||
cpumask_of(i % num_online_cpus()));
|
||||
}
|
||||
|
||||
/* Request Tx MSI irq */
|
||||
@ -3842,9 +3840,8 @@ static int stmmac_request_irq_multi_msi(struct net_device *dev)
|
||||
irq_idx = i;
|
||||
goto irq_error;
|
||||
}
|
||||
cpumask_clear(&cpu_mask);
|
||||
cpumask_set_cpu(i % num_online_cpus(), &cpu_mask);
|
||||
irq_set_affinity_hint(priv->tx_irq[i], &cpu_mask);
|
||||
irq_set_affinity_hint(priv->tx_irq[i],
|
||||
cpumask_of(i % num_online_cpus()));
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -1102,26 +1102,6 @@ static void wx_tx_ctxtdesc(struct wx_ring *tx_ring, u32 vlan_macip_lens,
|
||||
context_desc->mss_l4len_idx = cpu_to_le32(mss_l4len_idx);
|
||||
}
|
||||
|
||||
static void wx_get_ipv6_proto(struct sk_buff *skb, int offset, u8 *nexthdr)
|
||||
{
|
||||
struct ipv6hdr *hdr = (struct ipv6hdr *)(skb->data + offset);
|
||||
|
||||
*nexthdr = hdr->nexthdr;
|
||||
offset += sizeof(struct ipv6hdr);
|
||||
while (ipv6_ext_hdr(*nexthdr)) {
|
||||
struct ipv6_opt_hdr _hdr, *hp;
|
||||
|
||||
if (*nexthdr == NEXTHDR_NONE)
|
||||
return;
|
||||
hp = skb_header_pointer(skb, offset, sizeof(_hdr), &_hdr);
|
||||
if (!hp)
|
||||
return;
|
||||
if (*nexthdr == NEXTHDR_FRAGMENT)
|
||||
break;
|
||||
*nexthdr = hp->nexthdr;
|
||||
}
|
||||
}
|
||||
|
||||
union network_header {
|
||||
struct iphdr *ipv4;
|
||||
struct ipv6hdr *ipv6;
|
||||
@ -1132,6 +1112,8 @@ static u8 wx_encode_tx_desc_ptype(const struct wx_tx_buffer *first)
|
||||
{
|
||||
u8 tun_prot = 0, l4_prot = 0, ptype = 0;
|
||||
struct sk_buff *skb = first->skb;
|
||||
unsigned char *exthdr, *l4_hdr;
|
||||
__be16 frag_off;
|
||||
|
||||
if (skb->encapsulation) {
|
||||
union network_header hdr;
|
||||
@ -1142,14 +1124,18 @@ static u8 wx_encode_tx_desc_ptype(const struct wx_tx_buffer *first)
|
||||
ptype = WX_PTYPE_TUN_IPV4;
|
||||
break;
|
||||
case htons(ETH_P_IPV6):
|
||||
wx_get_ipv6_proto(skb, skb_network_offset(skb), &tun_prot);
|
||||
l4_hdr = skb_transport_header(skb);
|
||||
exthdr = skb_network_header(skb) + sizeof(struct ipv6hdr);
|
||||
tun_prot = ipv6_hdr(skb)->nexthdr;
|
||||
if (l4_hdr != exthdr)
|
||||
ipv6_skip_exthdr(skb, exthdr - skb->data, &tun_prot, &frag_off);
|
||||
ptype = WX_PTYPE_TUN_IPV6;
|
||||
break;
|
||||
default:
|
||||
return ptype;
|
||||
}
|
||||
|
||||
if (tun_prot == IPPROTO_IPIP) {
|
||||
if (tun_prot == IPPROTO_IPIP || tun_prot == IPPROTO_IPV6) {
|
||||
hdr.raw = (void *)inner_ip_hdr(skb);
|
||||
ptype |= WX_PTYPE_PKT_IPIP;
|
||||
} else if (tun_prot == IPPROTO_UDP) {
|
||||
@ -1186,7 +1172,11 @@ static u8 wx_encode_tx_desc_ptype(const struct wx_tx_buffer *first)
|
||||
l4_prot = hdr.ipv4->protocol;
|
||||
break;
|
||||
case 6:
|
||||
wx_get_ipv6_proto(skb, skb_inner_network_offset(skb), &l4_prot);
|
||||
l4_hdr = skb_inner_transport_header(skb);
|
||||
exthdr = skb_inner_network_header(skb) + sizeof(struct ipv6hdr);
|
||||
l4_prot = inner_ipv6_hdr(skb)->nexthdr;
|
||||
if (l4_hdr != exthdr)
|
||||
ipv6_skip_exthdr(skb, exthdr - skb->data, &l4_prot, &frag_off);
|
||||
ptype |= WX_PTYPE_PKT_IPV6;
|
||||
break;
|
||||
default:
|
||||
@ -1199,7 +1189,11 @@ static u8 wx_encode_tx_desc_ptype(const struct wx_tx_buffer *first)
|
||||
ptype = WX_PTYPE_PKT_IP;
|
||||
break;
|
||||
case htons(ETH_P_IPV6):
|
||||
wx_get_ipv6_proto(skb, skb_network_offset(skb), &l4_prot);
|
||||
l4_hdr = skb_transport_header(skb);
|
||||
exthdr = skb_network_header(skb) + sizeof(struct ipv6hdr);
|
||||
l4_prot = ipv6_hdr(skb)->nexthdr;
|
||||
if (l4_hdr != exthdr)
|
||||
ipv6_skip_exthdr(skb, exthdr - skb->data, &l4_prot, &frag_off);
|
||||
ptype = WX_PTYPE_PKT_IP | WX_PTYPE_PKT_IPV6;
|
||||
break;
|
||||
default:
|
||||
@ -1289,13 +1283,20 @@ static int wx_tso(struct wx_ring *tx_ring, struct wx_tx_buffer *first,
|
||||
|
||||
/* vlan_macip_lens: HEADLEN, MACLEN, VLAN tag */
|
||||
if (enc) {
|
||||
unsigned char *exthdr, *l4_hdr;
|
||||
__be16 frag_off;
|
||||
|
||||
switch (first->protocol) {
|
||||
case htons(ETH_P_IP):
|
||||
tun_prot = ip_hdr(skb)->protocol;
|
||||
first->tx_flags |= WX_TX_FLAGS_OUTER_IPV4;
|
||||
break;
|
||||
case htons(ETH_P_IPV6):
|
||||
l4_hdr = skb_transport_header(skb);
|
||||
exthdr = skb_network_header(skb) + sizeof(struct ipv6hdr);
|
||||
tun_prot = ipv6_hdr(skb)->nexthdr;
|
||||
if (l4_hdr != exthdr)
|
||||
ipv6_skip_exthdr(skb, exthdr - skb->data, &tun_prot, &frag_off);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -1318,6 +1319,7 @@ static int wx_tso(struct wx_ring *tx_ring, struct wx_tx_buffer *first,
|
||||
WX_TXD_TUNNEL_LEN_SHIFT);
|
||||
break;
|
||||
case IPPROTO_IPIP:
|
||||
case IPPROTO_IPV6:
|
||||
tunhdr_eiplen_tunlen = (((char *)inner_ip_hdr(skb) -
|
||||
(char *)ip_hdr(skb)) >> 2) <<
|
||||
WX_TXD_OUTER_IPLEN_SHIFT;
|
||||
@ -1355,12 +1357,15 @@ static void wx_tx_csum(struct wx_ring *tx_ring, struct wx_tx_buffer *first,
|
||||
u8 tun_prot = 0;
|
||||
|
||||
if (skb->ip_summed != CHECKSUM_PARTIAL) {
|
||||
csum_failed:
|
||||
if (!(first->tx_flags & WX_TX_FLAGS_HW_VLAN) &&
|
||||
!(first->tx_flags & WX_TX_FLAGS_CC))
|
||||
return;
|
||||
vlan_macip_lens = skb_network_offset(skb) <<
|
||||
WX_TXD_MACLEN_SHIFT;
|
||||
} else {
|
||||
unsigned char *exthdr, *l4_hdr;
|
||||
__be16 frag_off;
|
||||
u8 l4_prot = 0;
|
||||
union {
|
||||
struct iphdr *ipv4;
|
||||
@ -1382,7 +1387,12 @@ static void wx_tx_csum(struct wx_ring *tx_ring, struct wx_tx_buffer *first,
|
||||
tun_prot = ip_hdr(skb)->protocol;
|
||||
break;
|
||||
case htons(ETH_P_IPV6):
|
||||
l4_hdr = skb_transport_header(skb);
|
||||
exthdr = skb_network_header(skb) + sizeof(struct ipv6hdr);
|
||||
tun_prot = ipv6_hdr(skb)->nexthdr;
|
||||
if (l4_hdr != exthdr)
|
||||
ipv6_skip_exthdr(skb, exthdr - skb->data,
|
||||
&tun_prot, &frag_off);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
@ -1406,6 +1416,7 @@ static void wx_tx_csum(struct wx_ring *tx_ring, struct wx_tx_buffer *first,
|
||||
WX_TXD_TUNNEL_LEN_SHIFT);
|
||||
break;
|
||||
case IPPROTO_IPIP:
|
||||
case IPPROTO_IPV6:
|
||||
tunhdr_eiplen_tunlen = (((char *)inner_ip_hdr(skb) -
|
||||
(char *)ip_hdr(skb)) >> 2) <<
|
||||
WX_TXD_OUTER_IPLEN_SHIFT;
|
||||
@ -1428,7 +1439,10 @@ static void wx_tx_csum(struct wx_ring *tx_ring, struct wx_tx_buffer *first,
|
||||
break;
|
||||
case 6:
|
||||
vlan_macip_lens |= (transport_hdr.raw - network_hdr.raw) >> 1;
|
||||
exthdr = network_hdr.raw + sizeof(struct ipv6hdr);
|
||||
l4_prot = network_hdr.ipv6->nexthdr;
|
||||
if (transport_hdr.raw != exthdr)
|
||||
ipv6_skip_exthdr(skb, exthdr - skb->data, &l4_prot, &frag_off);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -1448,7 +1462,8 @@ static void wx_tx_csum(struct wx_ring *tx_ring, struct wx_tx_buffer *first,
|
||||
WX_TXD_L4LEN_SHIFT;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
skb_checksum_help(skb);
|
||||
goto csum_failed;
|
||||
}
|
||||
|
||||
/* update TX checksum flag */
|
||||
|
@ -226,5 +226,4 @@ void ipvlan_l3s_unregister(struct ipvl_port *port)
|
||||
|
||||
dev->priv_flags &= ~IFF_L3MDEV_RX_HANDLER;
|
||||
ipvlan_unregister_nf_hook(read_pnet(&port->pnet));
|
||||
dev->l3mdev_ops = NULL;
|
||||
}
|
||||
|
@ -537,7 +537,7 @@ static void mctp_i2c_xmit(struct mctp_i2c_dev *midev, struct sk_buff *skb)
|
||||
rc = __i2c_transfer(midev->adapter, &msg, 1);
|
||||
|
||||
/* on tx errors, the flow can no longer be considered valid */
|
||||
if (rc)
|
||||
if (rc < 0)
|
||||
mctp_i2c_invalidate_tx_flow(midev, skb);
|
||||
|
||||
break;
|
||||
|
@ -2033,6 +2033,11 @@ vmxnet3_rq_cleanup(struct vmxnet3_rx_queue *rq,
|
||||
|
||||
rq->comp_ring.gen = VMXNET3_INIT_GEN;
|
||||
rq->comp_ring.next2proc = 0;
|
||||
|
||||
if (xdp_rxq_info_is_reg(&rq->xdp_rxq))
|
||||
xdp_rxq_info_unreg(&rq->xdp_rxq);
|
||||
page_pool_destroy(rq->page_pool);
|
||||
rq->page_pool = NULL;
|
||||
}
|
||||
|
||||
|
||||
@ -2073,11 +2078,6 @@ static void vmxnet3_rq_destroy(struct vmxnet3_rx_queue *rq,
|
||||
}
|
||||
}
|
||||
|
||||
if (xdp_rxq_info_is_reg(&rq->xdp_rxq))
|
||||
xdp_rxq_info_unreg(&rq->xdp_rxq);
|
||||
page_pool_destroy(rq->page_pool);
|
||||
rq->page_pool = NULL;
|
||||
|
||||
if (rq->data_ring.base) {
|
||||
dma_free_coherent(&adapter->pdev->dev,
|
||||
rq->rx_ring[0].size * rq->data_ring.desc_size,
|
||||
|
@ -1343,7 +1343,7 @@ struct virtchnl_proto_hdrs {
|
||||
* 2 - from the second inner layer
|
||||
* ....
|
||||
**/
|
||||
int count; /* the proto layers must < VIRTCHNL_MAX_NUM_PROTO_HDRS */
|
||||
u32 count; /* the proto layers must < VIRTCHNL_MAX_NUM_PROTO_HDRS */
|
||||
union {
|
||||
struct virtchnl_proto_hdr
|
||||
proto_hdr[VIRTCHNL_MAX_NUM_PROTO_HDRS];
|
||||
@ -1395,7 +1395,7 @@ VIRTCHNL_CHECK_STRUCT_LEN(36, virtchnl_filter_action);
|
||||
|
||||
struct virtchnl_filter_action_set {
|
||||
/* action number must be less then VIRTCHNL_MAX_NUM_ACTIONS */
|
||||
int count;
|
||||
u32 count;
|
||||
struct virtchnl_filter_action actions[VIRTCHNL_MAX_NUM_ACTIONS];
|
||||
};
|
||||
|
||||
|
@ -65,11 +65,9 @@ struct br_ip_list {
|
||||
#define BR_DEFAULT_AGEING_TIME (300 * HZ)
|
||||
|
||||
struct net_bridge;
|
||||
void brioctl_set(int (*hook)(struct net *net, struct net_bridge *br,
|
||||
unsigned int cmd, struct ifreq *ifr,
|
||||
void brioctl_set(int (*hook)(struct net *net, unsigned int cmd,
|
||||
void __user *uarg));
|
||||
int br_ioctl_call(struct net *net, struct net_bridge *br, unsigned int cmd,
|
||||
struct ifreq *ifr, void __user *uarg);
|
||||
int br_ioctl_call(struct net *net, unsigned int cmd, void __user *uarg);
|
||||
|
||||
#if IS_ENABLED(CONFIG_BRIDGE) && IS_ENABLED(CONFIG_BRIDGE_IGMP_SNOOPING)
|
||||
int br_multicast_list_adjacent(struct net_device *dev,
|
||||
|
@ -418,7 +418,6 @@ void ax25_rt_device_down(struct net_device *);
|
||||
int ax25_rt_ioctl(unsigned int, void __user *);
|
||||
extern const struct seq_operations ax25_rt_seqops;
|
||||
ax25_route *ax25_get_route(ax25_address *addr, struct net_device *dev);
|
||||
int ax25_rt_autobind(ax25_cb *, ax25_address *);
|
||||
struct sk_buff *ax25_rt_build_path(struct sk_buff *, ax25_address *,
|
||||
ax25_address *, ax25_digi *);
|
||||
void ax25_rt_free(void);
|
||||
|
@ -695,6 +695,7 @@ void bond_debug_register(struct bonding *bond);
|
||||
void bond_debug_unregister(struct bonding *bond);
|
||||
void bond_debug_reregister(struct bonding *bond);
|
||||
const char *bond_mode_name(int mode);
|
||||
bool bond_xdp_check(struct bonding *bond, int mode);
|
||||
void bond_setup(struct net_device *bond_dev);
|
||||
unsigned int bond_get_num_tx_queues(void);
|
||||
int bond_netlink_init(void);
|
||||
|
@ -1314,6 +1314,8 @@ static void MPOA_cache_impos_rcvd(struct k_message *msg,
|
||||
holding_time = msg->content.eg_info.holding_time;
|
||||
dprintk("(%s) entry = %p, holding_time = %u\n",
|
||||
mpc->dev->name, entry, holding_time);
|
||||
if (entry == NULL && !holding_time)
|
||||
return;
|
||||
if (entry == NULL && holding_time) {
|
||||
entry = mpc->eg_ops->add_entry(msg, mpc);
|
||||
mpc->eg_ops->put(entry);
|
||||
|
@ -1270,28 +1270,18 @@ static int __must_check ax25_connect(struct socket *sock,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Must bind first - autobinding in this may or may not work. If
|
||||
* the socket is already bound, check to see if the device has
|
||||
* been filled in, error if it hasn't.
|
||||
*/
|
||||
/* Must bind first - autobinding does not work. */
|
||||
if (sock_flag(sk, SOCK_ZAPPED)) {
|
||||
/* check if we can remove this feature. It is broken. */
|
||||
printk(KERN_WARNING "ax25_connect(): %s uses autobind, please contact jreuter@yaina.de\n",
|
||||
current->comm);
|
||||
if ((err = ax25_rt_autobind(ax25, &fsa->fsa_ax25.sax25_call)) < 0) {
|
||||
kfree(digi);
|
||||
goto out_release;
|
||||
}
|
||||
kfree(digi);
|
||||
err = -EINVAL;
|
||||
goto out_release;
|
||||
}
|
||||
|
||||
ax25_fillin_cb(ax25, ax25->ax25_dev);
|
||||
ax25_cb_add(ax25);
|
||||
} else {
|
||||
if (ax25->ax25_dev == NULL) {
|
||||
kfree(digi);
|
||||
err = -EHOSTUNREACH;
|
||||
goto out_release;
|
||||
}
|
||||
/* Check to see if the device has been filled in, error if it hasn't. */
|
||||
if (ax25->ax25_dev == NULL) {
|
||||
kfree(digi);
|
||||
err = -EHOSTUNREACH;
|
||||
goto out_release;
|
||||
}
|
||||
|
||||
if (sk->sk_type == SOCK_SEQPACKET &&
|
||||
|
@ -373,80 +373,6 @@ ax25_route *ax25_get_route(ax25_address *addr, struct net_device *dev)
|
||||
return ax25_rt;
|
||||
}
|
||||
|
||||
/*
|
||||
* Adjust path: If you specify a default route and want to connect
|
||||
* a target on the digipeater path but w/o having a special route
|
||||
* set before, the path has to be truncated from your target on.
|
||||
*/
|
||||
static inline void ax25_adjust_path(ax25_address *addr, ax25_digi *digipeat)
|
||||
{
|
||||
int k;
|
||||
|
||||
for (k = 0; k < digipeat->ndigi; k++) {
|
||||
if (ax25cmp(addr, &digipeat->calls[k]) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
digipeat->ndigi = k;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Find which interface to use.
|
||||
*/
|
||||
int ax25_rt_autobind(ax25_cb *ax25, ax25_address *addr)
|
||||
{
|
||||
ax25_uid_assoc *user;
|
||||
ax25_route *ax25_rt;
|
||||
int err = 0;
|
||||
|
||||
ax25_route_lock_use();
|
||||
ax25_rt = ax25_get_route(addr, NULL);
|
||||
if (!ax25_rt) {
|
||||
ax25_route_lock_unuse();
|
||||
return -EHOSTUNREACH;
|
||||
}
|
||||
rcu_read_lock();
|
||||
if ((ax25->ax25_dev = ax25_dev_ax25dev(ax25_rt->dev)) == NULL) {
|
||||
err = -EHOSTUNREACH;
|
||||
goto put;
|
||||
}
|
||||
|
||||
user = ax25_findbyuid(current_euid());
|
||||
if (user) {
|
||||
ax25->source_addr = user->call;
|
||||
ax25_uid_put(user);
|
||||
} else {
|
||||
if (ax25_uid_policy && !capable(CAP_NET_BIND_SERVICE)) {
|
||||
err = -EPERM;
|
||||
goto put;
|
||||
}
|
||||
ax25->source_addr = *(ax25_address *)ax25->ax25_dev->dev->dev_addr;
|
||||
}
|
||||
|
||||
if (ax25_rt->digipeat != NULL) {
|
||||
ax25->digipeat = kmemdup(ax25_rt->digipeat, sizeof(ax25_digi),
|
||||
GFP_ATOMIC);
|
||||
if (ax25->digipeat == NULL) {
|
||||
err = -ENOMEM;
|
||||
goto put;
|
||||
}
|
||||
ax25_adjust_path(addr, ax25->digipeat);
|
||||
}
|
||||
|
||||
if (ax25->sk != NULL) {
|
||||
local_bh_disable();
|
||||
bh_lock_sock(ax25->sk);
|
||||
sock_reset_flag(ax25->sk, SOCK_ZAPPED);
|
||||
bh_unlock_sock(ax25->sk);
|
||||
local_bh_enable();
|
||||
}
|
||||
|
||||
put:
|
||||
rcu_read_unlock();
|
||||
ax25_route_lock_unuse();
|
||||
return err;
|
||||
}
|
||||
|
||||
struct sk_buff *ax25_rt_build_path(struct sk_buff *skb, ax25_address *src,
|
||||
ax25_address *dest, ax25_digi *digi)
|
||||
|
@ -394,10 +394,26 @@ static int old_deviceless(struct net *net, void __user *data)
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
int br_ioctl_stub(struct net *net, struct net_bridge *br, unsigned int cmd,
|
||||
struct ifreq *ifr, void __user *uarg)
|
||||
int br_ioctl_stub(struct net *net, unsigned int cmd, void __user *uarg)
|
||||
{
|
||||
int ret = -EOPNOTSUPP;
|
||||
struct ifreq ifr;
|
||||
|
||||
if (cmd == SIOCBRADDIF || cmd == SIOCBRDELIF) {
|
||||
void __user *data;
|
||||
char *colon;
|
||||
|
||||
if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
|
||||
return -EPERM;
|
||||
|
||||
if (get_user_ifreq(&ifr, &data, uarg))
|
||||
return -EFAULT;
|
||||
|
||||
ifr.ifr_name[IFNAMSIZ - 1] = 0;
|
||||
colon = strchr(ifr.ifr_name, ':');
|
||||
if (colon)
|
||||
*colon = 0;
|
||||
}
|
||||
|
||||
rtnl_lock();
|
||||
|
||||
@ -430,7 +446,21 @@ int br_ioctl_stub(struct net *net, struct net_bridge *br, unsigned int cmd,
|
||||
break;
|
||||
case SIOCBRADDIF:
|
||||
case SIOCBRDELIF:
|
||||
ret = add_del_if(br, ifr->ifr_ifindex, cmd == SIOCBRADDIF);
|
||||
{
|
||||
struct net_device *dev;
|
||||
|
||||
dev = __dev_get_by_name(net, ifr.ifr_name);
|
||||
if (!dev || !netif_device_present(dev)) {
|
||||
ret = -ENODEV;
|
||||
break;
|
||||
}
|
||||
if (!netif_is_bridge_master(dev)) {
|
||||
ret = -EOPNOTSUPP;
|
||||
break;
|
||||
}
|
||||
|
||||
ret = add_del_if(netdev_priv(dev), ifr.ifr_ifindex, cmd == SIOCBRADDIF);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -949,8 +949,7 @@ br_port_get_check_rtnl(const struct net_device *dev)
|
||||
/* br_ioctl.c */
|
||||
int br_dev_siocdevprivate(struct net_device *dev, struct ifreq *rq,
|
||||
void __user *data, int cmd);
|
||||
int br_ioctl_stub(struct net *net, struct net_bridge *br, unsigned int cmd,
|
||||
struct ifreq *ifr, void __user *uarg);
|
||||
int br_ioctl_stub(struct net *net, unsigned int cmd, void __user *uarg);
|
||||
|
||||
/* br_multicast.c */
|
||||
#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
|
||||
|
@ -554,7 +554,6 @@ static int dev_ifsioc(struct net *net, struct ifreq *ifr, void __user *data,
|
||||
int err;
|
||||
struct net_device *dev = __dev_get_by_name(net, ifr->ifr_name);
|
||||
const struct net_device_ops *ops;
|
||||
netdevice_tracker dev_tracker;
|
||||
|
||||
if (!dev)
|
||||
return -ENODEV;
|
||||
@ -628,22 +627,6 @@ static int dev_ifsioc(struct net *net, struct ifreq *ifr, void __user *data,
|
||||
case SIOCWANDEV:
|
||||
return dev_siocwandev(dev, &ifr->ifr_settings);
|
||||
|
||||
case SIOCBRADDIF:
|
||||
case SIOCBRDELIF:
|
||||
if (!netif_device_present(dev))
|
||||
return -ENODEV;
|
||||
if (!netif_is_bridge_master(dev))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
netdev_hold(dev, &dev_tracker, GFP_KERNEL);
|
||||
rtnl_net_unlock(net);
|
||||
|
||||
err = br_ioctl_call(net, netdev_priv(dev), cmd, ifr, NULL);
|
||||
|
||||
netdev_put(dev, &dev_tracker);
|
||||
rtnl_net_lock(net);
|
||||
return err;
|
||||
|
||||
case SIOCDEVPRIVATE ... SIOCDEVPRIVATE + 15:
|
||||
return dev_siocdevprivate(dev, ifr, data, cmd);
|
||||
|
||||
@ -826,8 +809,6 @@ int dev_ioctl(struct net *net, unsigned int cmd, struct ifreq *ifr,
|
||||
case SIOCBONDRELEASE:
|
||||
case SIOCBONDSETHWADDR:
|
||||
case SIOCBONDCHANGEACTIVE:
|
||||
case SIOCBRADDIF:
|
||||
case SIOCBRDELIF:
|
||||
case SIOCSHWTSTAMP:
|
||||
if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
|
||||
return -EPERM;
|
||||
|
19
net/socket.c
19
net/socket.c
@ -1139,12 +1139,10 @@ static ssize_t sock_write_iter(struct kiocb *iocb, struct iov_iter *from)
|
||||
*/
|
||||
|
||||
static DEFINE_MUTEX(br_ioctl_mutex);
|
||||
static int (*br_ioctl_hook)(struct net *net, struct net_bridge *br,
|
||||
unsigned int cmd, struct ifreq *ifr,
|
||||
static int (*br_ioctl_hook)(struct net *net, unsigned int cmd,
|
||||
void __user *uarg);
|
||||
|
||||
void brioctl_set(int (*hook)(struct net *net, struct net_bridge *br,
|
||||
unsigned int cmd, struct ifreq *ifr,
|
||||
void brioctl_set(int (*hook)(struct net *net, unsigned int cmd,
|
||||
void __user *uarg))
|
||||
{
|
||||
mutex_lock(&br_ioctl_mutex);
|
||||
@ -1153,8 +1151,7 @@ void brioctl_set(int (*hook)(struct net *net, struct net_bridge *br,
|
||||
}
|
||||
EXPORT_SYMBOL(brioctl_set);
|
||||
|
||||
int br_ioctl_call(struct net *net, struct net_bridge *br, unsigned int cmd,
|
||||
struct ifreq *ifr, void __user *uarg)
|
||||
int br_ioctl_call(struct net *net, unsigned int cmd, void __user *uarg)
|
||||
{
|
||||
int err = -ENOPKG;
|
||||
|
||||
@ -1163,7 +1160,7 @@ int br_ioctl_call(struct net *net, struct net_bridge *br, unsigned int cmd,
|
||||
|
||||
mutex_lock(&br_ioctl_mutex);
|
||||
if (br_ioctl_hook)
|
||||
err = br_ioctl_hook(net, br, cmd, ifr, uarg);
|
||||
err = br_ioctl_hook(net, cmd, uarg);
|
||||
mutex_unlock(&br_ioctl_mutex);
|
||||
|
||||
return err;
|
||||
@ -1263,7 +1260,9 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
|
||||
case SIOCSIFBR:
|
||||
case SIOCBRADDBR:
|
||||
case SIOCBRDELBR:
|
||||
err = br_ioctl_call(net, NULL, cmd, NULL, argp);
|
||||
case SIOCBRADDIF:
|
||||
case SIOCBRDELIF:
|
||||
err = br_ioctl_call(net, cmd, argp);
|
||||
break;
|
||||
case SIOCGIFVLAN:
|
||||
case SIOCSIFVLAN:
|
||||
@ -3423,6 +3422,8 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock,
|
||||
case SIOCGPGRP:
|
||||
case SIOCBRADDBR:
|
||||
case SIOCBRDELBR:
|
||||
case SIOCBRADDIF:
|
||||
case SIOCBRDELIF:
|
||||
case SIOCGIFVLAN:
|
||||
case SIOCSIFVLAN:
|
||||
case SIOCGSKNS:
|
||||
@ -3462,8 +3463,6 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock,
|
||||
case SIOCGIFPFLAGS:
|
||||
case SIOCGIFTXQLEN:
|
||||
case SIOCSIFTXQLEN:
|
||||
case SIOCBRADDIF:
|
||||
case SIOCBRDELIF:
|
||||
case SIOCGIFNAME:
|
||||
case SIOCSIFNAME:
|
||||
case SIOCGMIIPHY:
|
||||
|
Loading…
Reference in New Issue
Block a user