aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2026-10-09 06:40:28 +0200
committerLinus Torvalds <torvalds@linux-foundation.org>2026-10-09 06:40:28 +0200
commitaf32da41b0327b9c6a37856ba82b6760d6c8d10e (patch)
tree1908c1d636394d7ab56ed3e469eb41e9cd357fd6 /drivers
parent6c377d19d4a5116d9bec5203aa3c6c11523e7898 (diff)
parent37f12441f557468a56c1e27790413aa78c82afa2 (diff)
Merge tag 'net-7.3-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/netHEADmaster
Pull networking fixes from Jakub Kicinski: "Including fixes from wireless, wireguard, CAN and Bluetooth. We have one known regression to wrap up in VLAN handling. Current release - regressions: - Bluetooth: RFCOMM: fix deadlock on rfcomm_mutex Previous releases - regressions: - can: fix regression in handling RPS after migrating metadata to skb_ext - eth: - iavf: fix regressions in reconfig impacting bonding - mana: fix packet forwarding performance regression - stmmac: remove buggy VLAN acceleration support Previous releases - always broken: - a few high prio fixes for tun, and af_packet - amt: fix a UaF on tunnel teardown - eth: - bnxt: fix PCIe AER recovery and FLR handling issues - macb: don't modify Tx skbs before taking ownership - axienet: don't leak Tx skbs on interface stop - wifi: - nxpwifi: number of LLM-ish fixes - assorted mt76 fixes" * tag 'net-7.3-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (128 commits) net: macb: copy shared skbs before appending the FCS net: macb: check TX ring before modifying skb vsock: Fix memory leak in vmci_transport_recv_dgram_cb() wireguard: noise: reject response consumption after intermediate initiation wireguard: queueing: preserve tstamp_type when encapsulating packet net: openvswitch: validate transport header presence in set_ipv6_addr net/smc: protect clcsock lifetime in smc_getname ipv6: do not warn on route notification size race ipv4: do not warn on route notification size race ipv4: validate checksum_start before completing checksum ptp: ocp: fix PCIe delay estimation calculation xen/netfront: don't leak the skb when xennet_fill_frags() fails net/packet: call packet_parse_headers after virtio_net_hdr_to_skb xen/netfront: drop RX packets with a short Ethernet header net: skbuff: don't leave stale bytes in skb_copy_and_csum_bits() net: sparx5: free the matchall entry on destroy selftests: mlxsw: Test port range occupancy on template create mlxsw: spectrum_flower: Fix port range register leak in tmplt_create() net: dsa: microchip: fix KSZ8765 fiber detection net/mlx5e: Order ICOSQ cc update after CQ doorbell ...
Diffstat (limited to 'drivers')
-rw-r--r--drivers/bluetooth/btintel_pcie.c17
-rw-r--r--drivers/net/amt.c48
-rw-r--r--drivers/net/bareudp.c3
-rw-r--r--drivers/net/bonding/bond_main.c8
-rw-r--r--drivers/net/can/dev/skb.c4
-rw-r--r--drivers/net/can/usb/f81604.c2
-rw-r--r--drivers/net/can/vxcan.c3
-rw-r--r--drivers/net/dsa/microchip/ksz_common.h2
-rw-r--r--drivers/net/ethernet/airoha/airoha_eth.c32
-rw-r--r--drivers/net/ethernet/airoha/airoha_eth.h2
-rw-r--r--drivers/net/ethernet/allwinner/sun4i-emac.c5
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt.c189
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt.h1
-rw-r--r--drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c11
-rw-r--r--drivers/net/ethernet/cadence/macb_main.c80
-rw-r--r--drivers/net/ethernet/chelsio/inline_crypto/ch_ktls/chcr_ktls.c4
-rw-r--r--drivers/net/ethernet/google/gve/gve_main.c8
-rw-r--r--drivers/net/ethernet/google/gve/gve_rx_dqo.c13
-rw-r--r--drivers/net/ethernet/ibm/ibmveth.c22
-rw-r--r--drivers/net/ethernet/intel/e1000e/netdev.c7
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c35
-rw-r--r--drivers/net/ethernet/intel/iavf/iavf.h11
-rw-r--r--drivers/net/ethernet/intel/iavf/iavf_main.c85
-rw-r--r--drivers/net/ethernet/intel/iavf/iavf_virtchnl.c99
-rw-r--r--drivers/net/ethernet/intel/ice/devlink/port.c2
-rw-r--r--drivers/net/ethernet/intel/ice/ice_eswitch.c2
-rw-r--r--drivers/net/ethernet/intel/ice/ice_sriov.c32
-rw-r--r--drivers/net/ethernet/intel/ice/ice_txrx.c4
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_rx.c6
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/esw/adj_vport.c20
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c79
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/vport.c24
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum.h2
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c10
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c9
-rw-r--r--drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c28
-rw-r--r--drivers/net/ethernet/microchip/sparx5/sparx5_tc_matchall.c1
-rw-r--r--drivers/net/ethernet/microsoft/mana/mana_bpf.c8
-rw-r--r--drivers/net/ethernet/microsoft/mana/mana_en.c63
-rw-r--r--drivers/net/ethernet/microsoft/mana/mana_ethtool.c10
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/hwif.h2
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac.h2
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_main.c60
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c30
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_vlan.c65
-rw-r--r--drivers/net/ethernet/xilinx/xilinx_axienet.h7
-rw-r--r--drivers/net/ethernet/xilinx/xilinx_axienet_main.c51
-rw-r--r--drivers/net/pfcp.c7
-rw-r--r--drivers/net/team/team_core.c16
-rw-r--r--drivers/net/team/team_mode_broadcast.c2
-rw-r--r--drivers/net/tun.c23
-rw-r--r--drivers/net/usb/ax88179_178a.c6
-rw-r--r--drivers/net/veth.c1
-rw-r--r--drivers/net/virtio_net.c2
-rw-r--r--drivers/net/wireguard/noise.c7
-rw-r--r--drivers/net/wireguard/queueing.h2
-rw-r--r--drivers/net/wireless/ath/ath12k/core.c33
-rw-r--r--drivers/net/wireless/ath/ath12k/core.h3
-rw-r--r--drivers/net/wireless/ath/ath12k/hif.h9
-rw-r--r--drivers/net/wireless/ath/ath12k/pci.c8
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c27
-rw-r--r--drivers/net/wireless/marvell/libertas/tx.c7
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt76.h7
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7603/init.c1
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7915/init.c6
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7915/main.c2
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7925/mac.c3
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7925/main.c12
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt792x_acpi_sar.c128
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt792x_acpi_sar.h2
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7996/init.c3
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7996/main.c10
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7996/mcu.h3
-rw-r--r--drivers/net/wireless/mediatek/mt76/tx.c14
-rw-r--r--drivers/net/wireless/nxp/nxpwifi/11n.c2
-rw-r--r--drivers/net/wireless/nxp/nxpwifi/11n_aggr.c1
-rw-r--r--drivers/net/wireless/nxp/nxpwifi/11n_rxreorder.c11
-rw-r--r--drivers/net/wireless/nxp/nxpwifi/cfg80211.c31
-rw-r--r--drivers/net/wireless/nxp/nxpwifi/init.c2
-rw-r--r--drivers/net/wireless/nxp/nxpwifi/main.c4
-rw-r--r--drivers/net/wireless/nxp/nxpwifi/uap_event.c1
-rw-r--r--drivers/net/wireless/nxp/nxpwifi/util.c8
-rw-r--r--drivers/net/xen-netfront.c16
-rw-r--r--drivers/ptp/ptp_ocp.c2
84 files changed, 1037 insertions, 593 deletions
diff --git a/drivers/bluetooth/btintel_pcie.c b/drivers/bluetooth/btintel_pcie.c
index f333b01f7465..ac7193400769 100644
--- a/drivers/bluetooth/btintel_pcie.c
+++ b/drivers/bluetooth/btintel_pcie.c
@@ -401,7 +401,7 @@ static int btintel_pcie_send_sync(struct btintel_pcie_data *data,
tfd_index = data->ia.tr_hia[BTINTEL_PCIE_TXQ_NUM];
- if (tfd_index > txq->count)
+ if (tfd_index >= txq->count)
return -ERANGE;
if (skb->len > BTINTEL_PCIE_BUFFER_SIZE - BTINTEL_PCIE_HCI_TYPE_LEN) {
@@ -1777,7 +1777,7 @@ static irqreturn_t btintel_pcie_irq_msix_handler(int irq, void *dev_id)
static int btintel_pcie_setup_irq(struct btintel_pcie_data *data)
{
int err;
- int num_irqs, i;
+ int num_irqs, i, j;
for (i = 0; i < BTINTEL_PCIE_MSIX_VEC_MAX; i++)
data->msix_entries[i].entry = i;
@@ -1806,6 +1806,10 @@ static int btintel_pcie_setup_irq(struct btintel_pcie_data *data)
KBUILD_MODNAME,
msix_entry);
if (err) {
+ for (j = 0; j < i; j++)
+ devm_free_irq(&data->pdev->dev,
+ data->msix_entries[j].vector,
+ &data->msix_entries[j]);
pci_free_irq_vectors(data->pdev);
data->alloc_vecs = 0;
return err;
@@ -1877,6 +1881,13 @@ static int btintel_pcie_config_pcie(struct pci_dev *pdev,
if (IS_ERR(data->base_addr))
return PTR_ERR(data->base_addr);
+ /* Do shared hardware reset to ensure a clean start before
+ * configuring interrupts.
+ */
+ err = btintel_pcie_reset_bt(data);
+ if (err)
+ return err;
+
err = btintel_pcie_setup_irq(data);
if (err)
return err;
@@ -3138,7 +3149,7 @@ static void btintel_pcie_remove(struct pci_dev *pdev)
struct msix_entry *msix_entry;
msix_entry = &data->msix_entries[i];
- free_irq(msix_entry->vector, msix_entry);
+ devm_free_irq(&pdev->dev, msix_entry->vector, msix_entry);
}
pci_free_irq_vectors(pdev);
diff --git a/drivers/net/amt.c b/drivers/net/amt.c
index bddc24e1856d..b53f8ec55661 100644
--- a/drivers/net/amt.c
+++ b/drivers/net/amt.c
@@ -80,15 +80,6 @@ static struct in6_addr mld2_all_node = MLD2_ALL_NODE_INIT;
static struct mld2_grec mldv2_zero_grec;
#endif
-static struct amt_skb_cb *amt_skb_cb(struct sk_buff *skb)
-{
- BUILD_BUG_ON(sizeof(struct amt_skb_cb) + sizeof(struct tc_skb_cb) >
- sizeof_field(struct sk_buff, cb));
-
- return (struct amt_skb_cb *)((void *)skb->cb +
- sizeof(struct tc_skb_cb));
-}
-
static void __amt_source_gc_work(void)
{
struct amt_source_node *snode;
@@ -791,6 +782,11 @@ out:
rcu_read_unlock();
}
+static bool amt_send_membership_query(struct amt_dev *amt,
+ struct sk_buff *skb,
+ struct amt_tunnel_list *tunnel,
+ bool v6);
+
static void amt_send_igmp_gq(struct amt_dev *amt,
struct amt_tunnel_list *tunnel)
{
@@ -800,8 +796,11 @@ static void amt_send_igmp_gq(struct amt_dev *amt,
if (!skb)
return;
- amt_skb_cb(skb)->tunnel = tunnel;
- dev_queue_xmit(skb);
+ skb_pull(skb, sizeof(struct ethhdr));
+ if (amt_send_membership_query(amt, skb, tunnel, false)) {
+ amt->dev->stats.tx_dropped++;
+ kfree_skb(skb);
+ }
}
#if IS_ENABLED(CONFIG_IPV6)
@@ -885,8 +884,11 @@ static void amt_send_mld_gq(struct amt_dev *amt, struct amt_tunnel_list *tunnel)
if (!skb)
return;
- amt_skb_cb(skb)->tunnel = tunnel;
- dev_queue_xmit(skb);
+ skb_pull(skb, sizeof(struct ethhdr));
+ if (amt_send_membership_query(amt, skb, tunnel, true)) {
+ amt->dev->stats.tx_dropped++;
+ kfree_skb(skb);
+ }
}
#else
static void amt_send_mld_gq(struct amt_dev *amt, struct amt_tunnel_list *tunnel)
@@ -1186,7 +1188,6 @@ static netdev_tx_t amt_dev_xmit(struct sk_buff *skb, struct net_device *dev)
#endif
bool report = false;
struct igmphdr *ih;
- bool query = false;
struct iphdr *iph;
bool data = false;
bool v6 = false;
@@ -1204,9 +1205,6 @@ static netdev_tx_t amt_dev_xmit(struct sk_buff *skb, struct net_device *dev)
case IGMP_HOST_MEMBERSHIP_REPORT:
report = true;
break;
- case IGMP_HOST_MEMBERSHIP_QUERY:
- query = true;
- break;
default:
goto free;
}
@@ -1228,9 +1226,6 @@ static netdev_tx_t amt_dev_xmit(struct sk_buff *skb, struct net_device *dev)
case ICMPV6_MLD2_REPORT:
report = true;
break;
- case ICMPV6_MGM_QUERY:
- query = true;
- break;
default:
goto free;
}
@@ -1261,19 +1256,6 @@ static netdev_tx_t amt_dev_xmit(struct sk_buff *skb, struct net_device *dev)
goto free;
goto unlock;
} else if (amt->mode == AMT_MODE_RELAY) {
- if (query) {
- tunnel = amt_skb_cb(skb)->tunnel;
- if (!tunnel) {
- WARN_ON(1);
- goto free;
- }
-
- /* Do not forward unexpected query */
- if (amt_send_membership_query(amt, skb, tunnel, v6))
- goto free;
- goto unlock;
- }
-
if (!data)
goto free;
list_for_each_entry_rcu(tunnel, &amt->tunnel_list, list) {
diff --git a/drivers/net/bareudp.c b/drivers/net/bareudp.c
index c3b5ed52d877..b9fe54151e1a 100644
--- a/drivers/net/bareudp.c
+++ b/drivers/net/bareudp.c
@@ -356,7 +356,7 @@ static int bareudp_xmit_skb(struct sk_buff *skb, struct net_device *dev,
if (err)
goto free_dst;
- skb_set_inner_protocol(skb, bareudp->ethertype);
+ skb_set_inner_protocol(skb, skb->protocol);
udp_tunnel_xmit_skb(rt, sk, skb, saddr, info->key.u.ipv4.dst,
tos, ttl, df, sport, bareudp->port,
!net_eq(bareudp->net, dev_net(bareudp->dev)),
@@ -424,6 +424,7 @@ static int bareudp6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
if (err)
goto free_dst;
+ skb_set_inner_protocol(skb, skb->protocol);
daddr = info->key.u.ipv6.dst;
udp_tunnel6_xmit_skb(dst, sk, skb, dev,
&saddr, &daddr, prio, ttl,
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index de2489c3d9bf..09aa45d71fab 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -5732,12 +5732,12 @@ static int bond_xdp_set(struct net_device *dev, struct bpf_prog *prog,
bpf_prog_inc(prog);
}
- if (prog) {
+ if (prog && !old_prog)
static_branch_inc(&bpf_master_redirect_enabled_key);
- } else if (old_prog) {
- bpf_prog_put(old_prog);
+ else if (!prog && old_prog)
static_branch_dec(&bpf_master_redirect_enabled_key);
- }
+ if (old_prog)
+ bpf_prog_put(old_prog);
return 0;
diff --git a/drivers/net/can/dev/skb.c b/drivers/net/can/dev/skb.c
index 95fcdc1026f8..14edec5afb57 100644
--- a/drivers/net/can/dev/skb.c
+++ b/drivers/net/can/dev/skb.c
@@ -210,6 +210,10 @@ static void init_can_skb(struct sk_buff *skb)
{
skb->pkt_type = PACKET_BROADCAST;
skb->ip_summed = CHECKSUM_UNNECESSARY;
+
+ skb_reset_mac_header(skb);
+ skb_reset_network_header(skb);
+ skb_reset_transport_header(skb);
}
struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf)
diff --git a/drivers/net/can/usb/f81604.c b/drivers/net/can/usb/f81604.c
index f12318268e46..4c147b9d6d69 100644
--- a/drivers/net/can/usb/f81604.c
+++ b/drivers/net/can/usb/f81604.c
@@ -169,7 +169,7 @@ struct f81604_int_data {
u8 rxerr;
u8 txerr;
u8 val;
-} __packed __aligned(4);
+} __packed;
struct f81604_sff {
__be16 id;
diff --git a/drivers/net/can/vxcan.c b/drivers/net/can/vxcan.c
index 9e2e25d02471..51148a81d1d9 100644
--- a/drivers/net/can/vxcan.c
+++ b/drivers/net/can/vxcan.c
@@ -79,6 +79,9 @@ static netdev_tx_t vxcan_xmit(struct sk_buff *oskb, struct net_device *dev)
/* reset CAN GW hop counter */
csx->can_gw_hops = 0;
+ /* start with new CAN skb UID in the other namespace */
+ csx->can_skb_uid = 0;
+
skb->pkt_type = PACKET_BROADCAST;
skb->dev = peer;
skb->ip_summed = CHECKSUM_UNNECESSARY;
diff --git a/drivers/net/dsa/microchip/ksz_common.h b/drivers/net/dsa/microchip/ksz_common.h
index cbe98494578c..f6104f714a8d 100644
--- a/drivers/net/dsa/microchip/ksz_common.h
+++ b/drivers/net/dsa/microchip/ksz_common.h
@@ -853,7 +853,7 @@ static inline bool ksz_is_sgmii_port(struct ksz_device *dev, int port)
#define KSZ88_FAMILY_ID 0x88
#define KSZ8895_FAMILY_ID 0x95
-#define KSZ8_PORT_STATUS_0 0x08
+#define KSZ8_PORT_STATUS_0 0x18
#define KSZ8_PORT_FIBER_MODE BIT(7)
#define SW_CHIP_ID_M GENMASK(7, 4)
diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
index 64619e9a704d..6ca57875b6d6 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -2800,14 +2800,34 @@ static int airoha_qdma_set_trtcm_param(struct airoha_qdma *qdma, int channel,
FIELD_PREP(TRTCM_METER_GROUP_MASK, group) |
FIELD_PREP(TRTCM_PARAM_INDEX_MASK, idx) |
FIELD_PREP(TRTCM_PARAM_RATE_TYPE_MASK, mode);
+ int i;
- airoha_qdma_wr(qdma, REG_TRTCM_DATA_LOW(addr), val);
- airoha_qdma_wr(qdma, REG_TRTCM_CFG_PARAM(addr), config);
+ /*
+ * HW might be in the middle of bucket handling and might
+ * require an additional try to actually apply the new TRTCM
+ * config.
+ */
+ for (i = 0; i < TRTCM_CONFIG_RETRY_MAX; i++) {
+ u32 data = 0;
- return read_poll_timeout(airoha_qdma_rr, val,
- val & TRTCM_PARAM_RW_DONE_MASK,
- USEC_PER_MSEC, 10 * USEC_PER_MSEC, true,
- qdma, REG_TRTCM_CFG_PARAM(addr));
+ airoha_qdma_wr(qdma, REG_TRTCM_DATA_LOW(addr), val);
+ airoha_qdma_wr(qdma, REG_TRTCM_CFG_PARAM(addr), config);
+
+ if (read_poll_timeout(airoha_qdma_rr, data,
+ data & TRTCM_PARAM_RW_DONE_MASK,
+ USEC_PER_MSEC, 10 * USEC_PER_MSEC,
+ true, qdma, REG_TRTCM_CFG_PARAM(addr)))
+ continue;
+
+ if (airoha_qdma_get_trtcm_param(qdma, channel, addr, param,
+ mode, &data, NULL))
+ continue;
+
+ if (data == val)
+ return 0;
+ }
+
+ return -EBUSY;
}
static int airoha_qdma_set_trtcm_config(struct airoha_qdma *qdma, int channel,
diff --git a/drivers/net/ethernet/airoha/airoha_eth.h b/drivers/net/ethernet/airoha/airoha_eth.h
index 8277c1c87bb3..338fde03a149 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.h
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
@@ -171,6 +171,8 @@ enum trtcm_param {
#define TRTCM_TOKEN_RATE_MASK GENMASK(23, 6)
#define TRTCM_TOKEN_RATE_FRACTION_MASK GENMASK(5, 0)
+#define TRTCM_CONFIG_RETRY_MAX 2
+
enum airoha_dma_map_type {
AIROHA_DMA_UNMAPPED,
AIROHA_DMA_MAP_SINGLE,
diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.c b/drivers/net/ethernet/allwinner/sun4i-emac.c
index 0ba67a55705d..09b2abdfc9e8 100644
--- a/drivers/net/ethernet/allwinner/sun4i-emac.c
+++ b/drivers/net/ethernet/allwinner/sun4i-emac.c
@@ -300,7 +300,7 @@ static int emac_dma_inblk_32bit(struct emac_board_info *db,
if (!req) {
dev_err(db->dev, "alloc emac dma req error.\n");
ret = -ENOMEM;
- goto alloc_req_err;
+ goto prepare_err;
}
desc->callback_param = req;
@@ -319,9 +319,6 @@ static int emac_dma_inblk_32bit(struct emac_board_info *db,
submit_err:
emac_free_dma_req(req);
-alloc_req_err:
- dmaengine_desc_free(desc);
-
prepare_err:
dma_unmap_single(db->dev, rxbuf, count, DMA_FROM_DEVICE);
return ret;
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index d7728d0c5b6e..15a8349ccf7b 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -486,7 +486,7 @@ static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev)
struct netdev_queue *txq;
int i;
dma_addr_t mapping;
- unsigned int length, pad = 0;
+ unsigned int length;
u32 len, free_size, vlan_tag_flags, cfa_action, flags;
struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
struct pci_dev *pdev = bp->pdev;
@@ -536,6 +536,16 @@ static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev)
return rc < 0 ? NETDEV_TX_BUSY : NETDEV_TX_OK;
}
+ /* Pad after the SW USO branch: bnxt_sw_udp_gso_xmit() would
+ * otherwise account the padding as UDP payload.
+ * Must be done before skb_shinfo(skb)->nr_frags is sampled,
+ * because skb_put_padto() might linearize the skb.
+ */
+ if (skb_put_padto(skb, BNXT_MIN_PKT_SIZE)) {
+ /* SKB already freed. */
+ goto tx_kick_pending;
+ }
+
free_size = bnxt_tx_avail(bp, txr);
if (unlikely(free_size < skb_shinfo(skb)->nr_frags + 2)) {
/* We must have raced with NAPI cleanup */
@@ -672,14 +682,6 @@ static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev)
}
normal_tx:
- if (length < BNXT_MIN_PKT_SIZE) {
- pad