summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2026-06-25 12:25:36 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2026-06-25 12:25:36 -0700
commit805185b7c7a1069e407b6f7b3bc98e44d415f484 (patch)
tree8e252490fc55ac4a2ef591efa06d078211fc639f /drivers
parentc75597caada080effbfbc0a7fb10dc2a3bb543ad (diff)
parentfe9f4ee6c61a1410afd73bf011de5ae618004796 (diff)
Merge tag 'net-7.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
Pull networking fixes from Jakub Kicinski: "Including fixes from netfilter and IPsec. Current release - regressions: - do not acquire dev->tx_global_lock in netdev_watchdog_up() - ethtool: keep rtnl_lock for ops using ethtool_op_get_link() - fix deadlock in nested UP notifier events Current release - new code bugs: - eth: - cn20k: fix subbank free list indexing for search order - airoha: fix BQL underflow in shared QDMA TX ring Previous releases - regressions: - netfilter: - flowtable: fix offloaded ct timeout never being extended - nf_conncount: prevent connlimit drops for early confirmed ct Previous releases - always broken: - require CAP_NET_ADMIN in the originating netns when modifying cross-netns devices - report NAPI thread PID in the caller's pid namespace - mac802154: fix dirty frag in in-place crypto for IOT radios - sctp: hold socket lock when dumping endpoints in sctp_diag, avoid an overflow - eth: gve: fix header buffer corruption with header-split and HW-GRO - af_key: initialize alg_key_len for IPComp states, prevent OOB read" * tag 'net-7.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (213 commits) selftests: bonding: add a test for VLAN propagation over a bonded real device vlan: defer real device state propagation to netdev_work net: add the driver-facing netdev_work scheduling API net: turn the rx_mode work into a generic netdev_work facility net: ethtool: keep rtnl_lock for ops using ethtool_op_get_link() rxrpc: Fix rxrpc_rotate_tx_rotate() to check there's something to rotate rxrpc: Fix leak of released call in recvmsg(MSG_PEEK) rxrpc: Fix socket notification race rxrpc: Fix potential infinite loop in rxrpc_recvmsg() rxrpc: Fix oob challenge leak in cleanup after notification failure rxrpc: Fix the reception of a reply packet before data transmission afs: Fix uncancelled rxrpc OOB message handler afs: Fix further netns teardown to cancel the preallocation charger rxrpc: Fix double unlock in rxrpc_recvmsg() rxrpc: Fix leak of connection from OOB challenge rxrpc: Fix ACKALL packet handling net: hns3: differentiate autoneg default values between copper and fiber net: hns3: fix permanent link down deadlock after reset net: hns3: refactor MAC autoneg and speed configuration net: hns3: unify copper port ksettings configuration path ...
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/dsa/mxl862xx/mxl862xx-host.c18
-rw-r--r--drivers/net/dsa/realtek/rtl8366rb-leds.c8
-rw-r--r--drivers/net/dsa/sja1105/sja1105_ptp.c2
-rw-r--r--drivers/net/ethernet/airoha/airoha_eth.c197
-rw-r--r--drivers/net/ethernet/airoha/airoha_eth.h3
-rw-r--r--drivers/net/ethernet/airoha/airoha_ppe.c3
-rw-r--r--drivers/net/ethernet/amazon/ena/ena_netdev.c23
-rw-r--r--drivers/net/ethernet/amd/au1000_eth.c3
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c3
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt.c48
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt.h5
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c1
-rw-r--r--drivers/net/ethernet/cadence/macb_main.c8
-rw-r--r--drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c10
-rw-r--r--drivers/net/ethernet/freescale/enetc/enetc4_pf.c3
-rw-r--r--drivers/net/ethernet/google/gve/gve_ethtool.c3
-rw-r--r--drivers/net/ethernet/google/gve/gve_rx_dqo.c28
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c31
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c108
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h1
-rw-r--r--drivers/net/ethernet/ibm/ehea/ehea_main.c2
-rw-r--r--drivers/net/ethernet/ibm/emac/core.c13
-rw-r--r--drivers/net/ethernet/intel/e1000e/ich8lan.c3
-rw-r--r--drivers/net/ethernet/intel/e1000e/netdev.c15
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_debug.h2
-rw-r--r--drivers/net/ethernet/intel/iavf/iavf_ethtool.c1
-rw-r--r--drivers/net/ethernet/intel/ice/ice_common.c1
-rw-r--r--drivers/net/ethernet/intel/ice/ice_dpll.c20
-rw-r--r--drivers/net/ethernet/intel/ice/ice_eswitch.c4
-rw-r--r--drivers/net/ethernet/intel/ice/ice_ethtool.c12
-rw-r--r--drivers/net/ethernet/intel/ice/ice_main.c16
-rw-r--r--drivers/net/ethernet/intel/ice/ice_vf_lib.c2
-rw-r--r--drivers/net/ethernet/marvell/mvneta.c3
-rw-r--r--drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c60
-rw-r--r--drivers/net/ethernet/marvell/octeontx2/af/mcs.c6
-rw-r--r--drivers/net/ethernet/marvell/octeontx2/af/rvu_cn10k.c9
-rw-r--r--drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c59
-rw-r--r--drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c27
-rw-r--r--drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c11
-rw-r--r--drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c2
-rw-r--r--drivers/net/ethernet/marvell/octeontx2/nic/cn10k_macsec.c10
-rw-r--r--drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c1
-rw-r--r--drivers/net/ethernet/marvell/prestera/prestera_main.c2
-rw-r--r--drivers/net/ethernet/mediatek/mtk_eth_soc.c10
-rw-r--r--drivers/net/ethernet/mediatek/mtk_ppe.c4
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/Kconfig2
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c3
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_rep.c3
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/ipoib/ethtool.c4
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h1
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/port.c19
-rw-r--r--drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c3
-rw-r--r--drivers/net/ethernet/meta/fbnic/fbnic_fw.c9
-rw-r--r--drivers/net/ethernet/meta/fbnic/fbnic_netdev.c7
-rw-r--r--drivers/net/ethernet/meta/fbnic/fbnic_pci.c4
-rw-r--r--drivers/net/ethernet/meta/fbnic/fbnic_rpc.c2
-rw-r--r--drivers/net/ethernet/microchip/sparx5/sparx5_switchdev.c4
-rw-r--r--drivers/net/ethernet/microsoft/mana/gdma_main.c78
-rw-r--r--drivers/net/ethernet/microsoft/mana/mana_bpf.c3
-rw-r--r--drivers/net/ethernet/microsoft/mana/mana_en.c16
-rw-r--r--drivers/net/ethernet/microsoft/mana/mana_ethtool.c3
-rw-r--r--drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c38
-rw-r--r--drivers/net/ethernet/rocker/rocker_ofdpa.c3
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac-spacemit.c13
-rw-r--r--drivers/net/ethernet/sun/sungem.c13
-rw-r--r--drivers/net/ethernet/sunplus/spl2sw_phy.c6
-rw-r--r--drivers/net/ethernet/ti/icssg/icssg_common.c72
-rw-r--r--drivers/net/ethernet/wangxun/ngbe/ngbe_main.c1
-rw-r--r--drivers/net/ethernet/wangxun/txgbe/txgbe_main.c1
-rw-r--r--drivers/net/geneve.c18
-rw-r--r--drivers/net/ieee802154/ca8210.c9
-rw-r--r--drivers/net/netconsole.c12
-rw-r--r--drivers/net/phy/realtek/realtek_main.c3
-rw-r--r--drivers/net/pse-pd/pd692x0.c2
-rw-r--r--drivers/net/thunderbolt/main.c8
-rw-r--r--drivers/net/usb/kalmia.c8
-rw-r--r--drivers/net/usb/lan78xx.c37
-rw-r--r--drivers/net/veth.c2
-rw-r--r--drivers/net/virtio_net.c9
-rw-r--r--drivers/net/wan/hdlc_ppp.c15
-rw-r--r--drivers/net/wan/ixp4xx_hss.c4
-rw-r--r--drivers/net/wwan/t7xx/t7xx_hif_cldma.c3
82 files changed, 848 insertions, 391 deletions
diff --git a/drivers/net/dsa/mxl862xx/mxl862xx-host.c b/drivers/net/dsa/mxl862xx/mxl862xx-host.c
index d55f9dff6433..4acd216f7cc0 100644
--- a/drivers/net/dsa/mxl862xx/mxl862xx-host.c
+++ b/drivers/net/dsa/mxl862xx/mxl862xx-host.c
@@ -12,6 +12,7 @@
#include <linux/crc16.h>
#include <linux/iopoll.h>
#include <linux/limits.h>
+#include <linux/unaligned.h>
#include <net/dsa.h>
#include "mxl862xx.h"
#include "mxl862xx-host.h"
@@ -40,12 +41,13 @@ static void mxl862xx_crc_err_work_fn(struct work_struct *work)
crc_err_work);
struct dsa_port *dp;
- dev_warn(&priv->mdiodev->dev,
- "MDIO CRC error detected, shutting down all ports\n");
-
rtnl_lock();
- dsa_switch_for_each_cpu_port(dp, priv->ds)
- dev_close(dp->conduit);
+ if (!test_bit(MXL862XX_FLAG_WORK_STOPPED, &priv->flags)) {
+ dev_warn(&priv->mdiodev->dev,
+ "MDIO CRC error detected, shutting down all ports\n");
+ dsa_switch_for_each_cpu_port(dp, priv->ds)
+ dev_close(dp->conduit);
+ }
rtnl_unlock();
clear_bit(MXL862XX_FLAG_CRC_ERR, &priv->flags);
@@ -349,7 +351,7 @@ int mxl862xx_api_wrap(struct mxl862xx_priv *priv, u16 cmd, void *_data,
* zero words individually.
*/
for (i = 0, zeros = 0; i < size / 2 && zeros < RST_DATA_THRESHOLD; i++)
- if (!data[i])
+ if (!get_unaligned_le16(&data[i]))
zeros++;
if (zeros < RST_DATA_THRESHOLD && (size & 1) && !*(u8 *)&data[i])
@@ -395,7 +397,7 @@ int mxl862xx_api_wrap(struct mxl862xx_priv *priv, u16 cmd, void *_data,
*/
val = *(u8 *)&data[i] | ((crc & 0xff) << 8);
} else {
- val = le16_to_cpu(data[i]);
+ val = get_unaligned_le16(&data[i]);
}
/* After RST_DATA, skip zero data words as the registers
@@ -453,7 +455,7 @@ int mxl862xx_api_wrap(struct mxl862xx_priv *priv, u16 cmd, void *_data,
*(uint8_t *)&data[i] = ret & 0xff;
crc = (ret >> 8) & 0xff;
} else {
- data[i] = cpu_to_le16((u16)ret);
+ put_unaligned_le16((u16)ret, &data[i]);
}
}
diff --git a/drivers/net/dsa/realtek/rtl8366rb-leds.c b/drivers/net/dsa/realtek/rtl8366rb-leds.c
index 509ffd3f8db5..ba50d311cb15 100644
--- a/drivers/net/dsa/realtek/rtl8366rb-leds.c
+++ b/drivers/net/dsa/realtek/rtl8366rb-leds.c
@@ -89,6 +89,7 @@ static int rtl8366rb_setup_led(struct realtek_priv *priv, struct dsa_port *dp,
struct led_init_data init_data = { };
enum led_default_state state;
struct rtl8366rb_led *led;
+ char name[64];
u32 led_group;
int ret;
@@ -129,10 +130,9 @@ static int rtl8366rb_setup_led(struct realtek_priv *priv, struct dsa_port *dp,
init_data.fwnode = led_fwnode;
init_data.devname_mandatory = true;
- init_data.devicename = kasprintf(GFP_KERNEL, "Realtek-%d:0%d:%d",
- dp->ds->index, dp->index, led_group);
- if (!init_data.devicename)
- return -ENOMEM;
+ snprintf(name, sizeof(name), "Realtek-%d:0%d:%d",
+ dp->ds->index, dp->index, led_group);
+ init_data.devicename = name;
ret = devm_led_classdev_register_ext(priv->dev, &led->cdev, &init_data);
if (ret) {
diff --git a/drivers/net/dsa/sja1105/sja1105_ptp.c b/drivers/net/dsa/sja1105/sja1105_ptp.c
index fefe46e2a5e6..350f958dcb2a 100644
--- a/drivers/net/dsa/sja1105/sja1105_ptp.c
+++ b/drivers/net/dsa/sja1105/sja1105_ptp.c
@@ -755,7 +755,7 @@ static int sja1105_per_out_enable(struct sja1105_private *priv,
* 2 edges on PTP_CLK. So check for truncation which happens
* at periods larger than around 68.7 seconds.
*/
- pin_duration = ns_to_sja1105_ticks(pin_duration / 2);
+ pin_duration = max_t(u64, ns_to_sja1105_ticks(pin_duration / 2), 1);
if (pin_duration > U32_MAX) {
rc = -ERANGE;
goto out;
diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
index 64dde6464f3f..932b3a3df2e5 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -1004,6 +1004,7 @@ static int airoha_qdma_tx_napi_poll(struct napi_struct *napi, int budget)
e = &q->entry[index];
skb = e->skb;
+ e->skb = NULL;
dma_unmap_single(eth->dev, e->dma_addr, e->dma_len,
DMA_TO_DEVICE);
@@ -1147,55 +1148,76 @@ static int airoha_qdma_init_tx(struct airoha_qdma *qdma)
return 0;
}
-static void airoha_qdma_cleanup_tx_queue(struct airoha_queue *q)
+static void airoha_qdma_tx_cleanup(struct airoha_qdma *qdma)
{
- struct airoha_qdma *qdma = q->qdma;
- struct airoha_eth *eth = qdma->eth;
- int i, qid = q - &qdma->q_tx[0];
- u16 index = 0;
+ u32 status;
+ int i;
- spin_lock_bh(&q->lock);
- for (i = 0; i < q->ndesc; i++) {
- struct airoha_queue_entry *e = &q->entry[i];
- struct airoha_qdma_desc *desc = &q->desc[i];
+ airoha_qdma_clear(qdma, REG_QDMA_GLOBAL_CFG,
+ GLOBAL_CFG_TX_DMA_EN_MASK);
+ if (read_poll_timeout(airoha_qdma_rr, status,
+ !(status & GLOBAL_CFG_TX_DMA_BUSY_MASK),
+ USEC_PER_MSEC, 50 * USEC_PER_MSEC, true,
+ qdma, REG_QDMA_GLOBAL_CFG))
+ dev_warn(qdma->eth->dev, "QDMA TX DMA busy timeout\n");
- if (!e->dma_addr)
+ for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) {
+ struct airoha_queue *q = &qdma->q_tx[i];
+ u16 index = 0;
+ int j;
+
+ if (!q->ndesc)
continue;
- dma_unmap_single(eth->dev, e->dma_addr, e->dma_len,
- DMA_TO_DEVICE);
- dev_kfree_skb_any(e->skb);
- e->dma_addr = 0;
- e->skb = NULL;
- list_add_tail(&e->list, &q->tx_list);
+ spin_lock_bh(&q->lock);
- /* Reset DMA descriptor */
- WRITE_ONCE(desc->ctrl, 0);
- WRITE_ONCE(desc->addr, 0);
- WRITE_ONCE(desc->data, 0);
- WRITE_ONCE(desc->msg0, 0);
- WRITE_ONCE(desc->msg1, 0);
- WRITE_ONCE(desc->msg2, 0);
+ q->flushing = true;
+ for (j = 0; j < q->ndesc; j++) {
+ struct airoha_queue_entry *e = &q->entry[j];
+ struct airoha_qdma_desc *desc = &q->desc[j];
+ struct sk_buff *skb = e->skb;
- q->queued--;
- }
+ if (!e->dma_addr)
+ continue;
- if (!list_empty(&q->tx_list)) {
- struct airoha_queue_entry *e;
+ dma_unmap_single(qdma->eth->dev, e->dma_addr,
+ e->dma_len, DMA_TO_DEVICE);
+ e->dma_addr = 0;
+ list_add_tail(&e->list, &q->tx_list);
+
+ WRITE_ONCE(desc->ctrl, 0);
+ WRITE_ONCE(desc->addr, 0);
+ WRITE_ONCE(desc->data, 0);
+ WRITE_ONCE(desc->msg0, 0);
+ WRITE_ONCE(desc->msg1, 0);
+ WRITE_ONCE(desc->msg2, 0);
+
+ if (skb) {
+ struct netdev_queue *txq;
+
+ txq = skb_get_tx_queue(skb->dev, skb);
+ netdev_tx_completed_queue(txq, 1, skb->len);
+ dev_kfree_skb_any(skb);
+ e->skb = NULL;
+ }
- e = list_first_entry(&q->tx_list, struct airoha_queue_entry,
- list);
- index = e - q->entry;
- }
- /* Set TX_DMA_IDX to TX_CPU_IDX to notify the hw the QDMA TX ring is
- * empty.
- */
- airoha_qdma_rmw(qdma, REG_TX_CPU_IDX(qid), TX_RING_CPU_IDX_MASK,
- FIELD_PREP(TX_RING_CPU_IDX_MASK, index));
- airoha_qdma_rmw(qdma, REG_TX_DMA_IDX(qid), TX_RING_DMA_IDX_MASK,
- FIELD_PREP(TX_RING_DMA_IDX_MASK, index));
+ q->queued--;
+ }
- spin_unlock_bh(&q->lock);
+ if (!list_empty(&q->tx_list)) {
+ struct airoha_queue_entry *e;
+
+ e = list_first_entry(&q->tx_list,
+ struct airoha_queue_entry, list);
+ index = e - q->entry;
+ }
+ airoha_qdma_rmw(qdma, REG_TX_CPU_IDX(i), TX_RING_CPU_IDX_MASK,
+ FIELD_PREP(TX_RING_CPU_IDX_MASK, index));
+ airoha_qdma_rmw(qdma, REG_TX_DMA_IDX(i), TX_RING_DMA_IDX_MASK,
+ FIELD_PREP(TX_RING_DMA_IDX_MASK, index));
+
+ spin_unlock_bh(&q->lock);
+ }
}
static int airoha_qdma_init_hfwd_queues(struct airoha_qdma *qdma)
@@ -1523,10 +1545,23 @@ static int airoha_qdma_init(struct platform_device *pdev,
return airoha_qdma_hw_init(qdma);
}
-static void airoha_qdma_cleanup(struct airoha_qdma *qdma)
+static void airoha_qdma_cleanup(struct airoha_eth *eth,
+ struct airoha_qdma *qdma)
{
int i;
+ if (test_bit(DEV_STATE_INITIALIZED, &eth->state)) {
+ u32 status;
+
+ airoha_qdma_clear(qdma, REG_QDMA_GLOBAL_CFG,
+ GLOBAL_CFG_RX_DMA_EN_MASK);
+ if (read_poll_timeout(airoha_qdma_rr, status,
+ !(status & GLOBAL_CFG_RX_DMA_BUSY_MASK),
+ USEC_PER_MSEC, 50 * USEC_PER_MSEC, true,
+ qdma, REG_QDMA_GLOBAL_CFG))
+ dev_warn(eth->dev, "QDMA RX DMA busy timeout\n");
+ }
+
for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) {
if (!qdma->q_rx[i].ndesc)
continue;
@@ -1546,12 +1581,6 @@ static void airoha_qdma_cleanup(struct airoha_qdma *qdma)
netif_napi_del(&qdma->q_tx_irq[i].napi);
}
- for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) {
- if (!qdma->q_tx[i].ndesc)
- continue;
-
- airoha_qdma_cleanup_tx_queue(&qdma->q_tx[i]);
- }
}
static int airoha_hw_init(struct platform_device *pdev,
@@ -1593,7 +1622,7 @@ static int airoha_hw_init(struct platform_device *pdev,
return 0;
error:
for (i = 0; i < ARRAY_SIZE(eth->qdma); i++)
- airoha_qdma_cleanup(&eth->qdma[i]);
+ airoha_qdma_cleanup(eth, &eth->qdma[i]);
return err;
}
@@ -1603,7 +1632,7 @@ static void airoha_hw_cleanup(struct airoha_eth *eth)
int i;
for (i = 0; i < ARRAY_SIZE(eth->qdma); i++)
- airoha_qdma_cleanup(&eth->qdma[i]);
+ airoha_qdma_cleanup(eth, &eth->qdma[i]);
airoha_ppe_deinit(eth);
}
@@ -1837,11 +1866,6 @@ static int airoha_dev_open(struct net_device *netdev)
}
port->users++;
- airoha_qdma_set(qdma, REG_QDMA_GLOBAL_CFG,
- GLOBAL_CFG_TX_DMA_EN_MASK |
- GLOBAL_CFG_RX_DMA_EN_MASK);
- qdma->users++;
-
if (!airoha_is_lan_gdm_dev(dev) &&
airoha_ppe_is_enabled(qdma->eth, 1))
pse_port = FE_PSE_PORT_PPE2;
@@ -1880,12 +1904,9 @@ static int airoha_dev_stop(struct net_device *netdev)
struct airoha_gdm_dev *dev = netdev_priv(netdev);
struct airoha_gdm_port *port = dev->port;
struct airoha_qdma *qdma = dev->qdma;
- int i;
netif_tx_disable(netdev);
airoha_set_vip_for_gdm_port(dev, false);
- for (i = 0; i < netdev->num_tx_queues; i++)
- netdev_tx_reset_subqueue(netdev, i);
if (--port->users)
airoha_set_port_mtu(dev->eth, port);
@@ -1893,20 +1914,6 @@ static int airoha_dev_stop(struct net_device *netdev)
airoha_set_gdm_port_fwd_cfg(qdma->eth,
REG_GDM_FWD_CFG(port->id),
FE_PSE_PORT_DROP);
-
- if (!--qdma->users) {
- airoha_qdma_clear(qdma, REG_QDMA_GLOBAL_CFG,
- GLOBAL_CFG_TX_DMA_EN_MASK |
- GLOBAL_CFG_RX_DMA_EN_MASK);
-
- for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) {
- if (!qdma->q_tx[i].ndesc)
- continue;
-
- airoha_qdma_cleanup_tx_queue(&qdma->q_tx[i]);
- }
- }
-
return 0;
}
@@ -2110,7 +2117,7 @@ static u16 airoha_dev_select_queue(struct net_device *netdev,
*/
channel = netdev_uses_dsa(netdev) ? skb_get_queue_mapping(skb) : port->id;
channel = channel % AIROHA_NUM_QOS_CHANNELS;
- queue = (skb->priority - 1) % AIROHA_NUM_QOS_QUEUES; /* QoS queue */
+ queue = skb->priority % AIROHA_NUM_QOS_QUEUES;
queue = channel * AIROHA_NUM_QOS_QUEUES + queue;
return queue < netdev->num_tx_queues ? queue : 0;
@@ -2229,6 +2236,9 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
spin_lock_bh(&q->lock);
+ if (q->flushing)
+ goto error_unlock;
+
txq = skb_get_tx_queue(netdev, skb);
nr_frags = 1 + skb_shinfo(skb)->nr_frags;
@@ -2309,7 +2319,7 @@ error_unmap:
e->dma_addr = 0;
}
list_splice(&tx_list, &q->tx_list);
-
+error_unlock:
spin_unlock_bh(&q->lock);
error:
dev_kfree_skb_any(skb);
@@ -2395,7 +2405,7 @@ static int airoha_qdma_set_chan_tx_sched(struct net_device *netdev,
struct airoha_gdm_dev *dev = netdev_priv(netdev);
int i;
- for (i = 0; i < AIROHA_NUM_TX_RING; i++)
+ for (i = 0; i < AIROHA_NUM_QOS_QUEUES; i++)
airoha_qdma_clear(dev->qdma, REG_QUEUE_CLOSE_CFG(channel),
TXQ_DISABLE_CHAN_QUEUE_MASK(channel, i));
@@ -2789,7 +2799,7 @@ static int airoha_tc_htb_alloc_leaf_queue(struct net_device *netdev,
struct tc_htb_qopt_offload *opt)
{
u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS;
- int err, num_tx_queues = netdev->real_num_tx_queues;
+ int err, num_tx_queues = AIROHA_NUM_TX_RING + channel + 1;
struct airoha_gdm_dev *dev = netdev_priv(netdev);
struct airoha_qdma *qdma = dev->qdma;
@@ -2806,13 +2816,15 @@ static int airoha_tc_htb_alloc_leaf_queue(struct net_device *netdev,
if (err)
goto error;
- err = netif_set_real_num_tx_queues(netdev, num_tx_queues + 1);
- if (err) {
- airoha_qdma_set_tx_rate_limit(netdev, channel, 0,
- opt->quantum);
- NL_SET_ERR_MSG_MOD(opt->extack,
- "failed setting real_num_tx_queues");
- goto error;
+ if (num_tx_queues > netdev->real_num_tx_queues) {
+ err = netif_set_real_num_tx_queues(netdev, num_tx_queues);
+ if (err) {
+ airoha_qdma_set_tx_rate_limit(netdev, channel, 0,
+ opt->quantum);
+ NL_SET_ERR_MSG_MOD(opt->extack,
+ "failed setting real_num_tx_queues");
+ goto error;
+ }
}
set_bit(channel, dev->qos_sq_bmap);
@@ -3003,13 +3015,18 @@ static int airoha_dev_setup_tc_block(struct net_device *dev,
static void airoha_tc_remove_htb_queue(struct net_device *netdev, int queue)
{
struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ int num_tx_queues = AIROHA_NUM_TX_RING;
struct airoha_qdma *qdma = dev->qdma;
- netif_set_real_num_tx_queues(netdev, netdev->real_num_tx_queues - 1);
- airoha_qdma_set_tx_rate_limit(netdev, queue + 1, 0, 0);
+ airoha_qdma_set_tx_rate_limit(netdev, queue, 0, 0);
clear_bit(queue, qdma->qos_channel_map);
clear_bit(queue, dev->qos_sq_bmap);
+
+ if (!bitmap_empty(dev->qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS))
+ num_tx_queues += find_last_bit(dev->qos_sq_bmap,
+ AIROHA_NUM_QOS_CHANNELS) + 1;
+ netif_set_real_num_tx_queues(netdev, num_tx_queues);
}
static int airoha_tc_htb_delete_leaf_queue(struct net_device *netdev,
@@ -3413,8 +3430,12 @@ static int airoha_probe(struct platform_device *pdev)
if (err)
goto error_netdev_free;
- for (i = 0; i < ARRAY_SIZE(eth->qdma); i++)
+ for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) {
airoha_qdma_start_napi(&eth->qdma[i]);
+ airoha_qdma_set(&eth->qdma[i], REG_QDMA_GLOBAL_CFG,
+ GLOBAL_CFG_TX_DMA_EN_MASK |
+ GLOBAL_CFG_RX_DMA_EN_MASK);
+ }
for_each_child_of_node(pdev->dev.of_node, np) {
if (!of_device_is_compatible(np, "airoha,eth-mac"))
@@ -3437,8 +3458,10 @@ static int airoha_probe(struct platform_device *pdev)
return 0;
error_napi_stop:
- for (i = 0; i < ARRAY_SIZE(eth->qdma); i++)
+ for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) {
airoha_qdma_stop_napi(&eth->qdma[i]);
+ airoha_qdma_tx_cleanup(&eth->qdma[i]);
+ }
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
struct airoha_gdm_port *port = eth->ports[i];
@@ -3474,8 +3497,10 @@ static void airoha_remove(struct platform_device *pdev)
struct airoha_eth *eth = platform_get_drvdata(pdev);
int i;
- for (i = 0; i < ARRAY_SIZE(eth->qdma); i++)
+ for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) {
airoha_qdma_stop_napi(&eth->qdma[i]);
+ airoha_qdma_tx_cleanup(&eth->qdma[i]);
+ }
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
struct airoha_gdm_port *port = eth->ports[i];
diff --git a/drivers/net/ethernet/airoha/airoha_eth.h b/drivers/net/ethernet/airoha/airoha_eth.h
index 41d2e7a1f9fb..d7ff8c5200e2 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.h
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
@@ -197,6 +197,7 @@ struct airoha_queue {
int free_thr;
int buf_size;
bool txq_stopped;
+ bool flushing;
struct napi_struct napi;
struct page_pool *page_pool;
@@ -524,8 +525,6 @@ struct airoha_qdma {
struct airoha_eth *eth;
void __iomem *regs;
- int users;
-
struct airoha_irq_bank irq_banks[AIROHA_MAX_NUM_IRQ_BANKS];
struct airoha_tx_irq_queue q_tx_irq[AIROHA_NUM_TX_IRQ];
diff --git a/drivers/net/ethernet/airoha/airoha_ppe.c b/drivers/net/ethernet/airoha/airoha_ppe.c
index 329e7c2aae89..42f4b0f21d17 100644
--- a/drivers/net/ethernet/airoha/airoha_ppe.c
+++ b/drivers/net/ethernet/airoha/airoha_ppe.c
@@ -1601,7 +1601,8 @@ int airoha_ppe_init(struct airoha_eth *eth)
return -ENOMEM;
}
- ppe->foe_check_time = devm_kzalloc(eth->dev, ppe_num_entries,
+ ppe->foe_check_time = devm_kzalloc(eth->dev,
+ ppe_num_entries * sizeof(*ppe->foe_check_time),
GFP_KERNEL);
if (!ppe->foe_check_time)
return -ENOMEM;
diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index 92d149d4f091..5d05020a6d05 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -752,6 +752,18 @@ static void ena_destroy_all_tx_queues(struct ena_adapter *adapter)
}
}
+static void ena_destroy_xdp_tx_queues(struct ena_adapter *adapter)
+{
+ u16 ena_qid;
+ int i;
+
+ for (i = adapter->xdp_first_ring;
+ i < adapter->xdp_first_ring + adapter->xdp_num_queues; i++) {
+ ena_qid = ENA_IO_TXQ_IDX(i);
+ ena_com_destroy_io_queue(adapter->ena_dev, ena_qid);
+ }
+}
+
static void ena_destroy_all_rx_queues(struct ena_adapter *adapter)
{
u16 ena_qid;
@@ -2078,14 +2090,21 @@ static int create_queues_with_size_backoff(struct ena_adapter *adapter)
rc = ena_setup_tx_resources_in_range(adapter,
0,
adapter->num_io_queues);
- if (rc)
+ if (rc) {
+ ena_destroy_xdp_tx_queues(adapter);
+ ena_free_all_io_tx_resources_in_range(adapter,
+ adapter->xdp_first_ring,
+ adapter->xdp_num_queues);
goto err_setup_tx;
+ }
rc = ena_create_io_tx_queues_in_range(adapter,
0,
adapter->num_io_queues);
- if (rc)
+ if (rc) {
+ ena_destroy_xdp_tx_queues(adapter);
goto err_create_tx_queues;
+ }
rc = ena_setup_all_rx_resources(adapter);
if (rc)
diff --git a/drivers/net/ethernet/amd/au1000_eth.c b/drivers/net/ethernet/amd/au1000_eth.c
index 9d35ac348ebe..5a04056e38fa 100644
--- a/drivers/net/ethernet/amd/au1000_eth.c
+++ b/drivers/net/ethernet/amd/au1000_eth.c
@@ -943,9 +943,10 @@ static int au1000_close(struct net_device *dev)
/* stop the device */
netif_stop_queue(dev);
+ spin_unlock_irqrestore(&aup->lock, flags);
+
/* disable the interrupt */
free_irq(dev->irq, dev);
- spin_unlock_irqrestore(&aup->lock, flags);
return 0;
}
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
index 19e078479b0d..5b2640bd31c3 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
@@ -4748,6 +4748,7 @@ int bnx2x_alloc_mem_bp(struct bnx2x *bp)
fp = kzalloc_objs(*fp, bp->fp_array_size);
if (!fp)
goto alloc_err;
+ bp->fp = fp;
for (i = 0; i < bp->fp_array_size; i++) {
fp[i].tpa_info =
kzalloc_objs(struct bnx2x_agg_info,
@@ -4756,8 +4757,6 @@ int bnx2x_alloc_mem_bp(struct bnx2x *bp)
goto alloc_err;
}
- bp->fp = fp;
-
/* allocate sp objs */
bp->sp_objs = kzalloc_objs(struct bnx2x_sp_objs, bp->fp_array_size);
if (!bp->sp_objs)
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index 055e93a417b6..7513618793da 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -10530,7 +10530,7 @@ static void bnxt_accumulate_stats(struct bnxt_stats_mem *stats)
stats->hw_masks, stats->len / 8, false);
}
-static void bnxt_accumulate_all_stats(struct bnxt *bp)
+static void bnxt_accumulate_ring_stats(struct bnxt *bp)
{
struct bnxt_stats_mem *ring0_stats;
bool ignore_zero = false;
@@ -10553,6 +10553,10 @@ static void bnxt_accumulate_all_stats(struct bnxt *bp)
ring0_stats->hw_masks,
ring0_stats->len / 8, ignore_zero);
}
+}
+
+static void bnxt_accumulate_port_stats(struct bnxt *bp)
+{
if (bp->flags & BNXT_FLAG_PORT_STATS) {
struct bnxt_stats_mem *stats = &bp->port_stats;
__le64 *hw_stats = stats->hw_stats;
@@ -10575,6 +10579,41 @@ static void bnxt_accumulate_all_stats(struct bnxt *bp)
}
}
+static void bnxt_accumulate_all_stats(struct bnxt *bp)
+{
+ bnxt_accumulate_ring_stats(bp);
+ bnxt_accumulate_port_stats(bp);
+}
+
+/* Re-accumulate ring stats from DMA buffers if stale.
+ * uAPIs for reading sw_stats should call this first.
+ *
+ * We promise user space update frequency of bp->stats_coal_ticks but
+ * the update is a two step process - first device updates the DMA buffer,
+ * then we have to update from that buffer to driver stats in the service work.
+ * Worst case we would be 2x off from the desired frequency.
+ * Sync the stats sooner, if stale. The 20% threshold was chosen arbitrarily.
+ *
+ * Ideally we would split the user-configured time into two portions,
+ * i.e. also lower the DMA period by the 20%. But the DMA timer seems to have
+ * too coarse granularity to play such tricks.
+ */
+void bnxt_sync_ring_stats(struct bnxt *bp)
+{
+ unsigned long stale;
+
+ if (!netif_running(bp->dev) || !bp->stats_coal_ticks)
+ return;
+
+ spin_lock(&bp->stats_lock);
+ stale = usecs_to_jiffies(bp->stats_coal_ticks / 5);
+ if (time_after_eq(jiffies, bp->stats_updated_jiffies + stale)) {
+ bnxt_accumulate_ring_stats(bp);
+ bp->stats_updated_jiffies = jiffies;
+ }
+ spin_unlock(&bp->stats_lock);
+}
+
static int bnxt_hwrm_port_qstats(struct bnxt *bp, u8 flags)
{
struct hwrm_port_qstats_input *req;
@@ -13577,6 +13616,7 @@ bnxt_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
return;
}
+ bnxt_sync_ring_stats(bp);
bnxt_get_ring_stats(bp, stats);
bnxt_add_prev_stats(bp, stats);
@@ -14753,7 +14793,10 @@ static void bnxt_sp_task(struct work_struct *work)
if (test_and_clear_bit(BNXT_PERIODIC_STATS_SP_EVENT, &bp->sp_event)) {
bnxt_hwrm_port_qstats(bp, 0);
bnxt_hwrm_port_qstats_ext(bp, 0);
+ spin_lock(&bp->stats_lock);
bnxt_accumulate_all_stats(bp);
+ bp->stats_updated_jiffies = jiffies;
+ spin_unlock(&bp->stats_lock);
}
if (test_and_clear_bit(BNXT_LINK_CHNG_SP_EVENT, &bp->sp_event)) {
@@ -15488,6 +15531,7 @@ static int bnxt_init_board(struct pci_dev *pdev, struct net_device *dev)
INIT_DELAYED_WORK(&bp->fw_reset_task, bnxt_fw_reset_task);
spin_lock_init(&bp->ntp_fltr_lock);
+ spin_lock_init(&bp->stats_lock);
#if BITS_PER_LONG == 32
spin_lock_init(&bp->db_lock);
#endif
@@ -16056,6 +16100,7 @@ static void bnxt_get_queue_stats_rx(struct net_device *dev, int i,
if (!bp->bnapi)
return;
+ bnxt_sync_ring_stats(bp);
cpr = &bp->bnapi[i]->cp_ring;
sw = cpr->stats.sw_stats;
@@ -16084,6 +16129,7 @@ static void bnxt_get_queue_stats_tx(struct net_device *dev, int i,
if (!bp->tx_ring)
return;
+ bnxt_sync_ring_stats(bp);
bnapi = bp->tx_ring[bp->tx_ring_map[i]].bnapi;
sw = bnapi->cp_ring.stats.sw_stats;
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
index 6d312259f852..6335dfc14c98 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
@@ -2620,6 +2620,10 @@ struct bnxt {
#define BNXT_MIN_STATS_COAL_TICKS 250000
#define BNXT_MAX_STATS_COAL_TICKS 1000000
+ /* Protects stats_updated_jiffies and writes to sw_stats */
+ spinlock_t stats_lock;
+ unsigned long stats_updated_jiffies;
+
struct work_struct sp_task;
unsigned long sp_event;
#define BNXT_RX_NTP_FLTR_SP_EVENT 1
@@ -3027,6 +3031,7 @@ void bnxt_reenable_sriov(struct bnxt *bp);
void bnxt_close_nic(struct bnxt *, bool, bool);
void bnxt_get_ring_drv_stats(struct bnxt *bp,
struct bnxt_total_ring_drv_stats *stats);
+void bnxt_sync_ring_stats(struct bnxt *bp);
bool bnxt_rfs_capable(struct bnxt *bp, bool new_rss_ctx);
int bnxt_dbg_hwrm_rd_reg(struct bnxt *bp, u32 reg_off, u16 num_words,
u32 *reg_buf);
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
index 56d74a3c24b7..62bc9cae613c 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
@@ -606,6 +606,7 @@ static void bnxt_get_ethtool_stats(struct net_device *dev,
goto skip_ring_stats;
}
+ bnxt_sync_ring_stats(bp);
tpa_stats = bnxt_get_num_tpa_ring_stats(bp);
for (i = 0; i < bp->cp_nr_rings; i++) {
struct bnxt_napi *bnapi = bp->bnapi[i];
diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
index a12aa21244e8..fd282a1700fb 100644
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -4522,6 +4522,13 @@ static int macb_setup_tc(struct net_device *dev, enum tc_setup_type type,
}
}
+static void macb_tx_timeout(struct net_device *dev, unsigned int q)
+{
+ struct macb *bp = netdev_priv(dev);
+
+ macb_tx_restart(&bp->queues[q]);
+}
+
static const struct net_device_ops macb_netdev_ops = {
.ndo_open = macb_open,
.ndo_stop = macb_close,
@@ -4540,6 +4547,7 @@ static const struct net_device_ops macb_netdev_ops = {
.ndo_hwtstamp_set = macb_hwtstamp_set,
.ndo_hwtstamp_get = macb_hwtstamp_get,
.ndo_setup_tc = macb_setup_tc,
+ .ndo_tx_timeout = macb_tx_timeout,
};
/* Configure peripheral capabilities according to device tree
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
index 45f276c2c3ec..858ba844ac51 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
@@ -2212,7 +2212,7 @@ dpaa2_switch_prechangeupper_sanity_checks(struct net_device *netdev,
if (err) {
NL_SET_ERR_MSG_MOD(extack,
"Cannot join a bridge while VLAN uppers are present");
- return 0;
+ return err;
}
netdev_for_each_lower_dev(upper_dev, other_dev, iter) {
@@ -2233,6 +2233,7 @@ dpaa2_switch_prechangeupper_sanity_checks(struct net_device *netdev,
static int dpaa2_switch_port_prechangeupper(struct net_device *netdev,
struct netdev_notifier_changeupper_info *info)
{
+ struct ethsw_port_priv *port_priv;
struct netlink_ext_ack *extack;
struct net_device *upper_dev;
int err;
@@ -2251,6 +2252,13 @@ static int dpaa2_switch_port_prechangeupper(struct net_device *netdev,
if (!info->linking)
dpaa2_switch_port_pre_bridge_leave(netdev);
+ } else if (is_vlan_dev(upper_dev)) {
+ port_priv = netdev_priv(netdev);
+ if (port_priv->fdb->bridge_dev) {
+ NL_SET_ERR_MSG_MOD(extack,
+ "Cannot accept VLAN uppers while bridged");
+ return -EOPNOTSUPP;
+ }
}
return 0;
diff --git a/drivers/net/ethernet/freescale/enetc/enetc4_pf.c b/drivers/net/ethernet/freescale/enetc/enetc4_pf.c
index 4e771f852358..437a15bbb47b 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc4_pf.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc4_pf.c
@@ -322,6 +322,9 @@ static void enetc4_default_rings_allocation(struct enetc_pf *pf)
val = enetc4_psicfgr0_val_construct(false, num_tx_bdr, num_rx_bdr);
enetc_port_wr(hw, ENETC4_PSICFGR0(0), val);
+ if (!pf->caps.num_vsi)
+ return;
+
num_rx_bdr = pf->caps.num_rx_bdr - num_rx_bdr;
rx_rem = num_rx_bdr % pf->caps.num_vsi;
num_rx_bdr = num_rx_bdr / pf->caps.num_vsi;
diff --git a/drivers/net/ethernet/google/gve/gve_ethtool.c b/drivers/net/ethernet/google/gve/gve_ethtool.c
index 7cc22916852f..8199738ba979 100644
--- a/drivers/net/ethernet/google/gve/gve_ethtool.c
+++ b/drivers/net/ethernet/google/gve/gve_ethtool.c
@@ -984,7 +984,8 @@ const struct ethtool_ops gve_ethtool_ops = {
.supported_ring_params = ETHTOOL_RING_USE_TCP_DATA_SPLIT |
ETHTOOL_RING_USE_RX_BUF_LEN,
.op_needs_rtnl = ETHTOOL_OP_NEEDS_RTNL_SCHANNELS |
- ETHTOOL_OP_NEEDS_RTNL_SRINGPARAM,
+ ETHTOOL_OP_NEEDS_RTNL_SRINGPARAM |
+ ETHTOOL_OP_NEEDS_RTNL_GLINK,
.get_drvinfo = gve_get_drvinfo,
.get_strings = gve_get_strings,
.get_sset_count = gve_get_sset_count,
diff --git a/drivers/net/ethernet/google/gve/gve_rx_dqo.c b/drivers/net/ethernet/google/gve/gve_rx_dqo.c
index 7924dce719e2..02cba280d81a 100644
--- a/drivers/net/ethernet/google/gve/gve_rx_dqo.c
+++ b/drivers/net/ethernet/google/gve/gve_rx_dqo.c
@@ -21,11 +21,13 @@
static void gve_rx_free_hdr_bufs(struct gve_priv *priv, struct gve_rx_ring *rx)
{
struct device *hdev = &priv->pdev->dev;
- int buf_count = rx->dqo.bufq.mask + 1;
if (rx->dqo.hdr_bufs.data) {
- dma_free_coherent(hdev, priv->header_buf_size * buf_count,
- rx->dqo.hdr_bufs.data, rx->dqo.hdr_bufs.addr);
+ size_t size =
+ (size_t)priv->header_buf_size * rx->dqo.num_buf_states;
+
+ dma_free_coherent(hdev, size, rx->dqo.hdr_bufs.data,
+ rx->dqo.hdr_bufs.addr);
rx->dqo.hdr_bufs.data = NULL;
}
}
@@ -254,7 +256,7 @@ int gve_rx_alloc_ring_dqo(struct gve_priv *priv,
/* Allocate header buffers for header-split */
if (cfg->enable_header_split)
- if (gve_rx_alloc_hdr_bufs(priv, rx, buffer_queue_slots))
+ if (gve_rx_alloc_hdr_bufs(priv, rx, rx->dqo.num_buf_states))
goto err;
/* Allocate RX completion queue */
@@ -381,10 +383,13 @@ void gve_rx_post_buffers_dqo(struct gve_rx_ring *rx)
break;
}
- if (rx->dqo.hdr_bufs.data)
+ if (rx->dqo.hdr_bufs.data) {
+ u16 buf_id = le16_to_cpu(desc->buf_id);
+
desc->header_buf_addr =
cpu_to_le64(rx->dqo.hdr_bufs.addr +
- priv->header_buf_size * bufq->tail);
+ (size_t)priv->header_buf_size * buf_id);
+ }
bufq->tail = (bufq->tail + 1) & bufq->mask;
complq->num_free_slots--;
@@ -826,10 +831,13 @@ static int gve_rx_dqo(struct napi_struct *napi, struct gve_rx_ring *rx,
int unsplit = 0;
if (hdr_len && !hbo) {
- rx->ctx.skb_head = gve_rx_copy_data(priv->dev, napi,
- rx->dqo.hdr_bufs.data +
- desc_idx * priv->header_buf_size,
- hdr_len);
+ size_t offset =
+ (size_t)buffer_id * priv->header_buf_size;
+
+ rx->ctx.skb_head =
+ gve_rx_copy_data(priv->dev, napi,
+ rx->dqo.hdr_bufs.data + offset,
+ hdr_len);
if (unlikely(!rx->ctx.skb_head))
goto error;
rx->ctx.skb_tail = rx->ctx.skb_head;
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
index 9cb7ce9fd311..442f15476af3 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
@@ -811,12 +811,11 @@ static int hns3_get_link_ksettings(struct net_device *netdev,
}
static int hns3_check_ksettings_param(const struct net_device *netdev,
- const struct ethtool_link_ksettings *cmd)
+ const struct ethtool_link_ksettings *cmd,
+ u8 media_type)
{
struct hnae3_handle *handle = hns3_get_handle(netdev);
const struct hnae3_ae_ops *ops = hns3_get_ops(handle);
- u8 module_type = HNAE3_MODULE_TYPE_UNKNOWN;
- u8 media_type = HNAE3_MEDIA_TYPE_UNKNOWN;
u32 lane_num;
u8 autoneg;
u32 speed;
@@ -836,9 +835,6 @@ static int hns3_check_ksettings_param(const struct net_device *netdev,
return 0;
}
- if (ops->get_media_type)
- ops->get_media_type(handle, &media_type, &module_type);
-
if (cmd->base.duplex == DUPLEX_HALF &&
media_type != HNAE3_MEDIA_TYPE_COPPER) {
netdev_err(netdev,
@@ -863,6 +859,8 @@ static int hns3_set_link_ksettings(struct net_device *netdev,
struct hnae3_handle *handle = hns3_get_handle(netdev);
struct hnae3_ae_dev *ae_dev = hns3_get_ae_dev(handle);
const struct hnae3_ae_ops *ops = hns3_get_ops(handle);
+ u8 module_type = HNAE3_MODULE_TYPE_UNKNOWN;
+ u8 media_type = HNAE3_MEDIA_TYPE_UNKNOWN;
int ret;
/* Chip don't support this mode. */
@@ -878,22 +876,23 @@ static int hns3_set_link_ksettings(struct net_device *netdev,
cmd->base.autoneg, cmd->base.speed, cmd->base.duplex,
cmd->lanes);
- /* Only support ksettings_set for netdev with phy attached for now */
- if (netdev->phydev) {
- if (cmd->base.speed == SPEED_1000 &&
- cmd->base.autoneg == AUTONEG_DISABLE)
- return -EINVAL;
+ if (!ops->get_media_type)
+ return -EOPNOTSUPP;
+ ops->get_media_type(handle, &media_type, &module_type);
- return phy_ethtool_ksettings_set(netdev->phydev, cmd);
- } else if (test_bit(HNAE3_DEV_SUPPORT_PHY_IMP_B, ae_dev->caps) &&
- ops->set_phy_link_ksettings) {
- return ops->set_phy_link_ksettings(handle, cmd);
+ if (media_type == HNAE3_MEDIA_TYPE_COPPER) {
+ if (!ops->set_phy_link_ksettings)
+ return -EOPNOTSUPP;
+ ret = ops->set_phy_link_ksettings(handle, cmd);
+ if (ret != -ENODEV)
+ return ret;
+ /* PHY_INEXISTENT, use MAC-level configuration */
}
if (ae_dev->dev_version < HNAE3_DEVICE_VERSION_V2)
return -EOPNOTSUPP;
- ret = hns3_check_ksettings_param(netdev, cmd);
+ ret = hns3_check_ksettings_param(netdev, cmd, media_type);
if (ret)
return ret;
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index 2f1984930da2..fc8587c80813 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -1504,6 +1504,11 @@ static int hclge_configure(struct hclge_dev *hdev)
hdev->hw.mac.req_autoneg = AUTONEG_ENABLE;
hdev->hw.mac.req_duplex = DUPLEX_FULL;
+ /* When lane_num is 0, the firmware will automatically
+ * select the appropriate lane_num based on the speed.
+ */
+ hdev->hw.mac.req_lane_num = 0;
+
hclge_parse_link_mode(hdev, cfg.speed_ability);
hdev->hw.mac.max_speed = hclge_get_max_speed(cfg.speed_ability);
@@ -2579,8 +2584,11 @@ static int hclge_cfg_mac_speed_dup_h(struct hnae3_handle *handle, int speed,
if (ret)
return ret;
- hdev->hw.mac.req_speed = (u32)speed;
- hdev->hw.mac.req_duplex = duplex;
+ hdev->hw.mac.req_lane_num = lane_num;
+ if (speed != SPEED_UNKNOWN)
+ hdev->hw.mac.req_speed = (u32)speed;
+ if (duplex != DUPLEX_UNKNOWN)
+ hdev->hw.mac.req_duplex = duplex;
return 0;
}
@@ -2611,6 +2619,7 @@ static int hclge_set_autoneg(struct hnae3_handle *handle, bool enable)
{
struct hclge_vport *vport = hclge_get_vport(handle);
struct hclge_dev *hdev = vport->back;
+ int ret;
if (!hdev->hw.mac.support_autoneg) {
if (enable) {
@@ -2622,7 +2631,10 @@ static int hclge_set_autoneg(struct hnae3_handle *handle, bool enable)
}
}
- return hclge_set_autoneg_en(hdev, enable);
+ ret = hclge_set_autoneg_en(hdev, enable);
+ if (!ret)
+ hdev->hw.mac.req_autoneg = enable;
+ return ret;
}
static int hclge_get_autoneg(struct hnae3_handle *handle)
@@ -2884,20 +2896,6 @@ static int hclge_mac_init(struct hclge_dev *hdev)
if (!test_bit(HCLGE_STATE_RST_HANDLING, &hdev->state))
hdev->hw.mac.duplex = HCLGE_MAC_FULL;
- if (hdev->hw.mac.support_autoneg) {
- ret = hclge_set_autoneg_en(hdev, hdev->hw.mac.autoneg);
- if (ret)
- return ret;
- }
-
- if (!hdev->hw.mac.autoneg) {
- ret = hclge_cfg_mac_speed_dup_hw(hdev, hdev->hw.mac.req_speed,
- hdev->hw.mac.req_duplex,
- hdev->hw.mac.lane_num);
- if (ret)
- return ret;
- }
-
mac->link = 0;
if (mac->user_fec_mode & BIT(HNAE3_FEC_USER_DEF)) {
@@ -3285,8 +3283,8 @@ static int hclge_get_phy_link_ksettings(struct hnae3_handle *handle,
}
static int
-hclge_set_phy_link_ksettings(struct hnae3_handle *handle,
- const struct ethtool_link_ksettings *cmd)
+hclge_ethtool_ksettings_set(struct hnae3_handle *handle,
+ const struct ethtool_link_ksettings *cmd)
{
struct hclge_desc desc[HCLGE_PHY_LINK_SETTING_BD_NUM];
struct hclge_vport *vport = hclge_get_vport(handle);
@@ -3327,10 +3325,34 @@ hclge_set_phy_link_ksettings(struct hnae3_handle *handle,
return ret;
}
- hdev->hw.mac.req_autoneg = cmd->base.autoneg;
- hdev->hw.mac.req_speed = cmd->base.speed;
- hdev->hw.mac.req_duplex = cmd->base.duplex;
linkmode_copy(hdev->hw.mac.advertising, cmd->link_modes.advertising);
+ return 0;
+}
+
+static int
+hclge_set_phy_link_ksettings(struct hnae3_handle *handle,
+ const struct ethtool_link_ksettings *cmd)
+{
+ struct hclge_vport *vport = hclge_get_vport(handle);
+ struct hclge_dev *hdev = vport->back;
+ int ret = -ENODEV;
+
+ if (hnae3_dev_phy_imp_supported(hdev)) {
+ ret = hclge_ethtool_ksettings_set(handle, cmd);
+ } else if (handle->netdev->phydev) {
+ if (cmd->base.speed == SPEED_1000 &&
+ cmd->base.autoneg == AUTONEG_DISABLE)
+ return -EINVAL;
+ ret = phy_ethtool_ksettings_set(handle->netdev->phydev, cmd);
+ }
+ if (ret)
+ return ret;
+
+ hdev->hw.mac.req_autoneg = cmd->base.autoneg;
+ if (cmd->base.speed != SPEED_UNKNOWN)
+ hdev->hw.mac.req_speed = cmd->base.speed;
+ if (cmd->base.duplex != DUPLEX_UNKNOWN)
+ hdev->hw.mac.req_duplex = cmd->base.duplex;
return 0;
}
@@ -9294,6 +9316,27 @@ static int hclge_set_wol(struct hnae3_handle *handle,
return ret;
}
+static int hclge_set_autoneg_speed_dup(struct hclge_dev *hdev)
+{
+ int ret;
+
+ if (hdev->hw.mac.support_autoneg) {
+ ret = hclge_set_autoneg_en(hdev, hdev->hw.mac.req_autoneg);
+ if (ret)
+ return ret;
+ }
+
+ if (!hdev->hw.mac.req_autoneg) {
+ ret = hclge_cfg_mac_speed_dup_hw(hdev, hdev->hw.mac.req_speed,
+ hdev->hw.mac.req_duplex,
+ hdev->hw.mac.req_lane_num);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
{
struct pci_dev *pdev = ae_dev->pdev;
@@ -9455,6 +9498,20 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
if (ret)
goto err_ptp_uninit;
+ if (hdev->hw.mac.media_type != HNAE3_MEDIA_TYPE_COPPER) {
+ hdev->hw.mac.req_autoneg = hdev->hw.mac.autoneg;
+ if (hdev->hw.mac.autoneg == AUTONEG_DISABLE &&
+ hdev->hw.mac.speed != SPEED_UNKNOWN)
+ hdev->hw.mac.req_speed = hdev->hw.mac.speed;
+ }
+
+ ret = hclge_set_autoneg_speed_dup(hdev);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "failed to set autoneg speed duplex, ret = %d\n", ret);
+ goto err_ptp_uninit;
+ }
+
INIT_KFIFO(hdev->mac_tnl_log);
hclge_dcb_ops_set(hdev);
@@ -9785,6 +9842,13 @@ static int hclge_reset_ae_dev(struct hnae3_ae_dev *ae_dev)
return ret;
}
+ ret = hclge_set_autoneg_speed_dup(hdev);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "failed to set autoneg speed duplex, ret = %d\n", ret);
+ return ret;
+ }
+
ret = hclge_tp_port_init(hdev);
if (ret) {
dev_err(&pdev->dev, "failed to init tp port, ret = %d\n",
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
index 87adeb64e6ea..7419481422c3 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
@@ -287,6 +287,7 @@ struct hclge_mac {
u8 support_autoneg;
u8 speed_type; /* 0: sfp speed, 1: active speed */
u8 lane_num;
+ u8 req_lane_num;
u32 speed;
u32 req_speed;
u32 max_speed;
diff --git a/drivers/net/ethernet/ibm/ehea/ehea_main.c b/drivers/net/ethernet/ibm/ehea/ehea_main.c
index ff67c4fd66a3..bfc8699a05b9 100644
--- a/drivers/net/ethernet/ibm/ehea/ehea_main.c
+++ b/drivers/net/ethernet/ibm/ehea/ehea_main.c
@@ -3216,6 +3216,8 @@ static int ehea_create_device_sysfs(struct platform_device *dev)
goto out;
ret = device_create_file(&dev->dev, &dev_attr_remove_port);
+ if (ret)
+ device_remove_file(&dev->dev, &dev_attr_probe_port);
out:
return ret;
}
diff --git a/drivers/net/ethernet/ibm/emac/core.c b/drivers/net/ethernet/ibm/emac/core.c
index c0e1d85fce3f..1d46cf6c2c12 100644
--- a/drivers/net/ethernet/ibm/emac/core.c
+++ b/drivers/net/ethernet/ibm/emac/core.c
@@ -3044,6 +3044,12 @@ static int emac_probe(struct platform_device *ofdev)
if (err)
goto err_gone;
+ dev->emacp = devm_platform_ioremap_resource(ofdev, 0);
+ if (IS_ERR(dev->emacp)) {
+ err = PTR_ERR(dev->emacp);
+ goto err_gone;
+ }
+
/* Setup error IRQ handler */
dev->emac_irq = platform_get_irq(ofdev, 0);
if (dev->emac_irq < 0) {
@@ -3061,13 +3067,6 @@ static int emac_probe(struct platform_device *ofdev)
ndev->irq = dev->emac_irq;
- dev->emacp = devm_platform_ioremap_resource(ofdev, 0);
- if (IS_ERR(dev->emacp)) {
- dev_err(&ofdev->dev, "can't map device registers");
- err = PTR_ERR(dev->emacp);
- goto err_gone;
- }
-
/* Wait for dependent devices */
err = emac_wait_deps(dev);
if (err)
diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c
index dea208db1be5..aa90e0ce8aca 100644
--- a/drivers/net/ethernet/intel/e1000e/ich8lan.c
+++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c
@@ -1594,6 +1594,9 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
phy_reg &= ~I217_PLL_CLOCK_GATE_MASK;
if (speed == SPEED_100 || speed == SPEED_10)
phy_reg |= 0x3E8;
+ else if (hw->mac.type == e1000_pch_mtp ||
+ hw->mac.type == e1000_pch_ptp)
+ phy_reg |= 0x1D5;
else
phy_reg |= 0xFA;
e1e_wphy_locked(hw, I217_PLL_CLOCK_GATE_REG, phy_reg);
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c
index 808e5cddd6a9..844f31ab37ad 100644
--- a/drivers/net/ethernet/intel/e1000e/netdev.c
+++ b/drivers/net/ethernet/intel/e1000e/netdev.c
@@ -25,6 +25,7 @@
#include <linux/pm_runtime.h>
#include <linux/prefetch.h>
#include <linux/suspend.h>
+#include <linux/dmi.h>
#include "e1000.h"
#define CREATE_TRACE_POINTS
@@ -58,6 +59,17 @@ static const struct e1000_info *e1000_info_tbl[] = {
[board_pch_ptp] = &e1000_pch_ptp_info,
};
+static const struct dmi_system_id disable_k1_list[] = {
+ {
+ .ident = "Dell Pro 16 Plus PB16250",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Dell Pro 16 Plus PB16250"),
+ },
+ },
+ {}
+};
+
struct e1000_reg_info {
u32 ofs;
char *name;
@@ -7670,7 +7682,8 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/* init PTP hardware clock */
e1000e_ptp_init(adapter);
- if (hw->mac.type >= e1000_pch_mtp)
+ /* disable K1 by default on known problematic systems */
+ if (hw->mac.type >= e1000_pch_mtp && dmi_check_system(disable_k1_list))
adapter->flags2 |= FLAG2_DISABLE_K1;
/* reset the hardware with the new settings */
diff --git a/drivers/net/ethernet/intel/i40e/i40e_debug.h b/drivers/net/ethernet/intel/i40e/i40e_debug.h
index e9871dfb32bd..01fd70db9086 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_debug.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_debug.h
@@ -42,7 +42,7 @@ struct device *i40e_hw_to_dev(struct i40e_hw *hw);
#define i40e_debug(h, m, s, ...) \
do { \
if (((m) & (h)->debug_mask)) \
- dev_info(i40e_hw_to_dev(hw), s, ##__VA_ARGS__); \
+ dev_info(i40e_hw_to_dev(h), s, ##__VA_ARGS__); \
} while (0)
#endif /* _I40E_DEBUG_H_ */
diff --git a/drivers/net/ethernet/intel/iavf/iavf_ethtool.c b/drivers/net/ethernet/intel/iavf/iavf_ethtool.c
index a615d599b88e..e7cf12eaa268 100644
--- a/drivers/net/ethernet/intel/iavf/iavf_ethtool.c
+++ b/drivers/net/ethernet/intel/iavf/iavf_ethtool.c
@@ -1855,6 +1855,7 @@ static const struct ethtool_ops iavf_ethtool_ops = {
.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
ETHTOOL_COALESCE_USE_ADAPTIVE,
.supported_input_xfrm = RXH_XFRM_SYM_XOR,
+ .op_needs_rtnl = ETHTOOL_OP_NEEDS_RTNL_GLINK,
.get_drvinfo = iavf_get_drvinfo,
.get_link = ethtool_op_get_link,
.get_ringparam = iavf_get_ringparam,
diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c
index 31e0de9e7f60..ef1ce106f81b 100644
--- a/drivers/net/ethernet/intel/ice/ice_common.c
+++ b/drivers/net/ethernet/intel/ice/ice_common.c
@@ -3882,7 +3882,6 @@ ice_set_fc(struct ice_port_info *pi, u8 *aq_failures, bool ena_auto_link_update)
if (!pi || !aq_failures)
return -EINVAL;
- *aq_failures = 0;
hw = pi->hw;
pcaps = kzalloc_obj(*pcaps);
diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c b/drivers/net/ethernet/intel/ice/ice_dpll.c
index 462c69cc11e1..30c3a4db7d61 100644
--- a/drivers/net/ethernet/intel/ice/ice_dpll.c
+++ b/drivers/net/ethernet/intel/ice/ice_dpll.c
@@ -4645,9 +4645,13 @@ ice_dpll_init_pins_info(struct ice_pf *pf, enum ice_dpll_pin_type pin_type)
static void ice_dpll_deinit_info(struct ice_pf *pf)
{
kfree(pf->dplls.inputs);
+ pf->dplls.inputs = NULL;
kfree(pf->dplls.outputs);
+ pf->dplls.outputs = NULL;
kfree(pf->dplls.eec.input_prio);
+ pf->dplls.eec.input_prio = NULL;
kfree(pf->dplls.pps.input_prio);
+ pf->dplls.pps.input_prio = NULL;
}
/**
@@ -4748,12 +4752,16 @@ static int ice_dpll_init_info(struct ice_pf *pf, bool cgu)
alloc_size = sizeof(*de->input_prio) * d->num_inputs;
de->input_prio = kzalloc(alloc_size, GFP_KERNEL);
- if (!de->input_prio)
- return -ENOMEM;
+ if (!de->input_prio) {
+ ret = -ENOMEM;
+ goto deinit_info;
+ }
dp->input_prio = kzalloc(alloc_size, GFP_KERNEL);
- if (!dp->input_prio)
- return -ENOMEM;
+ if (!dp->input_prio) {
+ ret = -ENOMEM;
+ goto deinit_info;
+ }
ret = ice_dpll_init_pins_info(pf, ICE_DPLL_PIN_TYPE_INPUT);
if (ret)
@@ -4778,12 +4786,12 @@ static int ice_dpll_init_info(struct ice_pf *pf, bool cgu)
ret = ice_get_cgu_rclk_pin_info(&pf->hw, &d->base_rclk_idx,
&pf->dplls.rclk.num_parents);
if (ret)
- return ret;
+ goto deinit_info;
for (i = 0; i < pf->dplls.rclk.num_parents; i++)
pf->dplls.rclk.parent_idx[i] = d->base_rclk_idx + i;
ret = ice_dpll_init_pins_info(pf, ICE_DPLL_PIN_TYPE_RCLK_INPUT);
if (ret)
- return ret;
+ goto deinit_info;
de->mode = DPLL_MODE_AUTOMATIC;
dp->mode = DPLL_MODE_AUTOMATIC;
diff --git a/drivers/net/ethernet/intel/ice/ice_eswitch.c b/drivers/net/ethernet/intel/ice/ice_eswitch.c
index 2e4f0969035f..c30e27bbfe6e 100644
--- a/drivers/net/ethernet/intel/ice/ice_eswitch.c
+++ b/drivers/net/ethernet/intel/ice/ice_eswitch.c
@@ -117,8 +117,6 @@ static int ice_eswitch_setup_repr(struct ice_pf *pf, struct ice_repr *repr)
if (!repr->dst)
return -ENOMEM;
- netif_keep_dst(uplink_vsi->netdev);
-
dst = repr->dst;
dst->u.port_info.port_id = vsi->vsi_num;
dst->u.port_info.lower_dev = uplink_vsi->netdev;
@@ -312,6 +310,8 @@ static int ice_eswitch_enable_switchdev(struct ice_pf *pf)
if (ice_eswitch_br_offloads_init(pf))
goto err_br_offloads;
+ netif_keep_dst(uplink_vsi->netdev);
+
pf->eswitch.is_running = true;
return 0;
diff --git a/drivers/net/ethernet/intel/ice/ice_ethtool.c b/drivers/net/ethernet/intel/ice/ice_ethtool.c
index 236d293aba98..49371b065845 100644
--- a/drivers/net/ethernet/intel/ice/ice_ethtool.c
+++ b/drivers/net/ethernet/intel/ice/ice_ethtool.c
@@ -3508,7 +3508,7 @@ ice_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *pause)
struct ice_vsi *vsi = np->vsi;
struct ice_hw *hw = &pf->hw;
struct ice_port_info *pi;
- u8 aq_failures;
+ u8 aq_failures = 0;
bool link_up;
u32 is_an;
int err;
@@ -3579,18 +3579,22 @@ ice_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *pause)
/* Set the FC mode and only restart AN if link is up */
err = ice_set_fc(pi, &aq_failures, link_up);
- if (aq_failures & ICE_SET_FC_AQ_FAIL_GET) {
+ switch (aq_failures) {
+ case ICE_SET_FC_AQ_FAIL_GET:
netdev_info(netdev, "Set fc failed on the get_phy_capabilities call with err %d aq_err %s\n",
err, libie_aq_str(hw->adminq.sq_last_status));
err = -EAGAIN;
- } else if (aq_failures & ICE_SET_FC_AQ_FAIL_SET) {
+ break;
+ case ICE_SET_FC_AQ_FAIL_SET:
netdev_info(netdev, "Set fc failed on the set_phy_config call with err %d aq_err %s\n",
err, libie_aq_str(hw->adminq.sq_last_status));
err = -EAGAIN;
- } else if (aq_failures & ICE_SET_FC_AQ_FAIL_UPDATE) {
+ break;
+ case ICE_SET_FC_AQ_FAIL_UPDATE:
netdev_info(netdev, "Set fc failed on the get_link_info call with err %d aq_err %s\n",
err, libie_aq_str(hw->adminq.sq_last_status));
err = -EAGAIN;
+ break;
}
return err;
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
index e2fbe111f849..e2fd2dab03e3 100644
--- a/drivers/net/ethernet/intel/ice/ice_main.c
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
@@ -4789,16 +4789,14 @@ static void ice_init_wakeup(struct ice_pf *pf)
device_set_wakeup_enable(ice_pf_to_dev(pf), false);
}
-static int ice_init_link(struct ice_pf *pf)
+static void ice_init_link(struct ice_pf *pf)
{
struct device *dev = ice_pf_to_dev(pf);
int err;
err = ice_init_link_events(pf->hw.port_info);
- if (err) {
+ if (err)
dev_err(dev, "ice_init_link_events failed: %d\n", err);
- return err;
- }
/* not a fatal error if this fails */
err = ice_init_nvm_phy_type(pf->hw.port_info);
@@ -4838,8 +4836,6 @@ static int ice_init_link(struct ice_pf *pf)
} else {
set_bit(ICE_FLAG_NO_MEDIA, pf->flags);
}
-
- return err;
}
static int ice_init_pf_sw(struct ice_pf *pf)
@@ -4982,13 +4978,11 @@ static int ice_init(struct ice_pf *pf)
ice_init_wakeup(pf);
- err = ice_init_link(pf);
- if (err)
- goto err_init_link;
+ ice_init_link(pf);
err = ice_send_version(pf);
if (err)
- goto err_init_link;
+ goto err_deinit_pf_sw;
ice_verify_cacheline_size(pf);
@@ -5007,7 +5001,7 @@ static int ice_init(struct ice_pf *pf)
return 0;
-err_init_link:
+err_deinit_pf_sw:
ice_deinit_pf_sw(pf);
err_init_pf_sw:
ice_dealloc_vsis(pf);
diff --git a/drivers/net/ethernet/intel/ice/ice_vf_lib.c b/drivers/net/ethernet/intel/ice/ice_vf_lib.c
index b1f46707dcc0..27e4acb1620f 100644
--- a/drivers/net/ethernet/intel/ice/ice_vf_lib.c
+++ b/drivers/net/ethernet/intel/ice/ice_vf_lib.c
@@ -801,7 +801,7 @@ void ice_reset_all_vfs(struct ice_pf *pf)
* setup only when VF creates its first FDIR rule.
*/
if (vf->ctrl_vsi_idx != ICE_NO_VSI)
- ice_vf_ctrl_invalidate_vsi(vf);
+ ice_vf_ctrl_vsi_release(vf);
ice_vf_pre_vsi_rebuild(vf);
if (ice_vf_rebuild_vsi(vf)) {
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index 0c061fb0ed07..744d6585a949 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -5900,6 +5900,9 @@ static int mvneta_resume(struct device *device)
rtnl_unlock();
mvneta_set_rx_mode(dev);
+ if (!pp->neta_armada3700)
+ on_each_cpu(mvneta_percpu_enable, pp, true);
+
return 0;
}
#endif
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c
index 354c4e881c6a..3070700b952b 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c
@@ -3423,6 +3423,36 @@ static int npc_create_srch_order(int cnt)
return 0;
}
+static int npc_subbanks_srch_order_init(struct rvu *rvu)
+{
+ struct npc_subbank *sb;
+ int sb_idx;
+ int i, j;
+ int rc;
+
+ for (i = 0; i < npc_priv->num_subbanks; i++) {
+ sb_idx = subbank_srch_order[i];
+ sb = &npc_priv->sb[sb_idx];
+ sb->arr_idx = i;
+
+ dev_dbg(rvu->dev, "%s: sb->idx=%u sb->arr_idx=%u\n",
+ __func__, sb->idx, sb->arr_idx);
+
+ rc = xa_err(xa_store(&npc_priv->xa_sb_free, sb->arr_idx,
+ xa_mk_value(sb->idx), GFP_KERNEL));
+ if (rc) {
+ dev_err(rvu->dev,
+ "%s: xa_store(xa_sb_free) failed at slot %d (sb=%d): %d\n",
+ __func__, i, sb_idx, rc);
+ for (j = 0; j < i; j++)
+ xa_erase(&npc_priv->xa_sb_free, j);
+ return rc;
+ }
+ }
+
+ return 0;
+}
+
static void npc_subbank_init(struct rvu *rvu, struct npc_subbank *sb, int idx)
{
mutex_init(&sb->lock);
@@ -3435,16 +3465,6 @@ static void npc_subbank_init(struct rvu *rvu, struct npc_subbank *sb, int idx)
sb->flags = NPC_SUBBANK_FLAG_FREE;
sb->idx = idx;
- sb->arr_idx = subbank_srch_order[idx];
-
- dev_dbg(rvu->dev, "%s: sb->idx=%u sb->arr_idx=%u\n",
- __func__, sb->idx, sb->arr_idx);
-
- /* Keep first and last subbank at end of free array; so that
- * it will be used at last
- */
- xa_store(&npc_priv->xa_sb_free, sb->arr_idx,
- xa_mk_value(sb->idx), GFP_KERNEL);
}
static int npc_pcifunc_map_create(struct rvu *rvu)
@@ -3569,15 +3589,18 @@ static int npc_defrag_alloc_free_slots(struct rvu *rvu,
alloc_cnt2 = 0;
rc = __npc_subbank_alloc(rvu, sb,
- NPC_MCAM_KEY_X2, sb->b0b,
+ f->key_type, sb->b0b,
sb->b0t,
NPC_MCAM_LOWER_PRIO,
false, cnt, save, cnt, true,
&alloc_cnt1);
- if (alloc_cnt1 < cnt) {
+ /* X4 entries only occupy bank 0 (b0b..b0t); see npc_subbank_idx_2_mcam_idx().
+ * X2 uses both halves of the subbank, so spill into bank 1 if needed.
+ */
+ if (alloc_cnt1 < cnt && f->key_type == NPC_MCAM_KEY_X2) {
rc = __npc_subbank_alloc(rvu, sb,
- NPC_MCAM_KEY_X2, sb->b1b,
+ f->key_type, sb->b1b,
sb->b1t,
NPC_MCAM_LOWER_PRIO,
false, cnt - alloc_cnt1,
@@ -4635,6 +4658,7 @@ static int npc_priv_init(struct rvu *rvu)
int num_subbanks, subbank_depth;
u64 npc_const1, npc_const2 = 0;
struct npc_subbank *sb;
+ int ret = -ENOMEM;
u64 cfg;
int i;
@@ -4727,13 +4751,19 @@ static int npc_priv_init(struct rvu *rvu)
for (i = 0, sb = npc_priv->sb; i < num_subbanks; i++, sb++)
npc_subbank_init(rvu, sb, i);
+ ret = npc_subbanks_srch_order_init(rvu);
+ if (ret)
+ goto fail3;
+
/* Get number of pcifuncs in the system */
npc_priv->pf_cnt = npc_pcifunc_map_create(rvu);
npc_priv->xa_pf2idx_map = kcalloc(npc_priv->pf_cnt,
sizeof(struct xarray),
GFP_KERNEL);
- if (!npc_priv->xa_pf2idx_map)
+ if (!npc_priv->xa_pf2idx_map) {
+ ret = -ENOMEM;
goto fail3;
+ }
for (i = 0; i < npc_priv->pf_cnt; i++)
xa_init_flags(&npc_priv->xa_pf2idx_map[i], XA_FLAGS_ALLOC);
@@ -4760,7 +4790,7 @@ fail2:
fail1:
kfree(npc_priv);
npc_priv = NULL;
- return -ENOMEM;
+ return ret;
}
void npc_cn20k_deinit(struct rvu *rvu)
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mcs.c b/drivers/net/ethernet/marvell/octeontx2/af/mcs.c
index c1775bd01c2b..a07e0b3d8d00 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/mcs.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/mcs.c
@@ -120,13 +120,13 @@ void mcs_get_rx_secy_stats(struct mcs *mcs, struct mcs_secy_stats *stats, int id
reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSECYUNTAGGEDX(id);
stats->pkt_untaged_cnt = mcs_reg_read(mcs, reg);
- reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSECYCTLX(id);
- stats->pkt_ctl_cnt = mcs_reg_read(mcs, reg);
-
if (mcs->hw->mcs_blks > 1) {
reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSECYNOTAGX(id);
stats->pkt_notag_cnt = mcs_reg_read(mcs, reg);
+ return;
}
+ reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSECYCTLX(id);
+ stats->pkt_ctl_cnt = mcs_reg_read(mcs, reg);
}
void mcs_get_flowid_stats(struct mcs *mcs, struct mcs_flowid_stats *stats,
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cn10k.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cn10k.c
index d2163da28d18..fa4ea1258d29 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cn10k.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cn10k.c
@@ -178,6 +178,15 @@ int rvu_mbox_handler_lmtst_tbl_setup(struct rvu *rvu,
* pcifunc (will be the one who is calling this mailbox).
*/
if (req->base_pcifunc) {
+ /* A VF is untrusted and must not redirect its LMTLINE to
+ * another PF's region, so confine VF callers to their own PF.
+ */
+ if (is_vf(req->hdr.pcifunc) &&
+ (!is_pf_func_valid(rvu, req->base_pcifunc) ||
+ rvu_get_pf(rvu->pdev, req->hdr.pcifunc) !=
+ rvu_get_pf(rvu->pdev, req->base_pcifunc)))
+ return -EPERM;
+
/* Calculating the LMT table index equivalent to primary
* pcifunc.
*/
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c
index fa461489acdd..3456313d3b3c 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c
@@ -482,10 +482,11 @@ static int rvu_dbg_mcs_rx_secy_stats_display(struct seq_file *filp, void *unused
seq_printf(filp, "secy%d: Tagged ctrl pkts: %lld\n", secy_id,
stats.pkt_tagged_ctl_cnt);
seq_printf(filp, "secy%d: Untaged pkts: %lld\n", secy_id, stats.pkt_untaged_cnt);
- seq_printf(filp, "secy%d: Ctrl pkts: %lld\n", secy_id, stats.pkt_ctl_cnt);
if (mcs->hw->mcs_blks > 1)
seq_printf(filp, "secy%d: pkts notag: %lld\n", secy_id,
stats.pkt_notag_cnt);
+ else
+ seq_printf(filp, "secy%d: Ctrl pkts: %lld\n", secy_id, stats.pkt_ctl_cnt);
}
mutex_unlock(&mcs->stats_lock);
return 0;
@@ -2809,6 +2810,14 @@ static void rvu_dbg_npa_init(struct rvu *rvu)
&rvu_dbg_npa_ndc_hits_miss_fops);
}
+/* Per-lmac CGX debugfs files need both RVU and CGX handle; inode->i_private
+ * points here so seq_file ops avoid pci_get_device(PCI_DEVID_OCTEONTX2_RVU_AF).
+ */
+struct rvu_cgx_lmac_dbgfs_ctx {
+ struct rvu *rvu;
+ void *cgxd;
+};
+
#define PRINT_CGX_CUML_NIXRX_STATUS(idx, name) \
({ \
u64 cnt; \
@@ -2831,18 +2840,14 @@ static void rvu_dbg_npa_init(struct rvu *rvu)
static int cgx_print_stats(struct seq_file *s, int lmac_id)
{
+ struct rvu_cgx_lmac_dbgfs_ctx *dctx = s->private;
struct cgx_link_user_info linfo;
+ struct rvu *rvu = dctx->rvu;
struct mac_ops *mac_ops;
- void *cgxd = s->private;
+ void *cgxd = dctx->cgxd;
u64 ucast, mcast, bcast;
int stat = 0, err = 0;
u64 tx_stat, rx_stat;
- struct rvu *rvu;
-
- rvu = pci_get_drvdata(pci_get_device(PCI_VENDOR_ID_CAVIUM,
- PCI_DEVID_OCTEONTX2_RVU_AF, NULL));
- if (!rvu)
- return -ENODEV;
mac_ops = get_mac_ops(cgxd);
/* There can be no CGX devices at all */
@@ -2949,20 +2954,16 @@ RVU_DEBUG_SEQ_FOPS(cgx_stat, cgx_stat_display, NULL);
static int cgx_print_dmac_flt(struct seq_file *s, int lmac_id)
{
+ struct rvu_cgx_lmac_dbgfs_ctx *dctx = s->private;
+ struct rvu *rvu = dctx->rvu;
struct pci_dev *pdev = NULL;
- void *cgxd = s->private;
+ void *cgxd = dctx->cgxd;
char *bcast, *mcast;
u16 index, domain;
u8 dmac[ETH_ALEN];
- struct rvu *rvu;
u64 cfg, mac;
int pf;
- rvu = pci_get_drvdata(pci_get_device(PCI_VENDOR_ID_CAVIUM,
- PCI_DEVID_OCTEONTX2_RVU_AF, NULL));
- if (!rvu)
- return -ENODEV;
-
pf = cgxlmac_to_pf(rvu, cgx_get_cgxid(cgxd), lmac_id);
domain = 2;
@@ -3009,17 +3010,13 @@ RVU_DEBUG_SEQ_FOPS(cgx_dmac_flt, cgx_dmac_flt_display, NULL);
static int cgx_print_fwdata(struct seq_file *s, int lmac_id)
{
+ struct rvu_cgx_lmac_dbgfs_ctx *dctx = s->private;
struct cgx_lmac_fwdata_s *fwdata;
- void *cgxd = s->private;
+ struct rvu *rvu = dctx->rvu;
+ void *cgxd = dctx->cgxd;
struct phy_s *phy;
- struct rvu *rvu;
int cgx_id, i;
- rvu = pci_get_drvdata(pci_get_device(PCI_VENDOR_ID_CAVIUM,
- PCI_DEVID_OCTEONTX2_RVU_AF, NULL));
- if (!rvu)
- return -ENODEV;
-
if (!rvu->fwdata)
return -EAGAIN;
@@ -3100,6 +3097,7 @@ RVU_DEBUG_SEQ_FOPS(cgx_fwdata, cgx_fwdata_display, NULL);
static void rvu_dbg_cgx_init(struct rvu *rvu)
{
+ struct rvu_cgx_lmac_dbgfs_ctx *ctx;
struct mac_ops *mac_ops;
unsigned long lmac_bmap;
int i, lmac_id;
@@ -3126,6 +3124,13 @@ static void rvu_dbg_cgx_init(struct rvu *rvu)
rvu->rvu_dbg.cgx = debugfs_create_dir(dname,
rvu->rvu_dbg.cgx_root);
+ ctx = devm_kzalloc(rvu->dev, sizeof(*ctx), GFP_KERNEL);
+ if (!ctx)
+ continue;
+
+ ctx->rvu = rvu;
+ ctx->cgxd = cgx;
+
for_each_set_bit(lmac_id, &lmac_bmap, rvu->hw->lmac_per_cgx) {
/* lmac debugfs dir */
sprintf(dname, "lmac%d", lmac_id);
@@ -3133,13 +3138,13 @@ static void rvu_dbg_cgx_init(struct rvu *rvu)
debugfs_create_dir(dname, rvu->rvu_dbg.cgx);
debugfs_create_file_aux_num("stats", 0600, rvu->rvu_dbg.lmac,
- cgx, lmac_id, &rvu_dbg_cgx_stat_fops);
+ ctx, lmac_id, &rvu_dbg_cgx_stat_fops);
debugfs_create_file_aux_num("mac_filter", 0600,
- rvu->rvu_dbg.lmac, cgx, lmac_id,
+ rvu->rvu_dbg.lmac, ctx, lmac_id,
&rvu_dbg_cgx_dmac_flt_fops);
- debugfs_create_file("fwdata", 0600,
- rvu->rvu_dbg.lmac, cgx,
- &rvu_dbg_cgx_fwdata_fops);
+ debugfs_create_file_aux_num("fwdata", 0600,
+ rvu->rvu_dbg.lmac, ctx,
+ lmac_id, &rvu_dbg_cgx_fwdata_fops);
}
}
}
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c
index aa3ecab5ebd8..d63c3d33775a 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c
@@ -1511,7 +1511,9 @@ static int rvu_af_dl_nix_maxlf_validate(struct devlink *devlink, u32 id,
struct rvu_devlink *rvu_dl = devlink_priv(devlink);
struct rvu *rvu = rvu_dl->rvu;
u16 max_nix0_lf, max_nix1_lf;
- struct npc_mcam *mcam;
+ struct rvu_block *block;
+ int blkaddr = 0;
+ int free_lfs;
u64 cfg;
cfg = rvu_read64(rvu, BLKADDR_NIX0, NIX_AF_CONST2);
@@ -1519,14 +1521,23 @@ static int rvu_af_dl_nix_maxlf_validate(struct devlink *devlink, u32 id,
cfg = rvu_read64(rvu, BLKADDR_NIX1, NIX_AF_CONST2);
max_nix1_lf = cfg & 0xFFF;
- /* Do not allow user to modify maximum NIX LFs while mcam entries
- * have already been assigned.
+ /* Do not allow user to modify maximum NIX LFs while NIX LFs
+ * have already been assigned. Note that modifying NIX LFs count
+ * can be done only before any LF attach requests from PFs and VFs
+ * and not later or concurrently.
*/
- mcam = &rvu->hw->mcam;
- if (mcam->bmap_fcnt < mcam->bmap_entries) {
- NL_SET_ERR_MSG_MOD(extack,
- "mcam entries have already been assigned, can't resize");
- return -EPERM;
+ blkaddr = rvu_get_next_nix_blkaddr(rvu, blkaddr);
+ while (blkaddr) {
+ block = &rvu->hw->block[blkaddr];
+
+ free_lfs = rvu_rsrc_free_count(&block->lf);
+ if (free_lfs != block->lf.max) {
+ NL_SET_ERR_MSG_MOD(extack,
+ "NIX LFs already assigned, can't resize");
+ return -EPERM;
+ }
+
+ blkaddr = rvu_get_next_nix_blkaddr(rvu, blkaddr);
}
if (max_nix0_lf && val->vu16 > max_nix0_lf) {
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
index d8989395e875..0297c7ab0614 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
@@ -528,19 +528,24 @@ static int nix_setup_bpids(struct rvu *rvu, struct nix_hw *hw, int blkaddr)
bp->fn_map = devm_kcalloc(rvu->dev, bp->bpids.max,
sizeof(u16), GFP_KERNEL);
if (!bp->fn_map)
- return -ENOMEM;
+ goto free_bpids;
bp->intf_map = devm_kcalloc(rvu->dev, bp->bpids.max,
sizeof(u8), GFP_KERNEL);
if (!bp->intf_map)
- return -ENOMEM;
+ goto free_bpids;
bp->ref_cnt = devm_kcalloc(rvu->dev, bp->bpids.max,
sizeof(u8), GFP_KERNEL);
if (!bp->ref_cnt)
- return -ENOMEM;
+ goto free_bpids;
return 0;
+
+free_bpids:
+ rvu_free_bitmap(&bp->bpids);
+ bp->bpids.bmap = NULL;
+ return -ENOMEM;
}
void rvu_nix_flr_free_bpids(struct rvu *rvu, u16 pcifunc)
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c
index a22decbe3449..91b5947dae06 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c
@@ -2225,7 +2225,7 @@ int npc_install_mcam_drop_rule(struct rvu *rvu, int mcam_idx, u16 *counter_idx,
return err;
}
- dev_err(rvu->dev,
+ dev_dbg(rvu->dev,
"%s: Installed single drop on non hit rule at %d, cntr=%d\n",
__func__, mcam_idx, req.cntr);
diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_macsec.c b/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_macsec.c
index 2cc1bdfd9b2e..9524d38f1582 100644
--- a/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_macsec.c
+++ b/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_macsec.c
@@ -182,6 +182,7 @@ static void cn10k_mcs_free_rsrc(struct otx2_nic *pfvf, enum mcs_direction dir,
clear_req->id = hw_rsrc_id;
clear_req->type = type;
clear_req->dir = dir;
+ clear_req->all = all;
req = otx2_mbox_alloc_msg_mcs_free_resources(mbox);
if (!req)
@@ -1776,11 +1777,16 @@ fail:
void cn10k_mcs_free(struct otx2_nic *pfvf)
{
+ struct cn10k_mcs_cfg *cfg = pfvf->macsec_cfg;
+
if (!test_bit(CN10K_HW_MACSEC, &pfvf->hw.cap_flag))
return;
- cn10k_mcs_free_rsrc(pfvf, MCS_TX, MCS_RSRC_TYPE_SECY, 0, true);
- cn10k_mcs_free_rsrc(pfvf, MCS_RX, MCS_RSRC_TYPE_SECY, 0, true);
+ if (!list_empty(&cfg->txsc_list)) {
+ cn10k_mcs_free_rsrc(pfvf, MCS_TX, MCS_RSRC_TYPE_SECY, 0, true);
+ cn10k_mcs_free_rsrc(pfvf, MCS_RX, MCS_RSRC_TYPE_SECY, 0, true);
+ }
+
kfree(pfvf->macsec_cfg);
pfvf->macsec_cfg = NULL;
}
diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
index 41a0ebdf201e..b63df5737ff2 100644
--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
@@ -1575,6 +1575,7 @@ static void otx2_free_sq_res(struct otx2_nic *pf)
qmem_free(pf->dev, sq->sqe_ring);
qmem_free(pf->dev, sq->cpt_resp);
qmem_free(pf->dev, sq->tso_hdrs);
+ qmem_free(pf->dev, sq->timestamps);
kfree(sq->sg);
kfree(sq->sqb_ptrs);
}
diff --git a/drivers/net/ethernet/marvell/prestera/prestera_main.c b/drivers/net/ethernet/marvell/prestera/prestera_main.c
index 41e19e9ad28d..a82e7a802985 100644
--- a/drivers/net/ethernet/marvell/prestera/prestera_main.c
+++ b/drivers/net/ethernet/marvell/prestera/prestera_main.c
@@ -373,7 +373,7 @@ static int prestera_port_sfp_bind(struct prestera_port *port)
struct device_node *ports, *node;
struct fwnode_handle *fwnode;
struct phylink *phy_link;
- int err;
+ int err = 0;
if (!sw->np)
return 0;
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 7d771168b990..5d291e50a47b 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -4960,6 +4960,11 @@ static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np)
if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628))
mac_ops = &rt5350_phylink_ops;
+ if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_2P5GPHY) &&
+ id == MTK_GMAC2_ID)
+ __set_bit(PHY_INTERFACE_MODE_INTERNAL,
+ mac->phylink_config.supported_interfaces);
+
phylink = phylink_create(&mac->phylink_config,
of_fwnode_handle(mac->of_node),
phy_mode, mac_ops);
@@ -4970,11 +4975,6 @@ static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np)
mac->phylink = phylink;
- if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_2P5GPHY) &&
- id == MTK_GMAC2_ID)
- __set_bit(PHY_INTERFACE_MODE_INTERNAL,
- mac->phylink_config.supported_interfaces);
-
SET_NETDEV_DEV(eth->netdev[id], eth->dev);
eth->netdev[id]->watchdog_timeo = 5 * HZ;
eth->netdev[id]->netdev_ops = &mtk_netdev_ops;
diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.c b/drivers/net/ethernet/mediatek/mtk_ppe.c
index 18279e2a7022..8451dc3fd00a 100644
--- a/drivers/net/ethernet/mediatek/mtk_ppe.c
+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
@@ -918,7 +918,7 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int index)
mib = dmam_alloc_coherent(ppe->dev, MTK_PPE_ENTRIES * sizeof(*mib),
&ppe->mib_phys, GFP_KERNEL);
if (!mib)
- return NULL;
+ goto err_free_l2_flows;
ppe->mib_table = mib;
@@ -926,7 +926,7 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int index)
GFP_KERNEL);
if (!acct)
- return NULL;
+ goto err_free_l2_flows;
ppe->acct_table = acct;
}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/Kconfig b/drivers/net/ethernet/mellanox/mlx5/core/Kconfig
index 3c3e84100d5a..925ee25d05b4 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/Kconfig
+++ b/drivers/net/ethernet/mellanox/mlx5/core/Kconfig
@@ -143,7 +143,7 @@ config MLX5_CORE_IPOIB
config MLX5_MACSEC
bool "Connect-X support for MACSec offload"
depends on MLX5_CORE_EN
- depends on MACSEC
+ depends on MACSEC=y || MACSEC=MLX5_CORE
default n
help
Build support for MACsec cryptography-offload acceleration in the NIC.
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
index 2f5b626ba33f..112926d07634 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
@@ -2721,7 +2721,8 @@ const struct ethtool_ops mlx5e_ethtool_ops = {
.rxfh_max_num_contexts = MLX5E_MAX_NUM_RSS,
.op_needs_rtnl = ETHTOOL_OP_NEEDS_RTNL_SCHANNELS |
ETHTOOL_OP_NEEDS_RTNL_SRINGPARAM |
- ETHTOOL_OP_NEEDS_RTNL_SPFLAGS,
+ ETHTOOL_OP_NEEDS_RTNL_SPFLAGS |
+ ETHTOOL_OP_NEEDS_RTNL_GLINK,
.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
ETHTOOL_COALESCE_MAX_FRAMES |
ETHTOOL_COALESCE_USE_ADAPTIVE |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
index 1a8a19f980d3..c8b76d301c92 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
@@ -419,7 +419,8 @@ static const struct ethtool_ops mlx5e_rep_ethtool_ops = {
ETHTOOL_COALESCE_MAX_FRAMES |
ETHTOOL_COALESCE_USE_ADAPTIVE,
.op_needs_rtnl = ETHTOOL_OP_NEEDS_RTNL_SCHANNELS |
- ETHTOOL_OP_NEEDS_RTNL_SRINGPARAM,
+ ETHTOOL_OP_NEEDS_RTNL_SRINGPARAM |
+ ETHTOOL_OP_NEEDS_RTNL_GLINK,
.get_drvinfo = mlx5e_rep_get_drvinfo,
.get_link = ethtool_op_get_link,
.get_strings = mlx5e_rep_get_strings,
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ethtool.c
index 9b3b32408c64..01ddc3def9ac 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ethtool.c
@@ -286,7 +286,8 @@ const struct ethtool_ops mlx5i_ethtool_ops = {
ETHTOOL_COALESCE_MAX_FRAMES |
ETHTOOL_COALESCE_USE_ADAPTIVE,
.op_needs_rtnl = ETHTOOL_OP_NEEDS_RTNL_SCHANNELS |
- ETHTOOL_OP_NEEDS_RTNL_SRINGPARAM,
+ ETHTOOL_OP_NEEDS_RTNL_SRINGPARAM |
+ ETHTOOL_OP_NEEDS_RTNL_GLINK,
.get_drvinfo = mlx5i_get_drvinfo,
.get_strings = mlx5i_get_strings,
.get_sset_count = mlx5i_get_sset_count,
@@ -309,6 +310,7 @@ const struct ethtool_ops mlx5i_ethtool_ops = {
};
const struct ethtool_ops mlx5i_pkey_ethtool_ops = {
+ .op_needs_rtnl = ETHTOOL_OP_NEEDS_RTNL_GLINK,
.get_drvinfo = mlx5i_get_drvinfo,
.get_link = ethtool_op_get_link,
.get_ts_info = mlx5i_get_ts_info,
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h b/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
index 51637e58a48b..09e669f83dba 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
@@ -297,7 +297,6 @@ void mlx5_core_reps_aux_devs_remove(struct mlx5_core_dev *dev);
void mlx5_fw_reporters_create(struct mlx5_core_dev *dev);
int mlx5_query_mtpps(struct mlx5_core_dev *dev, u32 *mtpps, u32 mtpps_size);
int mlx5_set_mtpps(struct mlx5_core_dev *mdev, u32 *mtpps, u32 mtpps_size);
-int mlx5_query_mtppse(struct mlx5_core_dev *mdev, u8 pin, u8 *arm, u8 *mode);
int mlx5_set_mtppse(struct mlx5_core_dev *mdev, u8 pin, u8 arm, u8 mode);
struct mlx5_dm *mlx5_dm_create(struct mlx5_core_dev *dev);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/port.c b/drivers/net/ethernet/mellanox/mlx5/core/port.c
index ee8b9765c5ba..ddbe9ca8971d 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/port.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/port.c
@@ -908,25 +908,6 @@ int mlx5_set_mtpps(struct mlx5_core_dev *mdev, u32 *mtpps, u32 mtpps_size)
sizeof(out), MLX5_REG_MTPPS, 0, 1);
}
-int mlx5_query_mtppse(struct mlx5_core_dev *mdev, u8 pin, u8 *arm, u8 *mode)
-{
- u32 out[MLX5_ST_SZ_DW(mtppse_reg)] = {0};
- u32 in[MLX5_ST_SZ_DW(mtppse_reg)] = {0};
- int err = 0;
-
- MLX5_SET(mtppse_reg, in, pin, pin);
-
- err = mlx5_core_access_reg(mdev, in, sizeof(in), out,
- sizeof(out), MLX5_REG_MTPPSE, 0, 0);
- if (err)
- return err;
-
- *arm = MLX5_GET(mtppse_reg, in, event_arm);
- *mode = MLX5_GET(mtppse_reg, in, event_generation_mode);
-
- return err;
-}
-
int mlx5_set_mtppse(struct mlx5_core_dev *mdev, u8 pin, u8 arm, u8 mode)
{
u32 out[MLX5_ST_SZ_DW(mtppse_reg)] = {0};
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c b/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c
index cb34fc166ef9..0e47088ec44b 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c
@@ -2024,7 +2024,8 @@ static const struct ethtool_ops fbnic_ethtool_ops = {
ETHTOOL_OP_NEEDS_RTNL_GPAUSEPARAM |
ETHTOOL_OP_NEEDS_RTNL_SPAUSEPARAM |
ETHTOOL_OP_NEEDS_RTNL_SCHANNELS |
- ETHTOOL_OP_NEEDS_RTNL_SRINGPARAM,
+ ETHTOOL_OP_NEEDS_RTNL_SRINGPARAM |
+ ETHTOOL_OP_NEEDS_RTNL_GLINK,
.get_drvinfo = fbnic_get_drvinfo,
.get_regs_len = fbnic_get_regs_len,
.get_regs = fbnic_get_regs,
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_fw.c b/drivers/net/ethernet/meta/fbnic/fbnic_fw.c
index 0c6812fcf185..283d25fae79e 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_fw.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_fw.c
@@ -526,15 +526,10 @@ int fbnic_fw_xmit_ownership_msg(struct fbnic_dev *fbd, bool take_ownership)
goto free_message;
}
- err = fbnic_mbx_map_tlv_msg(fbd, msg);
- if (err)
- goto free_message;
-
/* Initialize heartbeat, set last response to 1 second in the past
* so that we will trigger a timeout if the firmware doesn't respond
*/
fbd->last_heartbeat_response = req_time - HZ;
-
fbd->last_heartbeat_request = req_time;
/* Set prev_firmware_time to 0 to avoid triggering firmware crash
@@ -542,6 +537,10 @@ int fbnic_fw_xmit_ownership_msg(struct fbnic_dev *fbd, bool take_ownership)
*/
fbd->prev_firmware_time = 0;
+ err = fbnic_mbx_map_tlv_msg(fbd, msg);
+ if (err)
+ goto free_message;
+
/* Set heartbeat detection based on if we are taking ownership */
fbd->fw_heartbeat_enabled = take_ownership;
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
index dd77ab6052c8..10bf99be3f24 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
@@ -264,8 +264,11 @@ static int fbnic_set_mac(struct net_device *netdev, void *p)
eth_hw_addr_set(netdev, addr->sa_data);
- if (netif_running(netdev))
+ if (netif_running(netdev)) {
+ netif_addr_lock_bh(netdev);
__fbnic_set_rx_mode(fbn->fbd, &netdev->uc, &netdev->mc);
+ netif_addr_unlock_bh(netdev);
+ }
return 0;
}
@@ -310,8 +313,10 @@ void fbnic_clear_rx_mode(struct fbnic_dev *fbd)
/* Write updates to hardware */
fbnic_write_macda(fbd);
+ netif_addr_lock_bh(netdev);
__dev_uc_unsync(netdev, NULL);
__dev_mc_unsync(netdev, NULL);
+ netif_addr_unlock_bh(netdev);
}
static int fbnic_hwtstamp_get(struct net_device *netdev,
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_pci.c b/drivers/net/ethernet/meta/fbnic/fbnic_pci.c
index 7e85b480203c..8b9bc9e8ea56 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_pci.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_pci.c
@@ -135,7 +135,9 @@ void fbnic_up(struct fbnic_net *fbn)
fbnic_rss_reinit_hw(fbn->fbd, fbn);
+ netif_addr_lock_bh(fbn->netdev);
__fbnic_set_rx_mode(fbn->fbd, &fbn->netdev->uc, &fbn->netdev->mc);
+ netif_addr_unlock_bh(fbn->netdev);
/* Enable Tx/Rx processing */
fbnic_napi_enable(fbn);
@@ -180,7 +182,9 @@ static int fbnic_fw_config_after_crash(struct fbnic_dev *fbd)
}
fbnic_rpc_reset_valid_entries(fbd);
+ netif_addr_lock_bh(fbd->netdev);
__fbnic_set_rx_mode(fbd, &fbd->netdev->uc, &fbd->netdev->mc);
+ netif_addr_unlock_bh(fbd->netdev);
return 0;
}
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_rpc.c b/drivers/net/ethernet/meta/fbnic/fbnic_rpc.c
index fe95b6f69646..bc0f38b6a2b2 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_rpc.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_rpc.c
@@ -244,7 +244,9 @@ void fbnic_bmc_rpc_check(struct fbnic_dev *fbd)
if (fbd->fw_cap.need_bmc_tcam_reinit) {
fbnic_bmc_rpc_init(fbd);
+ netif_addr_lock_bh(fbd->netdev);
__fbnic_set_rx_mode(fbd, &fbd->netdev->uc, &fbd->netdev->mc);
+ netif_addr_unlock_bh(fbd->netdev);
fbd->fw_cap.need_bmc_tcam_reinit = false;
}
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_switchdev.c b/drivers/net/ethernet/microchip/sparx5/sparx5_switchdev.c
index 644458108dd2..dac4dd833127 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_switchdev.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_switchdev.c
@@ -765,11 +765,13 @@ int sparx5_register_notifier_blocks(struct sparx5 *s5)
sparx5_owq = alloc_ordered_workqueue("sparx5_order", 0);
if (!sparx5_owq) {
err = -ENOMEM;
- goto err_switchdev_blocking_nb;
+ goto err_alloc_workqueue;
}
return 0;
+err_alloc_workqueue:
+ unregister_switchdev_blocking_notifier(&s5->switchdev_blocking_nb);
err_switchdev_blocking_nb:
unregister_switchdev_notifier(&s5->switchdev_nb);
err_switchdev_nb:
diff --git a/drivers/net/ethernet/microsoft/mana/gdma_main.c b/drivers/net/ethernet/microsoft/mana/gdma_main.c
index a0fdd052d7f1..e8b7ffb47eb9 100644
--- a/drivers/net/ethernet/microsoft/mana/gdma_main.c
+++ b/drivers/net/ethernet/microsoft/mana/gdma_main.c
@@ -210,6 +210,8 @@ static int mana_gd_query_max_resources(struct pci_dev *pdev)
} else {
/* If dynamic allocation is enabled we have already allocated
* hwc msi
+ * Also, we make sure in this case the following is always true
+ * (num_msix_usable - 1 HWC) <= num_online_cpus()
*/
gc->num_msix_usable = min(resp.max_msix, num_online_cpus() + 1);
}
@@ -1909,8 +1911,8 @@ void mana_gd_free_res_map(struct gdma_resource *r)
* do the same thing.
*/
-static int irq_setup(unsigned int *irqs, unsigned int len, int node,
- bool skip_first_cpu)
+static int mana_irq_setup_numa_aware(unsigned int *irqs, unsigned int len,
+ int node, bool skip_first_cpu)
{
const struct cpumask *next, *prev = cpu_none_mask;
cpumask_var_t cpus __free(free_cpumask_var);
@@ -1946,11 +1948,24 @@ done:
return 0;
}
+/* must be called with cpus_read_lock() held */
+static void mana_irq_setup_linear(unsigned int *irqs, unsigned int len)
+{
+ int cpu;
+
+ for_each_online_cpu(cpu) {
+ if (len == 0)
+ break;
+
+ irq_set_affinity_and_hint(*irqs++, cpumask_of(cpu));
+ len--;
+ }
+}
+
static int mana_gd_setup_dyn_irqs(struct pci_dev *pdev, int nvec)
{
struct gdma_context *gc = pci_get_drvdata(pdev);
struct gdma_irq_context *gic;
- bool skip_first_cpu = false;
int *irqs, err, i, msi;
irqs = kmalloc_objs(int, nvec);
@@ -1958,10 +1973,12 @@ static int mana_gd_setup_dyn_irqs(struct pci_dev *pdev, int nvec)
return -ENOMEM;
/*
+ * In this function, num_msix_usable = HWC IRQ + Queue IRQ.
+ * nvec is only Queue IRQ (HWC already setup).
* While processing the next pci irq vector, we start with index 1,
* as IRQ vector at index 0 is already processed for HWC.
* However, the population of irqs array starts with index 0, to be
- * further used in irq_setup()
+ * further used in mana_irq_setup_numa_aware()
*/
for (i = 1; i <= nvec; i++) {
msi = i;
@@ -1975,18 +1992,51 @@ static int mana_gd_setup_dyn_irqs(struct pci_dev *pdev, int nvec)
}
/*
- * When calling irq_setup() for dynamically added IRQs, if number of
- * CPUs is more than or equal to allocated MSI-X, we need to skip the
- * first CPU sibling group since they are already affinitized to HWC IRQ
+ * When calling mana_irq_setup_numa_aware() for dynamically added IRQs,
+ * if number of CPUs is more than or equal to allocated MSI-X, we need to
+ * skip the first CPU sibling group since they are already affinitized to
+ * HWC IRQ
*/
cpus_read_lock();
- if (gc->num_msix_usable <= num_online_cpus())
- skip_first_cpu = true;
+ if (gc->num_msix_usable <= num_online_cpus()) {
+ err = mana_irq_setup_numa_aware(irqs, nvec, gc->numa_node,
+ true);
+ if (err) {
+ cpus_read_unlock();
+ goto free_irq;
+ }
+ } else {
+ /*
+ * When num_msix_usable are more than num_online_cpus, our
+ * queue IRQs should be equal to num of online vCPUs.
+ * We try to make sure queue IRQs spread across all vCPUs.
+ * In such a case NUMA or CPU core affinity does not matter.
+ * Note: in this case the total mana IRQ should always be
+ * num_online_cpus + 1. The first HWC IRQ is already handled
+ * in HWC setup calls
+ * However, if CPUs went offline since num_msix_usable was
+ * computed, queue IRQs will be more than num_online_cpus().
+ * In such cases remaining extra IRQs will retain their default
+ * affinity.
+ */
+ int first_unassigned = num_online_cpus();
- err = irq_setup(irqs, nvec, gc->numa_node, skip_first_cpu);
- if (err) {
- cpus_read_unlock();
- goto free_irq;
+ if (nvec > first_unassigned) {
+ char buf[32];
+
+ if (first_unassigned == nvec - 1)
+ snprintf(buf, sizeof(buf), "%d",
+ first_unassigned);
+ else
+ snprintf(buf, sizeof(buf), "%d-%d",
+ first_unassigned, nvec - 1);
+
+ dev_dbg(&pdev->dev,
+ "MANA IRQ indices #%s will retain the default CPU affinity\n",
+ buf);
+ }
+
+ mana_irq_setup_linear(irqs, nvec);
}
cpus_read_unlock();
@@ -2041,7 +2091,7 @@ static int mana_gd_setup_irqs(struct pci_dev *pdev, int nvec)
nvec -= 1;
}
- err = irq_setup(irqs, nvec, gc->numa_node, false);
+ err = mana_irq_setup_numa_aware(irqs, nvec, gc->numa_node, false);
if (err) {
cpus_read_unlock();
goto free_irq;
diff --git a/drivers/net/ethernet/microsoft/mana/mana_bpf.c b/drivers/net/ethernet/microsoft/mana/mana_bpf.c
index b5e9bb184a1d..53308e139cbe 100644
--- a/drivers/net/ethernet/microsoft/mana/mana_bpf.c
+++ b/drivers/net/ethernet/microsoft/mana/mana_bpf.c
@@ -237,7 +237,8 @@ static int mana_xdp_set(struct net_device *ndev, struct bpf_prog *prog,
bpf_prog_put(old_prog);
if (prog)
- ndev->max_mtu = MANA_XDP_MTU_MAX;
+ ndev->max_mtu = min_t(unsigned int, MANA_XDP_MTU_MAX,
+ gc->adapter_mtu - ETH_HLEN);
else
ndev->max_mtu = gc->adapter_mtu - ETH_HLEN;
diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c
index 87862b0434c7..7438ea6b3f26 100644
--- a/drivers/net/ethernet/microsoft/mana/mana_en.c
+++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
@@ -1233,12 +1233,24 @@ int mana_gd_query_device_cfg(struct gdma_context *gc, u32 proto_major_ver,
*max_num_vports = resp.max_num_vports;
if (resp.hdr.response.msg_version >= GDMA_MESSAGE_V2) {
- if (resp.adapter_mtu < ETH_MIN_MTU + ETH_HLEN) {
+ if (resp.adapter_mtu == 0) {
+ /*
+ * Some older PF firmware versions report an
+ * adapter_mtu of 0. MANA hardware always supports the
+ * standard Ethernet MTU, so fall back to ETH_FRAME_LEN.
+ * Jumbo frames will not be available in this case.
+ */
+ dev_info(dev,
+ "PF reported adapter_mtu of 0, falling back to %u (jumbo frames disabled)\n",
+ ETH_FRAME_LEN);
+ gc->adapter_mtu = ETH_FRAME_LEN;
+ } else if (resp.adapter_mtu < ETH_MIN_MTU + ETH_HLEN) {
dev_err(dev, "Adapter MTU too small: %u\n",
resp.adapter_mtu);
return -EPROTO;
+ } else {
+ gc->adapter_mtu = resp.adapter_mtu;
}
- gc->adapter_mtu = resp.adapter_mtu;
} else {
gc->adapter_mtu = ETH_FRAME_LEN;
}
diff --git a/drivers/net/ethernet/microsoft/mana/mana_ethtool.c b/drivers/net/ethernet/microsoft/mana/mana_ethtool.c
index 94e658d07a27..881df597d7f9 100644
--- a/drivers/net/ethernet/microsoft/mana/mana_ethtool.c
+++ b/drivers/net/ethernet/microsoft/mana/mana_ethtool.c
@@ -597,7 +597,8 @@ static int mana_get_link_ksettings(struct net_device *ndev,
const struct ethtool_ops mana_ethtool_ops = {
.supported_coalesce_params = ETHTOOL_COALESCE_RX_CQE_FRAMES,
.op_needs_rtnl = ETHTOOL_OP_NEEDS_RTNL_SCHANNELS |
- ETHTOOL_OP_NEEDS_RTNL_SRINGPARAM,
+ ETHTOOL_OP_NEEDS_RTNL_SRINGPARAM |
+ ETHTOOL_OP_NEEDS_RTNL_GLINK,
.get_ethtool_stats = mana_get_ethtool_stats,
.get_sset_count = mana_get_sset_count,
.get_strings = mana_get_strings,
diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
index 62f05f4569b1..48b94ce77490 100644
--- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
+++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
@@ -1420,13 +1420,25 @@ pch_gbe_alloc_rx_buffers_pool(struct pch_gbe_adapter *adapter,
return 0;
}
+static void pch_gbe_free_rx_buffers_pool(struct pch_gbe_adapter *adapter,
+ struct pch_gbe_rx_ring *rx_ring)
+{
+ dma_free_coherent(&adapter->pdev->dev, rx_ring->rx_buff_pool_size,
+ rx_ring->rx_buff_pool, rx_ring->rx_buff_pool_logic);
+ rx_ring->rx_buff_pool_logic = 0;
+ rx_ring->rx_buff_pool_size = 0;
+ rx_ring->rx_buff_pool = NULL;
+}
+
/**
* pch_gbe_alloc_tx_buffers - Allocate transmit buffers
* @adapter: Board private structure
* @tx_ring: Tx descriptor ring
+ *
+ * Return: 0 on success, -ENOMEM if a TX skb allocation fails.
*/
-static void pch_gbe_alloc_tx_buffers(struct pch_gbe_adapter *adapter,
- struct pch_gbe_tx_ring *tx_ring)
+static int pch_gbe_alloc_tx_buffers(struct pch_gbe_adapter *adapter,
+ struct pch_gbe_tx_ring *tx_ring)
{
struct pch_gbe_buffer *buffer_info;
struct sk_buff *skb;
@@ -1440,12 +1452,17 @@ static void pch_gbe_alloc_tx_buffers(struct pch_gbe_adapter *adapter,
for (i = 0; i < tx_ring->count; i++) {
buffer_info = &tx_ring->buffer_info[i];
skb = netdev_alloc_skb(adapter->netdev, bufsz);
+ if (!skb) {
+ pch_gbe_clean_tx_ring(adapter, tx_ring);
+ return -ENOMEM;
+ }
skb_reserve(skb, PCH_GBE_DMA_ALIGN);
buffer_info->skb = skb;
tx_desc = PCH_GBE_TX_DESC(*tx_ring, i);
tx_desc->gbec_status = (DSC_INIT16);
}
- return;
+
+ return 0;
}
/**
@@ -1887,7 +1904,12 @@ int pch_gbe_up(struct pch_gbe_adapter *adapter)
"Error: can't bring device up - alloc rx buffers pool failed\n");
goto freeirq;
}
- pch_gbe_alloc_tx_buffers(adapter, tx_ring);
+ err = pch_gbe_alloc_tx_buffers(adapter, tx_ring);
+ if (err) {
+ netdev_err(netdev,
+ "Error: can't bring device up - alloc tx buffers failed\n");
+ goto freebuf;
+ }
pch_gbe_alloc_rx_buffers(adapter, rx_ring, rx_ring->count);
adapter->tx_queue_len = netdev->tx_queue_len;
pch_gbe_enable_dma_rx(&adapter->hw);
@@ -1901,6 +1923,8 @@ int pch_gbe_up(struct pch_gbe_adapter *adapter)
return 0;
+freebuf:
+ pch_gbe_free_rx_buffers_pool(adapter, rx_ring);
freeirq:
pch_gbe_free_irq(adapter);
out:
@@ -1936,11 +1960,7 @@ void pch_gbe_down(struct pch_gbe_adapter *adapter)
pch_gbe_clean_tx_ring(adapter, adapter->tx_ring);
pch_gbe_clean_rx_ring(adapter, adapter->rx_ring);
- dma_free_coherent(&adapter->pdev->dev, rx_ring->rx_buff_pool_size,
- rx_ring->rx_buff_pool, rx_ring->rx_buff_pool_logic);
- rx_ring->rx_buff_pool_logic = 0;
- rx_ring->rx_buff_pool_size = 0;
- rx_ring->rx_buff_pool = NULL;
+ pch_gbe_free_rx_buffers_pool(adapter, rx_ring);
}
/**
diff --git a/drivers/net/ethernet/rocker/rocker_ofdpa.c b/drivers/net/ethernet/rocker/rocker_ofdpa.c
index 66a8ae67c3ea..15d19a8a1710 100644
--- a/drivers/net/ethernet/rocker/rocker_ofdpa.c
+++ b/drivers/net/ethernet/rocker/rocker_ofdpa.c
@@ -1924,6 +1924,9 @@ static int ofdpa_port_fdb(struct ofdpa_port *ofdpa_port,
flags |= OFDPA_OP_FLAG_REFRESH;
}
+ if (found && removing)
+ kfree(found);
+
return ofdpa_port_fdb_learn(ofdpa_port, flags, addr, vlan_id);
}
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-spacemit.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-spacemit.c
index 223754cc5c79..322bdf167a4a 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-spacemit.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-spacemit.c
@@ -18,10 +18,12 @@
#include "stmmac_platform.h"
/* ctrl register bits */
-#define CTRL_PHY_INTF_RGMII BIT(3)
-#define CTRL_PHY_INTF_MII BIT(4)
-#define CTRL_WAKE_IRQ_EN BIT(9)
-#define CTRL_PHY_IRQ_EN BIT(12)
+#define CTRL_PHY_INTF_MODE GENMASK(4, 3)
+#define CTRL_PHY_INTF_RMII FIELD_PREP(CTRL_PHY_INTF_MODE, 0)
+#define CTRL_PHY_INTF_RGMII FIELD_PREP(CTRL_PHY_INTF_MODE, 1)
+#define CTRL_PHY_INTF_MII FIELD_PREP(CTRL_PHY_INTF_MODE, 3)
+#define CTRL_LPI_IRQ_EN BIT(9)
+#define CTRL_WAKE_IRQ_EN BIT(12)
/* dline register bits */
#define RGMII_RX_DLINE_EN BIT(0)
@@ -118,7 +120,7 @@ static void spacemit_get_interfaces(struct stmmac_priv *priv, void *bsp_priv,
static int spacemit_set_phy_intf_sel(void *bsp_priv, u8 phy_intf_sel)
{
- unsigned int mask = CTRL_PHY_INTF_MII | CTRL_PHY_INTF_RGMII;
+ unsigned int mask = CTRL_PHY_INTF_MODE;
struct spacmit_dwmac *dwmac = bsp_priv;
unsigned int val = 0;
@@ -128,6 +130,7 @@ static int spacemit_set_phy_intf_sel(void *bsp_priv, u8 phy_intf_sel)
break;
case PHY_INTF_SEL_RMII:
+ val = CTRL_PHY_INTF_RMII;
break;
case PHY_INTF_SEL_RGMII:
diff --git a/drivers/net/ethernet/sun/sungem.c b/drivers/net/ethernet/sun/sungem.c
index b56a0d4cdb12..dc5638d105db 100644
--- a/drivers/net/ethernet/sun/sungem.c
+++ b/drivers/net/ethernet/sun/sungem.c
@@ -2978,10 +2978,10 @@ static int gem_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
dev->max_mtu = GEM_MAX_MTU;
/* Register with kernel */
- if (register_netdev(dev)) {
+ err = register_netdev(dev);
+ if (err) {
pr_err("Cannot register net device, aborting\n");
- err = -ENOMEM;
- goto err_out_free_consistent;
+ goto err_out_clear_drvdata;
}
/* Undo the get_cell with appropriate locking (we could use
@@ -2995,8 +2995,13 @@ static int gem_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
dev->dev_addr);
return 0;
+err_out_clear_drvdata:
+ pci_set_drvdata(pdev, NULL);
+ netif_napi_del(&gp->napi);
+
err_out_free_consistent:
- gem_remove_one(pdev);
+ dma_free_coherent(&pdev->dev, sizeof(struct gem_init_block),
+ gp->init_block, gp->gblock_dvma);
err_out_iounmap:
gem_put_cell(gp);
iounmap(gp->regs);
diff --git a/drivers/net/ethernet/sunplus/spl2sw_phy.c b/drivers/net/ethernet/sunplus/spl2sw_phy.c
index 6f899e48f51d..a4889c52e00e 100644
--- a/drivers/net/ethernet/sunplus/spl2sw_phy.c
+++ b/drivers/net/ethernet/sunplus/spl2sw_phy.c
@@ -79,12 +79,14 @@ int spl2sw_phy_connect(struct spl2sw_common *comm)
void spl2sw_phy_remove(struct spl2sw_common *comm)
{
struct net_device *ndev;
+ struct spl2sw_mac *mac;
int i;
for (i = 0; i < MAX_NETDEV_NUM; i++)
if (comm->ndev[i]) {
ndev = comm->ndev[i];
- if (ndev)
- phy_disconnect(ndev->phydev);
+ mac = netdev_priv(ndev);
+ phy_disconnect(ndev->phydev);
+ of_node_put(mac->phy_node);
}
}
diff --git a/drivers/net/ethernet/ti/icssg/icssg_common.c b/drivers/net/ethernet/ti/icssg/icssg_common.c
index 82ddef9c17d5..4a7d1a6f470b 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_common.c
+++ b/drivers/net/ethernet/ti/icssg/icssg_common.c
@@ -93,8 +93,8 @@ void prueth_ndev_del_tx_napi(struct prueth_emac *emac, int num)
}
EXPORT_SYMBOL_GPL(prueth_ndev_del_tx_napi);
-static int emac_xsk_xmit_zc(struct prueth_emac *emac,
- unsigned int q_idx)
+static void emac_xsk_xmit_zc(struct prueth_emac *emac,
+ unsigned int q_idx)
{
struct prueth_tx_chn *tx_chn = &emac->tx_chns[q_idx];
struct xsk_buff_pool *pool = tx_chn->xsk_pool;
@@ -115,7 +115,7 @@ static int emac_xsk_xmit_zc(struct prueth_emac *emac,
* necessary
*/
if (descs_avail <= MAX_SKB_FRAGS)
- return 0;
+ return;
descs_avail -= MAX_SKB_FRAGS;
@@ -170,8 +170,8 @@ static int emac_xsk_xmit_zc(struct prueth_emac *emac,
num_tx++;
}
- xsk_tx_release(tx_chn->xsk_pool);
- return num_tx;
+ if (num_tx)
+ xsk_tx_release(tx_chn->xsk_pool);
}
void prueth_xmit_free(struct prueth_tx_chn *tx_chn,
@@ -279,9 +279,6 @@ int emac_tx_complete_packets(struct prueth_emac *emac, int chn,
num_tx++;
}
- if (!num_tx)
- return 0;
-
netif_txq = netdev_get_tx_queue(ndev, chn);
netdev_tx_completed_queue(netif_txq, num_tx, total_bytes);
@@ -297,16 +294,18 @@ int emac_tx_complete_packets(struct prueth_emac *emac, int chn,
__netif_tx_unlock(netif_txq);
}
- if (tx_chn->xsk_pool) {
- if (xsk_frames_done)
+ if (budget && tx_chn->xsk_pool) {
+ if (xsk_frames_done) {
xsk_tx_completed(tx_chn->xsk_pool, xsk_frames_done);
+ txq_trans_cond_update(netif_txq);
+ }
if (xsk_uses_need_wakeup(tx_chn->xsk_pool))
xsk_set_tx_need_wakeup(tx_chn->xsk_pool);
- netif_txq = netdev_get_tx_queue(ndev, chn);
- txq_trans_cond_update(netif_txq);
+ __netif_tx_lock(netif_txq, smp_processor_id());
emac_xsk_xmit_zc(emac, chn);
+ __netif_tx_unlock(netif_txq);
}
return num_tx;
@@ -1652,28 +1651,35 @@ void icssg_ndo_get_stats64(struct net_device *ndev,
stats->rx_over_errors = emac_get_stat_by_name(emac, "rx_over_errors");
stats->multicast = emac_get_stat_by_name(emac, "rx_multicast_frames");
- stats->rx_errors = ndev->stats.rx_errors +
- emac_get_stat_by_name(emac, "FW_RX_ERROR") +
- emac_get_stat_by_name(emac, "FW_RX_EOF_SHORT_FRMERR") +
- emac_get_stat_by_name(emac, "FW_RX_B0_DROP_EARLY_EOF") +
- emac_get_stat_by_name(emac, "FW_RX_EXP_FRAG_Q_DROP") +
- emac_get_stat_by_name(emac, "FW_RX_FIFO_OVERRUN");
- stats->rx_dropped = ndev->stats.rx_dropped +
- emac_get_stat_by_name(emac, "FW_DROPPED_PKT") +
- emac_get_stat_by_name(emac, "FW_INF_PORT_DISABLED") +
- emac_get_stat_by_name(emac, "FW_INF_SAV") +
- emac_get_stat_by_name(emac, "FW_INF_SA_DL") +
- emac_get_stat_by_name(emac, "FW_INF_PORT_BLOCKED") +
- emac_get_stat_by_name(emac, "FW_INF_DROP_TAGGED") +
- emac_get_stat_by_name(emac, "FW_INF_DROP_PRIOTAGGED") +
- emac_get_stat_by_name(emac, "FW_INF_DROP_NOTAG") +
- emac_get_stat_by_name(emac, "FW_INF_DROP_NOTMEMBER");
+ stats->rx_errors = ndev->stats.rx_errors;
+ stats->rx_dropped = ndev->stats.rx_dropped;
stats->tx_errors = ndev->stats.tx_errors;
- stats->tx_dropped = ndev->stats.tx_dropped +
- emac_get_stat_by_name(emac, "FW_RTU_PKT_DROP") +
- emac_get_stat_by_name(emac, "FW_TX_DROPPED_PACKET") +
- emac_get_stat_by_name(emac, "FW_TX_TS_DROPPED_PACKET") +
- emac_get_stat_by_name(emac, "FW_TX_JUMBO_FRM_CUTOFF");
+ stats->tx_dropped = ndev->stats.tx_dropped;
+
+ if (!emac->prueth->pa_stats)
+ return;
+
+ stats->rx_errors +=
+ emac_get_stat_by_name(emac, "FW_RX_ERROR") +
+ emac_get_stat_by_name(emac, "FW_RX_EOF_SHORT_FRMERR") +
+ emac_get_stat_by_name(emac, "FW_RX_B0_DROP_EARLY_EOF") +
+ emac_get_stat_by_name(emac, "FW_RX_EXP_FRAG_Q_DROP") +
+ emac_get_stat_by_name(emac, "FW_RX_FIFO_OVERRUN");
+ stats->rx_dropped +=
+ emac_get_stat_by_name(emac, "FW_DROPPED_PKT") +
+ emac_get_stat_by_name(emac, "FW_INF_PORT_DISABLED") +
+ emac_get_stat_by_name(emac, "FW_INF_SAV") +
+ emac_get_stat_by_name(emac, "FW_INF_SA_DL") +
+ emac_get_stat_by_name(emac, "FW_INF_PORT_BLOCKED") +
+ emac_get_stat_by_name(emac, "FW_INF_DROP_TAGGED") +
+ emac_get_stat_by_name(emac, "FW_INF_DROP_PRIOTAGGED") +
+ emac_get_stat_by_name(emac, "FW_INF_DROP_NOTAG") +
+ emac_get_stat_by_name(emac, "FW_INF_DROP_NOTMEMBER");
+ stats->tx_dropped +=
+ emac_get_stat_by_name(emac, "FW_RTU_PKT_DROP") +
+ emac_get_stat_by_name(emac, "FW_TX_DROPPED_PACKET") +
+ emac_get_stat_by_name(emac, "FW_TX_TS_DROPPED_PACKET") +
+ emac_get_stat_by_name(emac, "FW_TX_JUMBO_FRM_CUTOFF");
}
EXPORT_SYMBOL_GPL(icssg_ndo_get_stats64);
diff --git a/drivers/net/ethernet/wangxun/ngbe/ngbe_main.c b/drivers/net/ethernet/wangxun/ngbe/ngbe_main.c
index 8678c49b892a..a16221995909 100644
--- a/drivers/net/ethernet/wangxun/ngbe/ngbe_main.c
+++ b/drivers/net/ethernet/wangxun/ngbe/ngbe_main.c
@@ -715,7 +715,6 @@ static int ngbe_probe(struct pci_dev *pdev,
netdev->features |= NETIF_F_GRO;
netdev->priv_flags |= IFF_UNICAST_FLT;
- netdev->priv_flags |= IFF_SUPP_NOFCS;
netdev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
netdev->min_mtu = ETH_MIN_MTU;
diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c b/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c
index ce82e13aa8ae..20c5a295c6c2 100644
--- a/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c
+++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c
@@ -796,7 +796,6 @@ static int txgbe_probe(struct pci_dev *pdev,
netdev->features |= NETIF_F_RX_UDP_TUNNEL_PORT;
netdev->priv_flags |= IFF_UNICAST_FLT;
- netdev->priv_flags |= IFF_SUPP_NOFCS;
netdev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
netdev->min_mtu = ETH_MIN_MTU;
diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
index 9afff7bcaa0b..396e1a113cd4 100644
--- a/drivers/net/geneve.c
+++ b/drivers/net/geneve.c
@@ -954,13 +954,27 @@ static int geneve_gro_complete(struct sock *sk, struct sk_buff *skb,
struct genevehdr *gh;
struct packet_offload *ptype;
__be16 type;
- int gh_len;
+ unsigned int gh_len;
int err = -ENOSYS;
gh = (struct genevehdr *)(skb->data + nhoff);
gh_len = geneve_hlen(gh);
type = gh->proto_type;
- geneve_opt_gro_hint_off(gh, &type, &gh_len);
+ geneve_sk_gro_hint_off(sk, gh, &type, &gh_len);
+
+ /* Bail out if we are about to dispatch past the inner network header
+ * gro_receive() validated. An inner VLAN tag only pushes
+ * inner_network_offset out, so use a lower bound.
+ */
+ if (skb->encapsulation) {
+ unsigned int inner_nh = nhoff + gh_len;
+
+ if (type == htons(ETH_P_TEB))
+ inner_nh += ETH_HLEN;
+
+ if (unlikely(inner_nh > NAPI_GRO_CB(skb)->inner_network_offset))
+ return -EINVAL;
+ }
/* since skb->encapsulation is set, eth_gro_complete() sets the inner mac header */
if (likely(type == htons(ETH_P_TEB)))
diff --git a/drivers/net/ieee802154/ca8210.c b/drivers/net/ieee802154/ca8210.c
index ed4178155a5d..01af4f9cf7f2 100644
--- a/drivers/net/ieee802154/ca8210.c
+++ b/drivers/net/ieee802154/ca8210.c
@@ -595,7 +595,7 @@ static int ca8210_test_int_driver_write(
fifo_buffer = kmemdup(buf, len, GFP_KERNEL);
if (!fifo_buffer)
return -ENOMEM;
- kfifo_in(&test->up_fifo, &fifo_buffer, 4);
+ kfifo_in(&test->up_fifo, &fifo_buffer, sizeof(fifo_buffer));
wake_up_interruptible(&priv->test.readq);
return 0;
@@ -919,9 +919,10 @@ static int ca8210_spi_transfer(
if (status < 0) {
dev_crit(
&spi->dev,
- "status %d from spi_sync in write\n",
+ "status %d from spi_async in write\n",
status
);
+ kfree(cas_ctl);
}
return status;
@@ -2525,6 +2526,7 @@ static ssize_t ca8210_test_int_user_read(
struct ca8210_priv *priv = filp->private_data;
unsigned char *fifo_buffer;
unsigned long bytes_not_copied;
+ unsigned int copied;
if (filp->f_flags & O_NONBLOCK) {
/* Non-blocking mode */
@@ -2538,7 +2540,8 @@ static ssize_t ca8210_test_int_user_read(
);
}
- if (kfifo_out(&priv->test.up_fifo, &fifo_buffer, 4) != 4) {
+ copied = kfifo_out(&priv->test.up_fifo, &fifo_buffer, sizeof(fifo_buffer));
+ if (copied != sizeof(fifo_buffer)) {
dev_err(
&priv->spi->dev,
"test_interface: Wrong number of elements popped from upstream fifo\n"
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
index a159cb293981..862001d09aa8 100644
--- a/drivers/net/netconsole.c
+++ b/drivers/net/netconsole.c
@@ -190,8 +190,10 @@ struct netconsole_target {
bool extended;
bool release;
struct netpoll np;
- /* protected by target_list_lock */
- char buf[MAX_PRINT_CHUNK];
+ /* protected by target_list_lock; +1 gives scnprintf() room for its
+ * NUL terminator so a full MAX_PRINT_CHUNK payload is not truncated
+ */
+ char buf[MAX_PRINT_CHUNK + 1];
struct work_struct resume_wq;
};
@@ -1938,7 +1940,7 @@ static void send_msg_no_fragmentation(struct netconsole_target *nt,
if (release_len) {
release = init_utsname()->release;
- scnprintf(nt->buf, MAX_PRINT_CHUNK, "%s,%.*s", release,
+ scnprintf(nt->buf, sizeof(nt->buf), "%s,%.*s", release,
msg_len, msg);
msg_len += release_len;
} else {
@@ -1947,12 +1949,12 @@ static void send_msg_no_fragmentation(struct netconsole_target *nt,
if (userdata)
msg_len += scnprintf(&nt->buf[msg_len],
- MAX_PRINT_CHUNK - msg_len, "%s",
+ sizeof(nt->buf) - msg_len, "%s",
userdata);
if (sysdata)
msg_len += scnprintf(&nt->buf[msg_len],
- MAX_PRINT_CHUNK - msg_len, "%s",
+ sizeof(nt->buf) - msg_len, "%s",
sysdata);
send_udp(nt, nt->buf, msg_len);
diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c
index 27268811f564..b65d0f5fa1a0 100644
--- a/drivers/net/phy/realtek/realtek_main.c
+++ b/drivers/net/phy/realtek/realtek_main.c
@@ -1802,7 +1802,8 @@ static int rtl822x_config_aneg(struct phy_device *phydev)
ret = phy_modify_mmd_changed(phydev, MDIO_MMD_VEND2,
RTL_MDIO_AN_10GBT_CTRL,
MDIO_AN_10GBT_CTRL_ADV2_5G |
- MDIO_AN_10GBT_CTRL_ADV5G, adv);
+ MDIO_AN_10GBT_CTRL_ADV5G |
+ MDIO_AN_10GBT_CTRL_ADV10G, adv);
if (ret < 0)
return ret;
}
diff --git a/drivers/net/pse-pd/pd692x0.c b/drivers/net/pse-pd/pd692x0.c
index cb377d5ba7af..209de9cec849 100644
--- a/drivers/net/pse-pd/pd692x0.c
+++ b/drivers/net/pse-pd/pd692x0.c
@@ -200,7 +200,7 @@ static const struct pd692x0_msg pd692x0_msg_template_list[PD692X0_MSG_CNT] = {
},
[PD692X0_MSG_SET_USER_BYTE] = {
.key = PD692X0_KEY_PRG,
- .sub = {0x41, PD692X0_USER_BYTE},
+ .sub = {0x41, PD692X0_USER_BYTE, 0x4e},
.data = {0x4e, 0x4e, 0x4e, 0x4e,
0x4e, 0x4e, 0x4e, 0x4e},
},
diff --git a/drivers/net/thunderbolt/main.c b/drivers/net/thunderbolt/main.c
index f8f97e8e2226..02a91650561a 100644
--- a/drivers/net/thunderbolt/main.c
+++ b/drivers/net/thunderbolt/main.c
@@ -783,8 +783,12 @@ static bool tbnet_check_frame(struct tbnet *net, const struct tbnet_frame *tf,
return true;
}
- /* Start of packet, validate the frame header */
- if (frame_count == 0 || frame_count > TBNET_RING_SIZE / 4) {
+ /* Start of packet, validate the frame header. tbnet_poll() puts the
+ * first frame in the skb linear area and every further frame in a page
+ * fragment, so a packet may not span more than MAX_SKB_FRAGS + 1 frames
+ * without overflowing skb_shinfo()->frags[].
+ */
+ if (frame_count == 0 || frame_count > MAX_SKB_FRAGS + 1) {
net->stats.rx_length_errors++;
return false;
}
diff --git a/drivers/net/usb/kalmia.c b/drivers/net/usb/kalmia.c
index ee9c48f7f68f..0dd0a30c3db4 100644
--- a/drivers/net/usb/kalmia.c
+++ b/drivers/net/usb/kalmia.c
@@ -276,6 +276,14 @@ kalmia_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
"Received header: %6phC. Package length: %i\n",
header_start, skb->len - KALMIA_HEADER_LENGTH);
+ /* both framing headers must be present before we subtract
+ * them, otherwise usb_packet_length underflows and the
+ * device-supplied ether_packet_length drives an out of bounds
+ * access below
+ */
+ if (skb->len < 2 * KALMIA_HEADER_LENGTH)
+ return 0;
+
/* subtract start header and end header */
usb_packet_length = skb->len - (2 * KALMIA_HEADER_LENGTH);
ether_packet_length = get_unaligned_le16(&header_start[2]);
diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c
index bcf293ea1bd3..c4cebacabcb5 100644
--- a/drivers/net/usb/lan78xx.c
+++ b/drivers/net/usb/lan78xx.c
@@ -1452,6 +1452,15 @@ static inline u32 lan78xx_hash(char addr[ETH_ALEN])
return (ether_crc(ETH_ALEN, addr) >> 23) & 0x1ff;
}
+static int lan78xx_write_mchash_table(struct lan78xx_net *dev)
+{
+ struct lan78xx_priv *pdata = (struct lan78xx_priv *)(dev->data[0]);
+
+ return lan78xx_dataport_write(dev, DP_SEL_RSEL_VLAN_DA_,
+ DP_SEL_VHF_VLAN_LEN,
+ DP_SEL_VHF_HASH_LEN, pdata->mchash_table);
+}
+
static void lan78xx_deferred_multicast_write(struct work_struct *param)
{
struct lan78xx_priv *pdata =
@@ -1462,9 +1471,7 @@ static void lan78xx_deferred_multicast_write(struct work_struct *param)
netif_dbg(dev, drv, dev->net, "deferred multicast write 0x%08x\n",
pdata->rfe_ctl);
- ret = lan78xx_dataport_write(dev, DP_SEL_RSEL_VLAN_DA_,
- DP_SEL_VHF_VLAN_LEN,
- DP_SEL_VHF_HASH_LEN, pdata->mchash_table);
+ ret = lan78xx_write_mchash_table(dev);
if (ret < 0)
goto multicast_write_done;
@@ -1557,6 +1564,7 @@ static void lan78xx_set_multicast(struct net_device *netdev)
}
static void lan78xx_rx_urb_submit_all(struct lan78xx_net *dev);
+static int lan78xx_write_vlan_table(struct lan78xx_net *dev);
static int lan78xx_mac_reset(struct lan78xx_net *dev)
{
@@ -2514,6 +2522,17 @@ static void lan78xx_mac_link_up(struct phylink_config *config,
if (ret < 0)
goto link_up_fail;
+ /* The RFE clears the VLAN/DA hash filter (VHF) on a link down/up
+ * cycle, so reprogram both tables from their shadow copies.
+ */
+ ret = lan78xx_write_vlan_table(dev);
+ if (ret < 0)
+ goto link_up_fail;
+
+ ret = lan78xx_write_mchash_table(dev);
+ if (ret < 0)
+ goto link_up_fail;
+
netif_start_queue(net);
return;
@@ -3065,14 +3084,20 @@ static int lan78xx_set_features(struct net_device *netdev,
return lan78xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl);
}
+static int lan78xx_write_vlan_table(struct lan78xx_net *dev)
+{
+ struct lan78xx_priv *pdata = (struct lan78xx_priv *)(dev->data[0]);
+
+ return lan78xx_dataport_write(dev, DP_SEL_RSEL_VLAN_DA_, 0,
+ DP_SEL_VHF_VLAN_LEN, pdata->vlan_table);
+}
+
static void lan78xx_deferred_vlan_write(struct work_struct *param)
{
struct lan78xx_priv *pdata =
container_of(param, struct lan78xx_priv, set_vlan);
- struct lan78xx_net *dev = pdata->dev;
- lan78xx_dataport_write(dev, DP_SEL_RSEL_VLAN_DA_, 0,
- DP_SEL_VHF_VLAN_LEN, pdata->vlan_table);
+ lan78xx_write_vlan_table(pdata->dev);
}
static int lan78xx_vlan_rx_add_vid(struct net_device *netdev,
diff --git a/drivers/net/veth.c b/drivers/net/veth.c
index 0cfb19b760dd..1c5142149175 100644
--- a/drivers/net/veth.c
+++ b/drivers/net/veth.c
@@ -1137,6 +1137,8 @@ static int veth_enable_xdp_range(struct net_device *dev, int start, int end,
err_reg_mem:
xdp_rxq_info_unreg(&priv->rq[i].xdp_rxq);
err_rxq_reg:
+ if (!napi_already_on)
+ netif_napi_del(&priv->rq[i].xdp_napi);
for (i--; i >= start; i--) {
struct veth_rq *rq = &priv->rq[i];
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 7d2eeb9b1226..26afa6341d16 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -1999,15 +1999,18 @@ static struct sk_buff *receive_big(struct net_device *dev,
struct virtnet_rq_stats *stats)
{
struct page *page = buf;
+ unsigned long max_len;
struct sk_buff *skb;
+ max_len = (vi->big_packets_num_skbfrags + 1) * PAGE_SIZE -
+ sizeof(struct padded_vnet_hdr) + vi->hdr_len;
+
/* Make sure that len does not exceed the size allocated in
* add_recvbuf_big.
*/
- if (unlikely(len > (vi->big_packets_num_skbfrags + 1) * PAGE_SIZE)) {
+ if (unlikely(len > max_len)) {
pr_debug("%s: rx error: len %u exceeds allocated size %lu\n",
- dev->name, len,
- (vi->big_packets_num_skbfrags + 1) * PAGE_SIZE);
+ dev->name, len, max_len);
goto err;
}
diff --git a/drivers/net/wan/hdlc_ppp.c b/drivers/net/wan/hdlc_ppp.c
index 159295c4bd6d..302ed27944e7 100644
--- a/drivers/net/wan/hdlc_ppp.c
+++ b/drivers/net/wan/hdlc_ppp.c
@@ -619,7 +619,6 @@ static void ppp_start(struct net_device *dev)
struct proto *proto = &ppp->protos[i];
proto->dev = dev;
- timer_setup(&proto->timer, ppp_timer, 0);
proto->state = CLOSED;
}
ppp->protos[IDX_LCP].pid = PID_LCP;
@@ -639,6 +638,15 @@ static void ppp_close(struct net_device *dev)
ppp_tx_flush();
}
+static void ppp_timer_release(struct net_device *dev)
+{
+ struct ppp *ppp = get_ppp(dev);
+ int i;
+
+ for (i = 0; i < IDX_COUNT; i++)
+ timer_shutdown_sync(&ppp->protos[i].timer);
+}
+
static struct hdlc_proto proto = {
.start = ppp_start,
.stop = ppp_stop,
@@ -647,6 +655,7 @@ static struct hdlc_proto proto = {
.ioctl = ppp_ioctl,
.netif_rx = ppp_rx,
.module = THIS_MODULE,
+ .detach = ppp_timer_release,
};
static const struct header_ops ppp_header_ops = {
@@ -657,7 +666,7 @@ static int ppp_ioctl(struct net_device *dev, struct if_settings *ifs)
{
hdlc_device *hdlc = dev_to_hdlc(dev);
struct ppp *ppp;
- int result;
+ int i, result;
switch (ifs->type) {
case IF_GET_PROTO:
@@ -685,6 +694,8 @@ static int ppp_ioctl(struct net_device *dev, struct if_settings *ifs)
return result;
ppp = get_ppp(dev);
+ for (i = 0; i < IDX_COUNT; i++)
+ timer_setup(&ppp->protos[i].timer, ppp_timer, 0);
spin_lock_init(&ppp->lock);
ppp->req_timeout = 2;
ppp->cr_retries = 10;
diff --git a/drivers/net/wan/ixp4xx_hss.c b/drivers/net/wan/ixp4xx_hss.c
index 720c5dc889ea..7f4645ff90aa 100644
--- a/drivers/net/wan/ixp4xx_hss.c
+++ b/drivers/net/wan/ixp4xx_hss.c
@@ -1487,11 +1487,11 @@ static int ixp4xx_hss_probe(struct platform_device *pdev)
"unable to get CLK internal GPIO\n");
ndev = alloc_hdlcdev(port);
- port->netdev = alloc_hdlcdev(port);
- if (!port->netdev) {
+ if (!ndev) {
err = -ENOMEM;
goto err_plat;
}
+ port->netdev = ndev;
SET_NETDEV_DEV(ndev, &pdev->dev);
hdlc = dev_to_hdlc(ndev);
diff --git a/drivers/net/wwan/t7xx/t7xx_hif_cldma.c b/drivers/net/wwan/t7xx/t7xx_hif_cldma.c
index e10cb4f9104e..2917cee9b802 100644
--- a/drivers/net/wwan/t7xx/t7xx_hif_cldma.c
+++ b/drivers/net/wwan/t7xx/t7xx_hif_cldma.c
@@ -1063,6 +1063,9 @@ err_free_tx_ring:
while (i--)
t7xx_cldma_ring_free(md_ctrl, &md_ctrl->tx_ring[i], DMA_TO_DEVICE);
+ dma_pool_destroy(md_ctrl->gpd_dmapool);
+ md_ctrl->gpd_dmapool = NULL;
+
return ret;
}