Merge tag 'net-7.0-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net

Pull networking fixes from Jakub Kicinski:
 "With fixes from wireless, bluetooth and netfilter included we're back
  to each PR carrying 30%+ more fixes than in previous era.

  The good news is that so far none of the "extra" fixes are themselves
  causing real regressions. Not sure how much comfort that is.

  Current release - fix to a fix:

   - netdevsim: fix build if SKB_EXTENSIONS=n

   - eth: stmmac: skip VLAN restore when VLAN hash ops are missing

  Previous releases - regressions:

   - wifi: iwlwifi: mvm: don't send a 6E related command when
     not supported

  Previous releases - always broken:

   - some info leak fixes

   - add missing clearing of skb->cb[] on ICMP paths from tunnels

   - ipv6:
      - flowlabel: defer exclusive option free until RCU teardown
      - avoid overflows in ip6_datagram_send_ctl()

   - mpls: add seqcount to protect platform_labels from OOB access

   - bridge: improve safety of parsing ND options

   - bluetooth: fix leaks, overflows and races in hci_sync

   - netfilter: add more input validation, some to address bugs directly
     some to prevent exploits from cooking up broken configurations

   - wifi:
      - ath: avoid poor performance due to stopping the wrong
        aggregation session
      - virt_wifi: remove SET_NETDEV_DEV to avoid use-after-free

   - eth:
      - fec: fix the PTP periodic output sysfs interface
      - enetc: safely reinitialize TX BD ring when it has unsent frames"

* tag 'net-7.0-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (95 commits)
  eth: fbnic: Increase FBNIC_QUEUE_SIZE_MIN to 64
  ipv6: avoid overflows in ip6_datagram_send_ctl()
  net: hsr: fix VLAN add unwind on slave errors
  net: hsr: serialize seq_blocks merge across nodes
  vsock: initialize child_ns_mode_locked in vsock_net_init()
  selftests/tc-testing: add tests for cls_fw and cls_flow on shared blocks
  net/sched: cls_flow: fix NULL pointer dereference on shared blocks
  net/sched: cls_fw: fix NULL pointer dereference on shared blocks
  net/x25: Fix overflow when accumulating packets
  net/x25: Fix potential double free of skb
  bnxt_en: Restore default stat ctxs for ULP when resource is available
  bnxt_en: Don't assume XDP is never enabled in bnxt_init_dflt_ring_mode()
  bnxt_en: Refactor some basic ring setup and adjustment logic
  net/mlx5: Fix switchdev mode rollback in case of failure
  net/mlx5: Avoid "No data available" when FW version queries fail
  net/mlx5: lag: Check for LAG device before creating debugfs
  net: macb: properly unregister fixed rate clocks
  net: macb: fix clk handling on PCI glue driver removal
  virtio_net: clamp rss_max_key_size to NETDEV_RSS_KEY_LEN
  net/sched: sch_netem: fix out-of-bounds access in packet corruption
  ...
This commit is contained in:
Linus Torvalds
2026-04-02 09:57:06 -07:00
98 changed files with 1147 additions and 493 deletions
-3
View File
@@ -109,9 +109,6 @@ static int h4_recv(struct hci_uart *hu, const void *data, int count)
{
struct h4_struct *h4 = hu->priv;
if (!test_bit(HCI_UART_REGISTERED, &hu->flags))
return -EUNATCH;
h4->rx_skb = h4_recv_buf(hu, h4->rx_skb, data, count,
h4_recv_pkts, ARRAY_SIZE(h4_recv_pkts));
if (IS_ERR(h4->rx_skb)) {
+1 -1
View File
@@ -5326,7 +5326,7 @@ static netdev_tx_t bond_xmit_broadcast(struct sk_buff *skb,
if (!(bond_slave_is_up(slave) && slave->link == BOND_LINK_UP))
continue;
if (bond_is_last_slave(bond, slave)) {
if (i + 1 == slaves_count) {
skb2 = skb;
skb_used = true;
} else {
+19 -1
View File
@@ -794,18 +794,34 @@ static int airoha_qdma_init_rx_queue(struct airoha_queue *q,
static void airoha_qdma_cleanup_rx_queue(struct airoha_queue *q)
{
struct airoha_eth *eth = q->qdma->eth;
struct airoha_qdma *qdma = q->qdma;
struct airoha_eth *eth = qdma->eth;
int qid = q - &qdma->q_rx[0];
while (q->queued) {
struct airoha_queue_entry *e = &q->entry[q->tail];
struct airoha_qdma_desc *desc = &q->desc[q->tail];
struct page *page = virt_to_head_page(e->buf);
dma_sync_single_for_cpu(eth->dev, e->dma_addr, e->dma_len,
page_pool_get_dma_dir(q->page_pool));
page_pool_put_full_page(q->page_pool, page, false);
/* 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);
WRITE_ONCE(desc->msg3, 0);
q->tail = (q->tail + 1) % q->ndesc;
q->queued--;
}
q->head = q->tail;
airoha_qdma_rmw(qdma, REG_RX_DMA_IDX(qid), RX_RING_DMA_IDX_MASK,
FIELD_PREP(RX_RING_DMA_IDX_MASK, q->tail));
}
static int airoha_qdma_init_rx(struct airoha_qdma *qdma)
@@ -2946,6 +2962,8 @@ static int airoha_register_gdm_devices(struct airoha_eth *eth)
return err;
}
set_bit(DEV_STATE_REGISTERED, &eth->state);
return 0;
}
+1
View File
@@ -88,6 +88,7 @@ enum {
enum {
DEV_STATE_INITIALIZED,
DEV_STATE_REGISTERED,
};
enum {
+7
View File
@@ -1368,6 +1368,13 @@ int airoha_ppe_setup_tc_block_cb(struct airoha_ppe_dev *dev, void *type_data)
struct airoha_eth *eth = ppe->eth;
int err = 0;
/* Netfilter flowtable can try to offload flower rules while not all
* the net_devices are registered or initialized. Delay offloading
* until all net_devices are registered in the system.
*/
if (!test_bit(DEV_STATE_REGISTERED, &eth->state))
return -EBUSY;
mutex_lock(&flow_offload_mutex);
if (!eth->npu)
+52 -24
View File
@@ -8045,6 +8045,8 @@ static int __bnxt_reserve_rings(struct bnxt *bp)
ulp_msix = bnxt_get_avail_msix(bp, bp->ulp_num_msix_want);
if (!ulp_msix)
bnxt_set_ulp_stat_ctxs(bp, 0);
else
bnxt_set_dflt_ulp_stat_ctxs(bp);
if (ulp_msix > bp->ulp_num_msix_want)
ulp_msix = bp->ulp_num_msix_want;
@@ -8671,7 +8673,7 @@ static int bnxt_hwrm_func_backing_store_qcaps_v2(struct bnxt *bp)
struct hwrm_func_backing_store_qcaps_v2_output *resp;
struct hwrm_func_backing_store_qcaps_v2_input *req;
struct bnxt_ctx_mem_info *ctx = bp->ctx;
u16 type;
u16 type, next_type = 0;
int rc;
rc = hwrm_req_init(bp, req, HWRM_FUNC_BACKING_STORE_QCAPS_V2);
@@ -8687,7 +8689,7 @@ static int bnxt_hwrm_func_backing_store_qcaps_v2(struct bnxt *bp)
resp = hwrm_req_hold(bp, req);
for (type = 0; type < BNXT_CTX_V2_MAX; ) {
for (type = 0; type < BNXT_CTX_V2_MAX; type = next_type) {
struct bnxt_ctx_mem_type *ctxm = &ctx->ctx_arr[type];
u8 init_val, init_off, i;
u32 max_entries;
@@ -8700,7 +8702,7 @@ static int bnxt_hwrm_func_backing_store_qcaps_v2(struct bnxt *bp)
if (rc)
goto ctx_done;
flags = le32_to_cpu(resp->flags);
type = le16_to_cpu(resp->next_valid_type);
next_type = le16_to_cpu(resp->next_valid_type);
if (!(flags & BNXT_CTX_MEM_TYPE_VALID)) {
bnxt_free_one_ctx_mem(bp, ctxm, true);
continue;
@@ -8715,7 +8717,7 @@ static int bnxt_hwrm_func_backing_store_qcaps_v2(struct bnxt *bp)
else
continue;
}
ctxm->type = le16_to_cpu(resp->type);
ctxm->type = type;
ctxm->entry_size = entry_size;
ctxm->flags = flags;
ctxm->instance_bmap = le32_to_cpu(resp->instance_bit_map);
@@ -12992,6 +12994,21 @@ static int bnxt_tx_nr_rings_per_tc(struct bnxt *bp)
return bp->num_tc ? bp->tx_nr_rings / bp->num_tc : bp->tx_nr_rings;
}
static void bnxt_set_xdp_tx_rings(struct bnxt *bp)
{
bp->tx_nr_rings_xdp = bp->tx_nr_rings_per_tc;
bp->tx_nr_rings += bp->tx_nr_rings_xdp;
}
static void bnxt_adj_tx_rings(struct bnxt *bp)
{
/* Make adjustments if reserved TX rings are less than requested */
bp->tx_nr_rings -= bp->tx_nr_rings_xdp;
bp->tx_nr_rings_per_tc = bnxt_tx_nr_rings_per_tc(bp);
if (bp->tx_nr_rings_xdp)
bnxt_set_xdp_tx_rings(bp);
}
static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init)
{
int rc = 0;
@@ -13009,13 +13026,7 @@ static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init)
if (rc)
return rc;
/* Make adjustments if reserved TX rings are less than requested */
bp->tx_nr_rings -= bp->tx_nr_rings_xdp;
bp->tx_nr_rings_per_tc = bnxt_tx_nr_rings_per_tc(bp);
if (bp->tx_nr_rings_xdp) {
bp->tx_nr_rings_xdp = bp->tx_nr_rings_per_tc;
bp->tx_nr_rings += bp->tx_nr_rings_xdp;
}
bnxt_adj_tx_rings(bp);
rc = bnxt_alloc_mem(bp, irq_re_init);
if (rc) {
netdev_err(bp->dev, "bnxt_alloc_mem err: %x\n", rc);
@@ -15436,11 +15447,19 @@ static int bnxt_change_mtu(struct net_device *dev, int new_mtu)
return 0;
}
void bnxt_set_cp_rings(struct bnxt *bp, bool sh)
{
int tx_cp = bnxt_num_tx_to_cp(bp, bp->tx_nr_rings);
bp->cp_nr_rings = sh ? max_t(int, tx_cp, bp->rx_nr_rings) :
tx_cp + bp->rx_nr_rings;
}
int bnxt_setup_mq_tc(struct net_device *dev, u8 tc)
{
struct bnxt *bp = netdev_priv(dev);
bool sh = false;
int rc, tx_cp;
int rc;
if (tc > bp->max_tc) {
netdev_err(dev, "Too many traffic classes requested: %d. Max supported is %d.\n",
@@ -15473,9 +15492,7 @@ int bnxt_setup_mq_tc(struct net_device *dev, u8 tc)
bp->num_tc = 0;
}
bp->tx_nr_rings += bp->tx_nr_rings_xdp;
tx_cp = bnxt_num_tx_to_cp(bp, bp->tx_nr_rings);
bp->cp_nr_rings = sh ? max_t(int, tx_cp, bp->rx_nr_rings) :
tx_cp + bp->rx_nr_rings;
bnxt_set_cp_rings(bp, sh);
if (netif_running(bp->dev))
return bnxt_open_nic(bp, true, false);
@@ -16525,6 +16542,19 @@ static void bnxt_trim_dflt_sh_rings(struct bnxt *bp)
bp->tx_nr_rings = bnxt_tx_nr_rings(bp);
}
static void bnxt_adj_dflt_rings(struct bnxt *bp, bool sh)
{
if (sh)
bnxt_trim_dflt_sh_rings(bp);
else
bp->cp_nr_rings = bp->tx_nr_rings_per_tc + bp->rx_nr_rings;
bp->tx_nr_rings = bnxt_tx_nr_rings(bp);
if (sh && READ_ONCE(bp->xdp_prog)) {
bnxt_set_xdp_tx_rings(bp);
bnxt_set_cp_rings(bp, true);
}
}
static int bnxt_set_dflt_rings(struct bnxt *bp, bool sh)
{
int dflt_rings, max_rx_rings, max_tx_rings, rc;
@@ -16550,11 +16580,8 @@ static int bnxt_set_dflt_rings(struct bnxt *bp, bool sh)
return rc;
bp->rx_nr_rings = min_t(int, dflt_rings, max_rx_rings);
bp->tx_nr_rings_per_tc = min_t(int, dflt_rings, max_tx_rings);
if (sh)
bnxt_trim_dflt_sh_rings(bp);
else
bp->cp_nr_rings = bp->tx_nr_rings_per_tc + bp->rx_nr_rings;
bp->tx_nr_rings = bnxt_tx_nr_rings(bp);
bnxt_adj_dflt_rings(bp, sh);
avail_msix = bnxt_get_max_func_irqs(bp) - bp->cp_nr_rings;
if (avail_msix >= BNXT_MIN_ROCE_CP_RINGS) {
@@ -16567,16 +16594,17 @@ static int bnxt_set_dflt_rings(struct bnxt *bp, bool sh)
rc = __bnxt_reserve_rings(bp);
if (rc && rc != -ENODEV)
netdev_warn(bp->dev, "Unable to reserve tx rings\n");
bp->tx_nr_rings_per_tc = bnxt_tx_nr_rings_per_tc(bp);
bnxt_adj_tx_rings(bp);
if (sh)
bnxt_trim_dflt_sh_rings(bp);
bnxt_adj_dflt_rings(bp, true);
/* Rings may have been trimmed, re-reserve the trimmed rings. */
if (bnxt_need_reserve_rings(bp)) {
rc = __bnxt_reserve_rings(bp);
if (rc && rc != -ENODEV)
netdev_warn(bp->dev, "2nd rings reservation failed.\n");
bp->tx_nr_rings_per_tc = bnxt_tx_nr_rings_per_tc(bp);
bnxt_adj_tx_rings(bp);
}
if (BNXT_CHIP_TYPE_NITRO_A0(bp)) {
bp->rx_nr_rings++;
@@ -16610,7 +16638,7 @@ static int bnxt_init_dflt_ring_mode(struct bnxt *bp)
if (rc)
goto init_dflt_ring_err;
bp->tx_nr_rings_per_tc = bnxt_tx_nr_rings_per_tc(bp);
bnxt_adj_tx_rings(bp);
bnxt_set_dflt_rfs(bp);
@@ -2985,6 +2985,7 @@ int bnxt_check_rings(struct bnxt *bp, int tx, int rx, bool sh, int tcs,
int tx_xdp);
int bnxt_fw_init_one(struct bnxt *bp);
bool bnxt_hwrm_reset_permitted(struct bnxt *bp);
void bnxt_set_cp_rings(struct bnxt *bp, bool sh);
int bnxt_setup_mq_tc(struct net_device *dev, u8 tc);
struct bnxt_ntuple_filter *bnxt_lookup_ntp_filter_from_idx(struct bnxt *bp,
struct bnxt_ntuple_filter *fltr, u32 idx);
@@ -945,7 +945,6 @@ static int bnxt_set_channels(struct net_device *dev,
bool sh = false;
int tx_xdp = 0;
int rc = 0;
int tx_cp;
if (channel->other_count)
return -EINVAL;
@@ -1013,9 +1012,7 @@ static int bnxt_set_channels(struct net_device *dev,
if (tcs > 1)
bp->tx_nr_rings = bp->tx_nr_rings_per_tc * tcs + tx_xdp;
tx_cp = bnxt_num_tx_to_cp(bp, bp->tx_nr_rings);
bp->cp_nr_rings = sh ? max_t(int, tx_cp, bp->rx_nr_rings) :
tx_cp + bp->rx_nr_rings;
bnxt_set_cp_rings(bp, sh);
/* After changing number of rx channels, update NTUPLE feature. */
netdev_update_features(dev);
@@ -384,7 +384,7 @@ int bnxt_xdp_xmit(struct net_device *dev, int num_frames,
static int bnxt_xdp_set(struct bnxt *bp, struct bpf_prog *prog)
{
struct net_device *dev = bp->dev;
int tx_xdp = 0, tx_cp, rc, tc;
int tx_xdp = 0, rc, tc;
struct bpf_prog *old;
netdev_assert_locked(dev);
@@ -431,8 +431,7 @@ static int bnxt_xdp_set(struct bnxt *bp, struct bpf_prog *prog)
}
bp->tx_nr_rings_xdp = tx_xdp;
bp->tx_nr_rings = bp->tx_nr_rings_per_tc * tc + tx_xdp;
tx_cp = bnxt_num_tx_to_cp(bp, bp->tx_nr_rings);
bp->cp_nr_rings = max_t(int, tx_cp, bp->rx_nr_rings);
bnxt_set_cp_rings(bp, true);
bnxt_set_tpa_flags(bp);
bnxt_set_ring_params(bp);
+1 -1
View File
@@ -12299,7 +12299,7 @@ static int tg3_get_link_ksettings(struct net_device *dev,
ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.advertising,
advertising);
if (netif_running(dev) && tp->link_up) {
if (netif_running(dev) && netif_carrier_ok(dev)) {
cmd->base.speed = tp->link_config.active_speed;
cmd->base.duplex = tp->link_config.active_duplex;
ethtool_convert_legacy_u32_to_link_mode(
+6 -4
View File
@@ -96,10 +96,10 @@ static int macb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
return 0;
err_plat_dev_register:
clk_unregister(plat_data.hclk);
clk_unregister_fixed_rate(plat_data.hclk);
err_hclk_register:
clk_unregister(plat_data.pclk);
clk_unregister_fixed_rate(plat_data.pclk);
err_pclk_register:
return err;
@@ -109,10 +109,12 @@ static void macb_remove(struct pci_dev *pdev)
{
struct platform_device *plat_dev = pci_get_drvdata(pdev);
struct macb_platform_data *plat_data = dev_get_platdata(&plat_dev->dev);
struct clk *pclk = plat_data->pclk;
struct clk *hclk = plat_data->hclk;
clk_unregister(plat_data->pclk);
clk_unregister(plat_data->hclk);
platform_device_unregister(plat_dev);
clk_unregister_fixed_rate(pclk);
clk_unregister_fixed_rate(hclk);
}
static const struct pci_device_id dev_id_table[] = {
+24 -4
View File
@@ -977,19 +977,19 @@ static int ftgmac100_alloc_rings(struct ftgmac100 *priv)
priv->tx_skbs = kcalloc(MAX_TX_QUEUE_ENTRIES, sizeof(void *),
GFP_KERNEL);
if (!priv->tx_skbs)
return -ENOMEM;
goto err_free_rx_skbs;
/* Allocate descriptors */
priv->rxdes = dma_alloc_coherent(priv->dev,
MAX_RX_QUEUE_ENTRIES * sizeof(struct ftgmac100_rxdes),
&priv->rxdes_dma, GFP_KERNEL);
if (!priv->rxdes)
return -ENOMEM;
goto err_free_tx_skbs;
priv->txdes = dma_alloc_coherent(priv->dev,
MAX_TX_QUEUE_ENTRIES * sizeof(struct ftgmac100_txdes),
&priv->txdes_dma, GFP_KERNEL);
if (!priv->txdes)
return -ENOMEM;
goto err_free_rxdes;
/* Allocate scratch packet buffer */
priv->rx_scratch = dma_alloc_coherent(priv->dev,
@@ -997,9 +997,29 @@ static int ftgmac100_alloc_rings(struct ftgmac100 *priv)
&priv->rx_scratch_dma,
GFP_KERNEL);
if (!priv->rx_scratch)
return -ENOMEM;
goto err_free_txdes;
return 0;
err_free_txdes:
dma_free_coherent(priv->dev,
MAX_TX_QUEUE_ENTRIES *
sizeof(struct ftgmac100_txdes),
priv->txdes, priv->txdes_dma);
priv->txdes = NULL;
err_free_rxdes:
dma_free_coherent(priv->dev,
MAX_RX_QUEUE_ENTRIES *
sizeof(struct ftgmac100_rxdes),
priv->rxdes, priv->rxdes_dma);
priv->rxdes = NULL;
err_free_tx_skbs:
kfree(priv->tx_skbs);
priv->tx_skbs = NULL;
err_free_rx_skbs:
kfree(priv->rx_skbs);
priv->rx_skbs = NULL;
return -ENOMEM;
}
static void ftgmac100_init_rings(struct ftgmac100 *priv)
+12 -1
View File
@@ -2578,6 +2578,7 @@ EXPORT_SYMBOL_GPL(enetc_free_si_resources);
static void enetc_setup_txbdr(struct enetc_hw *hw, struct enetc_bdr *tx_ring)
{
struct enetc_si *si = container_of(hw, struct enetc_si, hw);
int idx = tx_ring->index;
u32 tbmr;
@@ -2591,10 +2592,20 @@ static void enetc_setup_txbdr(struct enetc_hw *hw, struct enetc_bdr *tx_ring)
enetc_txbdr_wr(hw, idx, ENETC_TBLENR,
ENETC_RTBLENR_LEN(tx_ring->bd_count));
/* clearing PI/CI registers for Tx not supported, adjust sw indexes */
/* For ENETC v1, clearing PI/CI registers for Tx not supported,
* adjust sw indexes
*/
tx_ring->next_to_use = enetc_txbdr_rd(hw, idx, ENETC_TBPIR);
tx_ring->next_to_clean = enetc_txbdr_rd(hw, idx, ENETC_TBCIR);
if (tx_ring->next_to_use != tx_ring->next_to_clean &&
!is_enetc_rev1(si)) {
tx_ring->next_to_use = 0;
tx_ring->next_to_clean = 0;
enetc_txbdr_wr(hw, idx, ENETC_TBPIR, 0);
enetc_txbdr_wr(hw, idx, ENETC_TBCIR, 0);
}
/* enable Tx ints by setting pkt thr to 1 */
enetc_txbdr_wr(hw, idx, ENETC_TBICR0, ENETC_TBICR0_ICEN | 0x1);
@@ -134,6 +134,12 @@
/* Port operational register */
#define ENETC4_POR 0x4100
#define POR_TXDIS BIT(0)
#define POR_RXDIS BIT(1)
/* Port status register */
#define ENETC4_PSR 0x4104
#define PSR_RX_BUSY BIT(1)
/* Port traffic class a transmit maximum SDU register */
#define ENETC4_PTCTMSDUR(a) ((a) * 0x20 + 0x4208)
@@ -173,6 +179,11 @@
/* Port internal MDIO base address, use to access PCS */
#define ENETC4_PM_IMDIO_BASE 0x5030
/* Port MAC 0/1 Interrupt Event Register */
#define ENETC4_PM_IEVENT(mac) (0x5040 + (mac) * 0x400)
#define PM_IEVENT_TX_EMPTY BIT(5)
#define PM_IEVENT_RX_EMPTY BIT(6)
/* Port MAC 0/1 Pause Quanta Register */
#define ENETC4_PM_PAUSE_QUANTA(mac) (0x5054 + (mac) * 0x400)
+104 -14
View File
@@ -444,20 +444,11 @@ static void enetc4_set_trx_frame_size(struct enetc_pf *pf)
enetc4_pf_reset_tc_msdu(&si->hw);
}
static void enetc4_enable_trx(struct enetc_pf *pf)
{
struct enetc_hw *hw = &pf->si->hw;
/* Enable port transmit/receive */
enetc_port_wr(hw, ENETC4_POR, 0);
}
static void enetc4_configure_port(struct enetc_pf *pf)
{
enetc4_configure_port_si(pf);
enetc4_set_trx_frame_size(pf);
enetc_set_default_rss_key(pf);
enetc4_enable_trx(pf);
}
static int enetc4_init_ntmp_user(struct enetc_si *si)
@@ -801,15 +792,112 @@ static void enetc4_set_tx_pause(struct enetc_pf *pf, int num_rxbdr, bool tx_paus
enetc_port_wr(hw, ENETC4_PPAUOFFTR, pause_off_thresh);
}
static void enetc4_enable_mac(struct enetc_pf *pf, bool en)
static void enetc4_mac_wait_tx_empty(struct enetc_si *si, int mac)
{
u32 val;
if (read_poll_timeout(enetc_port_rd, val,
val & PM_IEVENT_TX_EMPTY,
100, 10000, false, &si->hw,
ENETC4_PM_IEVENT(mac)))
dev_warn(&si->pdev->dev,
"MAC %d TX is not empty\n", mac);
}
static void enetc4_mac_tx_graceful_stop(struct enetc_pf *pf)
{
struct enetc_hw *hw = &pf->si->hw;
struct enetc_si *si = pf->si;
u32 val;
val = enetc_port_rd(hw, ENETC4_POR);
val |= POR_TXDIS;
enetc_port_wr(hw, ENETC4_POR, val);
if (enetc_is_pseudo_mac(si))
return;
enetc4_mac_wait_tx_empty(si, 0);
if (si->hw_features & ENETC_SI_F_QBU)
enetc4_mac_wait_tx_empty(si, 1);
val = enetc_port_mac_rd(si, ENETC4_PM_CMD_CFG(0));
val &= ~PM_CMD_CFG_TX_EN;
enetc_port_mac_wr(si, ENETC4_PM_CMD_CFG(0), val);
}
static void enetc4_mac_tx_enable(struct enetc_pf *pf)
{
struct enetc_hw *hw = &pf->si->hw;
struct enetc_si *si = pf->si;
u32 val;
val = enetc_port_mac_rd(si, ENETC4_PM_CMD_CFG(0));
val &= ~(PM_CMD_CFG_TX_EN | PM_CMD_CFG_RX_EN);
val |= en ? (PM_CMD_CFG_TX_EN | PM_CMD_CFG_RX_EN) : 0;
val |= PM_CMD_CFG_TX_EN;
enetc_port_mac_wr(si, ENETC4_PM_CMD_CFG(0), val);
val = enetc_port_rd(hw, ENETC4_POR);
val &= ~POR_TXDIS;
enetc_port_wr(hw, ENETC4_POR, val);
}
static void enetc4_mac_wait_rx_empty(struct enetc_si *si, int mac)
{
u32 val;
if (read_poll_timeout(enetc_port_rd, val,
val & PM_IEVENT_RX_EMPTY,
100, 10000, false, &si->hw,
ENETC4_PM_IEVENT(mac)))
dev_warn(&si->pdev->dev,
"MAC %d RX is not empty\n", mac);
}
static void enetc4_mac_rx_graceful_stop(struct enetc_pf *pf)
{
struct enetc_hw *hw = &pf->si->hw;
struct enetc_si *si = pf->si;
u32 val;
if (enetc_is_pseudo_mac(si))
goto check_rx_busy;
if (si->hw_features & ENETC_SI_F_QBU) {
val = enetc_port_rd(hw, ENETC4_PM_CMD_CFG(1));
val &= ~PM_CMD_CFG_RX_EN;
enetc_port_wr(hw, ENETC4_PM_CMD_CFG(1), val);
enetc4_mac_wait_rx_empty(si, 1);
}
val = enetc_port_rd(hw, ENETC4_PM_CMD_CFG(0));
val &= ~PM_CMD_CFG_RX_EN;
enetc_port_wr(hw, ENETC4_PM_CMD_CFG(0), val);
enetc4_mac_wait_rx_empty(si, 0);
check_rx_busy:
if (read_poll_timeout(enetc_port_rd, val,
!(val & PSR_RX_BUSY),
100, 10000, false, hw,
ENETC4_PSR))
dev_warn(&si->pdev->dev, "Port RX busy\n");
val = enetc_port_rd(hw, ENETC4_POR);
val |= POR_RXDIS;
enetc_port_wr(hw, ENETC4_POR, val);
}
static void enetc4_mac_rx_enable(struct enetc_pf *pf)
{
struct enetc_hw *hw = &pf->si->hw;
struct enetc_si *si = pf->si;
u32 val;
val = enetc_port_rd(hw, ENETC4_POR);
val &= ~POR_RXDIS;
enetc_port_wr(hw, ENETC4_POR, val);
val = enetc_port_mac_rd(si, ENETC4_PM_CMD_CFG(0));
val |= PM_CMD_CFG_RX_EN;
enetc_port_mac_wr(si, ENETC4_PM_CMD_CFG(0), val);
}
@@ -853,7 +941,8 @@ static void enetc4_pl_mac_link_up(struct phylink_config *config,
enetc4_set_hd_flow_control(pf, hd_fc);
enetc4_set_tx_pause(pf, priv->num_rx_rings, tx_pause);
enetc4_set_rx_pause(pf, rx_pause);
enetc4_enable_mac(pf, true);
enetc4_mac_tx_enable(pf);
enetc4_mac_rx_enable(pf);
}
static void enetc4_pl_mac_link_down(struct phylink_config *config,
@@ -862,7 +951,8 @@ static void enetc4_pl_mac_link_down(struct phylink_config *config,
{
struct enetc_pf *pf = phylink_to_enetc_pf(config);
enetc4_enable_mac(pf, false);
enetc4_mac_rx_graceful_stop(pf);
enetc4_mac_tx_graceful_stop(pf);
}
static const struct phylink_mac_ops enetc_pl_mac_ops = {
@@ -795,9 +795,17 @@ static int enetc_set_rxfh(struct net_device *ndev,
struct enetc_si *si = priv->si;
int err = 0;
if (rxfh->hfunc != ETH_RSS_HASH_NO_CHANGE &&
rxfh->hfunc != ETH_RSS_HASH_TOP)
return -EOPNOTSUPP;
/* set hash key, if PF */
if (rxfh->key && enetc_si_is_pf(si))
if (rxfh->key) {
if (!enetc_si_is_pf(si))
return -EOPNOTSUPP;
enetc_set_rss_key(si, rxfh->key);
}
/* set RSS table */
if (rxfh->indir)
-3
View File
@@ -545,9 +545,6 @@ static int fec_ptp_enable(struct ptp_clock_info *ptp,
if (rq->perout.flags)
return -EOPNOTSUPP;
if (rq->perout.index != fep->pps_channel)
return -EOPNOTSUPP;
period.tv_sec = rq->perout.period.sec;
period.tv_nsec = rq->perout.period.nsec;
period_ns = timespec64_to_ns(&period);
@@ -244,6 +244,25 @@ out:
return 0;
}
static bool
mtk_flow_is_valid_idev(const struct mtk_eth *eth, const struct net_device *idev)
{
size_t i;
if (!idev)
return false;
for (i = 0; i < ARRAY_SIZE(eth->netdev); i++) {
if (!eth->netdev[i])
continue;
if (idev->netdev_ops == eth->netdev[i]->netdev_ops)
return true;
}
return false;
}
static int
mtk_flow_offload_replace(struct mtk_eth *eth, struct flow_cls_offload *f,
int ppe_index)
@@ -270,7 +289,7 @@ mtk_flow_offload_replace(struct mtk_eth *eth, struct flow_cls_offload *f,
flow_rule_match_meta(rule, &match);
if (mtk_is_netsys_v2_or_greater(eth)) {
idev = __dev_get_by_index(&init_net, match.key->ingress_ifindex);
if (idev && idev->netdev_ops == eth->netdev[0]->netdev_ops) {
if (mtk_flow_is_valid_idev(eth, idev)) {
struct mtk_mac *mac = netdev_priv(idev);
if (WARN_ON(mac->ppe_idx >= eth->soc->ppe_num))
@@ -107,9 +107,7 @@ mlx5_devlink_info_get(struct devlink *devlink, struct devlink_info_req *req,
if (err)
return err;
err = mlx5_fw_version_query(dev, &running_fw, &stored_fw);
if (err)
return err;
mlx5_fw_version_query(dev, &running_fw, &stored_fw);
snprintf(version_str, sizeof(version_str), "%d.%d.%04d",
mlx5_fw_ver_major(running_fw), mlx5_fw_ver_minor(running_fw),
@@ -3761,6 +3761,8 @@ int esw_offloads_enable(struct mlx5_eswitch *esw)
return 0;
err_vports:
/* rollback to legacy, indicates don't unregister the uplink netdev */
esw->dev->priv.flags |= MLX5_PRIV_FLAGS_SWITCH_LEGACY;
mlx5_esw_offloads_rep_unload(esw, MLX5_VPORT_UPLINK);
err_uplink:
esw_offloads_steering_cleanup(esw);

Some files were not shown because too many files have changed in this diff Show More