mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/
synced 2025-04-19 20:58:31 +09:00
Including fixes from Bluetooth, CAN and Netfilter.
Current release - regressions: - 2 fixes for the netdev per-instance locking - batman-adv: fix double-hold of meshif when getting enabled Current release - new code bugs: - Bluetooth: increment TX timestamping tskey always for stream sockets - wifi: static analysis and build fixes for the new Intel sub-driver Previous releases - regressions: - net: fib_rules: fix iif / oif matching on L3 master (VRF) device - ipv6: add exception routes to GC list in rt6_insert_exception() - netfilter: conntrack: fix erroneous removal of offload bit - Bluetooth: - fix sending MGMT_EV_DEVICE_FOUND for invalid address - l2cap: process valid commands in too long frame - btnxpuart: Revert baudrate change in nxp_shutdown Previous releases - always broken: - ethtool: fix memory corruption during SFP FW flashing - eth: hibmcge: fixes for link and MTU handling, pause frames etc. - eth: igc: fixes for PTM (PCIe timestamping) - dsa: b53: enable BPDU reception for management port Misc: - fixes for Netlink protocol schemas Signed-off-by: Jakub Kicinski <kuba@kernel.org> -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEE6jPA+I1ugmIBA4hXMUZtbf5SIrsFAmgBMWAACgkQMUZtbf5S Irv3kw//enBPRBMhTdXop2g9Rlw8zQEwuMinq9ytgiNbWxshd7wXHNDYKICaX8qK KkN4InxF4ieESHGNUy9/UvZLAEHYV8BqugdUGurwCnEg9QJlThsDmRCYTxI37Sdx 8uUYoSYWvPcHUsw3s/qBzunAZ8R/5hbP99L1M8W+3DqnJUm6qjUYjWCmm+8sn6FW abZ8JiazJhGKfTtIGxxN3oOJBzKcdeTK+z29ujQBWegnau8uj92QKkuoTZTtHaYL MU5pRyDQS5vo/wLBizTGQQ7PrcIpKgM1mi5Oayl5WbvTUF1pJ8pvT1iT7jnGOt4c lWPImtdQwsNwAwFNU7/S+YkBvrYBsCUPDErQ82HtxRsNXcCzKvuM4SqkvzYS5SZd Qz0ZuKqXbxxSgRgasvikWP6qAI8vz4zT8pjXu/a3eE5xnsSqhwXVbEwez8KqRF79 Cxm/iYz/m/NhYW59YSobssNHjGM4QgOu/dFr37EPCgf8BK//RLFckwQVA1qBogO/ HEwkWhQFYNJY0BDXuzO8rCPFQbs/NBiuNU0xRbKqPGkGcqKRwTd/KLOeTe/NJvtE mQx5R+VNVEyNdlQtXh5muEJHhN2nLYzQUTM5gkt6jwIzcLt7HVE+ZF3nkAKf1EQB 1nYN8gxCO1convTNT84Eldpp2At8zazz+ltnC9gWIEZhdTct46Q= =EObk -----END PGP SIGNATURE----- Merge tag 'net-6.15-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net Pull networking fixes from Jakub Kicinski: "Including fixes from Bluetooth, CAN and Netfilter. Current release - regressions: - two fixes for the netdev per-instance locking - batman-adv: fix double-hold of meshif when getting enabled Current release - new code bugs: - Bluetooth: increment TX timestamping tskey always for stream sockets - wifi: static analysis and build fixes for the new Intel sub-driver Previous releases - regressions: - net: fib_rules: fix iif / oif matching on L3 master (VRF) device - ipv6: add exception routes to GC list in rt6_insert_exception() - netfilter: conntrack: fix erroneous removal of offload bit - Bluetooth: - fix sending MGMT_EV_DEVICE_FOUND for invalid address - l2cap: process valid commands in too long frame - btnxpuart: Revert baudrate change in nxp_shutdown Previous releases - always broken: - ethtool: fix memory corruption during SFP FW flashing - eth: - hibmcge: fixes for link and MTU handling, pause frames etc - igc: fixes for PTM (PCIe timestamping) - dsa: b53: enable BPDU reception for management port Misc: - fixes for Netlink protocol schemas" * tag 'net-6.15-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (81 commits) net: ethernet: mtk_eth_soc: revise QDMA packet scheduler settings net: ethernet: mtk_eth_soc: correct the max weight of the queue limit for 100Mbps net: ethernet: mtk_eth_soc: reapply mdc divider on reset net: ti: icss-iep: Fix possible NULL pointer dereference for perout request net: ti: icssg-prueth: Fix possible NULL pointer dereference inside emac_xmit_xdp_frame() net: ti: icssg-prueth: Fix kernel warning while bringing down network interface netfilter: conntrack: fix erronous removal of offload bit net: don't try to ops lock uninitialized devs ptp: ocp: fix start time alignment in ptp_ocp_signal_set net: dsa: avoid refcount warnings when ds->ops->tag_8021q_vlan_del() fails net: dsa: free routing table on probe failure net: dsa: clean up FDB, MDB, VLAN entries on unbind net: dsa: mv88e6xxx: fix -ENOENT when deleting VLANs and MST is unsupported net: dsa: mv88e6xxx: avoid unregistering devlink regions which were never registered net: txgbe: fix memory leak in txgbe_probe() error path net: bridge: switchdev: do not notify new brentries as changed net: b53: enable BPDU reception for management port netlink: specs: rt-neigh: prefix struct nfmsg members with ndm netlink: specs: rt-link: adjust mctp attribute naming netlink: specs: rtnetlink: attribute naming corrections ...
This commit is contained in:
commit
b5c6891b2c
@ -123,12 +123,12 @@ attribute-sets:
|
||||
|
||||
operations:
|
||||
name-prefix: ovs-vport-cmd-
|
||||
fixed-header: ovs-header
|
||||
list:
|
||||
-
|
||||
name: new
|
||||
doc: Create a new OVS vport
|
||||
attribute-set: vport
|
||||
fixed-header: ovs-header
|
||||
do:
|
||||
request:
|
||||
attributes:
|
||||
@ -141,7 +141,6 @@ operations:
|
||||
name: del
|
||||
doc: Delete existing OVS vport from a data path
|
||||
attribute-set: vport
|
||||
fixed-header: ovs-header
|
||||
do:
|
||||
request:
|
||||
attributes:
|
||||
@ -152,7 +151,6 @@ operations:
|
||||
name: get
|
||||
doc: Get / dump OVS vport configuration and state
|
||||
attribute-set: vport
|
||||
fixed-header: ovs-header
|
||||
do: &vport-get-op
|
||||
request:
|
||||
attributes:
|
||||
|
@ -1113,11 +1113,10 @@ attribute-sets:
|
||||
-
|
||||
name: prop-list
|
||||
type: nest
|
||||
nested-attributes: link-attrs
|
||||
nested-attributes: prop-list-link-attrs
|
||||
-
|
||||
name: alt-ifname
|
||||
type: string
|
||||
multi-attr: true
|
||||
-
|
||||
name: perm-address
|
||||
type: binary
|
||||
@ -1163,6 +1162,13 @@ attribute-sets:
|
||||
-
|
||||
name: netns-immutable
|
||||
type: u8
|
||||
-
|
||||
name: prop-list-link-attrs
|
||||
subset-of: link-attrs
|
||||
attributes:
|
||||
-
|
||||
name: alt-ifname
|
||||
multi-attr: true
|
||||
-
|
||||
name: af-spec-attrs
|
||||
attributes:
|
||||
@ -1585,7 +1591,7 @@ attribute-sets:
|
||||
name: nf-call-iptables
|
||||
type: u8
|
||||
-
|
||||
name: nf-call-ip6-tables
|
||||
name: nf-call-ip6tables
|
||||
type: u8
|
||||
-
|
||||
name: nf-call-arptables
|
||||
@ -2077,7 +2083,7 @@ attribute-sets:
|
||||
name: id
|
||||
type: u16
|
||||
-
|
||||
name: flag
|
||||
name: flags
|
||||
type: binary
|
||||
struct: ifla-vlan-flags
|
||||
-
|
||||
@ -2165,7 +2171,7 @@ attribute-sets:
|
||||
type: binary
|
||||
struct: ifla-cacheinfo
|
||||
-
|
||||
name: icmp6-stats
|
||||
name: icmp6stats
|
||||
type: binary
|
||||
struct: ifla-icmp6-stats
|
||||
-
|
||||
@ -2179,9 +2185,10 @@ attribute-sets:
|
||||
type: u32
|
||||
-
|
||||
name: mctp-attrs
|
||||
name-prefix: ifla-mctp-
|
||||
attributes:
|
||||
-
|
||||
name: mctp-net
|
||||
name: net
|
||||
type: u32
|
||||
-
|
||||
name: phys-binding
|
||||
@ -2453,7 +2460,6 @@ operations:
|
||||
- min-mtu
|
||||
- max-mtu
|
||||
- prop-list
|
||||
- alt-ifname
|
||||
- perm-address
|
||||
- proto-down-reason
|
||||
- parent-dev-name
|
||||
|
@ -13,25 +13,25 @@ definitions:
|
||||
type: struct
|
||||
members:
|
||||
-
|
||||
name: family
|
||||
name: ndm-family
|
||||
type: u8
|
||||
-
|
||||
name: pad
|
||||
name: ndm-pad
|
||||
type: pad
|
||||
len: 3
|
||||
-
|
||||
name: ifindex
|
||||
name: ndm-ifindex
|
||||
type: s32
|
||||
-
|
||||
name: state
|
||||
name: ndm-state
|
||||
type: u16
|
||||
enum: nud-state
|
||||
-
|
||||
name: flags
|
||||
name: ndm-flags
|
||||
type: u8
|
||||
enum: ntf-flags
|
||||
-
|
||||
name: type
|
||||
name: ndm-type
|
||||
type: u8
|
||||
enum: rtm-type
|
||||
-
|
||||
@ -189,7 +189,7 @@ attribute-sets:
|
||||
type: binary
|
||||
display-hint: ipv4
|
||||
-
|
||||
name: lladr
|
||||
name: lladdr
|
||||
type: binary
|
||||
display-hint: mac
|
||||
-
|
||||
|
@ -6335,6 +6335,7 @@ F: Documentation/process/cve.rst
|
||||
|
||||
CW1200 WLAN driver
|
||||
S: Orphan
|
||||
L: linux-wireless@vger.kernel.org
|
||||
F: drivers/net/wireless/st/
|
||||
F: include/linux/platform_data/net-cw1200.h
|
||||
|
||||
@ -14289,6 +14290,7 @@ S: Odd fixes
|
||||
F: drivers/net/ethernet/marvell/sk*
|
||||
|
||||
MARVELL LIBERTAS WIRELESS DRIVER
|
||||
L: linux-wireless@vger.kernel.org
|
||||
L: libertas-dev@lists.infradead.org
|
||||
S: Orphan
|
||||
F: drivers/net/wireless/marvell/libertas/
|
||||
@ -19752,6 +19754,7 @@ F: drivers/media/tuners/qt1010*
|
||||
|
||||
QUALCOMM ATH12K WIRELESS DRIVER
|
||||
M: Jeff Johnson <jjohnson@kernel.org>
|
||||
L: linux-wireless@vger.kernel.org
|
||||
L: ath12k@lists.infradead.org
|
||||
S: Supported
|
||||
W: https://wireless.wiki.kernel.org/en/users/Drivers/ath12k
|
||||
@ -19761,6 +19764,7 @@ N: ath12k
|
||||
|
||||
QUALCOMM ATHEROS ATH10K WIRELESS DRIVER
|
||||
M: Jeff Johnson <jjohnson@kernel.org>
|
||||
L: linux-wireless@vger.kernel.org
|
||||
L: ath10k@lists.infradead.org
|
||||
S: Supported
|
||||
W: https://wireless.wiki.kernel.org/en/users/Drivers/ath10k
|
||||
@ -19770,6 +19774,7 @@ N: ath10k
|
||||
|
||||
QUALCOMM ATHEROS ATH11K WIRELESS DRIVER
|
||||
M: Jeff Johnson <jjohnson@kernel.org>
|
||||
L: linux-wireless@vger.kernel.org
|
||||
L: ath11k@lists.infradead.org
|
||||
S: Supported
|
||||
W: https://wireless.wiki.kernel.org/en/users/Drivers/ath11k
|
||||
@ -22143,6 +22148,7 @@ F: drivers/platform/x86/touchscreen_dmi.c
|
||||
|
||||
SILICON LABS WIRELESS DRIVERS (for WFxxx series)
|
||||
M: Jérôme Pouiller <jerome.pouiller@silabs.com>
|
||||
L: linux-wireless@vger.kernel.org
|
||||
S: Supported
|
||||
F: Documentation/devicetree/bindings/net/wireless/silabs,wfx.yaml
|
||||
F: drivers/net/wireless/silabs/
|
||||
|
@ -1286,7 +1286,9 @@ static void nxp_coredump(struct hci_dev *hdev)
|
||||
u8 pcmd = 2;
|
||||
|
||||
skb = nxp_drv_send_cmd(hdev, HCI_NXP_TRIGGER_DUMP, 1, &pcmd);
|
||||
if (!IS_ERR(skb))
|
||||
if (IS_ERR(skb))
|
||||
bt_dev_err(hdev, "Failed to trigger FW Dump. (%ld)", PTR_ERR(skb));
|
||||
else
|
||||
kfree_skb(skb);
|
||||
}
|
||||
|
||||
@ -1445,9 +1447,6 @@ static int nxp_shutdown(struct hci_dev *hdev)
|
||||
/* HCI_NXP_IND_RESET command may not returns any response */
|
||||
if (!IS_ERR(skb))
|
||||
kfree_skb(skb);
|
||||
} else if (nxpdev->current_baudrate != nxpdev->fw_init_baudrate) {
|
||||
nxpdev->new_baudrate = nxpdev->fw_init_baudrate;
|
||||
nxp_set_baudrate_cmd(hdev, NULL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -1799,13 +1798,15 @@ static void nxp_serdev_remove(struct serdev_device *serdev)
|
||||
clear_bit(BTNXPUART_FW_DOWNLOADING, &nxpdev->tx_state);
|
||||
wake_up_interruptible(&nxpdev->check_boot_sign_wait_q);
|
||||
wake_up_interruptible(&nxpdev->fw_dnld_done_wait_q);
|
||||
}
|
||||
|
||||
if (test_bit(HCI_RUNNING, &hdev->flags)) {
|
||||
/* Ensure shutdown callback is executed before unregistering, so
|
||||
* that baudrate is reset to initial value.
|
||||
} else {
|
||||
/* Restore FW baudrate to fw_init_baudrate if changed.
|
||||
* This will ensure FW baudrate is in sync with
|
||||
* driver baudrate in case this driver is re-inserted.
|
||||
*/
|
||||
nxp_shutdown(hdev);
|
||||
if (nxpdev->current_baudrate != nxpdev->fw_init_baudrate) {
|
||||
nxpdev->new_baudrate = nxpdev->fw_init_baudrate;
|
||||
nxp_set_baudrate_cmd(hdev, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
ps_cleanup(nxpdev);
|
||||
|
@ -889,7 +889,7 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
|
||||
if (le32_to_cpu(ver.soc_id) == QCA_WCN3950_SOC_ID_T)
|
||||
variant = "t";
|
||||
else if (le32_to_cpu(ver.soc_id) == QCA_WCN3950_SOC_ID_S)
|
||||
variant = "u";
|
||||
variant = "s";
|
||||
|
||||
snprintf(config.fwname, sizeof(config.fwname),
|
||||
"qca/cmnv%02x%s.bin", rom_ver, variant);
|
||||
|
@ -1215,6 +1215,8 @@ next:
|
||||
rtl_dev_err(hdev, "mandatory config file %s not found",
|
||||
btrtl_dev->ic_info->cfg_name);
|
||||
ret = btrtl_dev->cfg_len;
|
||||
if (!ret)
|
||||
ret = -EINVAL;
|
||||
goto err_free;
|
||||
}
|
||||
}
|
||||
|
@ -289,18 +289,18 @@ static void vhci_coredump(struct hci_dev *hdev)
|
||||
|
||||
static void vhci_coredump_hdr(struct hci_dev *hdev, struct sk_buff *skb)
|
||||
{
|
||||
char buf[80];
|
||||
const char *buf;
|
||||
|
||||
snprintf(buf, sizeof(buf), "Controller Name: vhci_ctrl\n");
|
||||
buf = "Controller Name: vhci_ctrl\n";
|
||||
skb_put_data(skb, buf, strlen(buf));
|
||||
|
||||
snprintf(buf, sizeof(buf), "Firmware Version: vhci_fw\n");
|
||||
buf = "Firmware Version: vhci_fw\n";
|
||||
skb_put_data(skb, buf, strlen(buf));
|
||||
|
||||
snprintf(buf, sizeof(buf), "Driver: vhci_drv\n");
|
||||
buf = "Driver: vhci_drv\n";
|
||||
skb_put_data(skb, buf, strlen(buf));
|
||||
|
||||
snprintf(buf, sizeof(buf), "Vendor: vhci\n");
|
||||
buf = "Vendor: vhci\n";
|
||||
skb_put_data(skb, buf, strlen(buf));
|
||||
}
|
||||
|
||||
|
@ -850,8 +850,9 @@ static int bond_check_dev_link(struct bonding *bond,
|
||||
struct net_device *slave_dev, int reporting)
|
||||
{
|
||||
const struct net_device_ops *slave_ops = slave_dev->netdev_ops;
|
||||
struct ifreq ifr;
|
||||
struct mii_ioctl_data *mii;
|
||||
struct ifreq ifr;
|
||||
int ret;
|
||||
|
||||
if (!reporting && !netif_running(slave_dev))
|
||||
return 0;
|
||||
@ -860,9 +861,13 @@ static int bond_check_dev_link(struct bonding *bond,
|
||||
return netif_carrier_ok(slave_dev) ? BMSR_LSTATUS : 0;
|
||||
|
||||
/* Try to get link status using Ethtool first. */
|
||||
if (slave_dev->ethtool_ops->get_link)
|
||||
return slave_dev->ethtool_ops->get_link(slave_dev) ?
|
||||
BMSR_LSTATUS : 0;
|
||||
if (slave_dev->ethtool_ops->get_link) {
|
||||
netdev_lock_ops(slave_dev);
|
||||
ret = slave_dev->ethtool_ops->get_link(slave_dev);
|
||||
netdev_unlock_ops(slave_dev);
|
||||
|
||||
return ret ? BMSR_LSTATUS : 0;
|
||||
}
|
||||
|
||||
/* Ethtool can't be used, fallback to MII ioctls. */
|
||||
if (slave_ops->ndo_eth_ioctl) {
|
||||
|
@ -902,15 +902,16 @@ static int rkcanfd_probe(struct platform_device *pdev)
|
||||
priv->can.data_bittiming_const = &rkcanfd_data_bittiming_const;
|
||||
priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK |
|
||||
CAN_CTRLMODE_BERR_REPORTING;
|
||||
if (!(priv->devtype_data.quirks & RKCANFD_QUIRK_CANFD_BROKEN))
|
||||
priv->can.ctrlmode_supported |= CAN_CTRLMODE_FD;
|
||||
priv->can.do_set_mode = rkcanfd_set_mode;
|
||||
priv->can.do_get_berr_counter = rkcanfd_get_berr_counter;
|
||||
priv->ndev = ndev;
|
||||
|
||||
match = device_get_match_data(&pdev->dev);
|
||||
if (match)
|
||||
if (match) {
|
||||
priv->devtype_data = *(struct rkcanfd_devtype_data *)match;
|
||||
if (!(priv->devtype_data.quirks & RKCANFD_QUIRK_CANFD_BROKEN))
|
||||
priv->can.ctrlmode_supported |= CAN_CTRLMODE_FD;
|
||||
}
|
||||
|
||||
err = can_rx_offload_add_manual(ndev, &priv->offload,
|
||||
RKCANFD_NAPI_WEIGHT);
|
||||
|
@ -737,6 +737,15 @@ static void b53_enable_mib(struct b53_device *dev)
|
||||
b53_write8(dev, B53_MGMT_PAGE, B53_GLOBAL_CONFIG, gc);
|
||||
}
|
||||
|
||||
static void b53_enable_stp(struct b53_device *dev)
|
||||
{
|
||||
u8 gc;
|
||||
|
||||
b53_read8(dev, B53_MGMT_PAGE, B53_GLOBAL_CONFIG, &gc);
|
||||
gc |= GC_RX_BPDU_EN;
|
||||
b53_write8(dev, B53_MGMT_PAGE, B53_GLOBAL_CONFIG, gc);
|
||||
}
|
||||
|
||||
static u16 b53_default_pvid(struct b53_device *dev)
|
||||
{
|
||||
if (is5325(dev) || is5365(dev))
|
||||
@ -876,6 +885,7 @@ static int b53_switch_reset(struct b53_device *dev)
|
||||
}
|
||||
|
||||
b53_enable_mib(dev);
|
||||
b53_enable_stp(dev);
|
||||
|
||||
return b53_flush_arl(dev, FAST_AGE_STATIC);
|
||||
}
|
||||
|
@ -1852,6 +1852,8 @@ static int mv88e6xxx_vtu_get(struct mv88e6xxx_chip *chip, u16 vid,
|
||||
if (!chip->info->ops->vtu_getnext)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
memset(entry, 0, sizeof(*entry));
|
||||
|
||||
entry->vid = vid ? vid - 1 : mv88e6xxx_max_vid(chip);
|
||||
entry->valid = false;
|
||||
|
||||
@ -1960,7 +1962,16 @@ static int mv88e6xxx_mst_put(struct mv88e6xxx_chip *chip, u8 sid)
|
||||
struct mv88e6xxx_mst *mst, *tmp;
|
||||
int err;
|
||||
|
||||
if (!sid)
|
||||
/* If the SID is zero, it is for a VLAN mapped to the default MSTI,
|
||||
* and mv88e6xxx_stu_setup() made sure it is always present, and thus,
|
||||
* should not be removed here.
|
||||
*
|
||||
* If the chip lacks STU support, numerically the "sid" variable will
|
||||
* happen to also be zero, but we don't want to rely on that fact, so
|
||||
* we explicitly test that first. In that case, there is also nothing
|
||||
* to do here.
|
||||
*/
|
||||
if (!mv88e6xxx_has_stu(chip) || !sid)
|
||||
return 0;
|
||||
|
||||
list_for_each_entry_safe(mst, tmp, &chip->msts, node) {
|
||||
|
@ -736,7 +736,8 @@ void mv88e6xxx_teardown_devlink_regions_global(struct dsa_switch *ds)
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(mv88e6xxx_regions); i++)
|
||||
dsa_devlink_region_destroy(chip->regions[i]);
|
||||
if (chip->regions[i])
|
||||
dsa_devlink_region_destroy(chip->regions[i]);
|
||||
}
|
||||
|
||||
void mv88e6xxx_teardown_devlink_regions_port(struct dsa_switch *ds, int port)
|
||||
|
@ -154,8 +154,9 @@ void pdsc_debugfs_add_qcq(struct pdsc *pdsc, struct pdsc_qcq *qcq)
|
||||
debugfs_create_u32("index", 0400, intr_dentry, &intr->index);
|
||||
debugfs_create_u32("vector", 0400, intr_dentry, &intr->vector);
|
||||
|
||||
intr_ctrl_regset = kzalloc(sizeof(*intr_ctrl_regset),
|
||||
GFP_KERNEL);
|
||||
intr_ctrl_regset = devm_kzalloc(pdsc->dev,
|
||||
sizeof(*intr_ctrl_regset),
|
||||
GFP_KERNEL);
|
||||
if (!intr_ctrl_regset)
|
||||
return;
|
||||
intr_ctrl_regset->regs = intr_ctrl_regs;
|
||||
|
@ -787,7 +787,7 @@ tx_free:
|
||||
dev_kfree_skb_any(skb);
|
||||
tx_kick_pending:
|
||||
if (BNXT_TX_PTP_IS_SET(lflags)) {
|
||||
txr->tx_buf_ring[txr->tx_prod].is_ts_pkt = 0;
|
||||
txr->tx_buf_ring[RING_TX(bp, txr->tx_prod)].is_ts_pkt = 0;
|
||||
atomic64_inc(&bp->ptp_cfg->stats.ts_err);
|
||||
if (!(bp->fw_cap & BNXT_FW_CAP_TX_TS_CMP))
|
||||
/* set SKB to err so PTP worker will clean up */
|
||||
@ -795,7 +795,7 @@ tx_kick_pending:
|
||||
}
|
||||
if (txr->kick_pending)
|
||||
bnxt_txr_db_kick(bp, txr, txr->tx_prod);
|
||||
txr->tx_buf_ring[txr->tx_prod].skb = NULL;
|
||||
txr->tx_buf_ring[RING_TX(bp, txr->tx_prod)].skb = NULL;
|
||||
dev_core_stats_tx_dropped_inc(dev);
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
@ -2270,6 +2270,7 @@ int cxgb4_init_ethtool_filters(struct adapter *adap)
|
||||
eth_filter->port[i].bmap = bitmap_zalloc(nentries, GFP_KERNEL);
|
||||
if (!eth_filter->port[i].bmap) {
|
||||
ret = -ENOMEM;
|
||||
kvfree(eth_filter->port[i].loc_array);
|
||||
goto free_eth_finfo;
|
||||
}
|
||||
}
|
||||
|
@ -108,14 +108,16 @@ struct hbg_irq_info {
|
||||
bool re_enable;
|
||||
bool need_print;
|
||||
bool need_reset;
|
||||
u64 count;
|
||||
|
||||
void (*irq_handle)(struct hbg_priv *priv, struct hbg_irq_info *info);
|
||||
void (*irq_handle)(struct hbg_priv *priv,
|
||||
const struct hbg_irq_info *info);
|
||||
};
|
||||
|
||||
struct hbg_vector {
|
||||
char name[HBG_VECTOR_NUM][32];
|
||||
struct hbg_irq_info *info_array;
|
||||
|
||||
u64 *stats_array;
|
||||
const struct hbg_irq_info *info_array;
|
||||
u32 info_array_len;
|
||||
};
|
||||
|
||||
|
@ -61,7 +61,7 @@ static int hbg_dbg_irq_info(struct seq_file *s, void *unused)
|
||||
{
|
||||
struct net_device *netdev = dev_get_drvdata(s->private);
|
||||
struct hbg_priv *priv = netdev_priv(netdev);
|
||||
struct hbg_irq_info *info;
|
||||
const struct hbg_irq_info *info;
|
||||
u32 i;
|
||||
|
||||
for (i = 0; i < priv->vectors.info_array_len; i++) {
|
||||
@ -73,7 +73,7 @@ static int hbg_dbg_irq_info(struct seq_file *s, void *unused)
|
||||
info->mask)),
|
||||
str_true_false(info->need_reset),
|
||||
str_true_false(info->need_print),
|
||||
info->count);
|
||||
priv->vectors.stats_array[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -106,6 +106,7 @@ static int hbg_dbg_nic_state(struct seq_file *s, void *unused)
|
||||
{
|
||||
struct net_device *netdev = dev_get_drvdata(s->private);
|
||||
struct hbg_priv *priv = netdev_priv(netdev);
|
||||
bool np_link_fail;
|
||||
|
||||
seq_printf(s, "event handling state: %s\n",
|
||||
state_str_true_false(priv, HBG_NIC_STATE_EVENT_HANDLING));
|
||||
@ -117,8 +118,10 @@ static int hbg_dbg_nic_state(struct seq_file *s, void *unused)
|
||||
reset_type_str[priv->reset_type]);
|
||||
seq_printf(s, "need reset state: %s\n",
|
||||
state_str_true_false(priv, HBG_NIC_STATE_NEED_RESET));
|
||||
seq_printf(s, "np_link fail state: %s\n",
|
||||
state_str_true_false(priv, HBG_NIC_STATE_NP_LINK_FAIL));
|
||||
|
||||
np_link_fail = !hbg_reg_read_field(priv, HBG_REG_AN_NEG_STATE_ADDR,
|
||||
HBG_REG_AN_NEG_STATE_NP_LINK_OK_B);
|
||||
seq_printf(s, "np_link fail state: %s\n", str_true_false(np_link_fail));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -234,7 +234,7 @@ static u64 hbg_get_irq_stats(struct hbg_vector *vectors, u32 mask)
|
||||
|
||||
for (i = 0; i < vectors->info_array_len; i++)
|
||||
if (vectors->info_array[i].mask == mask)
|
||||
return vectors->info_array[i].count;
|
||||
return vectors->stats_array[i];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -26,12 +26,15 @@ static void hbg_restore_mac_table(struct hbg_priv *priv)
|
||||
|
||||
static void hbg_restore_user_def_settings(struct hbg_priv *priv)
|
||||
{
|
||||
/* The index of host mac is always 0. */
|
||||
u64 rx_pause_addr = ether_addr_to_u64(priv->filter.mac_table[0].addr);
|
||||
struct ethtool_pauseparam *pause_param = &priv->user_def.pause_param;
|
||||
|
||||
hbg_restore_mac_table(priv);
|
||||
hbg_hw_set_mtu(priv, priv->netdev->mtu);
|
||||
hbg_hw_set_pause_enable(priv, pause_param->tx_pause,
|
||||
pause_param->rx_pause);
|
||||
hbg_hw_set_rx_pause_mac_addr(priv, rx_pause_addr);
|
||||
}
|
||||
|
||||
int hbg_rebuild(struct hbg_priv *priv)
|
||||
|
@ -234,6 +234,10 @@ void hbg_hw_set_mac_filter_enable(struct hbg_priv *priv, u32 enable)
|
||||
{
|
||||
hbg_reg_write_field(priv, HBG_REG_REC_FILT_CTRL_ADDR,
|
||||
HBG_REG_REC_FILT_CTRL_UC_MATCH_EN_B, enable);
|
||||
|
||||
/* only uc filter is supported, so set all bits of mc mask reg to 1 */
|
||||
hbg_reg_write64(priv, HBG_REG_STATION_ADDR_LOW_MSK_0, U64_MAX);
|
||||
hbg_reg_write64(priv, HBG_REG_STATION_ADDR_LOW_MSK_1, U64_MAX);
|
||||
}
|
||||
|
||||
void hbg_hw_set_pause_enable(struct hbg_priv *priv, u32 tx_en, u32 rx_en)
|
||||
@ -242,6 +246,9 @@ void hbg_hw_set_pause_enable(struct hbg_priv *priv, u32 tx_en, u32 rx_en)
|
||||
HBG_REG_PAUSE_ENABLE_TX_B, tx_en);
|
||||
hbg_reg_write_field(priv, HBG_REG_PAUSE_ENABLE_ADDR,
|
||||
HBG_REG_PAUSE_ENABLE_RX_B, rx_en);
|
||||
|
||||
hbg_reg_write_field(priv, HBG_REG_REC_FILT_CTRL_ADDR,
|
||||
HBG_REG_REC_FILT_CTRL_PAUSE_FRM_PASS_B, rx_en);
|
||||
}
|
||||
|
||||
void hbg_hw_get_pause_enable(struct hbg_priv *priv, u32 *tx_en, u32 *rx_en)
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include "hbg_hw.h"
|
||||
|
||||
static void hbg_irq_handle_err(struct hbg_priv *priv,
|
||||
struct hbg_irq_info *irq_info)
|
||||
const struct hbg_irq_info *irq_info)
|
||||
{
|
||||
if (irq_info->need_print)
|
||||
dev_err(&priv->pdev->dev,
|
||||
@ -17,30 +17,30 @@ static void hbg_irq_handle_err(struct hbg_priv *priv,
|
||||
}
|
||||
|
||||
static void hbg_irq_handle_tx(struct hbg_priv *priv,
|
||||
struct hbg_irq_info *irq_info)
|
||||
const struct hbg_irq_info *irq_info)
|
||||
{
|
||||
napi_schedule(&priv->tx_ring.napi);
|
||||
}
|
||||
|
||||
static void hbg_irq_handle_rx(struct hbg_priv *priv,
|
||||
struct hbg_irq_info *irq_info)
|
||||
const struct hbg_irq_info *irq_info)
|
||||
{
|
||||
napi_schedule(&priv->rx_ring.napi);
|
||||
}
|
||||
|
||||
static void hbg_irq_handle_rx_buf_val(struct hbg_priv *priv,
|
||||
struct hbg_irq_info *irq_info)
|
||||
const struct hbg_irq_info *irq_info)
|
||||
{
|
||||
priv->stats.rx_fifo_less_empty_thrsld_cnt++;
|
||||
}
|
||||
|
||||
#define HBG_IRQ_I(name, handle) \
|
||||
{#name, HBG_INT_MSK_##name##_B, false, false, false, 0, handle}
|
||||
{#name, HBG_INT_MSK_##name##_B, false, false, false, handle}
|
||||
#define HBG_ERR_IRQ_I(name, need_print, ndde_reset) \
|
||||
{#name, HBG_INT_MSK_##name##_B, true, need_print, \
|
||||
ndde_reset, 0, hbg_irq_handle_err}
|
||||
ndde_reset, hbg_irq_handle_err}
|
||||
|
||||
static struct hbg_irq_info hbg_irqs[] = {
|
||||
static const struct hbg_irq_info hbg_irqs[] = {
|
||||
HBG_IRQ_I(RX, hbg_irq_handle_rx),
|
||||
HBG_IRQ_I(TX, hbg_irq_handle_tx),
|
||||
HBG_ERR_IRQ_I(TX_PKT_CPL, true, true),
|
||||
@ -64,7 +64,7 @@ static struct hbg_irq_info hbg_irqs[] = {
|
||||
|
||||
static irqreturn_t hbg_irq_handle(int irq_num, void *p)
|
||||
{
|
||||
struct hbg_irq_info *info;
|
||||
const struct hbg_irq_info *info;
|
||||
struct hbg_priv *priv = p;
|
||||
u32 status;
|
||||
u32 i;
|
||||
@ -79,7 +79,7 @@ static irqreturn_t hbg_irq_handle(int irq_num, void *p)
|
||||
hbg_hw_irq_enable(priv, info->mask, false);
|
||||
hbg_hw_irq_clear(priv, info->mask);
|
||||
|
||||
info->count++;
|
||||
priv->vectors.stats_array[i]++;
|
||||
if (info->irq_handle)
|
||||
info->irq_handle(priv, info);
|
||||
|
||||
@ -132,6 +132,12 @@ int hbg_irq_init(struct hbg_priv *priv)
|
||||
irq_names_map[i]);
|
||||
}
|
||||
|
||||
vectors->stats_array = devm_kcalloc(&priv->pdev->dev,
|
||||
ARRAY_SIZE(hbg_irqs),
|
||||
sizeof(u64), GFP_KERNEL);
|
||||
if (!vectors->stats_array)
|
||||
return -ENOMEM;
|
||||
|
||||
vectors->info_array = hbg_irqs;
|
||||
vectors->info_array_len = ARRAY_SIZE(hbg_irqs);
|
||||
return 0;
|
||||
|
@ -21,7 +21,7 @@
|
||||
|
||||
static void hbg_all_irq_enable(struct hbg_priv *priv, bool enabled)
|
||||
{
|
||||
struct hbg_irq_info *info;
|
||||
const struct hbg_irq_info *info;
|
||||
u32 i;
|
||||
|
||||
for (i = 0; i < priv->vectors.info_array_len; i++) {
|
||||
@ -203,12 +203,12 @@ static int hbg_net_change_mtu(struct net_device *netdev, int new_mtu)
|
||||
if (netif_running(netdev))
|
||||
return -EBUSY;
|
||||
|
||||
hbg_hw_set_mtu(priv, new_mtu);
|
||||
WRITE_ONCE(netdev->mtu, new_mtu);
|
||||
|
||||
dev_dbg(&priv->pdev->dev,
|
||||
"change mtu from %u to %u\n", netdev->mtu, new_mtu);
|
||||
|
||||
hbg_hw_set_mtu(priv, new_mtu);
|
||||
WRITE_ONCE(netdev->mtu, new_mtu);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
// Copyright (c) 2024 Hisilicon Limited.
|
||||
|
||||
#include <linux/phy.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
#include "hbg_common.h"
|
||||
#include "hbg_hw.h"
|
||||
#include "hbg_mdio.h"
|
||||
@ -133,12 +134,17 @@ void hbg_fix_np_link_fail(struct hbg_priv *priv)
|
||||
{
|
||||
struct device *dev = &priv->pdev->dev;
|
||||
|
||||
rtnl_lock();
|
||||
|
||||
if (priv->stats.np_link_fail_cnt >= HBG_NP_LINK_FAIL_RETRY_TIMES) {
|
||||
dev_err(dev, "failed to fix the MAC link status\n");
|
||||
priv->stats.np_link_fail_cnt = 0;
|
||||
return;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
if (!priv->mac.phydev->link)
|
||||
goto unlock;
|
||||
|
||||
priv->stats.np_link_fail_cnt++;
|
||||
dev_err(dev, "failed to link between MAC and PHY, try to fix...\n");
|
||||
|
||||
@ -147,6 +153,9 @@ void hbg_fix_np_link_fail(struct hbg_priv *priv)
|
||||
*/
|
||||
hbg_phy_stop(priv);
|
||||
hbg_phy_start(priv);
|
||||
|
||||
unlock:
|
||||
rtnl_unlock();
|
||||
}
|
||||
|
||||
static void hbg_phy_adjust_link(struct net_device *netdev)
|
||||
|
@ -68,6 +68,7 @@
|
||||
#define HBG_REG_TRANSMIT_CTRL_AN_EN_B BIT(5)
|
||||
#define HBG_REG_REC_FILT_CTRL_ADDR (HBG_REG_SGMII_BASE + 0x0064)
|
||||
#define HBG_REG_REC_FILT_CTRL_UC_MATCH_EN_B BIT(0)
|
||||
#define HBG_REG_REC_FILT_CTRL_PAUSE_FRM_PASS_B BIT(4)
|
||||
#define HBG_REG_RX_OCTETS_TOTAL_OK_ADDR (HBG_REG_SGMII_BASE + 0x0080)
|
||||
#define HBG_REG_RX_OCTETS_BAD_ADDR (HBG_REG_SGMII_BASE + 0x0084)
|
||||
#define HBG_REG_RX_UC_PKTS_ADDR (HBG_REG_SGMII_BASE + 0x0088)
|
||||
@ -134,6 +135,8 @@
|
||||
#define HBG_REG_STATION_ADDR_HIGH_4_ADDR (HBG_REG_SGMII_BASE + 0x0224)
|
||||
#define HBG_REG_STATION_ADDR_LOW_5_ADDR (HBG_REG_SGMII_BASE + 0x0228)
|
||||
#define HBG_REG_STATION_ADDR_HIGH_5_ADDR (HBG_REG_SGMII_BASE + 0x022C)
|
||||
#define HBG_REG_STATION_ADDR_LOW_MSK_0 (HBG_REG_SGMII_BASE + 0x0230)
|
||||
#define HBG_REG_STATION_ADDR_LOW_MSK_1 (HBG_REG_SGMII_BASE + 0x0238)
|
||||
|
||||
/* PCU */
|
||||
#define HBG_REG_TX_FIFO_THRSLD_ADDR (HBG_REG_SGMII_BASE + 0x0420)
|
||||
|
@ -319,6 +319,7 @@ struct igc_adapter {
|
||||
struct timespec64 prev_ptp_time; /* Pre-reset PTP clock */
|
||||
ktime_t ptp_reset_start; /* Reset time in clock mono */
|
||||
struct system_time_snapshot snapshot;
|
||||
struct mutex ptm_lock; /* Only allow one PTM transaction at a time */
|
||||
|
||||
char fw_version[32];
|
||||
|
||||
|
@ -574,7 +574,10 @@
|
||||
#define IGC_PTM_CTRL_SHRT_CYC(usec) (((usec) & 0x3f) << 2)
|
||||
#define IGC_PTM_CTRL_PTM_TO(usec) (((usec) & 0xff) << 8)
|
||||
|
||||
#define IGC_PTM_SHORT_CYC_DEFAULT 1 /* Default short cycle interval */
|
||||
/* A short cycle time of 1us theoretically should work, but appears to be too
|
||||
* short in practice.
|
||||
*/
|
||||
#define IGC_PTM_SHORT_CYC_DEFAULT 4 /* Default short cycle interval */
|
||||
#define IGC_PTM_CYC_TIME_DEFAULT 5 /* Default PTM cycle time */
|
||||
#define IGC_PTM_TIMEOUT_DEFAULT 255 /* Default timeout for PTM errors */
|
||||
|
||||
@ -593,6 +596,7 @@
|
||||
#define IGC_PTM_STAT_T4M1_OVFL BIT(3) /* T4 minus T1 overflow */
|
||||
#define IGC_PTM_STAT_ADJUST_1ST BIT(4) /* 1588 timer adjusted during 1st PTM cycle */
|
||||
#define IGC_PTM_STAT_ADJUST_CYC BIT(5) /* 1588 timer adjusted during non-1st PTM cycle */
|
||||
#define IGC_PTM_STAT_ALL GENMASK(5, 0) /* Used to clear all status */
|
||||
|
||||
/* PCIe PTM Cycle Control */
|
||||
#define IGC_PTM_CYCLE_CTRL_CYC_TIME(msec) ((msec) & 0x3ff) /* PTM Cycle Time (msec) */
|
||||
|
@ -7231,6 +7231,7 @@ static int igc_probe(struct pci_dev *pdev,
|
||||
|
||||
err_register:
|
||||
igc_release_hw_control(adapter);
|
||||
igc_ptp_stop(adapter);
|
||||
err_eeprom:
|
||||
if (!igc_check_reset_block(hw))
|
||||
igc_reset_phy(hw);
|
||||
|
@ -974,45 +974,62 @@ static void igc_ptm_log_error(struct igc_adapter *adapter, u32 ptm_stat)
|
||||
}
|
||||
}
|
||||
|
||||
/* The PTM lock: adapter->ptm_lock must be held when calling igc_ptm_trigger() */
|
||||
static void igc_ptm_trigger(struct igc_hw *hw)
|
||||
{
|
||||
u32 ctrl;
|
||||
|
||||
/* To "manually" start the PTM cycle we need to set the
|
||||
* trigger (TRIG) bit
|
||||
*/
|
||||
ctrl = rd32(IGC_PTM_CTRL);
|
||||
ctrl |= IGC_PTM_CTRL_TRIG;
|
||||
wr32(IGC_PTM_CTRL, ctrl);
|
||||
/* Perform flush after write to CTRL register otherwise
|
||||
* transaction may not start
|
||||
*/
|
||||
wrfl();
|
||||
}
|
||||
|
||||
/* The PTM lock: adapter->ptm_lock must be held when calling igc_ptm_reset() */
|
||||
static void igc_ptm_reset(struct igc_hw *hw)
|
||||
{
|
||||
u32 ctrl;
|
||||
|
||||
ctrl = rd32(IGC_PTM_CTRL);
|
||||
ctrl &= ~IGC_PTM_CTRL_TRIG;
|
||||
wr32(IGC_PTM_CTRL, ctrl);
|
||||
/* Write to clear all status */
|
||||
wr32(IGC_PTM_STAT, IGC_PTM_STAT_ALL);
|
||||
}
|
||||
|
||||
static int igc_phc_get_syncdevicetime(ktime_t *device,
|
||||
struct system_counterval_t *system,
|
||||
void *ctx)
|
||||
{
|
||||
u32 stat, t2_curr_h, t2_curr_l, ctrl;
|
||||
struct igc_adapter *adapter = ctx;
|
||||
struct igc_hw *hw = &adapter->hw;
|
||||
u32 stat, t2_curr_h, t2_curr_l;
|
||||
int err, count = 100;
|
||||
ktime_t t1, t2_curr;
|
||||
|
||||
/* Get a snapshot of system clocks to use as historic value. */
|
||||
ktime_get_snapshot(&adapter->snapshot);
|
||||
|
||||
/* Doing this in a loop because in the event of a
|
||||
* badly timed (ha!) system clock adjustment, we may
|
||||
* get PTM errors from the PCI root, but these errors
|
||||
* are transitory. Repeating the process returns valid
|
||||
* data eventually.
|
||||
*/
|
||||
do {
|
||||
/* Doing this in a loop because in the event of a
|
||||
* badly timed (ha!) system clock adjustment, we may
|
||||
* get PTM errors from the PCI root, but these errors
|
||||
* are transitory. Repeating the process returns valid
|
||||
* data eventually.
|
||||
*/
|
||||
/* Get a snapshot of system clocks to use as historic value. */
|
||||
ktime_get_snapshot(&adapter->snapshot);
|
||||
|
||||
/* To "manually" start the PTM cycle we need to clear and
|
||||
* then set again the TRIG bit.
|
||||
*/
|
||||
ctrl = rd32(IGC_PTM_CTRL);
|
||||
ctrl &= ~IGC_PTM_CTRL_TRIG;
|
||||
wr32(IGC_PTM_CTRL, ctrl);
|
||||
ctrl |= IGC_PTM_CTRL_TRIG;
|
||||
wr32(IGC_PTM_CTRL, ctrl);
|
||||
|
||||
/* The cycle only starts "for real" when software notifies
|
||||
* that it has read the registers, this is done by setting
|
||||
* VALID bit.
|
||||
*/
|
||||
wr32(IGC_PTM_STAT, IGC_PTM_STAT_VALID);
|
||||
igc_ptm_trigger(hw);
|
||||
|
||||
err = readx_poll_timeout(rd32, IGC_PTM_STAT, stat,
|
||||
stat, IGC_PTM_STAT_SLEEP,
|
||||
IGC_PTM_STAT_TIMEOUT);
|
||||
igc_ptm_reset(hw);
|
||||
|
||||
if (err < 0) {
|
||||
netdev_err(adapter->netdev, "Timeout reading IGC_PTM_STAT register\n");
|
||||
return err;
|
||||
@ -1021,15 +1038,7 @@ static int igc_phc_get_syncdevicetime(ktime_t *device,
|
||||
if ((stat & IGC_PTM_STAT_VALID) == IGC_PTM_STAT_VALID)
|
||||
break;
|
||||
|
||||
if (stat & ~IGC_PTM_STAT_VALID) {
|
||||
/* An error occurred, log it. */
|
||||
igc_ptm_log_error(adapter, stat);
|
||||
/* The STAT register is write-1-to-clear (W1C),
|
||||
* so write the previous error status to clear it.
|
||||
*/
|
||||
wr32(IGC_PTM_STAT, stat);
|
||||
continue;
|
||||
}
|
||||
igc_ptm_log_error(adapter, stat);
|
||||
} while (--count);
|
||||
|
||||
if (!count) {
|
||||
@ -1061,9 +1070,16 @@ static int igc_ptp_getcrosststamp(struct ptp_clock_info *ptp,
|
||||
{
|
||||
struct igc_adapter *adapter = container_of(ptp, struct igc_adapter,
|
||||
ptp_caps);
|
||||
int ret;
|
||||
|
||||
return get_device_system_crosststamp(igc_phc_get_syncdevicetime,
|
||||
adapter, &adapter->snapshot, cts);
|
||||
/* This blocks until any in progress PTM transactions complete */
|
||||
mutex_lock(&adapter->ptm_lock);
|
||||
|
||||
ret = get_device_system_crosststamp(igc_phc_get_syncdevicetime,
|
||||
adapter, &adapter->snapshot, cts);
|
||||
mutex_unlock(&adapter->ptm_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int igc_ptp_getcyclesx64(struct ptp_clock_info *ptp,
|
||||
@ -1162,6 +1178,7 @@ void igc_ptp_init(struct igc_adapter *adapter)
|
||||
spin_lock_init(&adapter->ptp_tx_lock);
|
||||
spin_lock_init(&adapter->free_timer_lock);
|
||||
spin_lock_init(&adapter->tmreg_lock);
|
||||
mutex_init(&adapter->ptm_lock);
|
||||
|
||||
adapter->tstamp_config.rx_filter = HWTSTAMP_FILTER_NONE;
|
||||
adapter->tstamp_config.tx_type = HWTSTAMP_TX_OFF;
|
||||
@ -1174,6 +1191,7 @@ void igc_ptp_init(struct igc_adapter *adapter)
|
||||
if (IS_ERR(adapter->ptp_clock)) {
|
||||
adapter->ptp_clock = NULL;
|
||||
netdev_err(netdev, "ptp_clock_register failed\n");
|
||||
mutex_destroy(&adapter->ptm_lock);
|
||||
} else if (adapter->ptp_clock) {
|
||||
netdev_info(netdev, "PHC added\n");
|
||||
adapter->ptp_flags |= IGC_PTP_ENABLED;
|
||||
@ -1203,10 +1221,12 @@ static void igc_ptm_stop(struct igc_adapter *adapter)
|
||||
struct igc_hw *hw = &adapter->hw;
|
||||
u32 ctrl;
|
||||
|
||||
mutex_lock(&adapter->ptm_lock);
|
||||
ctrl = rd32(IGC_PTM_CTRL);
|
||||
ctrl &= ~IGC_PTM_CTRL_EN;
|
||||
|
||||
wr32(IGC_PTM_CTRL, ctrl);
|
||||
mutex_unlock(&adapter->ptm_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1237,13 +1257,18 @@ void igc_ptp_suspend(struct igc_adapter *adapter)
|
||||
**/
|
||||
void igc_ptp_stop(struct igc_adapter *adapter)
|
||||
{
|
||||
if (!(adapter->ptp_flags & IGC_PTP_ENABLED))
|
||||
return;
|
||||
|
||||
igc_ptp_suspend(adapter);
|
||||
|
||||
adapter->ptp_flags &= ~IGC_PTP_ENABLED;
|
||||
if (adapter->ptp_clock) {
|
||||
ptp_clock_unregister(adapter->ptp_clock);
|
||||
netdev_info(adapter->netdev, "PHC removed\n");
|
||||
adapter->ptp_flags &= ~IGC_PTP_ENABLED;
|
||||
}
|
||||
mutex_destroy(&adapter->ptm_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1255,10 +1280,13 @@ void igc_ptp_stop(struct igc_adapter *adapter)
|
||||
void igc_ptp_reset(struct igc_adapter *adapter)
|
||||
{
|
||||
struct igc_hw *hw = &adapter->hw;
|
||||
u32 cycle_ctrl, ctrl;
|
||||
u32 cycle_ctrl, ctrl, stat;
|
||||
unsigned long flags;
|
||||
u32 timadj;
|
||||
|
||||
if (!(adapter->ptp_flags & IGC_PTP_ENABLED))
|
||||
return;
|
||||
|
||||
/* reset the tstamp_config */
|
||||
igc_ptp_set_timestamp_mode(adapter, &adapter->tstamp_config);
|
||||
|
||||
@ -1280,6 +1308,7 @@ void igc_ptp_reset(struct igc_adapter *adapter)
|
||||
if (!igc_is_crosststamp_supported(adapter))
|
||||
break;
|
||||
|
||||
mutex_lock(&adapter->ptm_lock);
|
||||
wr32(IGC_PCIE_DIG_DELAY, IGC_PCIE_DIG_DELAY_DEFAULT);
|
||||
wr32(IGC_PCIE_PHY_DELAY, IGC_PCIE_PHY_DELAY_DEFAULT);
|
||||
|
||||
@ -1290,14 +1319,20 @@ void igc_ptp_reset(struct igc_adapter *adapter)
|
||||
ctrl = IGC_PTM_CTRL_EN |
|
||||
IGC_PTM_CTRL_START_NOW |
|
||||
IGC_PTM_CTRL_SHRT_CYC(IGC_PTM_SHORT_CYC_DEFAULT) |
|
||||
IGC_PTM_CTRL_PTM_TO(IGC_PTM_TIMEOUT_DEFAULT) |
|
||||
IGC_PTM_CTRL_TRIG;
|
||||
IGC_PTM_CTRL_PTM_TO(IGC_PTM_TIMEOUT_DEFAULT);
|
||||
|
||||
wr32(IGC_PTM_CTRL, ctrl);
|
||||
|
||||
/* Force the first cycle to run. */
|
||||
wr32(IGC_PTM_STAT, IGC_PTM_STAT_VALID);
|
||||
igc_ptm_trigger(hw);
|
||||
|
||||
if (readx_poll_timeout_atomic(rd32, IGC_PTM_STAT, stat,
|
||||
stat, IGC_PTM_STAT_SLEEP,
|
||||
IGC_PTM_STAT_TIMEOUT))
|
||||
netdev_err(adapter->netdev, "Timeout reading IGC_PTM_STAT register\n");
|
||||
|
||||
igc_ptm_reset(hw);
|
||||
mutex_unlock(&adapter->ptm_lock);
|
||||
break;
|
||||
default:
|
||||
/* No work to do. */
|
||||
|
@ -67,6 +67,8 @@ static int rvu_rep_mcam_flow_init(struct rep_dev *rep)
|
||||
|
||||
rsp = (struct npc_mcam_alloc_entry_rsp *)otx2_mbox_get_rsp
|
||||
(&priv->mbox.mbox, 0, &req->hdr);
|
||||
if (IS_ERR(rsp))
|
||||
goto exit;
|
||||
|
||||
for (ent = 0; ent < rsp->count; ent++)
|
||||
rep->flow_cfg->flow_ent[ent + allocated] = rsp->entry_list[ent];
|
||||
|
@ -734,7 +734,7 @@ static void mtk_set_queue_speed(struct mtk_eth *eth, unsigned int idx,
|
||||
case SPEED_100:
|
||||
val |= MTK_QTX_SCH_MAX_RATE_EN |
|
||||
FIELD_PREP(MTK_QTX_SCH_MAX_RATE_MAN, 103) |
|
||||
FIELD_PREP(MTK_QTX_SCH_MAX_RATE_EXP, 3);
|
||||
FIELD_PREP(MTK_QTX_SCH_MAX_RATE_EXP, 3) |
|
||||
FIELD_PREP(MTK_QTX_SCH_MAX_RATE_WEIGHT, 1);
|
||||
break;
|
||||
case SPEED_1000:
|
||||
@ -757,13 +757,13 @@ static void mtk_set_queue_speed(struct mtk_eth *eth, unsigned int idx,
|
||||
case SPEED_100:
|
||||
val |= MTK_QTX_SCH_MAX_RATE_EN |
|
||||
FIELD_PREP(MTK_QTX_SCH_MAX_RATE_MAN, 1) |
|
||||
FIELD_PREP(MTK_QTX_SCH_MAX_RATE_EXP, 5);
|
||||
FIELD_PREP(MTK_QTX_SCH_MAX_RATE_EXP, 5) |
|
||||
FIELD_PREP(MTK_QTX_SCH_MAX_RATE_WEIGHT, 1);
|
||||
break;
|
||||
case SPEED_1000:
|
||||
val |= MTK_QTX_SCH_MAX_RATE_EN |
|
||||
FIELD_PREP(MTK_QTX_SCH_MAX_RATE_MAN, 10) |
|
||||
FIELD_PREP(MTK_QTX_SCH_MAX_RATE_EXP, 5) |
|
||||
FIELD_PREP(MTK_QTX_SCH_MAX_RATE_MAN, 1) |
|
||||
FIELD_PREP(MTK_QTX_SCH_MAX_RATE_EXP, 6) |
|
||||
FIELD_PREP(MTK_QTX_SCH_MAX_RATE_WEIGHT, 10);
|
||||
break;
|
||||
default:
|
||||
@ -871,9 +871,25 @@ static const struct phylink_mac_ops mtk_phylink_ops = {
|
||||
.mac_enable_tx_lpi = mtk_mac_enable_tx_lpi,
|
||||
};
|
||||
|
||||
static void mtk_mdio_config(struct mtk_eth *eth)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
/* Configure MDC Divider */
|
||||
val = FIELD_PREP(PPSC_MDC_CFG, eth->mdc_divider);
|
||||
|
||||
/* Configure MDC Turbo Mode */
|
||||
if (mtk_is_netsys_v3_or_greater(eth))
|
||||
mtk_m32(eth, 0, MISC_MDC_TURBO, MTK_MAC_MISC_V3);
|
||||
else
|
||||
val |= PPSC_MDC_TURBO;
|
||||
|
||||
mtk_m32(eth, PPSC_MDC_CFG, val, MTK_PPSC);
|
||||
}
|
||||
|
||||
static int mtk_mdio_init(struct mtk_eth *eth)
|
||||
{
|
||||
unsigned int max_clk = 2500000, divider;
|
||||
unsigned int max_clk = 2500000;
|
||||
struct device_node *mii_np;
|
||||
int ret;
|
||||
u32 val;
|
||||
@ -908,20 +924,9 @@ static int mtk_mdio_init(struct mtk_eth *eth)
|
||||
}
|
||||
max_clk = val;
|
||||
}
|
||||
divider = min_t(unsigned int, DIV_ROUND_UP(MDC_MAX_FREQ, max_clk), 63);
|
||||
|
||||
/* Configure MDC Turbo Mode */
|
||||
if (mtk_is_netsys_v3_or_greater(eth))
|
||||
mtk_m32(eth, 0, MISC_MDC_TURBO, MTK_MAC_MISC_V3);
|
||||
|
||||
/* Configure MDC Divider */
|
||||
val = FIELD_PREP(PPSC_MDC_CFG, divider);
|
||||
if (!mtk_is_netsys_v3_or_greater(eth))
|
||||
val |= PPSC_MDC_TURBO;
|
||||
mtk_m32(eth, PPSC_MDC_CFG, val, MTK_PPSC);
|
||||
|
||||
dev_dbg(eth->dev, "MDC is running on %d Hz\n", MDC_MAX_FREQ / divider);
|
||||
|
||||
eth->mdc_divider = min_t(unsigned int, DIV_ROUND_UP(MDC_MAX_FREQ, max_clk), 63);
|
||||
mtk_mdio_config(eth);
|
||||
dev_dbg(eth->dev, "MDC is running on %d Hz\n", MDC_MAX_FREQ / eth->mdc_divider);
|
||||
ret = of_mdiobus_register(eth->mii_bus, mii_np);
|
||||
|
||||
err_put_node:
|
||||
@ -3315,7 +3320,7 @@ static int mtk_start_dma(struct mtk_eth *eth)
|
||||
if (mtk_is_netsys_v2_or_greater(eth))
|
||||
val |= MTK_MUTLI_CNT | MTK_RESV_BUF |
|
||||
MTK_WCOMP_EN | MTK_DMAD_WR_WDONE |
|
||||
MTK_CHK_DDONE_EN | MTK_LEAKY_BUCKET_EN;
|
||||
MTK_CHK_DDONE_EN;
|
||||
else
|
||||
val |= MTK_RX_BT_32DWORDS;
|
||||
mtk_w32(eth, val, reg_map->qdma.glo_cfg);
|
||||
@ -3974,6 +3979,10 @@ static int mtk_hw_init(struct mtk_eth *eth, bool reset)
|
||||
else
|
||||
mtk_hw_reset(eth);
|
||||
|
||||
/* No MT7628/88 support yet */
|
||||
if (reset && !MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628))
|
||||
mtk_mdio_config(eth);
|
||||
|
||||
if (mtk_is_netsys_v3_or_greater(eth)) {
|
||||
/* Set FE to PDMAv2 if necessary */
|
||||
val = mtk_r32(eth, MTK_FE_GLO_MISC);
|
||||
|
@ -1271,6 +1271,7 @@ struct mtk_eth {
|
||||
struct clk *clks[MTK_CLK_MAX];
|
||||
|
||||
struct mii_bus *mii_bus;
|
||||
unsigned int mdc_divider;
|
||||
struct work_struct pending_work;
|
||||
unsigned long state;
|
||||
|
||||
|
@ -2666,7 +2666,7 @@ static int am65_cpsw_nuss_init_slave_ports(struct am65_cpsw_common *common)
|
||||
of_property_read_bool(port_np, "ti,mac-only");
|
||||
|
||||
/* get phy/link info */
|
||||
port->slave.port_np = port_np;
|
||||
port->slave.port_np = of_node_get(port_np);
|
||||
ret = of_get_phy_mode(port_np, &port->slave.phy_if);
|
||||
if (ret) {
|
||||
dev_err(dev, "%pOF read phy-mode err %d\n",
|
||||
@ -2720,6 +2720,17 @@ static void am65_cpsw_nuss_phylink_cleanup(struct am65_cpsw_common *common)
|
||||
}
|
||||
}
|
||||
|
||||
static void am65_cpsw_remove_dt(struct am65_cpsw_common *common)
|
||||
{
|
||||
struct am65_cpsw_port *port;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < common->port_num; i++) {
|
||||
port = &common->ports[i];
|
||||
of_node_put(port->slave.port_np);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
am65_cpsw_nuss_init_port_ndev(struct am65_cpsw_common *common, u32 port_idx)
|
||||
{
|
||||
@ -3622,6 +3633,7 @@ err_ndevs_clear:
|
||||
am65_cpsw_nuss_cleanup_ndev(common);
|
||||
am65_cpsw_nuss_phylink_cleanup(common);
|
||||
am65_cpts_release(common->cpts);
|
||||
am65_cpsw_remove_dt(common);
|
||||
err_of_clear:
|
||||
if (common->mdio_dev)
|
||||
of_platform_device_destroy(common->mdio_dev, NULL);
|
||||
@ -3661,6 +3673,7 @@ static void am65_cpsw_nuss_remove(struct platform_device *pdev)
|
||||
am65_cpsw_nuss_phylink_cleanup(common);
|
||||
am65_cpts_release(common->cpts);
|
||||
am65_cpsw_disable_serdes_phy(common);
|
||||
am65_cpsw_remove_dt(common);
|
||||
|
||||
if (common->mdio_dev)
|
||||
of_platform_device_destroy(common->mdio_dev, NULL);
|
||||
|
@ -412,6 +412,22 @@ static int icss_iep_perout_enable_hw(struct icss_iep *iep,
|
||||
int ret;
|
||||
u64 cmp;
|
||||
|
||||
if (!on) {
|
||||
/* Disable CMP 1 */
|
||||
regmap_update_bits(iep->map, ICSS_IEP_CMP_CFG_REG,
|
||||
IEP_CMP_CFG_CMP_EN(1), 0);
|
||||
|
||||
/* clear CMP regs */
|
||||
regmap_write(iep->map, ICSS_IEP_CMP1_REG0, 0);
|
||||
if (iep->plat_data->flags & ICSS_IEP_64BIT_COUNTER_SUPPORT)
|
||||
regmap_write(iep->map, ICSS_IEP_CMP1_REG1, 0);
|
||||
|
||||
/* Disable sync */
|
||||
regmap_write(iep->map, ICSS_IEP_SYNC_CTRL_REG, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Calculate width of the signal for PPS/PEROUT handling */
|
||||
ts.tv_sec = req->on.sec;
|
||||
ts.tv_nsec = req->on.nsec;
|
||||
@ -430,64 +446,39 @@ static int icss_iep_perout_enable_hw(struct icss_iep *iep,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (on) {
|
||||
/* Configure CMP */
|
||||
regmap_write(iep->map, ICSS_IEP_CMP1_REG0, lower_32_bits(cmp));
|
||||
if (iep->plat_data->flags & ICSS_IEP_64BIT_COUNTER_SUPPORT)
|
||||
regmap_write(iep->map, ICSS_IEP_CMP1_REG1, upper_32_bits(cmp));
|
||||
/* Configure SYNC, based on req on width */
|
||||
regmap_write(iep->map, ICSS_IEP_SYNC_PWIDTH_REG,
|
||||
div_u64(ns_width, iep->def_inc));
|
||||
regmap_write(iep->map, ICSS_IEP_SYNC0_PERIOD_REG, 0);
|
||||
regmap_write(iep->map, ICSS_IEP_SYNC_START_REG,
|
||||
div_u64(ns_start, iep->def_inc));
|
||||
regmap_write(iep->map, ICSS_IEP_SYNC_CTRL_REG, 0); /* one-shot mode */
|
||||
/* Enable CMP 1 */
|
||||
regmap_update_bits(iep->map, ICSS_IEP_CMP_CFG_REG,
|
||||
IEP_CMP_CFG_CMP_EN(1), IEP_CMP_CFG_CMP_EN(1));
|
||||
} else {
|
||||
/* Disable CMP 1 */
|
||||
regmap_update_bits(iep->map, ICSS_IEP_CMP_CFG_REG,
|
||||
IEP_CMP_CFG_CMP_EN(1), 0);
|
||||
|
||||
/* clear regs */
|
||||
regmap_write(iep->map, ICSS_IEP_CMP1_REG0, 0);
|
||||
if (iep->plat_data->flags & ICSS_IEP_64BIT_COUNTER_SUPPORT)
|
||||
regmap_write(iep->map, ICSS_IEP_CMP1_REG1, 0);
|
||||
}
|
||||
/* Configure CMP */
|
||||
regmap_write(iep->map, ICSS_IEP_CMP1_REG0, lower_32_bits(cmp));
|
||||
if (iep->plat_data->flags & ICSS_IEP_64BIT_COUNTER_SUPPORT)
|
||||
regmap_write(iep->map, ICSS_IEP_CMP1_REG1, upper_32_bits(cmp));
|
||||
/* Configure SYNC, based on req on width */
|
||||
regmap_write(iep->map, ICSS_IEP_SYNC_PWIDTH_REG,
|
||||
div_u64(ns_width, iep->def_inc));
|
||||
regmap_write(iep->map, ICSS_IEP_SYNC0_PERIOD_REG, 0);
|
||||
regmap_write(iep->map, ICSS_IEP_SYNC_START_REG,
|
||||
div_u64(ns_start, iep->def_inc));
|
||||
regmap_write(iep->map, ICSS_IEP_SYNC_CTRL_REG, 0); /* one-shot mode */
|
||||
/* Enable CMP 1 */
|
||||
regmap_update_bits(iep->map, ICSS_IEP_CMP_CFG_REG,
|
||||
IEP_CMP_CFG_CMP_EN(1), IEP_CMP_CFG_CMP_EN(1));
|
||||
} else {
|
||||
if (on) {
|
||||
u64 start_ns;
|
||||
u64 start_ns;
|
||||
|
||||
iep->period = ((u64)req->period.sec * NSEC_PER_SEC) +
|
||||
req->period.nsec;
|
||||
start_ns = ((u64)req->period.sec * NSEC_PER_SEC)
|
||||
+ req->period.nsec;
|
||||
icss_iep_update_to_next_boundary(iep, start_ns);
|
||||
iep->period = ((u64)req->period.sec * NSEC_PER_SEC) +
|
||||
req->period.nsec;
|
||||
start_ns = ((u64)req->period.sec * NSEC_PER_SEC)
|
||||
+ req->period.nsec;
|
||||
icss_iep_update_to_next_boundary(iep, start_ns);
|
||||
|
||||
regmap_write(iep->map, ICSS_IEP_SYNC_PWIDTH_REG,
|
||||
div_u64(ns_width, iep->def_inc));
|
||||
regmap_write(iep->map, ICSS_IEP_SYNC_START_REG,
|
||||
div_u64(ns_start, iep->def_inc));
|
||||
/* Enable Sync in single shot mode */
|
||||
regmap_write(iep->map, ICSS_IEP_SYNC_CTRL_REG,
|
||||
IEP_SYNC_CTRL_SYNC_N_EN(0) | IEP_SYNC_CTRL_SYNC_EN);
|
||||
/* Enable CMP 1 */
|
||||
regmap_update_bits(iep->map, ICSS_IEP_CMP_CFG_REG,
|
||||
IEP_CMP_CFG_CMP_EN(1), IEP_CMP_CFG_CMP_EN(1));
|
||||
} else {
|
||||
/* Disable CMP 1 */
|
||||
regmap_update_bits(iep->map, ICSS_IEP_CMP_CFG_REG,
|
||||
IEP_CMP_CFG_CMP_EN(1), 0);
|
||||
|
||||
/* clear CMP regs */
|
||||
regmap_write(iep->map, ICSS_IEP_CMP1_REG0, 0);
|
||||
if (iep->plat_data->flags & ICSS_IEP_64BIT_COUNTER_SUPPORT)
|
||||
regmap_write(iep->map, ICSS_IEP_CMP1_REG1, 0);
|
||||
|
||||
/* Disable sync */
|
||||
regmap_write(iep->map, ICSS_IEP_SYNC_CTRL_REG, 0);
|
||||
}
|
||||
regmap_write(iep->map, ICSS_IEP_SYNC_PWIDTH_REG,
|
||||
div_u64(ns_width, iep->def_inc));
|
||||
regmap_write(iep->map, ICSS_IEP_SYNC_START_REG,
|
||||
div_u64(ns_start, iep->def_inc));
|
||||
/* Enable Sync in single shot mode */
|
||||
regmap_write(iep->map, ICSS_IEP_SYNC_CTRL_REG,
|
||||
IEP_SYNC_CTRL_SYNC_N_EN(0) | IEP_SYNC_CTRL_SYNC_EN);
|
||||
/* Enable CMP 1 */
|
||||
regmap_update_bits(iep->map, ICSS_IEP_CMP_CFG_REG,
|
||||
IEP_CMP_CFG_CMP_EN(1), IEP_CMP_CFG_CMP_EN(1));
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -498,11 +489,21 @@ static int icss_iep_perout_enable(struct icss_iep *iep,
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (!on)
|
||||
goto disable;
|
||||
|
||||
/* Reject requests with unsupported flags */
|
||||
if (req->flags & ~(PTP_PEROUT_DUTY_CYCLE |
|
||||
PTP_PEROUT_PHASE))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
/* Set default "on" time (1ms) for the signal if not passed by the app */
|
||||
if (!(req->flags & PTP_PEROUT_DUTY_CYCLE)) {
|
||||
req->on.sec = 0;
|
||||
req->on.nsec = NSEC_PER_MSEC;
|
||||
}
|
||||
|
||||
disable:
|
||||
mutex_lock(&iep->ptp_clk_mutex);
|
||||
|
||||
if (iep->pps_enabled) {
|
||||
@ -513,12 +514,6 @@ static int icss_iep_perout_enable(struct icss_iep *iep,
|
||||
if (iep->perout_enabled == !!on)
|
||||
goto exit;
|
||||
|
||||
/* Set default "on" time (1ms) for the signal if not passed by the app */
|
||||
if (!(req->flags & PTP_PEROUT_DUTY_CYCLE)) {
|
||||
req->on.sec = 0;
|
||||
req->on.nsec = NSEC_PER_MSEC;
|
||||
}
|
||||
|
||||
ret = icss_iep_perout_enable_hw(iep, req, on);
|
||||
if (!ret)
|
||||
iep->perout_enabled = !!on;
|
||||
|
@ -583,7 +583,7 @@ u32 emac_xmit_xdp_frame(struct prueth_emac *emac,
|
||||
first_desc = k3_cppi_desc_pool_alloc(tx_chn->desc_pool);
|
||||
if (!first_desc) {
|
||||
netdev_dbg(ndev, "xdp tx: failed to allocate descriptor\n");
|
||||
goto drop_free_descs; /* drop */
|
||||
return ICSSG_XDP_CONSUMED; /* drop */
|
||||
}
|
||||
|
||||
if (page) { /* already DMA mapped by page_pool */
|
||||
@ -671,8 +671,10 @@ static u32 emac_run_xdp(struct prueth_emac *emac, struct xdp_buff *xdp,
|
||||
|
||||
q_idx = smp_processor_id() % emac->tx_ch_num;
|
||||
result = emac_xmit_xdp_frame(emac, xdpf, page, q_idx);
|
||||
if (result == ICSSG_XDP_CONSUMED)
|
||||
if (result == ICSSG_XDP_CONSUMED) {
|
||||
ndev->stats.tx_dropped++;
|
||||
goto drop;
|
||||
}
|
||||
|
||||
dev_sw_netstats_rx_add(ndev, xdpf->len);
|
||||
return result;
|
||||
@ -1215,9 +1217,6 @@ void prueth_reset_rx_chan(struct prueth_rx_chn *chn,
|
||||
prueth_rx_cleanup);
|
||||
if (disable)
|
||||
k3_udma_glue_disable_rx_chn(chn->rx_chn);
|
||||
|
||||
page_pool_destroy(chn->pg_pool);
|
||||
chn->pg_pool = NULL;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(prueth_reset_rx_chan);
|
||||
|
||||
|
@ -625,7 +625,7 @@ static int ngbe_probe(struct pci_dev *pdev,
|
||||
/* setup the private structure */
|
||||
err = ngbe_sw_init(wx);
|
||||
if (err)
|
||||
goto err_free_mac_table;
|
||||
goto err_pci_release_regions;
|
||||
|
||||
/* check if flash load is done after hw power up */
|
||||
err = wx_check_flash_load(wx, NGBE_SPI_ILDR_STATUS_PERST);
|
||||
@ -719,6 +719,7 @@ err_register:
|
||||
err_clear_interrupt_scheme:
|
||||
wx_clear_interrupt_scheme(wx);
|
||||
err_free_mac_table:
|
||||
kfree(wx->rss_key);
|
||||
kfree(wx->mac_table);
|
||||
err_pci_release_regions:
|
||||
pci_release_selected_regions(pdev,
|
||||
|
@ -611,7 +611,7 @@ static int txgbe_probe(struct pci_dev *pdev,
|
||||
/* setup the private structure */
|
||||
err = txgbe_sw_init(wx);
|
||||
if (err)
|
||||
goto err_free_mac_table;
|
||||
goto err_pci_release_regions;
|
||||
|
||||
/* check if flash load is done after hw power up */
|
||||
err = wx_check_flash_load(wx, TXGBE_SPI_ILDR_STATUS_PERST);
|
||||
@ -769,6 +769,7 @@ err_release_hw:
|
||||
wx_clear_interrupt_scheme(wx);
|
||||
wx_control_hw(wx, false);
|
||||
err_free_mac_table:
|
||||
kfree(wx->rss_key);
|
||||
kfree(wx->mac_table);
|
||||
err_pci_release_regions:
|
||||
pci_release_selected_regions(pdev,
|
||||
|
@ -2552,7 +2552,7 @@ static void at76_disconnect(struct usb_interface *interface)
|
||||
|
||||
wiphy_info(priv->hw->wiphy, "disconnecting\n");
|
||||
at76_delete_device(priv);
|
||||
usb_put_dev(priv->udev);
|
||||
usb_put_dev(interface_to_usbdev(interface));
|
||||
dev_info(&interface->dev, "disconnected\n");
|
||||
}
|
||||
|
||||
|
@ -561,8 +561,10 @@ struct brcmf_mp_device *brcmf_get_module_param(struct device *dev,
|
||||
if (!found) {
|
||||
/* No platform data for this device, try OF and DMI data */
|
||||
brcmf_dmi_probe(settings, chip, chiprev);
|
||||
if (brcmf_of_probe(dev, bus_type, settings) == -EPROBE_DEFER)
|
||||
if (brcmf_of_probe(dev, bus_type, settings) == -EPROBE_DEFER) {
|
||||
kfree(settings);
|
||||
return ERR_PTR(-EPROBE_DEFER);
|
||||
}
|
||||
brcmf_acpi_probe(dev, bus_type, settings);
|
||||
}
|
||||
return settings;
|
||||
|
@ -1895,7 +1895,6 @@ int iwl_mld_wowlan_resume(struct iwl_mld *mld)
|
||||
int link_id;
|
||||
int ret;
|
||||
bool fw_err = false;
|
||||
bool keep_connection;
|
||||
|
||||
lockdep_assert_wiphy(mld->wiphy);
|
||||
|
||||
@ -1965,7 +1964,7 @@ int iwl_mld_wowlan_resume(struct iwl_mld *mld)
|
||||
iwl_mld_process_netdetect_res(mld, bss_vif, &resume_data);
|
||||
mld->netdetect = false;
|
||||
} else {
|
||||
keep_connection =
|
||||
bool keep_connection =
|
||||
iwl_mld_process_wowlan_status(mld, bss_vif,
|
||||
resume_data.wowlan_status);
|
||||
|
||||
@ -1973,11 +1972,10 @@ int iwl_mld_wowlan_resume(struct iwl_mld *mld)
|
||||
if (keep_connection)
|
||||
iwl_mld_unblock_emlsr(mld, bss_vif,
|
||||
IWL_MLD_EMLSR_BLOCKED_WOWLAN);
|
||||
else
|
||||
ieee80211_resume_disconnect(bss_vif);
|
||||
}
|
||||
|
||||
if (!mld->netdetect && !keep_connection)
|
||||
ieee80211_resume_disconnect(bss_vif);
|
||||
|
||||
goto out;
|
||||
|
||||
err:
|
||||
|
@ -396,8 +396,8 @@ static ssize_t iwl_dbgfs_tas_get_status_read(struct iwl_mld *mld, char *buf,
|
||||
.data[0] = &cmd,
|
||||
};
|
||||
struct iwl_dhc_tas_status_resp *resp = NULL;
|
||||
u32 resp_len = 0;
|
||||
ssize_t pos = 0;
|
||||
u32 resp_len;
|
||||
u32 status;
|
||||
int ret;
|
||||
|
||||
|
@ -166,7 +166,7 @@ struct iwl_mld_vif {
|
||||
|
||||
struct iwl_mld_emlsr emlsr;
|
||||
|
||||
#if CONFIG_PM_SLEEP
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
struct iwl_mld_wowlan_data wowlan_data;
|
||||
#endif
|
||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||
|
@ -475,8 +475,8 @@ static
|
||||
int iwl_mld_mac80211_start(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw);
|
||||
int ret;
|
||||
bool in_d3 = false;
|
||||
int ret = 0;
|
||||
|
||||
lockdep_assert_wiphy(mld->wiphy);
|
||||
|
||||
@ -537,7 +537,8 @@ void iwl_mld_mac80211_stop(struct ieee80211_hw *hw, bool suspend)
|
||||
/* if the suspend flow fails the fw is in error. Stop it here, and it
|
||||
* will be started upon wakeup
|
||||
*/
|
||||
if (!suspend || iwl_mld_no_wowlan_suspend(mld))
|
||||
if (!suspend ||
|
||||
(IS_ENABLED(CONFIG_PM_SLEEP) && iwl_mld_no_wowlan_suspend(mld)))
|
||||
iwl_mld_stop_fw(mld);
|
||||
|
||||
/* HW is stopped, no more coming RX. OTOH, the worker can't run as the
|
||||
@ -1943,6 +1944,7 @@ static void iwl_mld_sta_rc_update(struct ieee80211_hw *hw,
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static void iwl_mld_set_wakeup(struct ieee80211_hw *hw, bool enabled)
|
||||
{
|
||||
struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw);
|
||||
@ -1994,6 +1996,7 @@ static int iwl_mld_resume(struct ieee80211_hw *hw)
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int iwl_mld_alloc_ptk_pn(struct iwl_mld *mld,
|
||||
struct iwl_mld_sta *mld_sta,
|
||||
|
@ -147,8 +147,14 @@ static void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans)
|
||||
return;
|
||||
|
||||
if (trans->state >= IWL_TRANS_FW_STARTED &&
|
||||
trans_pcie->fw_reset_handshake)
|
||||
trans_pcie->fw_reset_handshake) {
|
||||
/*
|
||||
* Reset handshake can dump firmware on timeout, but that
|
||||
* should assume that the firmware is already dead.
|
||||
*/
|
||||
trans->state = IWL_TRANS_NO_FW;
|
||||
iwl_trans_pcie_fw_reset_handshake(trans);
|
||||
}
|
||||
|
||||
trans_pcie->is_down = true;
|
||||
|
||||
|
@ -342,8 +342,10 @@ void wl1251_tx_work(struct work_struct *work)
|
||||
while ((skb = skb_dequeue(&wl->tx_queue))) {
|
||||
if (!woken_up) {
|
||||
ret = wl1251_ps_elp_wakeup(wl);
|
||||
if (ret < 0)
|
||||
if (ret < 0) {
|
||||
skb_queue_head(&wl->tx_queue, skb);
|
||||
goto out;
|
||||
}
|
||||
woken_up = true;
|
||||
}
|
||||
|
||||
|
@ -2067,6 +2067,7 @@ ptp_ocp_signal_set(struct ptp_ocp *bp, int gen, struct ptp_ocp_signal *s)
|
||||
if (!s->start) {
|
||||
/* roundup() does not work on 32-bit systems */
|
||||
s->start = DIV64_U64_ROUND_UP(start_ns, s->period);
|
||||
s->start *= s->period;
|
||||
s->start = ktime_add(s->start, s->phase);
|
||||
}
|
||||
|
||||
|
@ -45,6 +45,8 @@ struct fib_rule {
|
||||
struct fib_rule_port_range dport_range;
|
||||
u16 sport_mask;
|
||||
u16 dport_mask;
|
||||
u8 iif_is_l3_master;
|
||||
u8 oif_is_l3_master;
|
||||
struct rcu_head rcu;
|
||||
};
|
||||
|
||||
|
@ -38,6 +38,7 @@ struct flowi_common {
|
||||
__u8 flowic_flags;
|
||||
#define FLOWI_FLAG_ANYSRC 0x01
|
||||
#define FLOWI_FLAG_KNOWN_NH 0x02
|
||||
#define FLOWI_FLAG_L3MDEV_OIF 0x04
|
||||
__u32 flowic_secid;
|
||||
kuid_t flowic_uid;
|
||||
__u32 flowic_multipath_hash;
|
||||
|
@ -59,6 +59,20 @@ int l3mdev_ifindex_lookup_by_table_id(enum l3mdev_type l3type, struct net *net,
|
||||
int l3mdev_fib_rule_match(struct net *net, struct flowi *fl,
|
||||
struct fib_lookup_arg *arg);
|
||||
|
||||
static inline
|
||||
bool l3mdev_fib_rule_iif_match(const struct flowi *fl, int iifindex)
|
||||
{
|
||||
return !(fl->flowi_flags & FLOWI_FLAG_L3MDEV_OIF) &&
|
||||
fl->flowi_l3mdev == iifindex;
|
||||
}
|
||||
|
||||
static inline
|
||||
bool l3mdev_fib_rule_oif_match(const struct flowi *fl, int oifindex)
|
||||
{
|
||||
return fl->flowi_flags & FLOWI_FLAG_L3MDEV_OIF &&
|
||||
fl->flowi_l3mdev == oifindex;
|
||||
}
|
||||
|
||||
void l3mdev_update_flow(struct net *net, struct flowi *fl);
|
||||
|
||||
int l3mdev_master_ifindex_rcu(const struct net_device *dev);
|
||||
@ -327,6 +341,19 @@ int l3mdev_fib_rule_match(struct net *net, struct flowi *fl,
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline
|
||||
bool l3mdev_fib_rule_iif_match(const struct flowi *fl, int iifindex)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline
|
||||
bool l3mdev_fib_rule_oif_match(const struct flowi *fl, int oifindex)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline
|
||||
void l3mdev_update_flow(struct net *net, struct flowi *fl)
|
||||
{
|
||||
|
@ -725,7 +725,6 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
|
||||
|
||||
kref_get(&hard_iface->refcount);
|
||||
|
||||
dev_hold(mesh_iface);
|
||||
netdev_hold(mesh_iface, &hard_iface->meshif_dev_tracker, GFP_ATOMIC);
|
||||
hard_iface->mesh_iface = mesh_iface;
|
||||
bat_priv = netdev_priv(hard_iface->mesh_iface);
|
||||
|
@ -3072,6 +3072,7 @@ void hci_setup_tx_timestamp(struct sk_buff *skb, size_t key_offset,
|
||||
const struct sockcm_cookie *sockc)
|
||||
{
|
||||
struct sock *sk = skb ? skb->sk : NULL;
|
||||
int key;
|
||||
|
||||
/* This shall be called on a single skb of those generated by user
|
||||
* sendmsg(), and only when the sendmsg() does not return error to
|
||||
@ -3087,13 +3088,16 @@ void hci_setup_tx_timestamp(struct sk_buff *skb, size_t key_offset,
|
||||
|
||||
sock_tx_timestamp(sk, sockc, &skb_shinfo(skb)->tx_flags);
|
||||
|
||||
if (sk->sk_type == SOCK_STREAM)
|
||||
key = atomic_add_return(key_offset, &sk->sk_tskey);
|
||||
|
||||
if (sockc->tsflags & SOF_TIMESTAMPING_OPT_ID &&
|
||||
sockc->tsflags & SOF_TIMESTAMPING_TX_RECORD_MASK) {
|
||||
if (sockc->tsflags & SOCKCM_FLAG_TS_OPT_ID) {
|
||||
skb_shinfo(skb)->tskey = sockc->ts_opt_id;
|
||||
} else {
|
||||
int key = atomic_add_return(key_offset, &sk->sk_tskey);
|
||||
|
||||
if (sk->sk_type != SOCK_STREAM)
|
||||
key = atomic_inc_return(&sk->sk_tskey);
|
||||
skb_shinfo(skb)->tskey = key - 1;
|
||||
}
|
||||
}
|
||||
|
@ -6160,11 +6160,12 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
|
||||
* event or send an immediate device found event if the data
|
||||
* should not be stored for later.
|
||||
*/
|
||||
if (!ext_adv && !has_pending_adv_report(hdev)) {
|
||||
if (!has_pending_adv_report(hdev)) {
|
||||
/* If the report will trigger a SCAN_REQ store it for
|
||||
* later merging.
|
||||
*/
|
||||
if (type == LE_ADV_IND || type == LE_ADV_SCAN_IND) {
|
||||
if (!ext_adv && (type == LE_ADV_IND ||
|
||||
type == LE_ADV_SCAN_IND)) {
|
||||
store_pending_adv_report(hdev, bdaddr, bdaddr_type,
|
||||
rssi, flags, data, len);
|
||||
return;
|
||||
|
@ -3991,7 +3991,8 @@ static void l2cap_connect(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd,
|
||||
|
||||
/* Check if the ACL is secure enough (if not SDP) */
|
||||
if (psm != cpu_to_le16(L2CAP_PSM_SDP) &&
|
||||
!hci_conn_check_link_mode(conn->hcon)) {
|
||||
(!hci_conn_check_link_mode(conn->hcon) ||
|
||||
!l2cap_check_enc_key_size(conn->hcon))) {
|
||||
conn->disc_reason = HCI_ERROR_AUTH_FAILURE;
|
||||
result = L2CAP_CR_SEC_BLOCK;
|
||||
goto response;
|
||||
@ -7538,8 +7539,24 @@ void l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
|
||||
if (skb->len > len) {
|
||||
BT_ERR("Frame is too long (len %u, expected len %d)",
|
||||
skb->len, len);
|
||||
/* PTS test cases L2CAP/COS/CED/BI-14-C and BI-15-C
|
||||
* (Multiple Signaling Command in one PDU, Data
|
||||
* Truncated, BR/EDR) send a C-frame to the IUT with
|
||||
* PDU Length set to 8 and Channel ID set to the
|
||||
* correct signaling channel for the logical link.
|
||||
* The Information payload contains one L2CAP_ECHO_REQ
|
||||
* packet with Data Length set to 0 with 0 octets of
|
||||
* echo data and one invalid command packet due to
|
||||
* data truncated in PDU but present in HCI packet.
|
||||
*
|
||||
* Shorter the socket buffer to the PDU length to
|
||||
* allow to process valid commands from the PDU before
|
||||
* setting the socket unreliable.
|
||||
*/
|
||||
skb->len = len;
|
||||
l2cap_recv_frame(conn, skb);
|
||||
l2cap_conn_unreliable(conn, ECOMM);
|
||||
goto drop;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
/* Append fragment into frame (with header) */
|
||||
|
@ -715,8 +715,8 @@ static int br_vlan_add_existing(struct net_bridge *br,
|
||||
u16 flags, bool *changed,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
bool would_change = __vlan_flags_would_change(vlan, flags);
|
||||
bool becomes_brentry = false;
|
||||
bool would_change = false;
|
||||
int err;
|
||||
|
||||
if (!br_vlan_is_brentry(vlan)) {
|
||||
@ -725,6 +725,8 @@ static int br_vlan_add_existing(struct net_bridge *br,
|
||||
return -EINVAL;
|
||||
|
||||
becomes_brentry = true;
|
||||
} else {
|
||||
would_change = __vlan_flags_would_change(vlan, flags);
|
||||
}
|
||||
|
||||
/* Master VLANs that aren't brentries weren't notified before,
|
||||
|
@ -655,6 +655,7 @@ static int j1939_sk_release(struct socket *sock)
|
||||
sock->sk = NULL;
|
||||
|
||||
release_sock(sk);
|
||||
sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
|
||||
sock_put(sk);
|
||||
|
||||
return 0;
|
||||
|
@ -1520,6 +1520,8 @@ EXPORT_SYMBOL(netdev_features_change);
|
||||
|
||||
void netif_state_change(struct net_device *dev)
|
||||
{
|
||||
netdev_ops_assert_locked_or_invisible(dev);
|
||||
|
||||
if (dev->flags & IFF_UP) {
|
||||
struct netdev_notifier_change_info change_info = {
|
||||
.info.dev = dev,
|
||||
@ -11932,15 +11934,24 @@ void unregister_netdevice_many_notify(struct list_head *head,
|
||||
BUG_ON(dev->reg_state != NETREG_REGISTERED);
|
||||
}
|
||||
|
||||
/* If device is running, close it first. */
|
||||
/* If device is running, close it first. Start with ops locked... */
|
||||
list_for_each_entry(dev, head, unreg_list) {
|
||||
list_add_tail(&dev->close_list, &close_head);
|
||||
netdev_lock_ops(dev);
|
||||
if (netdev_need_ops_lock(dev)) {
|
||||
list_add_tail(&dev->close_list, &close_head);
|
||||
netdev_lock(dev);
|
||||
}
|
||||
}
|
||||
dev_close_many(&close_head, true);
|
||||
/* ... now unlock them and go over the rest. */
|
||||
list_for_each_entry(dev, head, unreg_list) {
|
||||
if (netdev_need_ops_lock(dev))
|
||||
netdev_unlock(dev);
|
||||
else
|
||||
list_add_tail(&dev->close_list, &close_head);
|
||||
}
|
||||
dev_close_many(&close_head, true);
|
||||
|
||||
list_for_each_entry(dev, head, unreg_list) {
|
||||
netdev_unlock_ops(dev);
|
||||
/* And unlink it from device chain. */
|
||||
unlist_netdevice(dev);
|
||||
netdev_lock(dev);
|
||||
|
@ -257,6 +257,24 @@ static int nla_put_port_range(struct sk_buff *skb, int attrtype,
|
||||
return nla_put(skb, attrtype, sizeof(*range), range);
|
||||
}
|
||||
|
||||
static bool fib_rule_iif_match(const struct fib_rule *rule, int iifindex,
|
||||
const struct flowi *fl)
|
||||
{
|
||||
u8 iif_is_l3_master = READ_ONCE(rule->iif_is_l3_master);
|
||||
|
||||
return iif_is_l3_master ? l3mdev_fib_rule_iif_match(fl, iifindex) :
|
||||
fl->flowi_iif == iifindex;
|
||||
}
|
||||
|
||||
static bool fib_rule_oif_match(const struct fib_rule *rule, int oifindex,
|
||||
const struct flowi *fl)
|
||||
{
|
||||
u8 oif_is_l3_master = READ_ONCE(rule->oif_is_l3_master);
|
||||
|
||||
return oif_is_l3_master ? l3mdev_fib_rule_oif_match(fl, oifindex) :
|
||||
fl->flowi_oif == oifindex;
|
||||
}
|
||||
|
||||
static int fib_rule_match(struct fib_rule *rule, struct fib_rules_ops *ops,
|
||||
struct flowi *fl, int flags,
|
||||
struct fib_lookup_arg *arg)
|
||||
@ -264,11 +282,11 @@ static int fib_rule_match(struct fib_rule *rule, struct fib_rules_ops *ops,
|
||||
int iifindex, oifindex, ret = 0;
|
||||
|
||||
iifindex = READ_ONCE(rule->iifindex);
|
||||
if (iifindex && (iifindex != fl->flowi_iif))
|
||||
if (iifindex && !fib_rule_iif_match(rule, iifindex, fl))
|
||||
goto out;
|
||||
|
||||
oifindex = READ_ONCE(rule->oifindex);
|
||||
if (oifindex && (oifindex != fl->flowi_oif))
|
||||
if (oifindex && !fib_rule_oif_match(rule, oifindex, fl))
|
||||
goto out;
|
||||
|
||||
if ((rule->mark ^ fl->flowi_mark) & rule->mark_mask)
|
||||
@ -736,16 +754,20 @@ static int fib_nl2rule_rtnl(struct fib_rule *nlrule,
|
||||
struct net_device *dev;
|
||||
|
||||
dev = __dev_get_by_name(nlrule->fr_net, nlrule->iifname);
|
||||
if (dev)
|
||||
if (dev) {
|
||||
nlrule->iifindex = dev->ifindex;
|
||||
nlrule->iif_is_l3_master = netif_is_l3_master(dev);
|
||||
}
|
||||
}
|
||||
|
||||
if (tb[FRA_OIFNAME]) {
|
||||
struct net_device *dev;
|
||||
|
||||
dev = __dev_get_by_name(nlrule->fr_net, nlrule->oifname);
|
||||
if (dev)
|
||||
if (dev) {
|
||||
nlrule->oifindex = dev->ifindex;
|
||||
nlrule->oif_is_l3_master = netif_is_l3_master(dev);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -1336,11 +1358,17 @@ static void attach_rules(struct list_head *rules, struct net_device *dev)
|
||||
|
||||
list_for_each_entry(rule, rules, list) {
|
||||
if (rule->iifindex == -1 &&
|
||||
strcmp(dev->name, rule->iifname) == 0)
|
||||
strcmp(dev->name, rule->iifname) == 0) {
|
||||
WRITE_ONCE(rule->iifindex, dev->ifindex);
|
||||
WRITE_ONCE(rule->iif_is_l3_master,
|
||||
netif_is_l3_master(dev));
|
||||
}
|
||||
if (rule->oifindex == -1 &&
|
||||
strcmp(dev->name, rule->oifname) == 0)
|
||||
strcmp(dev->name, rule->oifname) == 0) {
|
||||
WRITE_ONCE(rule->oifindex, dev->ifindex);
|
||||
WRITE_ONCE(rule->oif_is_l3_master,
|
||||
netif_is_l3_master(dev));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1349,10 +1377,14 @@ static void detach_rules(struct list_head *rules, struct net_device *dev)
|
||||
struct fib_rule *rule;
|
||||
|
||||
list_for_each_entry(rule, rules, list) {
|
||||
if (rule->iifindex == dev->ifindex)
|
||||
if (rule->iifindex == dev->ifindex) {
|
||||
WRITE_ONCE(rule->iifindex, -1);
|
||||
if (rule->oifindex == dev->ifindex)
|
||||
WRITE_ONCE(rule->iif_is_l3_master, false);
|
||||
}
|
||||
if (rule->oifindex == dev->ifindex) {
|
||||
WRITE_ONCE(rule->oifindex, -1);
|
||||
WRITE_ONCE(rule->oif_is_l3_master, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3676,11 +3676,8 @@ struct net_device *rtnl_create_link(struct net *net, const char *ifname,
|
||||
nla_len(tb[IFLA_BROADCAST]));
|
||||
if (tb[IFLA_TXQLEN])
|
||||
dev->tx_queue_len = nla_get_u32(tb[IFLA_TXQLEN]);
|
||||
if (tb[IFLA_OPERSTATE]) {
|
||||
netdev_lock_ops(dev);
|
||||
if (tb[IFLA_OPERSTATE])
|
||||
set_operstate(dev, nla_get_u8(tb[IFLA_OPERSTATE]));
|
||||
netdev_unlock_ops(dev);
|
||||
}
|
||||
if (tb[IFLA_LINKMODE])
|
||||
dev->link_mode = nla_get_u8(tb[IFLA_LINKMODE]);
|
||||
if (tb[IFLA_GROUP])
|
||||
|
@ -862,6 +862,16 @@ static void dsa_tree_teardown_lags(struct dsa_switch_tree *dst)
|
||||
kfree(dst->lags);
|
||||
}
|
||||
|
||||
static void dsa_tree_teardown_routing_table(struct dsa_switch_tree *dst)
|
||||
{
|
||||
struct dsa_link *dl, *next;
|
||||
|
||||
list_for_each_entry_safe(dl, next, &dst->rtable, list) {
|
||||
list_del(&dl->list);
|
||||
kfree(dl);
|
||||
}
|
||||
}
|
||||
|
||||
static int dsa_tree_setup(struct dsa_switch_tree *dst)
|
||||
{
|
||||
bool complete;
|
||||
@ -879,7 +889,7 @@ static int dsa_tree_setup(struct dsa_switch_tree *dst)
|
||||
|
||||
err = dsa_tree_setup_cpu_ports(dst);
|
||||
if (err)
|
||||
return err;
|
||||
goto teardown_rtable;
|
||||
|
||||
err = dsa_tree_setup_switches(dst);
|
||||
if (err)
|
||||
@ -911,14 +921,14 @@ teardown_switches:
|
||||
dsa_tree_teardown_switches(dst);
|
||||
teardown_cpu_ports:
|
||||
dsa_tree_teardown_cpu_ports(dst);
|
||||
teardown_rtable:
|
||||
dsa_tree_teardown_routing_table(dst);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void dsa_tree_teardown(struct dsa_switch_tree *dst)
|
||||
{
|
||||
struct dsa_link *dl, *next;
|
||||
|
||||
if (!dst->setup)
|
||||
return;
|
||||
|
||||
@ -932,10 +942,7 @@ static void dsa_tree_teardown(struct dsa_switch_tree *dst)
|
||||
|
||||
dsa_tree_teardown_cpu_ports(dst);
|
||||
|
||||
list_for_each_entry_safe(dl, next, &dst->rtable, list) {
|
||||
list_del(&dl->list);
|
||||
kfree(dl);
|
||||
}
|
||||
dsa_tree_teardown_routing_table(dst);
|
||||
|
||||
pr_info("DSA: tree %d torn down\n", dst->index);
|
||||
|
||||
@ -1478,12 +1485,44 @@ static int dsa_switch_parse(struct dsa_switch *ds, struct dsa_chip_data *cd)
|
||||
|
||||
static void dsa_switch_release_ports(struct dsa_switch *ds)
|
||||
{
|
||||
struct dsa_mac_addr *a, *tmp;
|
||||
struct dsa_port *dp, *next;
|
||||
struct dsa_vlan *v, *n;
|
||||
|
||||
dsa_switch_for_each_port_safe(dp, next, ds) {
|
||||
WARN_ON(!list_empty(&dp->fdbs));
|
||||
WARN_ON(!list_empty(&dp->mdbs));
|
||||
WARN_ON(!list_empty(&dp->vlans));
|
||||
/* These are either entries that upper layers lost track of
|
||||
* (probably due to bugs), or installed through interfaces
|
||||
* where one does not necessarily have to remove them, like
|
||||
* ndo_dflt_fdb_add().
|
||||
*/
|
||||
list_for_each_entry_safe(a, tmp, &dp->fdbs, list) {
|
||||
dev_info(ds->dev,
|
||||
"Cleaning up unicast address %pM vid %u from port %d\n",
|
||||
a->addr, a->vid, dp->index);
|
||||
list_del(&a->list);
|
||||
kfree(a);
|
||||
}
|
||||
|
||||
list_for_each_entry_safe(a, tmp, &dp->mdbs, list) {
|
||||
dev_info(ds->dev,
|
||||
"Cleaning up multicast address %pM vid %u from port %d\n",
|
||||
a->addr, a->vid, dp->index);
|
||||
list_del(&a->list);
|
||||
kfree(a);
|
||||
}
|
||||
|
||||
/* These are entries that upper layers have lost track of,
|
||||
* probably due to bugs, but also due to dsa_port_do_vlan_del()
|
||||
* having failed and the VLAN entry still lingering on.
|
||||
*/
|
||||
list_for_each_entry_safe(v, n, &dp->vlans, list) {
|
||||
dev_info(ds->dev,
|
||||
"Cleaning up vid %u from port %d\n",
|
||||
v->vid, dp->index);
|
||||
list_del(&v->list);
|
||||
kfree(v);
|
||||
}
|
||||
|
||||
list_del(&dp->list);
|
||||
kfree(dp);
|
||||
}
|
||||
|
@ -197,7 +197,7 @@ static int dsa_port_do_tag_8021q_vlan_del(struct dsa_port *dp, u16 vid)
|
||||
|
||||
err = ds->ops->tag_8021q_vlan_del(ds, port, vid);
|
||||
if (err) {
|
||||
refcount_inc(&v->refcount);
|
||||
refcount_set(&v->refcount, 1);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -351,7 +351,7 @@ ethtool_cmis_module_poll(struct net_device *dev,
|
||||
struct netlink_ext_ack extack = {};
|
||||
int err;
|
||||
|
||||
ethtool_cmis_page_init(&page_data, 0, offset, sizeof(rpl));
|
||||
ethtool_cmis_page_init(&page_data, 0, offset, sizeof(*rpl));
|
||||
page_data.data = (u8 *)rpl;
|
||||
|
||||
err = ops->get_module_eeprom_by_page(dev, &page_data, &extack);
|
||||
|
@ -1771,6 +1771,7 @@ out:
|
||||
if (!err) {
|
||||
spin_lock_bh(&f6i->fib6_table->tb6_lock);
|
||||
fib6_update_sernum(net, f6i);
|
||||
fib6_add_gc_list(f6i);
|
||||
spin_unlock_bh(&f6i->fib6_table->tb6_lock);
|
||||
fib6_force_start_gc(net);
|
||||
}
|
||||
|
@ -277,8 +277,10 @@ void l3mdev_update_flow(struct net *net, struct flowi *fl)
|
||||
if (fl->flowi_oif) {
|
||||
dev = dev_get_by_index_rcu(net, fl->flowi_oif);
|
||||
if (dev) {
|
||||
if (!fl->flowi_l3mdev)
|
||||
if (!fl->flowi_l3mdev) {
|
||||
fl->flowi_l3mdev = l3mdev_master_ifindex_rcu(dev);
|
||||
fl->flowi_flags |= FLOWI_FLAG_L3MDEV_OIF;
|
||||
}
|
||||
|
||||
/* oif set to L3mdev directs lookup to its table;
|
||||
* reset to avoid oif match in fib_lookup
|
||||
|
@ -659,6 +659,9 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do
|
||||
if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
|
||||
ieee80211_txq_remove_vlan(local, sdata);
|
||||
|
||||
if (sdata->vif.txq)
|
||||
ieee80211_txq_purge(sdata->local, to_txq_info(sdata->vif.txq));
|
||||
|
||||
sdata->bss = NULL;
|
||||
|
||||
if (local->open_count == 0)
|
||||
|
@ -630,6 +630,9 @@ static int mctp_sk_hash(struct sock *sk)
|
||||
{
|
||||
struct net *net = sock_net(sk);
|
||||
|
||||
/* Bind lookup runs under RCU, remain live during that. */
|
||||
sock_set_flag(sk, SOCK_RCU_FREE);
|
||||
|
||||
mutex_lock(&net->mctp.bind_lock);
|
||||
sk_add_node_rcu(sk, &net->mctp.binds);
|
||||
mutex_unlock(&net->mctp.bind_lock);
|
||||
|
@ -383,8 +383,8 @@ static void flow_offload_del(struct nf_flowtable *flow_table,
|
||||
void flow_offload_teardown(struct flow_offload *flow)
|
||||
{
|
||||
clear_bit(IPS_OFFLOAD_BIT, &flow->ct->status);
|
||||
set_bit(NF_FLOW_TEARDOWN, &flow->flags);
|
||||
flow_offload_fixup_ct(flow);
|
||||
if (!test_and_set_bit(NF_FLOW_TEARDOWN, &flow->flags))
|
||||
flow_offload_fixup_ct(flow);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(flow_offload_teardown);
|
||||
|
||||
@ -558,10 +558,12 @@ static void nf_flow_offload_gc_step(struct nf_flowtable *flow_table,
|
||||
|
||||
if (nf_flow_has_expired(flow) ||
|
||||
nf_ct_is_dying(flow->ct) ||
|
||||
nf_flow_custom_gc(flow_table, flow))
|
||||
nf_flow_custom_gc(flow_table, flow)) {
|
||||
flow_offload_teardown(flow);
|
||||
else if (!teardown)
|
||||
teardown = true;
|
||||
} else if (!teardown) {
|
||||
nf_flow_table_extend_ct_timeout(flow->ct);
|
||||
}
|
||||
|
||||
if (teardown) {
|
||||
if (test_bit(NF_FLOW_HW, &flow->flags)) {
|
||||
|
@ -2876,7 +2876,8 @@ static int validate_set(const struct nlattr *a,
|
||||
size_t key_len;
|
||||
|
||||
/* There can be only one key in a action */
|
||||
if (nla_total_size(nla_len(ovs_key)) != nla_len(a))
|
||||
if (!nla_ok(ovs_key, nla_len(a)) ||
|
||||
nla_total_size(nla_len(ovs_key)) != nla_len(a))
|
||||
return -EINVAL;
|
||||
|
||||
key_len = nla_len(ovs_key);
|
||||
|
@ -362,6 +362,9 @@ static void smc_destruct(struct sock *sk)
|
||||
return;
|
||||
}
|
||||
|
||||
static struct lock_class_key smc_key;
|
||||
static struct lock_class_key smc_slock_key;
|
||||
|
||||
void smc_sk_init(struct net *net, struct sock *sk, int protocol)
|
||||
{
|
||||
struct smc_sock *smc = smc_sk(sk);
|
||||
@ -375,6 +378,8 @@ void smc_sk_init(struct net *net, struct sock *sk, int protocol)
|
||||
INIT_WORK(&smc->connect_work, smc_connect_work);
|
||||
INIT_DELAYED_WORK(&smc->conn.tx_work, smc_tx_work);
|
||||
INIT_LIST_HEAD(&smc->accept_q);
|
||||
sock_lock_init_class_and_name(sk, "slock-AF_SMC", &smc_slock_key,
|
||||
"sk_lock-AF_SMC", &smc_key);
|
||||
spin_lock_init(&smc->accept_q_lock);
|
||||
spin_lock_init(&smc->conn.send_lock);
|
||||
sk->sk_prot->hash(sk);
|
||||
|
@ -162,9 +162,15 @@ class Type(SpecAttr):
|
||||
def free_needs_iter(self):
|
||||
return False
|
||||
|
||||
def free(self, ri, var, ref):
|
||||
def _free_lines(self, ri, var, ref):
|
||||
if self.is_multi_val() or self.presence_type() == 'len':
|
||||
ri.cw.p(f'free({var}->{ref}{self.c_name});')
|
||||
return [f'free({var}->{ref}{self.c_name});']
|
||||
return []
|
||||
|
||||
def free(self, ri, var, ref):
|
||||
lines = self._free_lines(ri, var, ref)
|
||||
for line in lines:
|
||||
ri.cw.p(line)
|
||||
|
||||
def arg_member(self, ri):
|
||||
member = self._complex_member_type(ri)
|
||||
@ -263,6 +269,10 @@ class Type(SpecAttr):
|
||||
var = "req"
|
||||
member = f"{var}->{'.'.join(ref)}"
|
||||
|
||||
local_vars = []
|
||||
if self.free_needs_iter():
|
||||
local_vars += ['unsigned int i;']
|
||||
|
||||
code = []
|
||||
presence = ''
|
||||
for i in range(0, len(ref)):
|
||||
@ -272,6 +282,10 @@ class Type(SpecAttr):
|
||||
if i == len(ref) - 1 and self.presence_type() != 'bit':
|
||||
continue
|
||||
code.append(presence + ' = 1;')
|
||||
ref_path = '.'.join(ref[:-1])
|
||||
if ref_path:
|
||||
ref_path += '.'
|
||||
code += self._free_lines(ri, var, ref_path)
|
||||
code += self._setter_lines(ri, member, presence)
|
||||
|
||||
func_name = f"{op_prefix(ri, direction, deref=deref)}_set_{'_'.join(ref)}"
|
||||
@ -279,7 +293,8 @@ class Type(SpecAttr):
|
||||
alloc = bool([x for x in code if 'alloc(' in x])
|
||||
if free and not alloc:
|
||||
func_name = '__' + func_name
|
||||
ri.cw.write_func('static inline void', func_name, body=code,
|
||||
ri.cw.write_func('static inline void', func_name, local_vars=local_vars,
|
||||
body=code,
|
||||
args=[f'{type_name(ri, direction, deref=deref)} *{var}'] + self.arg_member(ri))
|
||||
|
||||
|
||||
@ -482,8 +497,7 @@ class TypeString(Type):
|
||||
['unsigned int len;']
|
||||
|
||||
def _setter_lines(self, ri, member, presence):
|
||||
return [f"free({member});",
|
||||
f"{presence}_len = strlen({self.c_name});",
|
||||
return [f"{presence}_len = strlen({self.c_name});",
|
||||
f"{member} = malloc({presence}_len + 1);",
|
||||
f'memcpy({member}, {self.c_name}, {presence}_len);',
|
||||
f'{member}[{presence}_len] = 0;']
|
||||
@ -536,8 +550,7 @@ class TypeBinary(Type):
|
||||
['unsigned int len;']
|
||||
|
||||
def _setter_lines(self, ri, member, presence):
|
||||
return [f"free({member});",
|
||||
f"{presence}_len = len;",
|
||||
return [f"{presence}_len = len;",
|
||||
f"{member} = malloc({presence}_len);",
|
||||
f'memcpy({member}, {self.c_name}, {presence}_len);']
|
||||
|
||||
@ -574,12 +587,14 @@ class TypeNest(Type):
|
||||
def _complex_member_type(self, ri):
|
||||
return self.nested_struct_type
|
||||
|
||||
def free(self, ri, var, ref):
|
||||
def _free_lines(self, ri, var, ref):
|
||||
lines = []
|
||||
at = '&'
|
||||
if self.is_recursive_for_op(ri):
|
||||
at = ''
|
||||
ri.cw.p(f'if ({var}->{ref}{self.c_name})')
|
||||
ri.cw.p(f'{self.nested_render_name}_free({at}{var}->{ref}{self.c_name});')
|
||||
lines += [f'if ({var}->{ref}{self.c_name})']
|
||||
lines += [f'{self.nested_render_name}_free({at}{var}->{ref}{self.c_name});']
|
||||
return lines
|
||||
|
||||
def _attr_typol(self):
|
||||
return f'.type = YNL_PT_NEST, .nest = &{self.nested_render_name}_nest, '
|
||||
@ -632,15 +647,19 @@ class TypeMultiAttr(Type):
|
||||
def free_needs_iter(self):
|
||||
return 'type' not in self.attr or self.attr['type'] == 'nest'
|
||||
|
||||
def free(self, ri, var, ref):
|
||||
def _free_lines(self, ri, var, ref):
|
||||
lines = []
|
||||
if self.attr['type'] in scalars:
|
||||
ri.cw.p(f"free({var}->{ref}{self.c_name});")
|
||||
lines += [f"free({var}->{ref}{self.c_name});"]
|
||||
elif 'type' not in self.attr or self.attr['type'] == 'nest':
|
||||
ri.cw.p(f"for (i = 0; i < {var}->{ref}n_{self.c_name}; i++)")
|
||||
ri.cw.p(f'{self.nested_render_name}_free(&{var}->{ref}{self.c_name}[i]);')
|
||||
ri.cw.p(f"free({var}->{ref}{self.c_name});")
|
||||
lines += [
|
||||
f"for (i = 0; i < {var}->{ref}n_{self.c_name}; i++)",
|
||||
f'{self.nested_render_name}_free(&{var}->{ref}{self.c_name}[i]);',
|
||||
f"free({var}->{ref}{self.c_name});",
|
||||
]
|
||||
else:
|
||||
raise Exception(f"Free of MultiAttr sub-type {self.attr['type']} not supported yet")
|
||||
return lines
|
||||
|
||||
def _attr_policy(self, policy):
|
||||
return self.base_type._attr_policy(policy)
|
||||
@ -654,10 +673,10 @@ class TypeMultiAttr(Type):
|
||||
def attr_put(self, ri, var):
|
||||
if self.attr['type'] in scalars:
|
||||
put_type = self.type
|
||||
ri.cw.p(f"for (unsigned int i = 0; i < {var}->n_{self.c_name}; i++)")
|
||||
ri.cw.p(f"for (i = 0; i < {var}->n_{self.c_name}; i++)")
|
||||
ri.cw.p(f"ynl_attr_put_{put_type}(nlh, {self.enum_name}, {var}->{self.c_name}[i]);")
|
||||
elif 'type' not in self.attr or self.attr['type'] == 'nest':
|
||||
ri.cw.p(f"for (unsigned int i = 0; i < {var}->n_{self.c_name}; i++)")
|
||||
ri.cw.p(f"for (i = 0; i < {var}->n_{self.c_name}; i++)")
|
||||
self._attr_put_line(ri, var, f"{self.nested_render_name}_put(nlh, " +
|
||||
f"{self.enum_name}, &{var}->{self.c_name}[i])")
|
||||
else:
|
||||
@ -666,8 +685,7 @@ class TypeMultiAttr(Type):
|
||||
def _setter_lines(self, ri, member, presence):
|
||||
# For multi-attr we have a count, not presence, hack up the presence
|
||||
presence = presence[:-(len('_present.') + len(self.c_name))] + "n_" + self.c_name
|
||||
return [f"free({member});",
|
||||
f"{member} = {self.c_name};",
|
||||
return [f"{member} = {self.c_name};",
|
||||
f"{presence} = n_{self.c_name};"]
|
||||
|
||||
|
||||
@ -696,8 +714,11 @@ class TypeArrayNest(Type):
|
||||
def _attr_get(self, ri, var):
|
||||
local_vars = ['const struct nlattr *attr2;']
|
||||
get_lines = [f'attr_{self.c_name} = attr;',
|
||||
'ynl_attr_for_each_nested(attr2, attr)',
|
||||
f'\t{var}->n_{self.c_name}++;']
|
||||
'ynl_attr_for_each_nested(attr2, attr) {',
|
||||
'\tif (ynl_attr_validate(yarg, attr2))',
|
||||
'\t\treturn YNL_PARSE_CB_ERROR;',
|
||||
f'\t{var}->n_{self.c_name}++;',
|
||||
'}']
|
||||
return get_lines, None, local_vars
|
||||
|
||||
|
||||
@ -755,6 +776,7 @@ class Struct:
|
||||
self.request = False
|
||||
self.reply = False
|
||||
self.recursive = False
|
||||
self.in_multi_val = False # used by a MultiAttr or and legacy arrays
|
||||
|
||||
self.attr_list = []
|
||||
self.attrs = dict()
|
||||
@ -1122,6 +1144,10 @@ class Family(SpecFamily):
|
||||
if attr in rs_members['reply']:
|
||||
self.pure_nested_structs[nested].reply = True
|
||||
|
||||
if spec.is_multi_val():
|
||||
child = self.pure_nested_structs.get(nested)
|
||||
child.in_multi_val = True
|
||||
|
||||
self._sort_pure_types()
|
||||
|
||||
# Propagate the request / reply / recursive
|
||||
@ -1136,6 +1162,8 @@ class Family(SpecFamily):
|
||||
struct.child_nests.update(child.child_nests)
|
||||
child.request |= struct.request
|
||||
child.reply |= struct.reply
|
||||
if spec.is_multi_val():
|
||||
child.in_multi_val = True
|
||||
if attr_set in struct.child_nests:
|
||||
struct.recursive = True
|
||||
|
||||
@ -1399,9 +1427,9 @@ class CodeWriter:
|
||||
|
||||
def write_func(self, qual_ret, name, body, args=None, local_vars=None):
|
||||
self.write_func_prot(qual_ret=qual_ret, name=name, args=args)
|
||||
self.block_start()
|
||||
self.write_func_lvar(local_vars=local_vars)
|
||||
|
||||
self.block_start()
|
||||
for line in body:
|
||||
self.p(line)
|
||||
self.block_end()
|
||||
@ -1644,11 +1672,23 @@ def put_req_nested_prototype(ri, struct, suffix=';'):
|
||||
|
||||
|
||||
def put_req_nested(ri, struct):
|
||||
local_vars = []
|
||||
init_lines = []
|
||||
|
||||
local_vars.append('struct nlattr *nest;')
|
||||
init_lines.append("nest = ynl_attr_nest_start(nlh, attr_type);")
|
||||
|
||||
for _, arg in struct.member_list():
|
||||
if arg.presence_type() == 'count':
|
||||
local_vars.append('unsigned int i;')
|
||||
break
|
||||
|
||||
put_req_nested_prototype(ri, struct, suffix='')
|
||||
ri.cw.block_start()
|
||||
ri.cw.write_func_lvar('struct nlattr *nest;')
|
||||
ri.cw.write_func_lvar(local_vars)
|
||||
|
||||
ri.cw.p("nest = ynl_attr_nest_start(nlh, attr_type);")
|
||||
for line in init_lines:
|
||||
ri.cw.p(line)
|
||||
|
||||
for _, arg in struct.member_list():
|
||||
arg.attr_put(ri, "obj")
|
||||
@ -1850,6 +1890,11 @@ def print_req(ri):
|
||||
local_vars += ['size_t hdr_len;',
|
||||
'void *hdr;']
|
||||
|
||||
for _, attr in ri.struct["request"].member_list():
|
||||
if attr.presence_type() == 'count':
|
||||
local_vars += ['unsigned int i;']
|
||||
break
|
||||
|
||||
print_prototype(ri, direction, terminate=False)
|
||||
ri.cw.block_start()
|
||||
ri.cw.write_func_lvar(local_vars)
|
||||
@ -2941,6 +2986,9 @@ def main():
|
||||
for attr_set, struct in parsed.pure_nested_structs.items():
|
||||
ri = RenderInfo(cw, parsed, args.mode, "", "", attr_set)
|
||||
print_type_full(ri, struct)
|
||||
if struct.request and struct.in_multi_val:
|
||||
free_rsp_nested_prototype(ri)
|
||||
cw.nl()
|
||||
|
||||
for op_name, op in parsed.ops.items():
|
||||
cw.p(f"/* ============== {op.enum_name} ============== */")
|
||||
|
@ -35,6 +35,7 @@ def test_zcrx(cfg) -> None:
|
||||
rx_ring = _get_rx_ring_entries(cfg)
|
||||
|
||||
try:
|
||||
ethtool(f"-G {cfg.ifname} tcp-data-split on", host=cfg.remote)
|
||||
ethtool(f"-G {cfg.ifname} rx 64", host=cfg.remote)
|
||||
ethtool(f"-X {cfg.ifname} equal {combined_chans - 1}", host=cfg.remote)
|
||||
flow_rule_id = _set_flow_rule(cfg, combined_chans - 1)
|
||||
@ -48,6 +49,7 @@ def test_zcrx(cfg) -> None:
|
||||
ethtool(f"-N {cfg.ifname} delete {flow_rule_id}", host=cfg.remote)
|
||||
ethtool(f"-X {cfg.ifname} default", host=cfg.remote)
|
||||
ethtool(f"-G {cfg.ifname} rx {rx_ring}", host=cfg.remote)
|
||||
ethtool(f"-G {cfg.ifname} tcp-data-split auto", host=cfg.remote)
|
||||
|
||||
|
||||
def test_zcrx_oneshot(cfg) -> None:
|
||||
@ -59,6 +61,7 @@ def test_zcrx_oneshot(cfg) -> None:
|
||||
rx_ring = _get_rx_ring_entries(cfg)
|
||||
|
||||
try:
|
||||
ethtool(f"-G {cfg.ifname} tcp-data-split on", host=cfg.remote)
|
||||
ethtool(f"-G {cfg.ifname} rx 64", host=cfg.remote)
|
||||
ethtool(f"-X {cfg.ifname} equal {combined_chans - 1}", host=cfg.remote)
|
||||
flow_rule_id = _set_flow_rule(cfg, combined_chans - 1)
|
||||
@ -72,6 +75,7 @@ def test_zcrx_oneshot(cfg) -> None:
|
||||
ethtool(f"-N {cfg.ifname} delete {flow_rule_id}", host=cfg.remote)
|
||||
ethtool(f"-X {cfg.ifname} default", host=cfg.remote)
|
||||
ethtool(f"-G {cfg.ifname} rx {rx_ring}", host=cfg.remote)
|
||||
ethtool(f"-G {cfg.ifname} tcp-data-split auto", host=cfg.remote)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
|
@ -359,6 +359,23 @@ fib_rule6_test()
|
||||
"$getnomatch" "iif flowlabel masked redirect to table" \
|
||||
"iif flowlabel masked no redirect to table"
|
||||
fi
|
||||
|
||||
$IP link show dev $DEV | grep -q vrf0
|
||||
if [ $? -eq 0 ]; then
|
||||
match="oif vrf0"
|
||||
getmatch="oif $DEV"
|
||||
getnomatch="oif lo"
|
||||
fib_rule6_test_match_n_redirect "$match" "$getmatch" \
|
||||
"$getnomatch" "VRF oif redirect to table" \
|
||||
"VRF oif no redirect to table"
|
||||
|
||||
match="from $SRC_IP6 iif vrf0"
|
||||
getmatch="from $SRC_IP6 iif $DEV"
|
||||
getnomatch="from $SRC_IP6 iif lo"
|
||||
fib_rule6_test_match_n_redirect "$match" "$getmatch" \
|
||||
"$getnomatch" "VRF iif redirect to table" \
|
||||
"VRF iif no redirect to table"
|
||||
fi
|
||||
}
|
||||
|
||||
fib_rule6_vrf_test()
|
||||
@ -635,6 +652,23 @@ fib_rule4_test()
|
||||
"$getnomatch" "iif dscp masked redirect to table" \
|
||||
"iif dscp masked no redirect to table"
|
||||
fi
|
||||
|
||||
$IP link show dev $DEV | grep -q vrf0
|
||||
if [ $? -eq 0 ]; then
|
||||
match="oif vrf0"
|
||||
getmatch="oif $DEV"
|
||||
getnomatch="oif lo"
|
||||
fib_rule4_test_match_n_redirect "$match" "$getmatch" \
|
||||
"$getnomatch" "VRF oif redirect to table" \
|
||||
"VRF oif no redirect to table"
|
||||
|
||||
match="from $SRC_IP iif vrf0"
|
||||
getmatch="from $SRC_IP iif $DEV"
|
||||
getnomatch="from $SRC_IP iif lo"
|
||||
fib_rule4_test_match_n_redirect "$match" "$getmatch" \
|
||||
"$getnomatch" "VRF iif redirect to table" \
|
||||
"VRF iif no redirect to table"
|
||||
fi
|
||||
}
|
||||
|
||||
fib_rule4_vrf_test()
|
||||
|
@ -412,5 +412,27 @@
|
||||
"teardown": [
|
||||
"$TC qdisc del dev $DUMMY ingress"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "33f4",
|
||||
"name": "Check echo of big filter command",
|
||||
"category": [
|
||||
"infra",
|
||||
"u32"
|
||||
],
|
||||
"plugins": {
|
||||
"requires": "nsPlugin"
|
||||
},
|
||||
"setup": [
|
||||
"$TC qdisc add dev $DUMMY parent root handle 10: fq_codel"
|
||||
],
|
||||
"cmdUnderTest": "bash -c '$TC -echo filter add dev $DUMMY parent 10: u32 match u32 0 0 $(for i in $(seq 32); do echo action pedit munge ip dport set 22; done) | grep \"added filter\"'",
|
||||
"verifyCmd": "",
|
||||
"expExitCode": "0",
|
||||
"matchCount": "0",
|
||||
"matchPattern": "",
|
||||
"teardown": [
|
||||
"$TC qdisc del dev $DUMMY parent root fq_codel"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
Loading…
x
Reference in New Issue
Block a user