mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-16 17:57:38 -04: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:
3
.mailmap
3
.mailmap
@@ -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
|
||||
================================
|
||||
|
||||
|
||||
@@ -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 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
|
||||
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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 @@ static int npc_priv_init(struct rvu *rvu)
|
||||
fail1:
|
||||
kfree(npc_priv);
|
||||
npc_priv = NULL;
|
||||
return -ENOMEM;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void npc_cn20k_deinit(struct rvu *rvu)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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 @@ int cn10k_mcs_init(struct otx2_nic *pfvf)
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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};
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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 @@ static int irq_setup(unsigned int *irqs, unsigned int len, int node,
|
||||
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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)))
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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},
|
||||
},
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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];
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -1063,6 +1063,9 @@ static int t7xx_cldma_late_init(struct cldma_ctrl *md_ctrl)
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -101,7 +101,8 @@ void afs_process_oob_queue(struct work_struct *work)
|
||||
struct sk_buff *oob;
|
||||
enum rxrpc_oob_type type;
|
||||
|
||||
while ((oob = rxrpc_kernel_dequeue_oob(net->socket, &type))) {
|
||||
while (READ_ONCE(net->live) &&
|
||||
(oob = rxrpc_kernel_dequeue_oob(net->socket, &type))) {
|
||||
switch (type) {
|
||||
case RXRPC_OOB_CHALLENGE:
|
||||
afs_respond_to_challenge(oob);
|
||||
|
||||
@@ -128,8 +128,14 @@ void afs_close_socket(struct afs_net *net)
|
||||
_enter("");
|
||||
|
||||
cancel_work_sync(&net->charge_preallocation_work);
|
||||
cancel_work_sync(&net->rx_oob_work);
|
||||
/* Future work items should now see ->live is false. */
|
||||
|
||||
kernel_listen(net->socket, 0);
|
||||
|
||||
/* Make sure work items are no longer running. */
|
||||
flush_workqueue(afs_async_calls);
|
||||
cancel_work_sync(&net->charge_preallocation_work);
|
||||
|
||||
if (net->spare_incoming_call) {
|
||||
afs_put_call(net->spare_incoming_call);
|
||||
@@ -143,6 +149,7 @@ void afs_close_socket(struct afs_net *net)
|
||||
|
||||
kernel_sock_shutdown(net->socket, SHUT_RDWR);
|
||||
flush_workqueue(afs_async_calls);
|
||||
cancel_work_sync(&net->rx_oob_work);
|
||||
net->socket->sk->sk_user_data = NULL;
|
||||
sock_release(net->socket);
|
||||
key_put(net->fs_cm_token_key);
|
||||
@@ -984,5 +991,6 @@ static void afs_rx_notify_oob(struct sock *sk, struct sk_buff *oob)
|
||||
{
|
||||
struct afs_net *net = sk->sk_user_data;
|
||||
|
||||
schedule_work(&net->rx_oob_work);
|
||||
if (READ_ONCE(net->live))
|
||||
queue_work(afs_wq, &net->rx_oob_work);
|
||||
}
|
||||
|
||||
@@ -942,6 +942,7 @@ struct kernel_ethtool_ts_info {
|
||||
#define ETHTOOL_OP_NEEDS_RTNL_GPAUSEPARAM BIT(5)
|
||||
#define ETHTOOL_OP_NEEDS_RTNL_SPAUSEPARAM BIT(6)
|
||||
#define ETHTOOL_OP_NEEDS_RTNL_RSS BIT(7)
|
||||
#define ETHTOOL_OP_NEEDS_RTNL_GLINK BIT(8)
|
||||
|
||||
/**
|
||||
* struct ethtool_ops - optional netdev operations
|
||||
@@ -978,6 +979,7 @@ struct kernel_ethtool_ts_info {
|
||||
* - phylink helpers (note that phydev is currently unsupported!)
|
||||
* - netdev_update_features()
|
||||
* - netif_set_real_num_tx_queues()
|
||||
* - ethtool_op_get_link() (syncs link watch under rtnl_lock)
|
||||
*
|
||||
* @get_drvinfo: Report driver/device information. Modern drivers no
|
||||
* longer have to implement this callback. Most fields are
|
||||
|
||||
@@ -1131,6 +1131,9 @@ struct netdev_net_notifier {
|
||||
* netdev_hw_addr_list_for_each(ha, uc). Return 0 on success or a
|
||||
* negative errno to request a retry via the core backoff.
|
||||
*
|
||||
* void (*ndo_work)(struct net_device *dev, unsigned long events);
|
||||
* Run deferred work scheduled with netdev_work_sched(@events).
|
||||
*
|
||||
* int (*ndo_set_mac_address)(struct net_device *dev, void *addr);
|
||||
* This function is called when the Media Access Control address
|
||||
* needs to be changed. If this interface is not defined, the
|
||||
@@ -1460,6 +1463,8 @@ struct net_device_ops {
|
||||
struct net_device *dev,
|
||||
struct netdev_hw_addr_list *uc,
|
||||
struct netdev_hw_addr_list *mc);
|
||||
void (*ndo_work)(struct net_device *dev,
|
||||
unsigned long events);
|
||||
int (*ndo_set_mac_address)(struct net_device *dev,
|
||||
void *addr);
|
||||
int (*ndo_validate_addr)(struct net_device *dev);
|
||||
@@ -1930,8 +1935,11 @@ enum netdev_reg_state {
|
||||
* has been enabled due to the need to listen to
|
||||
* additional unicast addresses in a device that
|
||||
* does not implement ndo_set_rx_mode()
|
||||
* @rx_mode_node: List entry for rx_mode work processing
|
||||
* @rx_mode_tracker: Refcount tracker for rx_mode work
|
||||
* @work_node: List entry for async netdev_work processing
|
||||
* @work_tracker: Refcount tracker for async netdev_work
|
||||
* @work_pending: Driver-defined pending netdev_work, passed to
|
||||
* ndo_work() (see netdev_work_sched())
|
||||
* @work_core_pending: Core-defined pending netdev_work (NETDEV_WORK_*)
|
||||
* @rx_mode_addr_cache: Recycled snapshot entries for rx_mode work
|
||||
* @rx_mode_retry_timer: Timer that re-queues rx_mode work after failure
|
||||
* @rx_mode_retry_count: Number of consecutive retries already scheduled
|
||||
@@ -2326,8 +2334,10 @@ struct net_device {
|
||||
unsigned int promiscuity;
|
||||
unsigned int allmulti;
|
||||
bool uc_promisc;
|
||||
struct list_head rx_mode_node;
|
||||
netdevice_tracker rx_mode_tracker;
|
||||
struct list_head work_node;
|
||||
netdevice_tracker work_tracker;
|
||||
unsigned long work_pending;
|
||||
unsigned long work_core_pending;
|
||||
struct netdev_hw_addr_list rx_mode_addr_cache;
|
||||
struct timer_list rx_mode_retry_timer;
|
||||
unsigned int rx_mode_retry_count;
|
||||
@@ -5176,6 +5186,9 @@ void dev_fetch_sw_netstats(struct rtnl_link_stats64 *s,
|
||||
const struct pcpu_sw_netstats __percpu *netstats);
|
||||
void dev_get_tstats64(struct net_device *dev, struct rtnl_link_stats64 *s);
|
||||
|
||||
void netdev_work_sched(struct net_device *dev, unsigned long events);
|
||||
unsigned long netdev_work_cancel(struct net_device *dev, unsigned long mask);
|
||||
|
||||
enum {
|
||||
NESTED_SYNC_IMM_BIT,
|
||||
NESTED_SYNC_TODO_BIT,
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
* @match: the match extension
|
||||
* @target: the target extension
|
||||
* @matchinfo: per-match data
|
||||
* @targetinfo: per-target data
|
||||
* @targinfo: per-target data
|
||||
* @state: pointer to hook state this packet came from
|
||||
* @fragoff: packet is a fragment, this is the data offset
|
||||
* @thoff: position of transport header relative to skb->data
|
||||
@@ -77,7 +77,9 @@ static inline u_int8_t xt_family(const struct xt_action_param *par)
|
||||
* @match: struct xt_match through which this function was invoked
|
||||
* @matchinfo: per-match data
|
||||
* @hook_mask: via which hooks the new rule is reachable
|
||||
* Other fields as above.
|
||||
* @family: actual NFPROTO_* through which the function is invoked
|
||||
* (helpful when match->family == NFPROTO_UNSPEC)
|
||||
* @nft_compat: running from the nft compat layer if true
|
||||
*/
|
||||
struct xt_mtchk_param {
|
||||
struct net *net;
|
||||
@@ -91,8 +93,13 @@ struct xt_mtchk_param {
|
||||
};
|
||||
|
||||
/**
|
||||
* struct xt_mdtor_param - match destructor parameters
|
||||
* Fields as above.
|
||||
* struct xt_mtdtor_param - match destructor parameters
|
||||
*
|
||||
* @net: network namespace through which the check was invoked
|
||||
* @match: struct xt_match through which this function was invoked
|
||||
* @matchinfo: per-match data
|
||||
* @family: actual NFPROTO_* through which the function is invoked
|
||||
* (helpful when match->family == NFPROTO_UNSPEC)
|
||||
*/
|
||||
struct xt_mtdtor_param {
|
||||
struct net *net;
|
||||
@@ -105,10 +112,16 @@ struct xt_mtdtor_param {
|
||||
* struct xt_tgchk_param - parameters for target extensions'
|
||||
* checkentry functions
|
||||
*
|
||||
* @net: network namespace through which the check was invoked
|
||||
* @table: table the rule is tried to be inserted into
|
||||
* @entryinfo: the family-specific rule data
|
||||
* (struct ipt_entry, ip6t_entry, arpt_entry, ebt_entry)
|
||||
*
|
||||
* Other fields see above.
|
||||
* @target: the target extension
|
||||
* @targinfo: per-target data
|
||||
* @hook_mask: via which hooks the new rule is reachable
|
||||
* @family: actual NFPROTO_* through which the function is invoked
|
||||
* (helpful when match->family == NFPROTO_UNSPEC)
|
||||
* @nft_compat: running from the nft compat layer if true
|
||||
*/
|
||||
struct xt_tgchk_param {
|
||||
struct net *net;
|
||||
@@ -336,9 +349,9 @@ struct xt_table_info *xt_alloc_table_info(unsigned int size);
|
||||
void xt_free_table_info(struct xt_table_info *info);
|
||||
|
||||
/**
|
||||
* xt_recseq - recursive seqcount for netfilter use
|
||||
* var xt_recseq - recursive seqcount for netfilter use
|
||||
*
|
||||
* Packet processing changes the seqcount only if no recursion happened
|
||||
* Packet processing changes the seqcount only if no recursion happened.
|
||||
* get_counters() can use read_seqcount_begin()/read_seqcount_retry(),
|
||||
* because we use the normal seqcount convention :
|
||||
* Low order bit set to 1 if a writer is active.
|
||||
|
||||
@@ -164,8 +164,11 @@ static inline struct metadata_dst *tun_dst_unclone(struct sk_buff *skb)
|
||||
if (!new_md)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
memcpy(&new_md->u.tun_info, &md_dst->u.tun_info,
|
||||
sizeof(struct ip_tunnel_info) + md_size);
|
||||
/* Copy in two stages to keep the __counted_by happy. */
|
||||
new_md->u.tun_info = md_dst->u.tun_info;
|
||||
memcpy(ip_tunnel_info_opts(&new_md->u.tun_info),
|
||||
ip_tunnel_info_opts(&md_dst->u.tun_info), md_size);
|
||||
|
||||
#ifdef CONFIG_DST_CACHE
|
||||
/* Unclone the dst cache if there is one */
|
||||
if (new_md->u.tun_info.dst_cache.cache) {
|
||||
|
||||
@@ -374,7 +374,7 @@ static inline int fib_lookup(struct net *net, struct flowi4 *flp,
|
||||
struct fib_result *res, unsigned int flags)
|
||||
{
|
||||
struct fib_table *tb;
|
||||
int err = -ENETUNREACH;
|
||||
int err = -EAGAIN;
|
||||
|
||||
flags |= FIB_LOOKUP_NOREF;
|
||||
if (net->ipv4.fib_has_custom_rules)
|
||||
@@ -388,17 +388,16 @@ static inline int fib_lookup(struct net *net, struct flowi4 *flp,
|
||||
if (tb)
|
||||
err = fib_table_lookup(tb, flp, res, flags);
|
||||
|
||||
if (!err)
|
||||
if (err != -EAGAIN)
|
||||
goto out;
|
||||
|
||||
tb = rcu_dereference_rtnl(net->ipv4.fib_default);
|
||||
if (tb)
|
||||
err = fib_table_lookup(tb, flp, res, flags);
|
||||
|
||||
out:
|
||||
if (err == -EAGAIN)
|
||||
err = -ENETUNREACH;
|
||||
|
||||
out:
|
||||
rcu_read_unlock();
|
||||
|
||||
return err;
|
||||
|
||||
@@ -26,6 +26,7 @@ struct nf_conntrack_expect {
|
||||
possible_net_t net;
|
||||
|
||||
/* We expect this tuple, with the following mask */
|
||||
struct nf_conntrack_tuple master_tuple;
|
||||
struct nf_conntrack_tuple tuple;
|
||||
struct nf_conntrack_tuple_mask mask;
|
||||
|
||||
@@ -54,8 +55,8 @@ struct nf_conntrack_expect {
|
||||
/* The conntrack of the master connection */
|
||||
struct nf_conn *master;
|
||||
|
||||
/* Timer function; deletes the expectation. */
|
||||
struct timer_list timeout;
|
||||
/* jiffies32 when this expectation expires */
|
||||
u32 timeout;
|
||||
|
||||
#if IS_ENABLED(CONFIG_NF_NAT)
|
||||
union nf_inet_addr saved_addr;
|
||||
@@ -69,6 +70,14 @@ struct nf_conntrack_expect {
|
||||
struct rcu_head rcu;
|
||||
};
|
||||
|
||||
static inline bool nf_ct_exp_is_expired(const struct nf_conntrack_expect *exp)
|
||||
{
|
||||
if (READ_ONCE(exp->flags) & NF_CT_EXPECT_DEAD)
|
||||
return true;
|
||||
|
||||
return (__s32)(READ_ONCE(exp->timeout) - nfct_time_stamp) <= 0;
|
||||
}
|
||||
|
||||
static inline struct net *nf_ct_exp_net(struct nf_conntrack_expect *exp)
|
||||
{
|
||||
return read_pnet(&exp->net);
|
||||
@@ -130,7 +139,6 @@ static inline void nf_ct_unlink_expect(struct nf_conntrack_expect *exp)
|
||||
|
||||
void nf_ct_remove_expectations(struct nf_conn *ct);
|
||||
void nf_ct_unexpect_related(struct nf_conntrack_expect *exp);
|
||||
bool nf_ct_remove_expect(struct nf_conntrack_expect *exp);
|
||||
|
||||
void nf_ct_expect_iterate_destroy(bool (*iter)(struct nf_conntrack_expect *e, void *data), void *data);
|
||||
void nf_ct_expect_iterate_net(struct net *net,
|
||||
@@ -153,5 +161,8 @@ static inline int nf_ct_expect_related(struct nf_conntrack_expect *expect,
|
||||
return nf_ct_expect_related_report(expect, 0, 0, flags);
|
||||
}
|
||||
|
||||
struct nf_conn_help;
|
||||
void nf_ct_expectation_gc(struct nf_conn_help *master_help);
|
||||
|
||||
#endif /*_NF_CONNTRACK_EXPECT_H*/
|
||||
|
||||
|
||||
@@ -114,6 +114,10 @@ int nf_conntrack_helpers_register(struct nf_conntrack_helper *, unsigned int,
|
||||
void nf_conntrack_helpers_unregister(struct nf_conntrack_helper **,
|
||||
unsigned int);
|
||||
|
||||
#define nf_conntrack_helper_deprecated(name) \
|
||||
pr_warn("The %s conntrack helper is scheduled for removal.\n" \
|
||||
"Please contact the netfilter-devel mailing list if you still need this.\n", name)
|
||||
|
||||
struct nf_conn_help *nf_ct_helper_ext_add(struct nf_conn *ct, gfp_t gfp);
|
||||
|
||||
int __nf_ct_try_assign_helper(struct nf_conn *ct, struct nf_conn *tmpl,
|
||||
|
||||
@@ -18,6 +18,7 @@ struct nf_queue_entry {
|
||||
unsigned int id;
|
||||
unsigned int hook_index; /* index in hook_entries->hook[] */
|
||||
#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
|
||||
struct net_device *bridge_dev;
|
||||
struct net_device *physin;
|
||||
struct net_device *physout;
|
||||
#endif
|
||||
|
||||
@@ -40,6 +40,8 @@ void nft_meta_set_eval(const struct nft_expr *expr,
|
||||
void nft_meta_set_destroy(const struct nft_ctx *ctx,
|
||||
const struct nft_expr *expr);
|
||||
|
||||
int nft_meta_get_validate(const struct nft_ctx *ctx,
|
||||
const struct nft_expr *expr);
|
||||
int nft_meta_set_validate(const struct nft_ctx *ctx,
|
||||
const struct nft_expr *expr);
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user