summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-09-07 17:23:00 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-09-07 17:23:00 +0200
commitdcf5b8a7ae4e3875878529597c05f8cac4121515 (patch)
tree0d86567a8feacb35b2a62c1ba6cf6c2fe3be65de /drivers/net/ethernet
parent864c971e923f55d3ff5ac3ebc87aab8108d30c8a (diff)
parent7cfc41f8e80f11ffa8382ed1a505154ceffb79c7 (diff)
Merge v6.18.50linux-rolling-lts
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/net/ethernet')
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c3
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt.c7
-rw-r--r--drivers/net/ethernet/ibm/emac/mal.c13
-rw-r--r--drivers/net/ethernet/nvidia/forcedeth.c4
-rw-r--r--drivers/net/ethernet/qlogic/qede/qede.h8
-rw-r--r--drivers/net/ethernet/qlogic/qede/qede_fp.c1
-rw-r--r--drivers/net/ethernet/renesas/ravb.h3
-rw-r--r--drivers/net/ethernet/renesas/ravb_main.c9
-rw-r--r--drivers/net/ethernet/renesas/ravb_ptp.c44
9 files changed, 69 insertions, 23 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index 8e6eec828d48..c4ea14f8fbe9 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -13474,10 +13474,13 @@ static int bnx2x_init_firmware(struct bnx2x *bp)
iro_alloc_err:
kfree(bp->init_ops_offsets);
+ bp->init_ops_offsets = NULL;
init_offsets_alloc_err:
kfree(bp->init_ops);
+ bp->init_ops = NULL;
init_ops_alloc_err:
kfree(bp->init_data);
+ bp->init_data = NULL;
request_firmware_exit:
release_firmware(bp->firmware);
bp->firmware = NULL;
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index 29e52df2502e..186fc98a555d 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -499,11 +499,8 @@ static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (skb_shinfo(skb)->nr_frags > TX_MAX_FRAGS) {
netdev_warn_once(dev, "SKB has too many (%d) fragments, max supported is %d. SKB will be linearized.\n",
skb_shinfo(skb)->nr_frags, TX_MAX_FRAGS);
- if (skb_linearize(skb)) {
- dev_kfree_skb_any(skb);
- dev_core_stats_tx_dropped_inc(dev);
- return NETDEV_TX_OK;
- }
+ if (skb_linearize(skb))
+ goto tx_free;
}
#endif
free_size = bnxt_tx_avail(bp, txr);
diff --git a/drivers/net/ethernet/ibm/emac/mal.c b/drivers/net/ethernet/ibm/emac/mal.c
index 7d70056e9008..a423496421e9 100644
--- a/drivers/net/ethernet/ibm/emac/mal.c
+++ b/drivers/net/ethernet/ibm/emac/mal.c
@@ -35,6 +35,7 @@ int mal_register_commac(struct mal_instance *mal, struct mal_commac *commac)
{
unsigned long flags;
+ netdev_lock(mal->napi.dev);
spin_lock_irqsave(&mal->lock, flags);
MAL_DBG(mal, "reg(%08x, %08x)" NL,
@@ -44,18 +45,20 @@ int mal_register_commac(struct mal_instance *mal, struct mal_commac *commac)
if ((mal->tx_chan_mask & commac->tx_chan_mask) ||
(mal->rx_chan_mask & commac->rx_chan_mask)) {
spin_unlock_irqrestore(&mal->lock, flags);
+ netdev_unlock(mal->napi.dev);
printk(KERN_WARNING "mal%d: COMMAC channels conflict!\n",
mal->index);
return -EBUSY;
}
if (list_empty(&mal->list))
- napi_enable(&mal->napi);
+ napi_enable_locked(&mal->napi);
mal->tx_chan_mask |= commac->tx_chan_mask;
mal->rx_chan_mask |= commac->rx_chan_mask;
list_add(&commac->list, &mal->list);
spin_unlock_irqrestore(&mal->lock, flags);
+ netdev_unlock(mal->napi.dev);
return 0;
}
@@ -64,7 +67,9 @@ void mal_unregister_commac(struct mal_instance *mal,
struct mal_commac *commac)
{
unsigned long flags;
+ bool disable_napi;
+ netdev_lock(mal->napi.dev);
spin_lock_irqsave(&mal->lock, flags);
MAL_DBG(mal, "unreg(%08x, %08x)" NL,
@@ -73,10 +78,12 @@ void mal_unregister_commac(struct mal_instance *mal,
mal->tx_chan_mask &= ~commac->tx_chan_mask;
mal->rx_chan_mask &= ~commac->rx_chan_mask;
list_del_init(&commac->list);
- if (list_empty(&mal->list))
- napi_disable(&mal->napi);
+ disable_napi = list_empty(&mal->list);
spin_unlock_irqrestore(&mal->lock, flags);
+ if (disable_napi)
+ napi_disable_locked(&mal->napi);
+ netdev_unlock(mal->napi.dev);
}
int mal_set_rcbs(struct mal_instance *mal, int channel, unsigned long size)
diff --git a/drivers/net/ethernet/nvidia/forcedeth.c b/drivers/net/ethernet/nvidia/forcedeth.c
index c09fb7694fac..01eb1c75f2da 100644
--- a/drivers/net/ethernet/nvidia/forcedeth.c
+++ b/drivers/net/ethernet/nvidia/forcedeth.c
@@ -6221,7 +6221,7 @@ static int nv_suspend(struct device *device)
netif_device_detach(dev);
/* save non-pci configuration space */
- for (i = 0; i <= np->register_size/sizeof(u32); i++)
+ for (i = 0; i < np->register_size/sizeof(u32); i++)
np->saved_config_space[i] = readl(base + i*sizeof(u32));
return 0;
@@ -6236,7 +6236,7 @@ static int nv_resume(struct device *device)
int i, rc = 0;
/* restore non-pci configuration space */
- for (i = 0; i <= np->register_size/sizeof(u32); i++)
+ for (i = 0; i < np->register_size/sizeof(u32); i++)
writel(np->saved_config_space[i], base+i*sizeof(u32));
if (np->driver_data & DEV_NEED_MSI_FIX)
diff --git a/drivers/net/ethernet/qlogic/qede/qede.h b/drivers/net/ethernet/qlogic/qede/qede.h
index 042a75f34060..0e7a0c2c1765 100644
--- a/drivers/net/ethernet/qlogic/qede/qede.h
+++ b/drivers/net/ethernet/qlogic/qede/qede.h
@@ -303,10 +303,10 @@ enum qede_agg_state {
};
struct qede_agg_info {
- /* rx_buf is a data buffer that can be placed / consumed from rx bd
- * chain. It has two purposes: We will preallocate the data buffer
- * for each aggregation when we open the interface and will place this
- * buffer on the rx-bd-ring when we receive TPA_START. We don't want
+ /* buffer is used to retain the Rx consumer descriptor when a TPA
+ * session starts. If the SKB allocation fails during TPA_START,
+ * we use this saved buffer to safely recycle the physical page
+ * back into the rx-bd-ring via qede_reuse_page(). We don't want
* to be in a state where allocation fails, as we can't reuse the
* consumer buffer in the rx-chain since FW may still be writing to it
* (since header needs to be modified for TPA).
diff --git a/drivers/net/ethernet/qlogic/qede/qede_fp.c b/drivers/net/ethernet/qlogic/qede/qede_fp.c
index c11e0d8f98aa..a02624f6d6d5 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_fp.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_fp.c
@@ -850,6 +850,7 @@ static void qede_tpa_start(struct qede_dev *edev,
pad, false);
tpa_info->buffer.page_offset = sw_rx_data_cons->page_offset;
tpa_info->buffer.mapping = sw_rx_data_cons->mapping;
+ tpa_info->buffer.data = sw_rx_data_cons->data;
if (unlikely(!tpa_info->skb)) {
DP_NOTICE(edev, "Failed to allocate SKB for gro\n");
diff --git a/drivers/net/ethernet/renesas/ravb.h b/drivers/net/ethernet/renesas/ravb.h
index 7b48060c250b..330379c4f405 100644
--- a/drivers/net/ethernet/renesas/ravb.h
+++ b/drivers/net/ethernet/renesas/ravb.h
@@ -1039,6 +1039,7 @@ struct ravb_ptp_perout {
struct ravb_ptp {
struct ptp_clock *clock;
struct ptp_clock_info info;
+ int phc_index;
u32 default_addend;
u32 current_addend;
int extts[N_EXT_TS];
@@ -1133,6 +1134,8 @@ struct ravb_private {
int msg_enable;
int speed;
int emac_irq;
+ int err_irq;
+ int mgmt_irq;
unsigned no_avb_link:1;
unsigned avb_link_active_low:1;
diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
index e2d7ce1a85e8..cd0d65cd699a 100644
--- a/drivers/net/ethernet/renesas/ravb_main.c
+++ b/drivers/net/ethernet/renesas/ravb_main.c
@@ -1757,7 +1757,7 @@ static int ravb_get_ts_info(struct net_device *ndev,
(1 << HWTSTAMP_FILTER_NONE) |
(1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
(1 << HWTSTAMP_FILTER_ALL);
- info->phc_index = ptp_clock_index(priv->ptp.clock);
+ info->phc_index = READ_ONCE(priv->ptp.phc_index);
}
return 0;
@@ -2896,11 +2896,13 @@ static int ravb_setup_irqs(struct ravb_private *priv)
return error;
if (info->err_mgmt_irqs) {
- error = ravb_setup_irq(priv, "err_a", "err_a", NULL, ravb_multi_interrupt);
+ error = ravb_setup_irq(priv, "err_a", "err_a", &priv->err_irq,
+ ravb_multi_interrupt);
if (error)
return error;
- error = ravb_setup_irq(priv, "mgmt_a", "mgmt_a", NULL, ravb_multi_interrupt);
+ error = ravb_setup_irq(priv, "mgmt_a", "mgmt_a", &priv->mgmt_irq,
+ ravb_multi_interrupt);
if (error)
return error;
}
@@ -2963,6 +2965,7 @@ static int ravb_probe(struct platform_device *pdev)
priv->rstc = rstc;
priv->ndev = ndev;
priv->pdev = pdev;
+ priv->ptp.phc_index = -1;
priv->num_tx_ring[RAVB_BE] = BE_TX_RING_SIZE;
priv->num_rx_ring[RAVB_BE] = BE_RX_RING_SIZE;
if (info->nc_queues) {
diff --git a/drivers/net/ethernet/renesas/ravb_ptp.c b/drivers/net/ethernet/renesas/ravb_ptp.c
index 226c6c0ab945..43218bc15b15 100644
--- a/drivers/net/ethernet/renesas/ravb_ptp.c
+++ b/drivers/net/ethernet/renesas/ravb_ptp.c
@@ -289,16 +289,17 @@ static const struct ptp_clock_info ravb_ptp_info = {
void ravb_ptp_interrupt(struct net_device *ndev)
{
struct ravb_private *priv = netdev_priv(ndev);
+ struct ptp_clock *clock = READ_ONCE(priv->ptp.clock);
u32 gis = ravb_read(ndev, GIS);
gis &= ravb_read(ndev, GIC);
- if (gis & GIS_PTCF) {
+ if ((gis & GIS_PTCF) && clock) {
struct ptp_clock_event event;
event.type = PTP_CLOCK_EXTTS;
event.index = 0;
event.timestamp = ravb_read(ndev, GCPT);
- ptp_clock_event(priv->ptp.clock, &event);
+ ptp_clock_event(clock, &event);
}
if (gis & GIS_PTMF) {
struct ravb_ptp_perout *perout = priv->ptp.perout;
@@ -315,6 +316,7 @@ void ravb_ptp_interrupt(struct net_device *ndev)
void ravb_ptp_init(struct net_device *ndev, struct platform_device *pdev)
{
struct ravb_private *priv = netdev_priv(ndev);
+ struct ptp_clock *clock;
unsigned long flags;
priv->ptp.info = ravb_ptp_info;
@@ -327,15 +329,45 @@ void ravb_ptp_init(struct net_device *ndev, struct platform_device *pdev)
ravb_modify(ndev, GCCR, GCCR_TCSS, GCCR_TCSS_ADJGPTP);
spin_unlock_irqrestore(&priv->lock, flags);
- priv->ptp.clock = ptp_clock_register(&priv->ptp.info, &pdev->dev);
+ clock = ptp_clock_register(&priv->ptp.info, &pdev->dev);
+ if (IS_ERR(clock)) {
+ netdev_err(ndev, "failed to register PTP clock: %pe\n", clock);
+ clock = NULL;
+ }
+
+ WRITE_ONCE(priv->ptp.clock, clock);
+ if (clock)
+ WRITE_ONCE(priv->ptp.phc_index, ptp_clock_index(clock));
+}
+
+static void ravb_ptp_disable(struct net_device *ndev)
+{
+ ravb_write(ndev, 0, GIC);
+ ravb_write(ndev, 0, GIS);
+}
+
+static void ravb_ptp_sync_irqs(struct net_device *ndev)
+{
+ struct ravb_private *priv = netdev_priv(ndev);
+
+ synchronize_irq(ndev->irq);
+ if (priv->info->err_mgmt_irqs) {
+ synchronize_irq(priv->err_irq);
+ synchronize_irq(priv->mgmt_irq);
+ }
}
void ravb_ptp_stop(struct net_device *ndev)
{
struct ravb_private *priv = netdev_priv(ndev);
+ struct ptp_clock *clock;
- ravb_write(ndev, 0, GIC);
- ravb_write(ndev, 0, GIS);
+ WRITE_ONCE(priv->ptp.phc_index, -1);
+ clock = xchg(&priv->ptp.clock, NULL);
+
+ ravb_ptp_disable(ndev);
+ ravb_ptp_sync_irqs(ndev);
- ptp_clock_unregister(priv->ptp.clock);
+ if (clock)
+ ptp_clock_unregister(clock);
}