mirror of
https://github.com/linux-msm/laptops-kernel.git
synced 2026-08-13 14:19:53 -07:00
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
...
This commit is contained in:
@@ -530,7 +530,8 @@ Luca Ceresoli <luca.ceresoli@bootlin.com> <luca@lucaceresoli.net>
|
||||
Luca Weiss <luca@lucaweiss.eu> <luca@z3ntu.xyz>
|
||||
Lucas De Marchi <demarchi@kernel.org> <lucas.demarchi@intel.com>
|
||||
Lukasz Luba <lukasz.luba@arm.com> <l.luba@partner.samsung.com>
|
||||
Luo Jie <quic_luoj@quicinc.com> <luoj@codeaurora.org>
|
||||
Luo Jie <jie.luo@oss.qualcomm.com> <luoj@codeaurora.org>
|
||||
Luo Jie <jie.luo@oss.qualcomm.com> <quic_luoj@quicinc.com>
|
||||
Lance Yang <lance.yang@linux.dev> <ioworker0@gmail.com>
|
||||
Lance Yang <lance.yang@linux.dev> <mingzhe.yang@ly.com>
|
||||
Maciej W. Rozycki <macro@mips.com> <macro@imgtec.com>
|
||||
|
||||
@@ -8,7 +8,7 @@ title: Qualcomm CMN PLL Clock Controller on IPQ SoC
|
||||
|
||||
maintainers:
|
||||
- Bjorn Andersson <andersson@kernel.org>
|
||||
- Luo Jie <quic_luoj@quicinc.com>
|
||||
- Luo Jie <jie.luo@oss.qualcomm.com>
|
||||
|
||||
description:
|
||||
The CMN (or common) PLL clock controller expects a reference
|
||||
|
||||
@@ -8,7 +8,7 @@ title: Qualcomm NSS Clock & Reset Controller on QCA8386/QCA8084
|
||||
|
||||
maintainers:
|
||||
- Bjorn Andersson <andersson@kernel.org>
|
||||
- Luo Jie <quic_luoj@quicinc.com>
|
||||
- Luo Jie <jie.luo@oss.qualcomm.com>
|
||||
|
||||
description: |
|
||||
Qualcomm NSS clock control module provides the clocks and resets
|
||||
|
||||
@@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
title: Qualcomm IPQ packet process engine (PPE)
|
||||
|
||||
maintainers:
|
||||
- Luo Jie <quic_luoj@quicinc.com>
|
||||
- Luo Jie <jie.luo@oss.qualcomm.com>
|
||||
- Lei Wei <quic_leiwei@quicinc.com>
|
||||
- Suruchi Agarwal <quic_suruchia@quicinc.com>
|
||||
- Pavithra R <quic_pavir@quicinc.com>
|
||||
|
||||
@@ -121,8 +121,7 @@ examples:
|
||||
#size-cells = <0>;
|
||||
|
||||
phy1: ethernet-phy@1 {
|
||||
compatible = "ethernet-phy-id0022.1537",
|
||||
"ethernet-phy-ieee802.3-c22";
|
||||
compatible = "ethernet-phy-id0022.1537";
|
||||
reg = <1>;
|
||||
interrupt-parent = <&irqc0>;
|
||||
interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
|
||||
@@ -433,6 +433,8 @@ exceptions) notifiers run under the instance lock. Please extend this
|
||||
documentation whenever you make explicit assumption about lock being held
|
||||
from a notifier.
|
||||
|
||||
Drivers **must not** generate nested notifications of the ops-locked types.
|
||||
|
||||
NETDEV_INTERNAL symbol namespace
|
||||
================================
|
||||
|
||||
|
||||
+3
-4
@@ -22323,9 +22323,9 @@ F: Documentation/devicetree/bindings/power/supply/qcom,pmi8998-charger.yaml
|
||||
F: drivers/power/supply/qcom_smbx.c
|
||||
|
||||
QUALCOMM PPE DRIVER
|
||||
M: Luo Jie <quic_luoj@quicinc.com>
|
||||
M: Luo Jie <jie.luo@oss.qualcomm.com>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Supported
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/net/qcom,ipq9574-ppe.yaml
|
||||
F: Documentation/networking/device_drivers/ethernet/qualcomm/ppe/ppe.rst
|
||||
F: drivers/net/ethernet/qualcomm/ppe/
|
||||
@@ -26001,9 +26001,8 @@ S: Maintained
|
||||
F: drivers/net/ethernet/dlink/sundance.c
|
||||
|
||||
SUNPLUS ETHERNET DRIVER
|
||||
M: Wells Lu <wellslutw@gmail.com>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
S: Orphan
|
||||
W: https://sunplus.atlassian.net/wiki/spaces/doc/overview
|
||||
F: Documentation/devicetree/bindings/net/sunplus,sp7021-emac.yaml
|
||||
F: drivers/net/ethernet/sunplus/
|
||||
|
||||
@@ -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]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
q->queued--;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
/* 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));
|
||||
|
||||
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, ð->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(ð->qdma[i]);
|
||||
airoha_qdma_cleanup(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(ð->qdma[i]);
|
||||
airoha_qdma_cleanup(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(ð->qdma[i]);
|
||||
airoha_qdma_set(ð->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(ð->qdma[i]);
|
||||
airoha_qdma_tx_cleanup(ð->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(ð->qdma[i]);
|
||||
airoha_qdma_tx_cleanup(ð->qdma[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
|
||||
struct airoha_gdm_port *port = eth->ports[i];
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user