Including fixes from CAN and WPAN.
Current release - regressions: - phy: micrel: correct KSZ9131RNX EEE capabilities and advertisement Current release - new code bugs: - eth: wangxun: fix vector length of interrupt cause - vsock/loopback: consistently protect the packet queue with sk_buff_head.lock - virtio/vsock: fix header length on skb merging - wpan: ca8210: fix unsigned mac_len comparison with zero Previous releases - regressions: - eth: stmmac: don't reject VLANs when IFF_PROMISC is set - eth: smsc911x: avoid PHY being resumed when interface is not up - eth: mtk_eth_soc: fix tx throughput regression with direct 1G links - eth: bnx2x: use the right build_skb() helper after core rework - wwan: iosm: fix 7560 modem crash on use on unsupported channel Previous releases - always broken: - eth: sfc: don't overwrite offload features at NIC reset - eth: r8169: fix RTL8168H and RTL8107E rx crc error - can: j1939: prevent deadlock by moving j1939_sk_errqueue() - virt: vmxnet3: use GRO callback when UPT is enabled - virt: xen: don't do grant copy across page boundary - phy: dp83869: fix default value for tx-/rx-internal-delay - dsa: ksz8: fix multiple issues with ksz8_fdb_dump - eth: mvpp2: fix classification/RSS of VLAN and fragmented packets - eth: mtk_eth_soc: fix flow block refcounting logic Misc: - constify fwnode pointers in SFP handling Signed-off-by: Jakub Kicinski <kuba@kernel.org> -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEE6jPA+I1ugmIBA4hXMUZtbf5SIrsFAmQl6Z8ACgkQMUZtbf5S Irsodw//SxeZ16kZHdSuLsUd1bWWPyANsNG4UzKsS912sD8yErzvy3OAiRvTWXxH A7t6QCFZeCHOHLXVuaHXqdyrWcC1eJdCaSnJiDffCwS2oeP9d4IBs3pyLJaeQSXJ 0bep4EcFpxPwCpzFCYNbShvKBLi8vRCX2ZjNii76eMAc0bZ/HvY0rCvULsJ3cwOo cDdsL+lbPSI6suMm5ekm8Hdt7NuSB5jxNFlj2ene4pV7DqHC/a8UErak4fOKbX4h QguePqawC22ZurzXeWvstgcNlJPoPLpcYyXGxSU8qirhbkn1WmkXR11TNEbYE4UD YvJlKIyYOxjN36/xBiJ8LpXV+BQBpfZEV/LSaWByhclVS4c2bY0KkSRfZKOBY82K ejBbMJiGaAyA86QUFkkWxC+zfHiFIywy2nOYCKBsDhW17krBOu3vaFS/jNVC7Ef4 ilk4tUXTYs3ojBUeROnuI1NcR2o0wNeCob/0U/bMMdn51khee70G/muHYTGr/NWA JAZIT/3bOWr5syarpnvtb/PtLlWcoClN022W4iExgFmzbMlQGyD46g+XhsvoXAYO wpo/js0/J+kVfuVsTSQT5MmsVjnzs1r9Y+wNJUM6dE35Z4iIXc1NJhmAZ7nJz0+P ryn8rdnIgCbqzX3DeJC0i9uv0alwLXA/xGCFRV3xflfV/nvxiR0= =/1Gi -----END PGP SIGNATURE----- Merge tag 'net-6.3-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net Pull networking fixes from Jakub Kicinski: "Including fixes from CAN and WPAN. Still quite a few bugs from this release. This pull is a bit smaller because major subtrees went into the previous one. Or maybe people took spring break off? Current release - regressions: - phy: micrel: correct KSZ9131RNX EEE capabilities and advertisement Current release - new code bugs: - eth: wangxun: fix vector length of interrupt cause - vsock/loopback: consistently protect the packet queue with sk_buff_head.lock - virtio/vsock: fix header length on skb merging - wpan: ca8210: fix unsigned mac_len comparison with zero Previous releases - regressions: - eth: stmmac: don't reject VLANs when IFF_PROMISC is set - eth: smsc911x: avoid PHY being resumed when interface is not up - eth: mtk_eth_soc: fix tx throughput regression with direct 1G links - eth: bnx2x: use the right build_skb() helper after core rework - wwan: iosm: fix 7560 modem crash on use on unsupported channel Previous releases - always broken: - eth: sfc: don't overwrite offload features at NIC reset - eth: r8169: fix RTL8168H and RTL8107E rx crc error - can: j1939: prevent deadlock by moving j1939_sk_errqueue() - virt: vmxnet3: use GRO callback when UPT is enabled - virt: xen: don't do grant copy across page boundary - phy: dp83869: fix default value for tx-/rx-internal-delay - dsa: ksz8: fix multiple issues with ksz8_fdb_dump - eth: mvpp2: fix classification/RSS of VLAN and fragmented packets - eth: mtk_eth_soc: fix flow block refcounting logic Misc: - constify fwnode pointers in SFP handling" * tag 'net-6.3-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (55 commits) net: ethernet: mtk_eth_soc: add missing ppe cache flush when deleting a flow net: ethernet: mtk_eth_soc: fix L2 offloading with DSA untag offload net: ethernet: mtk_eth_soc: fix flow block refcounting logic net: mvneta: fix potential double-frees in mvneta_txq_sw_deinit() net: dsa: sync unicast and multicast addresses for VLAN filters too net: dsa: mv88e6xxx: Enable IGMP snooping on user ports only xen/netback: use same error messages for same errors test/vsock: new skbuff appending test virtio/vsock: WARN_ONCE() for invalid state of socket virtio/vsock: fix header length on skb merging bnxt_en: Add missing 200G link speed reporting bnxt_en: Fix typo in PCI id to device description string mapping bnxt_en: Fix reporting of test result in ethtool selftest i40e: fix registers dump after run ethtool adapter self test bnx2x: use the right build_skb() helper net: ipa: compute DMA pool size properly net: wwan: iosm: fixes 7560 modem crash net: ethernet: mtk_eth_soc: fix tx throughput regression with direct 1G links ice: fix invalid check for empty list in ice_sched_assoc_vsi_to_agg() ice: add profile conflict check for AVF FDIR ...
This commit is contained in:
commit
b2bc47e9b2
@ -8216,6 +8216,7 @@ F: drivers/net/ethernet/freescale/dpaa
|
||||
|
||||
FREESCALE QORIQ DPAA FMAN DRIVER
|
||||
M: Madalin Bucur <madalin.bucur@nxp.com>
|
||||
R: Sean Anderson <sean.anderson@seco.com>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/net/fsl-fman.txt
|
||||
@ -14656,10 +14657,8 @@ F: net/ipv4/nexthop.c
|
||||
|
||||
NFC SUBSYSTEM
|
||||
M: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
|
||||
L: linux-nfc@lists.01.org (subscribers-only)
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
B: mailto:linux-nfc@lists.01.org
|
||||
F: Documentation/devicetree/bindings/net/nfc/
|
||||
F: drivers/nfc/
|
||||
F: include/linux/platform_data/nfcmrvl.h
|
||||
@ -14670,7 +14669,6 @@ F: net/nfc/
|
||||
NFC VIRTUAL NCI DEVICE DRIVER
|
||||
M: Bongsu Jeon <bongsu.jeon@samsung.com>
|
||||
L: netdev@vger.kernel.org
|
||||
L: linux-nfc@lists.01.org (subscribers-only)
|
||||
S: Supported
|
||||
F: drivers/nfc/virtual_ncidev.c
|
||||
F: tools/testing/selftests/nci/
|
||||
@ -15042,7 +15040,6 @@ F: Documentation/devicetree/bindings/sound/nxp,tfa989x.yaml
|
||||
F: sound/soc/codecs/tfa989x.c
|
||||
|
||||
NXP-NCI NFC DRIVER
|
||||
L: linux-nfc@lists.01.org (subscribers-only)
|
||||
S: Orphan
|
||||
F: Documentation/devicetree/bindings/net/nfc/nxp,nci.yaml
|
||||
F: drivers/nfc/nxp-nci
|
||||
@ -18487,7 +18484,6 @@ F: include/media/drv-intf/s3c_camif.h
|
||||
|
||||
SAMSUNG S3FWRN5 NFC DRIVER
|
||||
M: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
|
||||
L: linux-nfc@lists.01.org (subscribers-only)
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/net/nfc/samsung,s3fwrn5.yaml
|
||||
F: drivers/nfc/s3fwrn5
|
||||
@ -20980,7 +20976,6 @@ F: drivers/iio/magnetometer/tmag5273.c
|
||||
TI TRF7970A NFC DRIVER
|
||||
M: Mark Greer <mgreer@animalcreek.com>
|
||||
L: linux-wireless@vger.kernel.org
|
||||
L: linux-nfc@lists.01.org (subscribers-only)
|
||||
S: Supported
|
||||
F: Documentation/devicetree/bindings/net/nfc/ti,trf7970a.yaml
|
||||
F: drivers/nfc/trf7970a.c
|
||||
|
@ -216,6 +216,18 @@ static int b53_mmap_write64(struct b53_device *dev, u8 page, u8 reg,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int b53_mmap_phy_read16(struct b53_device *dev, int addr, int reg,
|
||||
u16 *value)
|
||||
{
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
static int b53_mmap_phy_write16(struct b53_device *dev, int addr, int reg,
|
||||
u16 value)
|
||||
{
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
static const struct b53_io_ops b53_mmap_ops = {
|
||||
.read8 = b53_mmap_read8,
|
||||
.read16 = b53_mmap_read16,
|
||||
@ -227,6 +239,8 @@ static const struct b53_io_ops b53_mmap_ops = {
|
||||
.write32 = b53_mmap_write32,
|
||||
.write48 = b53_mmap_write48,
|
||||
.write64 = b53_mmap_write64,
|
||||
.phy_read16 = b53_mmap_phy_read16,
|
||||
.phy_write16 = b53_mmap_phy_write16,
|
||||
};
|
||||
|
||||
static int b53_mmap_probe_of(struct platform_device *pdev,
|
||||
|
@ -958,15 +958,14 @@ int ksz8_fdb_dump(struct ksz_device *dev, int port,
|
||||
u16 entries = 0;
|
||||
u8 timestamp = 0;
|
||||
u8 fid;
|
||||
u8 member;
|
||||
struct alu_struct alu;
|
||||
u8 src_port;
|
||||
u8 mac[ETH_ALEN];
|
||||
|
||||
do {
|
||||
alu.is_static = false;
|
||||
ret = ksz8_r_dyn_mac_table(dev, i, alu.mac, &fid, &member,
|
||||
ret = ksz8_r_dyn_mac_table(dev, i, mac, &fid, &src_port,
|
||||
×tamp, &entries);
|
||||
if (!ret && (member & BIT(port))) {
|
||||
ret = cb(alu.mac, alu.fid, alu.is_static, data);
|
||||
if (!ret && port == src_port) {
|
||||
ret = cb(mac, fid, false, data);
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
|
@ -82,22 +82,16 @@ static const struct regmap_bus regmap_smi[] = {
|
||||
{
|
||||
.read = ksz8863_mdio_read,
|
||||
.write = ksz8863_mdio_write,
|
||||
.max_raw_read = 1,
|
||||
.max_raw_write = 1,
|
||||
},
|
||||
{
|
||||
.read = ksz8863_mdio_read,
|
||||
.write = ksz8863_mdio_write,
|
||||
.val_format_endian_default = REGMAP_ENDIAN_BIG,
|
||||
.max_raw_read = 2,
|
||||
.max_raw_write = 2,
|
||||
},
|
||||
{
|
||||
.read = ksz8863_mdio_read,
|
||||
.write = ksz8863_mdio_write,
|
||||
.val_format_endian_default = REGMAP_ENDIAN_BIG,
|
||||
.max_raw_read = 4,
|
||||
.max_raw_write = 4,
|
||||
}
|
||||
};
|
||||
|
||||
@ -108,7 +102,6 @@ static const struct regmap_config ksz8863_regmap_config[] = {
|
||||
.pad_bits = 24,
|
||||
.val_bits = 8,
|
||||
.cache_type = REGCACHE_NONE,
|
||||
.use_single_read = 1,
|
||||
.lock = ksz_regmap_lock,
|
||||
.unlock = ksz_regmap_unlock,
|
||||
},
|
||||
@ -118,7 +111,6 @@ static const struct regmap_config ksz8863_regmap_config[] = {
|
||||
.pad_bits = 24,
|
||||
.val_bits = 16,
|
||||
.cache_type = REGCACHE_NONE,
|
||||
.use_single_read = 1,
|
||||
.lock = ksz_regmap_lock,
|
||||
.unlock = ksz_regmap_unlock,
|
||||
},
|
||||
@ -128,7 +120,6 @@ static const struct regmap_config ksz8863_regmap_config[] = {
|
||||
.pad_bits = 24,
|
||||
.val_bits = 32,
|
||||
.cache_type = REGCACHE_NONE,
|
||||
.use_single_read = 1,
|
||||
.lock = ksz_regmap_lock,
|
||||
.unlock = ksz_regmap_unlock,
|
||||
}
|
||||
|
@ -404,13 +404,13 @@ static const u32 ksz8863_masks[] = {
|
||||
[VLAN_TABLE_VALID] = BIT(19),
|
||||
[STATIC_MAC_TABLE_VALID] = BIT(19),
|
||||
[STATIC_MAC_TABLE_USE_FID] = BIT(21),
|
||||
[STATIC_MAC_TABLE_FID] = GENMASK(29, 26),
|
||||
[STATIC_MAC_TABLE_FID] = GENMASK(25, 22),
|
||||
[STATIC_MAC_TABLE_OVERRIDE] = BIT(20),
|
||||
[STATIC_MAC_TABLE_FWD_PORTS] = GENMASK(18, 16),
|
||||
[DYNAMIC_MAC_TABLE_ENTRIES_H] = GENMASK(5, 0),
|
||||
[DYNAMIC_MAC_TABLE_MAC_EMPTY] = BIT(7),
|
||||
[DYNAMIC_MAC_TABLE_ENTRIES_H] = GENMASK(1, 0),
|
||||
[DYNAMIC_MAC_TABLE_MAC_EMPTY] = BIT(2),
|
||||
[DYNAMIC_MAC_TABLE_NOT_READY] = BIT(7),
|
||||
[DYNAMIC_MAC_TABLE_ENTRIES] = GENMASK(31, 28),
|
||||
[DYNAMIC_MAC_TABLE_ENTRIES] = GENMASK(31, 24),
|
||||
[DYNAMIC_MAC_TABLE_FID] = GENMASK(19, 16),
|
||||
[DYNAMIC_MAC_TABLE_SRC_PORT] = GENMASK(21, 20),
|
||||
[DYNAMIC_MAC_TABLE_TIMESTAMP] = GENMASK(23, 22),
|
||||
@ -420,10 +420,10 @@ static u8 ksz8863_shifts[] = {
|
||||
[VLAN_TABLE_MEMBERSHIP_S] = 16,
|
||||
[STATIC_MAC_FWD_PORTS] = 16,
|
||||
[STATIC_MAC_FID] = 22,
|
||||
[DYNAMIC_MAC_ENTRIES_H] = 3,
|
||||
[DYNAMIC_MAC_ENTRIES_H] = 8,
|
||||
[DYNAMIC_MAC_ENTRIES] = 24,
|
||||
[DYNAMIC_MAC_FID] = 16,
|
||||
[DYNAMIC_MAC_TIMESTAMP] = 24,
|
||||
[DYNAMIC_MAC_TIMESTAMP] = 22,
|
||||
[DYNAMIC_MAC_SRC_PORT] = 20,
|
||||
};
|
||||
|
||||
|
@ -3354,9 +3354,14 @@ static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port)
|
||||
* If this is the upstream port for this switch, enable
|
||||
* forwarding of unknown unicasts and multicasts.
|
||||
*/
|
||||
reg = MV88E6XXX_PORT_CTL0_IGMP_MLD_SNOOP |
|
||||
MV88E6185_PORT_CTL0_USE_TAG | MV88E6185_PORT_CTL0_USE_IP |
|
||||
reg = MV88E6185_PORT_CTL0_USE_TAG | MV88E6185_PORT_CTL0_USE_IP |
|
||||
MV88E6XXX_PORT_CTL0_STATE_FORWARDING;
|
||||
/* Forward any IPv4 IGMP or IPv6 MLD frames received
|
||||
* by a USER port to the CPU port to allow snooping.
|
||||
*/
|
||||
if (dsa_is_user_port(ds, port))
|
||||
reg |= MV88E6XXX_PORT_CTL0_IGMP_MLD_SNOOP;
|
||||
|
||||
err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
|
||||
if (err)
|
||||
return err;
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/overflow.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#include "realtek.h"
|
||||
@ -152,7 +153,9 @@ static int realtek_mdio_probe(struct mdio_device *mdiodev)
|
||||
if (!var)
|
||||
return -EINVAL;
|
||||
|
||||
priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL);
|
||||
priv = devm_kzalloc(&mdiodev->dev,
|
||||
size_add(sizeof(*priv), var->chip_data_sz),
|
||||
GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -672,6 +672,18 @@ static int bnx2x_fill_frag_skb(struct bnx2x *bp, struct bnx2x_fastpath *fp,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct sk_buff *
|
||||
bnx2x_build_skb(const struct bnx2x_fastpath *fp, void *data)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
if (fp->rx_frag_size)
|
||||
skb = build_skb(data, fp->rx_frag_size);
|
||||
else
|
||||
skb = slab_build_skb(data);
|
||||
return skb;
|
||||
}
|
||||
|
||||
static void bnx2x_frag_free(const struct bnx2x_fastpath *fp, void *data)
|
||||
{
|
||||
if (fp->rx_frag_size)
|
||||
@ -779,7 +791,7 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp,
|
||||
dma_unmap_single(&bp->pdev->dev, dma_unmap_addr(rx_buf, mapping),
|
||||
fp->rx_buf_size, DMA_FROM_DEVICE);
|
||||
if (likely(new_data))
|
||||
skb = build_skb(data, fp->rx_frag_size);
|
||||
skb = bnx2x_build_skb(fp, data);
|
||||
|
||||
if (likely(skb)) {
|
||||
#ifdef BNX2X_STOP_ON_ERROR
|
||||
@ -1046,7 +1058,7 @@ static int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget)
|
||||
dma_unmap_addr(rx_buf, mapping),
|
||||
fp->rx_buf_size,
|
||||
DMA_FROM_DEVICE);
|
||||
skb = build_skb(data, fp->rx_frag_size);
|
||||
skb = bnx2x_build_skb(fp, data);
|
||||
if (unlikely(!skb)) {
|
||||
bnx2x_frag_free(fp, data);
|
||||
bnx2x_fp_qstats(bp, fp)->
|
||||
|
@ -175,12 +175,12 @@ static const struct pci_device_id bnxt_pci_tbl[] = {
|
||||
{ PCI_VDEVICE(BROADCOM, 0x1750), .driver_data = BCM57508 },
|
||||
{ PCI_VDEVICE(BROADCOM, 0x1751), .driver_data = BCM57504 },
|
||||
{ PCI_VDEVICE(BROADCOM, 0x1752), .driver_data = BCM57502 },
|
||||
{ PCI_VDEVICE(BROADCOM, 0x1800), .driver_data = BCM57508_NPAR },
|
||||
{ PCI_VDEVICE(BROADCOM, 0x1800), .driver_data = BCM57502_NPAR },
|
||||
{ PCI_VDEVICE(BROADCOM, 0x1801), .driver_data = BCM57504_NPAR },
|
||||
{ PCI_VDEVICE(BROADCOM, 0x1802), .driver_data = BCM57502_NPAR },
|
||||
{ PCI_VDEVICE(BROADCOM, 0x1803), .driver_data = BCM57508_NPAR },
|
||||
{ PCI_VDEVICE(BROADCOM, 0x1802), .driver_data = BCM57508_NPAR },
|
||||
{ PCI_VDEVICE(BROADCOM, 0x1803), .driver_data = BCM57502_NPAR },
|
||||
{ PCI_VDEVICE(BROADCOM, 0x1804), .driver_data = BCM57504_NPAR },
|
||||
{ PCI_VDEVICE(BROADCOM, 0x1805), .driver_data = BCM57502_NPAR },
|
||||
{ PCI_VDEVICE(BROADCOM, 0x1805), .driver_data = BCM57508_NPAR },
|
||||
{ PCI_VDEVICE(BROADCOM, 0xd802), .driver_data = BCM58802 },
|
||||
{ PCI_VDEVICE(BROADCOM, 0xd804), .driver_data = BCM58804 },
|
||||
#ifdef CONFIG_BNXT_SRIOV
|
||||
|
@ -1226,6 +1226,7 @@ struct bnxt_link_info {
|
||||
#define BNXT_LINK_SPEED_40GB PORT_PHY_QCFG_RESP_LINK_SPEED_40GB
|
||||
#define BNXT_LINK_SPEED_50GB PORT_PHY_QCFG_RESP_LINK_SPEED_50GB
|
||||
#define BNXT_LINK_SPEED_100GB PORT_PHY_QCFG_RESP_LINK_SPEED_100GB
|
||||
#define BNXT_LINK_SPEED_200GB PORT_PHY_QCFG_RESP_LINK_SPEED_200GB
|
||||
u16 support_speeds;
|
||||
u16 support_pam4_speeds;
|
||||
u16 auto_link_speeds; /* fw adv setting */
|
||||
|
@ -1714,6 +1714,8 @@ u32 bnxt_fw_to_ethtool_speed(u16 fw_link_speed)
|
||||
return SPEED_50000;
|
||||
case BNXT_LINK_SPEED_100GB:
|
||||
return SPEED_100000;
|
||||
case BNXT_LINK_SPEED_200GB:
|
||||
return SPEED_200000;
|
||||
default:
|
||||
return SPEED_UNKNOWN;
|
||||
}
|
||||
@ -3738,6 +3740,7 @@ static void bnxt_self_test(struct net_device *dev, struct ethtool_test *etest,
|
||||
bnxt_ulp_stop(bp);
|
||||
rc = bnxt_close_nic(bp, true, false);
|
||||
if (rc) {
|
||||
etest->flags |= ETH_TEST_FL_FAILED;
|
||||
bnxt_ulp_start(bp, rc);
|
||||
return;
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ static int i40e_diag_reg_pattern_test(struct i40e_hw *hw,
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct i40e_diag_reg_test_info i40e_reg_list[] = {
|
||||
const struct i40e_diag_reg_test_info i40e_reg_list[] = {
|
||||
/* offset mask elements stride */
|
||||
{I40E_QTX_CTL(0), 0x0000FFBF, 1,
|
||||
I40E_QTX_CTL(1) - I40E_QTX_CTL(0)},
|
||||
@ -78,27 +78,28 @@ int i40e_diag_reg_test(struct i40e_hw *hw)
|
||||
{
|
||||
int ret_code = 0;
|
||||
u32 reg, mask;
|
||||
u32 elements;
|
||||
u32 i, j;
|
||||
|
||||
for (i = 0; i40e_reg_list[i].offset != 0 &&
|
||||
!ret_code; i++) {
|
||||
|
||||
elements = i40e_reg_list[i].elements;
|
||||
/* set actual reg range for dynamically allocated resources */
|
||||
if (i40e_reg_list[i].offset == I40E_QTX_CTL(0) &&
|
||||
hw->func_caps.num_tx_qp != 0)
|
||||
i40e_reg_list[i].elements = hw->func_caps.num_tx_qp;
|
||||
elements = hw->func_caps.num_tx_qp;
|
||||
if ((i40e_reg_list[i].offset == I40E_PFINT_ITRN(0, 0) ||
|
||||
i40e_reg_list[i].offset == I40E_PFINT_ITRN(1, 0) ||
|
||||
i40e_reg_list[i].offset == I40E_PFINT_ITRN(2, 0) ||
|
||||
i40e_reg_list[i].offset == I40E_QINT_TQCTL(0) ||
|
||||
i40e_reg_list[i].offset == I40E_QINT_RQCTL(0)) &&
|
||||
hw->func_caps.num_msix_vectors != 0)
|
||||
i40e_reg_list[i].elements =
|
||||
hw->func_caps.num_msix_vectors - 1;
|
||||
elements = hw->func_caps.num_msix_vectors - 1;
|
||||
|
||||
/* test register access */
|
||||
mask = i40e_reg_list[i].mask;
|
||||
for (j = 0; j < i40e_reg_list[i].elements && !ret_code; j++) {
|
||||
for (j = 0; j < elements && !ret_code; j++) {
|
||||
reg = i40e_reg_list[i].offset +
|
||||
(j * i40e_reg_list[i].stride);
|
||||
ret_code = i40e_diag_reg_pattern_test(hw, reg, mask);
|
||||
|
@ -20,7 +20,7 @@ struct i40e_diag_reg_test_info {
|
||||
u32 stride; /* bytes between each element */
|
||||
};
|
||||
|
||||
extern struct i40e_diag_reg_test_info i40e_reg_list[];
|
||||
extern const struct i40e_diag_reg_test_info i40e_reg_list[];
|
||||
|
||||
int i40e_diag_reg_test(struct i40e_hw *hw);
|
||||
int i40e_diag_eeprom_test(struct i40e_hw *hw);
|
||||
|
@ -2788,7 +2788,7 @@ static int
|
||||
ice_sched_assoc_vsi_to_agg(struct ice_port_info *pi, u32 agg_id,
|
||||
u16 vsi_handle, unsigned long *tc_bitmap)
|
||||
{
|
||||
struct ice_sched_agg_vsi_info *agg_vsi_info, *old_agg_vsi_info = NULL;
|
||||
struct ice_sched_agg_vsi_info *agg_vsi_info, *iter, *old_agg_vsi_info = NULL;
|
||||
struct ice_sched_agg_info *agg_info, *old_agg_info;
|
||||
struct ice_hw *hw = pi->hw;
|
||||
int status = 0;
|
||||
@ -2806,12 +2806,14 @@ ice_sched_assoc_vsi_to_agg(struct ice_port_info *pi, u32 agg_id,
|
||||
if (old_agg_info && old_agg_info != agg_info) {
|
||||
struct ice_sched_agg_vsi_info *vtmp;
|
||||
|
||||
list_for_each_entry_safe(old_agg_vsi_info, vtmp,
|
||||
list_for_each_entry_safe(iter, vtmp,
|
||||
&old_agg_info->agg_vsi_list,
|
||||
list_entry)
|
||||
if (old_agg_vsi_info->vsi_handle == vsi_handle)
|
||||
if (iter->vsi_handle == vsi_handle) {
|
||||
old_agg_vsi_info = iter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* check if entry already exist */
|
||||
agg_vsi_info = ice_get_agg_vsi_info(agg_info, vsi_handle);
|
||||
|
@ -1780,18 +1780,36 @@ ice_update_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx,
|
||||
int
|
||||
ice_cfg_rdma_fltr(struct ice_hw *hw, u16 vsi_handle, bool enable)
|
||||
{
|
||||
struct ice_vsi_ctx *ctx;
|
||||
struct ice_vsi_ctx *ctx, *cached_ctx;
|
||||
int status;
|
||||
|
||||
ctx = ice_get_vsi_ctx(hw, vsi_handle);
|
||||
cached_ctx = ice_get_vsi_ctx(hw, vsi_handle);
|
||||
if (!cached_ctx)
|
||||
return -ENOENT;
|
||||
|
||||
ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
|
||||
if (!ctx)
|
||||
return -EIO;
|
||||
return -ENOMEM;
|
||||
|
||||
ctx->info.q_opt_rss = cached_ctx->info.q_opt_rss;
|
||||
ctx->info.q_opt_tc = cached_ctx->info.q_opt_tc;
|
||||
ctx->info.q_opt_flags = cached_ctx->info.q_opt_flags;
|
||||
|
||||
ctx->info.valid_sections = cpu_to_le16(ICE_AQ_VSI_PROP_Q_OPT_VALID);
|
||||
|
||||
if (enable)
|
||||
ctx->info.q_opt_flags |= ICE_AQ_VSI_Q_OPT_PE_FLTR_EN;
|
||||
else
|
||||
ctx->info.q_opt_flags &= ~ICE_AQ_VSI_Q_OPT_PE_FLTR_EN;
|
||||
|
||||
return ice_update_vsi(hw, vsi_handle, ctx, NULL);
|
||||
status = ice_update_vsi(hw, vsi_handle, ctx, NULL);
|
||||
if (!status) {
|
||||
cached_ctx->info.q_opt_flags = ctx->info.q_opt_flags;
|
||||
cached_ctx->info.valid_sections |= ctx->info.valid_sections;
|
||||
}
|
||||
|
||||
kfree(ctx);
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -938,6 +938,7 @@ ice_reuse_rx_page(struct ice_rx_ring *rx_ring, struct ice_rx_buf *old_buf)
|
||||
* ice_get_rx_buf - Fetch Rx buffer and synchronize data for use
|
||||
* @rx_ring: Rx descriptor ring to transact packets on
|
||||
* @size: size of buffer to add to skb
|
||||
* @ntc: index of next to clean element
|
||||
*
|
||||
* This function will pull an Rx buffer from the ring and synchronize it
|
||||
* for use by the CPU.
|
||||
@ -1026,7 +1027,6 @@ ice_build_skb(struct ice_rx_ring *rx_ring, struct xdp_buff *xdp)
|
||||
/**
|
||||
* ice_construct_skb - Allocate skb and populate it
|
||||
* @rx_ring: Rx descriptor ring to transact packets on
|
||||
* @rx_buf: Rx buffer to pull data from
|
||||
* @xdp: xdp_buff pointing to the data
|
||||
*
|
||||
* This function allocates an skb. It then populates it with the page
|
||||
|
@ -438,6 +438,7 @@ busy:
|
||||
* ice_finalize_xdp_rx - Bump XDP Tx tail and/or flush redirect map
|
||||
* @xdp_ring: XDP ring
|
||||
* @xdp_res: Result of the receive batch
|
||||
* @first_idx: index to write from caller
|
||||
*
|
||||
* This function bumps XDP Tx tail and/or flush redirect map, and
|
||||
* should be called when a batch of packets has been processed in the
|
||||
|
@ -541,6 +541,72 @@ static void ice_vc_fdir_rem_prof_all(struct ice_vf *vf)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_vc_fdir_has_prof_conflict
|
||||
* @vf: pointer to the VF structure
|
||||
* @conf: FDIR configuration for each filter
|
||||
*
|
||||
* Check if @conf has conflicting profile with existing profiles
|
||||
*
|
||||
* Return: true on success, and false on error.
|
||||
*/
|
||||
static bool
|
||||
ice_vc_fdir_has_prof_conflict(struct ice_vf *vf,
|
||||
struct virtchnl_fdir_fltr_conf *conf)
|
||||
{
|
||||
struct ice_fdir_fltr *desc;
|
||||
|
||||
list_for_each_entry(desc, &vf->fdir.fdir_rule_list, fltr_node) {
|
||||
struct virtchnl_fdir_fltr_conf *existing_conf;
|
||||
enum ice_fltr_ptype flow_type_a, flow_type_b;
|
||||
struct ice_fdir_fltr *a, *b;
|
||||
|
||||
existing_conf = to_fltr_conf_from_desc(desc);
|
||||
a = &existing_conf->input;
|
||||
b = &conf->input;
|
||||
flow_type_a = a->flow_type;
|
||||
flow_type_b = b->flow_type;
|
||||
|
||||
/* No need to compare two rules with different tunnel types or
|
||||
* with the same protocol type.
|
||||
*/
|
||||
if (existing_conf->ttype != conf->ttype ||
|
||||
flow_type_a == flow_type_b)
|
||||
continue;
|
||||
|
||||
switch (flow_type_a) {
|
||||
case ICE_FLTR_PTYPE_NONF_IPV4_UDP:
|
||||
case ICE_FLTR_PTYPE_NONF_IPV4_TCP:
|
||||
case ICE_FLTR_PTYPE_NONF_IPV4_SCTP:
|
||||
if (flow_type_b == ICE_FLTR_PTYPE_NONF_IPV4_OTHER)
|
||||
return true;
|
||||
break;
|
||||
case ICE_FLTR_PTYPE_NONF_IPV4_OTHER:
|
||||
if (flow_type_b == ICE_FLTR_PTYPE_NONF_IPV4_UDP ||
|
||||
flow_type_b == ICE_FLTR_PTYPE_NONF_IPV4_TCP ||
|
||||
flow_type_b == ICE_FLTR_PTYPE_NONF_IPV4_SCTP)
|
||||
return true;
|
||||
break;
|
||||
case ICE_FLTR_PTYPE_NONF_IPV6_UDP:
|
||||
case ICE_FLTR_PTYPE_NONF_IPV6_TCP:
|
||||
case ICE_FLTR_PTYPE_NONF_IPV6_SCTP:
|
||||
if (flow_type_b == ICE_FLTR_PTYPE_NONF_IPV6_OTHER)
|
||||
return true;
|
||||
break;
|
||||
case ICE_FLTR_PTYPE_NONF_IPV6_OTHER:
|
||||
if (flow_type_b == ICE_FLTR_PTYPE_NONF_IPV6_UDP ||
|
||||
flow_type_b == ICE_FLTR_PTYPE_NONF_IPV6_TCP ||
|
||||
flow_type_b == ICE_FLTR_PTYPE_NONF_IPV6_SCTP)
|
||||
return true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_vc_fdir_write_flow_prof
|
||||
* @vf: pointer to the VF structure
|
||||
@ -677,6 +743,13 @@ ice_vc_fdir_config_input_set(struct ice_vf *vf, struct virtchnl_fdir_add *fltr,
|
||||
enum ice_fltr_ptype flow;
|
||||
int ret;
|
||||
|
||||
ret = ice_vc_fdir_has_prof_conflict(vf, conf);
|
||||
if (ret) {
|
||||
dev_dbg(dev, "Found flow profile conflict for VF %d\n",
|
||||
vf->vf_id);
|
||||
return ret;
|
||||
}
|
||||
|
||||
flow = input->flow_type;
|
||||
ret = ice_vc_fdir_alloc_prof(vf, flow);
|
||||
if (ret) {
|
||||
|
@ -3549,6 +3549,8 @@ static void mvneta_txq_sw_deinit(struct mvneta_port *pp,
|
||||
|
||||
netdev_tx_reset_queue(nq);
|
||||
|
||||
txq->buf = NULL;
|
||||
txq->tso_hdrs = NULL;
|
||||
txq->descs = NULL;
|
||||
txq->last_desc = 0;
|
||||
txq->next_desc_to_proc = 0;
|
||||
|
@ -62,35 +62,38 @@ static const struct mvpp2_cls_flow cls_flows[MVPP2_N_PRS_FLOWS] = {
|
||||
MVPP2_DEF_FLOW(MVPP22_FLOW_TCP4, MVPP2_FL_IP4_TCP_FRAG_UNTAG,
|
||||
MVPP22_CLS_HEK_IP4_2T,
|
||||
MVPP2_PRS_RI_VLAN_NONE | MVPP2_PRS_RI_L3_IP4 |
|
||||
MVPP2_PRS_RI_L4_TCP,
|
||||
MVPP2_PRS_RI_IP_FRAG_TRUE | MVPP2_PRS_RI_L4_TCP,
|
||||
MVPP2_PRS_IP_MASK | MVPP2_PRS_RI_VLAN_MASK),
|
||||
|
||||
MVPP2_DEF_FLOW(MVPP22_FLOW_TCP4, MVPP2_FL_IP4_TCP_FRAG_UNTAG,
|
||||
MVPP22_CLS_HEK_IP4_2T,
|
||||
MVPP2_PRS_RI_VLAN_NONE | MVPP2_PRS_RI_L3_IP4_OPT |
|
||||
MVPP2_PRS_RI_L4_TCP,
|
||||
MVPP2_PRS_RI_IP_FRAG_TRUE | MVPP2_PRS_RI_L4_TCP,
|
||||
MVPP2_PRS_IP_MASK | MVPP2_PRS_RI_VLAN_MASK),
|
||||
|
||||
MVPP2_DEF_FLOW(MVPP22_FLOW_TCP4, MVPP2_FL_IP4_TCP_FRAG_UNTAG,
|
||||
MVPP22_CLS_HEK_IP4_2T,
|
||||
MVPP2_PRS_RI_VLAN_NONE | MVPP2_PRS_RI_L3_IP4_OTHER |
|
||||
MVPP2_PRS_RI_L4_TCP,
|
||||
MVPP2_PRS_RI_IP_FRAG_TRUE | MVPP2_PRS_RI_L4_TCP,
|
||||
MVPP2_PRS_IP_MASK | MVPP2_PRS_RI_VLAN_MASK),
|
||||
|
||||
/* TCP over IPv4 flows, fragmented, with vlan tag */
|
||||
MVPP2_DEF_FLOW(MVPP22_FLOW_TCP4, MVPP2_FL_IP4_TCP_FRAG_TAG,
|
||||
MVPP22_CLS_HEK_IP4_2T | MVPP22_CLS_HEK_TAGGED,
|
||||
MVPP2_PRS_RI_L3_IP4 | MVPP2_PRS_RI_L4_TCP,
|
||||
MVPP2_PRS_RI_L3_IP4 | MVPP2_PRS_RI_IP_FRAG_TRUE |
|
||||
MVPP2_PRS_RI_L4_TCP,
|
||||
MVPP2_PRS_IP_MASK),
|
||||
|
||||
MVPP2_DEF_FLOW(MVPP22_FLOW_TCP4, MVPP2_FL_IP4_TCP_FRAG_TAG,
|
||||
MVPP22_CLS_HEK_IP4_2T | MVPP22_CLS_HEK_TAGGED,
|
||||
MVPP2_PRS_RI_L3_IP4_OPT | MVPP2_PRS_RI_L4_TCP,
|
||||
MVPP2_PRS_RI_L3_IP4_OPT | MVPP2_PRS_RI_IP_FRAG_TRUE |
|
||||
MVPP2_PRS_RI_L4_TCP,
|
||||
MVPP2_PRS_IP_MASK),
|
||||
|
||||
MVPP2_DEF_FLOW(MVPP22_FLOW_TCP4, MVPP2_FL_IP4_TCP_FRAG_TAG,
|
||||
MVPP22_CLS_HEK_IP4_2T | MVPP22_CLS_HEK_TAGGED,
|
||||
MVPP2_PRS_RI_L3_IP4_OTHER | MVPP2_PRS_RI_L4_TCP,
|
||||
MVPP2_PRS_RI_L3_IP4_OTHER | MVPP2_PRS_RI_IP_FRAG_TRUE |
|
||||
MVPP2_PRS_RI_L4_TCP,
|
||||
MVPP2_PRS_IP_MASK),
|
||||
|
||||
/* UDP over IPv4 flows, Not fragmented, no vlan tag */
|
||||
@ -132,35 +135,38 @@ static const struct mvpp2_cls_flow cls_flows[MVPP2_N_PRS_FLOWS] = {
|
||||
MVPP2_DEF_FLOW(MVPP22_FLOW_UDP4, MVPP2_FL_IP4_UDP_FRAG_UNTAG,
|
||||
MVPP22_CLS_HEK_IP4_2T,
|
||||
MVPP2_PRS_RI_VLAN_NONE | MVPP2_PRS_RI_L3_IP4 |
|
||||
MVPP2_PRS_RI_L4_UDP,
|
||||
MVPP2_PRS_RI_IP_FRAG_TRUE | MVPP2_PRS_RI_L4_UDP,
|
||||
MVPP2_PRS_IP_MASK | MVPP2_PRS_RI_VLAN_MASK),
|
||||
|
||||
MVPP2_DEF_FLOW(MVPP22_FLOW_UDP4, MVPP2_FL_IP4_UDP_FRAG_UNTAG,
|
||||
MVPP22_CLS_HEK_IP4_2T,
|
||||
MVPP2_PRS_RI_VLAN_NONE | MVPP2_PRS_RI_L3_IP4_OPT |
|
||||
MVPP2_PRS_RI_L4_UDP,
|
||||
MVPP2_PRS_RI_IP_FRAG_TRUE | MVPP2_PRS_RI_L4_UDP,
|
||||
MVPP2_PRS_IP_MASK | MVPP2_PRS_RI_VLAN_MASK),
|
||||
|
||||
MVPP2_DEF_FLOW(MVPP22_FLOW_UDP4, MVPP2_FL_IP4_UDP_FRAG_UNTAG,
|
||||
MVPP22_CLS_HEK_IP4_2T,
|
||||
MVPP2_PRS_RI_VLAN_NONE | MVPP2_PRS_RI_L3_IP4_OTHER |
|
||||
MVPP2_PRS_RI_L4_UDP,
|
||||
MVPP2_PRS_RI_IP_FRAG_TRUE | MVPP2_PRS_RI_L4_UDP,
|
||||
MVPP2_PRS_IP_MASK | MVPP2_PRS_RI_VLAN_MASK),
|
||||
|
||||
/* UDP over IPv4 flows, fragmented, with vlan tag */
|
||||
MVPP2_DEF_FLOW(MVPP22_FLOW_UDP4, MVPP2_FL_IP4_UDP_FRAG_TAG,
|
||||
MVPP22_CLS_HEK_IP4_2T | MVPP22_CLS_HEK_TAGGED,
|
||||
MVPP2_PRS_RI_L3_IP4 | MVPP2_PRS_RI_L4_UDP,
|
||||
MVPP2_PRS_RI_L3_IP4 | MVPP2_PRS_RI_IP_FRAG_TRUE |
|
||||
MVPP2_PRS_RI_L4_UDP,
|
||||
MVPP2_PRS_IP_MASK),
|
||||
|
||||
MVPP2_DEF_FLOW(MVPP22_FLOW_UDP4, MVPP2_FL_IP4_UDP_FRAG_TAG,
|
||||
MVPP22_CLS_HEK_IP4_2T | MVPP22_CLS_HEK_TAGGED,
|
||||
MVPP2_PRS_RI_L3_IP4_OPT | MVPP2_PRS_RI_L4_UDP,
|
||||
MVPP2_PRS_RI_L3_IP4_OPT | MVPP2_PRS_RI_IP_FRAG_TRUE |
|
||||
MVPP2_PRS_RI_L4_UDP,
|
||||
MVPP2_PRS_IP_MASK),
|
||||
|
||||
MVPP2_DEF_FLOW(MVPP22_FLOW_UDP4, MVPP2_FL_IP4_UDP_FRAG_TAG,
|
||||
MVPP22_CLS_HEK_IP4_2T | MVPP22_CLS_HEK_TAGGED,
|
||||
MVPP2_PRS_RI_L3_IP4_OTHER | MVPP2_PRS_RI_L4_UDP,
|
||||
MVPP2_PRS_RI_L3_IP4_OTHER | MVPP2_PRS_RI_IP_FRAG_TRUE |
|
||||
MVPP2_PRS_RI_L4_UDP,
|
||||
MVPP2_PRS_IP_MASK),
|
||||
|
||||
/* TCP over IPv6 flows, not fragmented, no vlan tag */
|
||||
|
@ -1539,8 +1539,8 @@ static int mvpp2_prs_vlan_init(struct platform_device *pdev, struct mvpp2 *priv)
|
||||
if (!priv->prs_double_vlans)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Double VLAN: 0x8100, 0x88A8 */
|
||||
err = mvpp2_prs_double_vlan_add(priv, ETH_P_8021Q, ETH_P_8021AD,
|
||||
/* Double VLAN: 0x88A8, 0x8100 */
|
||||
err = mvpp2_prs_double_vlan_add(priv, ETH_P_8021AD, ETH_P_8021Q,
|
||||
MVPP2_PRS_PORT_MASK);
|
||||
if (err)
|
||||
return err;
|
||||
@ -1607,9 +1607,10 @@ static int mvpp2_prs_vlan_init(struct platform_device *pdev, struct mvpp2 *priv)
|
||||
static int mvpp2_prs_pppoe_init(struct mvpp2 *priv)
|
||||
{
|
||||
struct mvpp2_prs_entry pe;
|
||||
int tid;
|
||||
int tid, ihl;
|
||||
|
||||
/* IPv4 over PPPoE with options */
|
||||
/* IPv4 over PPPoE with header length >= 5 */
|
||||
for (ihl = MVPP2_PRS_IPV4_IHL_MIN; ihl <= MVPP2_PRS_IPV4_IHL_MAX; ihl++) {
|
||||
tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID,
|
||||
MVPP2_PE_LAST_FREE_TID);
|
||||
if (tid < 0)
|
||||
@ -1620,11 +1621,15 @@ static int mvpp2_prs_pppoe_init(struct mvpp2 *priv)
|
||||
pe.index = tid;
|
||||
|
||||
mvpp2_prs_match_etype(&pe, 0, PPP_IP);
|
||||
mvpp2_prs_tcam_data_byte_set(&pe, MVPP2_ETH_TYPE_LEN,
|
||||
MVPP2_PRS_IPV4_HEAD | ihl,
|
||||
MVPP2_PRS_IPV4_HEAD_MASK |
|
||||
MVPP2_PRS_IPV4_IHL_MASK);
|
||||
|
||||
mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_IP4);
|
||||
mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_IP4_OPT,
|
||||
mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_IP4,
|
||||
MVPP2_PRS_RI_L3_PROTO_MASK);
|
||||
/* goto ipv4 dest-address (skip eth_type + IP-header-size - 4) */
|
||||
/* goto ipv4 dst-address (skip eth_type + IP-header-size - 4) */
|
||||
mvpp2_prs_sram_shift_set(&pe, MVPP2_ETH_TYPE_LEN +
|
||||
sizeof(struct iphdr) - 4,
|
||||
MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
|
||||
@ -1632,34 +1637,15 @@ static int mvpp2_prs_pppoe_init(struct mvpp2 *priv)
|
||||
mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L3,
|
||||
MVPP2_ETH_TYPE_LEN,
|
||||
MVPP2_PRS_SRAM_OP_SEL_UDF_ADD);
|
||||
/* Set L4 offset */
|
||||
mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L4,
|
||||
MVPP2_ETH_TYPE_LEN + (ihl * 4),
|
||||
MVPP2_PRS_SRAM_OP_SEL_UDF_ADD);
|
||||
|
||||
/* Update shadow table and hw entry */
|
||||
mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_PPPOE);
|
||||
mvpp2_prs_hw_write(priv, &pe);
|
||||
|
||||
/* IPv4 over PPPoE without options */
|
||||
tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID,
|
||||
MVPP2_PE_LAST_FREE_TID);
|
||||
if (tid < 0)
|
||||
return tid;
|
||||
|
||||
pe.index = tid;
|
||||
|
||||
mvpp2_prs_tcam_data_byte_set(&pe, MVPP2_ETH_TYPE_LEN,
|
||||
MVPP2_PRS_IPV4_HEAD |
|
||||
MVPP2_PRS_IPV4_IHL_MIN,
|
||||
MVPP2_PRS_IPV4_HEAD_MASK |
|
||||
MVPP2_PRS_IPV4_IHL_MASK);
|
||||
|
||||
/* Clear ri before updating */
|
||||
pe.sram[MVPP2_PRS_SRAM_RI_WORD] = 0x0;
|
||||
pe.sram[MVPP2_PRS_SRAM_RI_CTRL_WORD] = 0x0;
|
||||
mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_IP4,
|
||||
MVPP2_PRS_RI_L3_PROTO_MASK);
|
||||
|
||||
/* Update shadow table and hw entry */
|
||||
mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_PPPOE);
|
||||
mvpp2_prs_hw_write(priv, &pe);
|
||||
}
|
||||
|
||||
/* IPv6 over PPPoE */
|
||||
tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID,
|
||||
|
@ -763,8 +763,6 @@ static void mtk_mac_link_up(struct phylink_config *config,
|
||||
break;
|
||||
}
|
||||
|
||||
mtk_set_queue_speed(mac->hw, mac->id, speed);
|
||||
|
||||
/* Configure duplex */
|
||||
if (duplex == DUPLEX_FULL)
|
||||
mcr |= MAC_MCR_FORCE_DPX;
|
||||
@ -2059,9 +2057,6 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
|
||||
skb_checksum_none_assert(skb);
|
||||
skb->protocol = eth_type_trans(skb, netdev);
|
||||
|
||||
if (reason == MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED)
|
||||
mtk_ppe_check_skb(eth->ppe[0], skb, hash);
|
||||
|
||||
if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX) {
|
||||
if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
|
||||
if (trxd.rxd3 & RX_DMA_VTAG_V2) {
|
||||
@ -2089,6 +2084,9 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
|
||||
__vlan_hwaccel_put_tag(skb, htons(vlan_proto), vlan_tci);
|
||||
}
|
||||
|
||||
if (reason == MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED)
|
||||
mtk_ppe_check_skb(eth->ppe[0], skb, hash);
|
||||
|
||||
skb_record_rx_queue(skb, 0);
|
||||
napi_gro_receive(napi, skb);
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/if_vlan.h>
|
||||
#include <net/dst_metadata.h>
|
||||
#include <net/dsa.h>
|
||||
#include "mtk_eth_soc.h"
|
||||
#include "mtk_ppe.h"
|
||||
@ -458,6 +459,7 @@ __mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
|
||||
hwe->ib1 &= ~MTK_FOE_IB1_STATE;
|
||||
hwe->ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_INVALID);
|
||||
dma_wmb();
|
||||
mtk_ppe_cache_clear(ppe);
|
||||
}
|
||||
entry->hash = 0xffff;
|
||||
|
||||
@ -699,7 +701,9 @@ void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash)
|
||||
skb->dev->dsa_ptr->tag_ops->proto != DSA_TAG_PROTO_MTK)
|
||||
goto out;
|
||||
|
||||
if (!skb_metadata_dst(skb))
|
||||
tag += 4;
|
||||
|
||||
if (get_unaligned_be16(tag) != ETH_P_8021Q)
|
||||
break;
|
||||
|
||||
|
@ -576,6 +576,7 @@ mtk_eth_setup_tc_block(struct net_device *dev, struct flow_block_offload *f)
|
||||
if (IS_ERR(block_cb))
|
||||
return PTR_ERR(block_cb);
|
||||
|
||||
flow_block_cb_incref(block_cb);
|
||||
flow_block_cb_add(block_cb, f);
|
||||
list_add_tail(&block_cb->driver_list, &block_cb_list);
|
||||
return 0;
|
||||
@ -584,7 +585,7 @@ mtk_eth_setup_tc_block(struct net_device *dev, struct flow_block_offload *f)
|
||||
if (!block_cb)
|
||||
return -ENOENT;
|
||||
|
||||
if (flow_block_cb_decref(block_cb)) {
|
||||
if (!flow_block_cb_decref(block_cb)) {
|
||||
flow_block_cb_remove(block_cb, f);
|
||||
list_del(&block_cb->driver_list);
|
||||
}
|
||||
|
@ -826,6 +826,9 @@ static void rtl8168h_2_hw_phy_config(struct rtl8169_private *tp,
|
||||
/* disable phy pfm mode */
|
||||
phy_modify_paged(phydev, 0x0a44, 0x11, BIT(7), 0);
|
||||
|
||||
/* disable 10m pll off */
|
||||
phy_modify_paged(phydev, 0x0a43, 0x10, BIT(0), 0);
|
||||
|
||||
rtl8168g_disable_aldps(phydev);
|
||||
rtl8168g_config_eee_phy(phydev);
|
||||
}
|
||||
|
@ -1304,7 +1304,8 @@ static void efx_ef10_fini_nic(struct efx_nic *efx)
|
||||
static int efx_ef10_init_nic(struct efx_nic *efx)
|
||||
{
|
||||
struct efx_ef10_nic_data *nic_data = efx->nic_data;
|
||||
netdev_features_t hw_enc_features = 0;
|
||||
struct net_device *net_dev = efx->net_dev;
|
||||
netdev_features_t tun_feats, tso_feats;
|
||||
int rc;
|
||||
|
||||
if (nic_data->must_check_datapath_caps) {
|
||||
@ -1349,20 +1350,30 @@ static int efx_ef10_init_nic(struct efx_nic *efx)
|
||||
nic_data->must_restore_piobufs = false;
|
||||
}
|
||||
|
||||
/* add encapsulated checksum offload features */
|
||||
/* encap features might change during reset if fw variant changed */
|
||||
if (efx_has_cap(efx, VXLAN_NVGRE) && !efx_ef10_is_vf(efx))
|
||||
hw_enc_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
|
||||
/* add encapsulated TSO features */
|
||||
if (efx_has_cap(efx, TX_TSO_V2_ENCAP)) {
|
||||
netdev_features_t encap_tso_features;
|
||||
net_dev->hw_enc_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
|
||||
else
|
||||
net_dev->hw_enc_features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
|
||||
|
||||
encap_tso_features = NETIF_F_GSO_UDP_TUNNEL | NETIF_F_GSO_GRE |
|
||||
tun_feats = NETIF_F_GSO_UDP_TUNNEL | NETIF_F_GSO_GRE |
|
||||
NETIF_F_GSO_UDP_TUNNEL_CSUM | NETIF_F_GSO_GRE_CSUM;
|
||||
tso_feats = NETIF_F_TSO | NETIF_F_TSO6;
|
||||
|
||||
hw_enc_features |= encap_tso_features | NETIF_F_TSO;
|
||||
efx->net_dev->features |= encap_tso_features;
|
||||
if (efx_has_cap(efx, TX_TSO_V2_ENCAP)) {
|
||||
/* If this is first nic_init, or if it is a reset and a new fw
|
||||
* variant has added new features, enable them by default.
|
||||
* If the features are not new, maintain their current value.
|
||||
*/
|
||||
if (!(net_dev->hw_features & tun_feats))
|
||||
net_dev->features |= tun_feats;
|
||||
net_dev->hw_enc_features |= tun_feats | tso_feats;
|
||||
net_dev->hw_features |= tun_feats;
|
||||
} else {
|
||||
net_dev->hw_enc_features &= ~(tun_feats | tso_feats);
|
||||
net_dev->hw_features &= ~tun_feats;
|
||||
net_dev->features &= ~tun_feats;
|
||||
}
|
||||
efx->net_dev->hw_enc_features = hw_enc_features;
|
||||
|
||||
/* don't fail init if RSS setup doesn't work */
|
||||
rc = efx->type->rx_push_rss_config(efx, false,
|
||||
@ -4021,7 +4032,10 @@ static unsigned int efx_ef10_recycle_ring_size(const struct efx_nic *efx)
|
||||
NETIF_F_HW_VLAN_CTAG_FILTER | \
|
||||
NETIF_F_IPV6_CSUM | \
|
||||
NETIF_F_RXHASH | \
|
||||
NETIF_F_NTUPLE)
|
||||
NETIF_F_NTUPLE | \
|
||||
NETIF_F_SG | \
|
||||
NETIF_F_RXCSUM | \
|
||||
NETIF_F_RXALL)
|
||||
|
||||
const struct efx_nic_type efx_hunt_a0_vf_nic_type = {
|
||||
.is_vf = true,
|
||||
|
@ -1001,21 +1001,18 @@ static int efx_pci_probe_post_io(struct efx_nic *efx)
|
||||
}
|
||||
|
||||
/* Determine netdevice features */
|
||||
net_dev->features |= (efx->type->offload_features | NETIF_F_SG |
|
||||
NETIF_F_TSO | NETIF_F_RXCSUM | NETIF_F_RXALL);
|
||||
if (efx->type->offload_features & (NETIF_F_IPV6_CSUM | NETIF_F_HW_CSUM)) {
|
||||
net_dev->features |= NETIF_F_TSO6;
|
||||
if (efx_has_cap(efx, TX_TSO_V2_ENCAP))
|
||||
net_dev->hw_enc_features |= NETIF_F_TSO6;
|
||||
}
|
||||
/* Check whether device supports TSO */
|
||||
if (!efx->type->tso_versions || !efx->type->tso_versions(efx))
|
||||
net_dev->features &= ~NETIF_F_ALL_TSO;
|
||||
net_dev->features |= efx->type->offload_features;
|
||||
|
||||
/* Add TSO features */
|
||||
if (efx->type->tso_versions && efx->type->tso_versions(efx))
|
||||
net_dev->features |= NETIF_F_TSO | NETIF_F_TSO6;
|
||||
|
||||
/* Mask for features that also apply to VLAN devices */
|
||||
net_dev->vlan_features |= (NETIF_F_HW_CSUM | NETIF_F_SG |
|
||||
NETIF_F_HIGHDMA | NETIF_F_ALL_TSO |
|
||||
NETIF_F_RXCSUM);
|
||||
|
||||
/* Determine user configurable features */
|
||||
net_dev->hw_features |= net_dev->features & ~efx->fixed_features;
|
||||
|
||||
/* Disable receiving frames with bad FCS, by default. */
|
||||
|
@ -1037,8 +1037,6 @@ static int smsc911x_mii_probe(struct net_device *dev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Indicate that the MAC is responsible for managing PHY PM */
|
||||
phydev->mac_managed_pm = true;
|
||||
phy_attached_info(phydev);
|
||||
|
||||
phy_set_max_speed(phydev, SPEED_100);
|
||||
@ -1066,6 +1064,7 @@ static int smsc911x_mii_init(struct platform_device *pdev,
|
||||
struct net_device *dev)
|
||||
{
|
||||
struct smsc911x_data *pdata = netdev_priv(dev);
|
||||
struct phy_device *phydev;
|
||||
int err = -ENXIO;
|
||||
|
||||
pdata->mii_bus = mdiobus_alloc();
|
||||
@ -1108,6 +1107,10 @@ static int smsc911x_mii_init(struct platform_device *pdev,
|
||||
goto err_out_free_bus_2;
|
||||
}
|
||||
|
||||
phydev = phy_find_first(pdata->mii_bus);
|
||||
if (phydev)
|
||||
phydev->mac_managed_pm = true;
|
||||
|
||||
return 0;
|
||||
|
||||
err_out_free_bus_2:
|
||||
|
@ -532,7 +532,6 @@ struct mac_device_info {
|
||||
unsigned int xlgmac;
|
||||
unsigned int num_vlan;
|
||||
u32 vlan_filter[32];
|
||||
unsigned int promisc;
|
||||
bool vlan_fail_q_en;
|
||||
u8 vlan_fail_q;
|
||||
};
|
||||
|
@ -472,12 +472,6 @@ static int dwmac4_add_hw_vlan_rx_fltr(struct net_device *dev,
|
||||
if (vid > 4095)
|
||||
return -EINVAL;
|
||||
|
||||
if (hw->promisc) {
|
||||
netdev_err(dev,
|
||||
"Adding VLAN in promisc mode not supported\n");
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
/* Single Rx VLAN Filter */
|
||||
if (hw->num_vlan == 1) {
|
||||
/* For single VLAN filter, VID 0 means VLAN promiscuous */
|
||||
@ -527,12 +521,6 @@ static int dwmac4_del_hw_vlan_rx_fltr(struct net_device *dev,
|
||||
{
|
||||
int i, ret = 0;
|
||||
|
||||
if (hw->promisc) {
|
||||
netdev_err(dev,
|
||||
"Deleting VLAN in promisc mode not supported\n");
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
/* Single Rx VLAN Filter */
|
||||
if (hw->num_vlan == 1) {
|
||||
if ((hw->vlan_filter[0] & GMAC_VLAN_TAG_VID) == vid) {
|
||||
@ -557,39 +545,6 @@ static int dwmac4_del_hw_vlan_rx_fltr(struct net_device *dev,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void dwmac4_vlan_promisc_enable(struct net_device *dev,
|
||||
struct mac_device_info *hw)
|
||||
{
|
||||
void __iomem *ioaddr = hw->pcsr;
|
||||
u32 value;
|
||||
u32 hash;
|
||||
u32 val;
|
||||
int i;
|
||||
|
||||
/* Single Rx VLAN Filter */
|
||||
if (hw->num_vlan == 1) {
|
||||
dwmac4_write_single_vlan(dev, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Extended Rx VLAN Filter Enable */
|
||||
for (i = 0; i < hw->num_vlan; i++) {
|
||||
if (hw->vlan_filter[i] & GMAC_VLAN_TAG_DATA_VEN) {
|
||||
val = hw->vlan_filter[i] & ~GMAC_VLAN_TAG_DATA_VEN;
|
||||
dwmac4_write_vlan_filter(dev, hw, i, val);
|
||||
}
|
||||
}
|
||||
|
||||
hash = readl(ioaddr + GMAC_VLAN_HASH_TABLE);
|
||||
if (hash & GMAC_VLAN_VLHT) {
|
||||
value = readl(ioaddr + GMAC_VLAN_TAG);
|
||||
if (value & GMAC_VLAN_VTHM) {
|
||||
value &= ~GMAC_VLAN_VTHM;
|
||||
writel(value, ioaddr + GMAC_VLAN_TAG);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void dwmac4_restore_hw_vlan_rx_fltr(struct net_device *dev,
|
||||
struct mac_device_info *hw)
|
||||
{
|
||||
@ -709,22 +664,12 @@ static void dwmac4_set_filter(struct mac_device_info *hw,
|
||||
}
|
||||
|
||||
/* VLAN filtering */
|
||||
if (dev->features & NETIF_F_HW_VLAN_CTAG_FILTER)
|
||||
if (dev->flags & IFF_PROMISC && !hw->vlan_fail_q_en)
|
||||
value &= ~GMAC_PACKET_FILTER_VTFE;
|
||||
else if (dev->features & NETIF_F_HW_VLAN_CTAG_FILTER)
|
||||
value |= GMAC_PACKET_FILTER_VTFE;
|
||||
|
||||
writel(value, ioaddr + GMAC_PACKET_FILTER);
|
||||
|
||||
if (dev->flags & IFF_PROMISC && !hw->vlan_fail_q_en) {
|
||||
if (!hw->promisc) {
|
||||
hw->promisc = 1;
|
||||
dwmac4_vlan_promisc_enable(dev, hw);
|
||||
}
|
||||
} else {
|
||||
if (hw->promisc) {
|
||||
hw->promisc = 0;
|
||||
dwmac4_restore_hw_vlan_rx_fltr(dev, hw);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void dwmac4_flow_ctrl(struct mac_device_info *hw, unsigned int duplex,
|
||||
|
@ -222,7 +222,7 @@
|
||||
#define WX_PX_INTA 0x110
|
||||
#define WX_PX_GPIE 0x118
|
||||
#define WX_PX_GPIE_MODEL BIT(0)
|
||||
#define WX_PX_IC 0x120
|
||||
#define WX_PX_IC(_i) (0x120 + (_i) * 4)
|
||||
#define WX_PX_IMS(_i) (0x140 + (_i) * 4)
|
||||
#define WX_PX_IMC(_i) (0x150 + (_i) * 4)
|
||||
#define WX_PX_ISB_ADDR_L 0x160
|
||||
|
@ -352,7 +352,7 @@ static void ngbe_up(struct wx *wx)
|
||||
netif_tx_start_all_queues(wx->netdev);
|
||||
|
||||
/* clear any pending interrupts, may auto mask */
|
||||
rd32(wx, WX_PX_IC);
|
||||
rd32(wx, WX_PX_IC(0));
|
||||
rd32(wx, WX_PX_MISC_IC);
|
||||
ngbe_irq_enable(wx, true);
|
||||
if (wx->gpio_ctrl)
|
||||
|
@ -229,7 +229,8 @@ static void txgbe_up_complete(struct wx *wx)
|
||||
wx_napi_enable_all(wx);
|
||||
|
||||
/* clear any pending interrupts, may auto mask */
|
||||
rd32(wx, WX_PX_IC);
|
||||
rd32(wx, WX_PX_IC(0));
|
||||
rd32(wx, WX_PX_IC(1));
|
||||
rd32(wx, WX_PX_MISC_IC);
|
||||
txgbe_irq_enable(wx, true);
|
||||
|
||||
|
@ -1902,10 +1902,9 @@ static int ca8210_skb_tx(
|
||||
struct ca8210_priv *priv
|
||||
)
|
||||
{
|
||||
int status;
|
||||
struct ieee802154_hdr header = { };
|
||||
struct secspec secspec;
|
||||
unsigned int mac_len;
|
||||
int mac_len, status;
|
||||
|
||||
dev_dbg(&priv->spi->dev, "%s called\n", __func__);
|
||||
|
||||
|
@ -156,7 +156,7 @@ int gsi_trans_pool_init_dma(struct device *dev, struct gsi_trans_pool *pool,
|
||||
* gsi_trans_pool_exit_dma() can assume the total allocated
|
||||
* size is exactly (count * size).
|
||||
*/
|
||||
total_size = get_order(total_size) << PAGE_SHIFT;
|
||||
total_size = PAGE_SIZE << get_order(total_size);
|
||||
|
||||
virt = dma_alloc_coherent(dev, total_size, &addr, GFP_KERNEL);
|
||||
if (!virt)
|
||||
|
@ -130,13 +130,9 @@ static u16 net_failover_select_queue(struct net_device *dev,
|
||||
txq = ops->ndo_select_queue(primary_dev, skb, sb_dev);
|
||||
else
|
||||
txq = netdev_pick_tx(primary_dev, skb, NULL);
|
||||
|
||||
qdisc_skb_cb(skb)->slave_dev_queue_mapping = skb->queue_mapping;
|
||||
|
||||
return txq;
|
||||
}
|
||||
|
||||
} else {
|
||||
txq = skb_rx_queue_recorded(skb) ? skb_get_rx_queue(skb) : 0;
|
||||
}
|
||||
|
||||
/* Save the original txq to restore before passing to the driver */
|
||||
qdisc_skb_cb(skb)->slave_dev_queue_mapping = skb->queue_mapping;
|
||||
|
@ -588,15 +588,13 @@ static int dp83869_of_init(struct phy_device *phydev)
|
||||
&dp83869_internal_delay[0],
|
||||
delay_size, true);
|
||||
if (dp83869->rx_int_delay < 0)
|
||||
dp83869->rx_int_delay =
|
||||
dp83869_internal_delay[DP83869_CLK_DELAY_DEF];
|
||||
dp83869->rx_int_delay = DP83869_CLK_DELAY_DEF;
|
||||
|
||||
dp83869->tx_int_delay = phy_get_internal_delay(phydev, dev,
|
||||
&dp83869_internal_delay[0],
|
||||
delay_size, false);
|
||||
if (dp83869->tx_int_delay < 0)
|
||||
dp83869->tx_int_delay =
|
||||
dp83869_internal_delay[DP83869_CLK_DELAY_DEF];
|
||||
dp83869->tx_int_delay = DP83869_CLK_DELAY_DEF;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -4151,6 +4151,7 @@ static struct phy_driver ksphy_driver[] = {
|
||||
.resume = kszphy_resume,
|
||||
.cable_test_start = ksz9x31_cable_test_start,
|
||||
.cable_test_get_status = ksz9x31_cable_test_get_status,
|
||||
.get_features = ksz9477_get_features,
|
||||
}, {
|
||||
.phy_id = PHY_ID_KSZ8873MLL,
|
||||
.phy_id_mask = MICREL_PHY_ID_MASK,
|
||||
|
@ -3057,7 +3057,7 @@ EXPORT_SYMBOL_GPL(device_phy_find_device);
|
||||
* and "phy-device" are not supported in ACPI. DT supports all the three
|
||||
* named references to the phy node.
|
||||
*/
|
||||
struct fwnode_handle *fwnode_get_phy_node(struct fwnode_handle *fwnode)
|
||||
struct fwnode_handle *fwnode_get_phy_node(const struct fwnode_handle *fwnode)
|
||||
{
|
||||
struct fwnode_handle *phy_node;
|
||||
|
||||
|
@ -17,7 +17,7 @@ struct sfp_bus {
|
||||
/* private: */
|
||||
struct kref kref;
|
||||
struct list_head node;
|
||||
struct fwnode_handle *fwnode;
|
||||
const struct fwnode_handle *fwnode;
|
||||
|
||||
const struct sfp_socket_ops *socket_ops;
|
||||
struct device *sfp_dev;
|
||||
@ -390,7 +390,7 @@ static const struct sfp_upstream_ops *sfp_get_upstream_ops(struct sfp_bus *bus)
|
||||
return bus->registered ? bus->upstream_ops : NULL;
|
||||
}
|
||||
|
||||
static struct sfp_bus *sfp_bus_get(struct fwnode_handle *fwnode)
|
||||
static struct sfp_bus *sfp_bus_get(const struct fwnode_handle *fwnode)
|
||||
{
|
||||
struct sfp_bus *sfp, *new, *found = NULL;
|
||||
|
||||
@ -593,7 +593,7 @@ static void sfp_upstream_clear(struct sfp_bus *bus)
|
||||
* - %-ENOMEM if we failed to allocate the bus.
|
||||
* - an error from the upstream's connect_phy() method.
|
||||
*/
|
||||
struct sfp_bus *sfp_bus_find_fwnode(struct fwnode_handle *fwnode)
|
||||
struct sfp_bus *sfp_bus_find_fwnode(const struct fwnode_handle *fwnode)
|
||||
{
|
||||
struct fwnode_reference_args ref;
|
||||
struct sfp_bus *bus;
|
||||
|
@ -1688,7 +1688,9 @@ not_lro:
|
||||
if (unlikely(rcd->ts))
|
||||
__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), rcd->tci);
|
||||
|
||||
if (adapter->netdev->features & NETIF_F_LRO)
|
||||
/* Use GRO callback if UPT is enabled */
|
||||
if ((adapter->netdev->features & NETIF_F_LRO) &&
|
||||
!rq->shared->updateRxProd)
|
||||
netif_receive_skb(skb);
|
||||
else
|
||||
napi_gro_receive(&rq->napi, skb);
|
||||
|
@ -587,6 +587,13 @@ static void ipc_imem_run_state_worker(struct work_struct *instance)
|
||||
while (ctrl_chl_idx < IPC_MEM_MAX_CHANNELS) {
|
||||
if (!ipc_chnl_cfg_get(&chnl_cfg_port, ctrl_chl_idx)) {
|
||||
ipc_imem->ipc_port[ctrl_chl_idx] = NULL;
|
||||
|
||||
if (ipc_imem->pcie->pci->device == INTEL_CP_DEVICE_7560_ID &&
|
||||
chnl_cfg_port.wwan_port_type == WWAN_PORT_XMMRPC) {
|
||||
ctrl_chl_idx++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ipc_imem->pcie->pci->device == INTEL_CP_DEVICE_7360_ID &&
|
||||
chnl_cfg_port.wwan_port_type == WWAN_PORT_MBIM) {
|
||||
ctrl_chl_idx++;
|
||||
|
@ -166,7 +166,7 @@ struct xenvif_queue { /* Per-queue data for xenvif */
|
||||
struct pending_tx_info pending_tx_info[MAX_PENDING_REQS];
|
||||
grant_handle_t grant_tx_handle[MAX_PENDING_REQS];
|
||||
|
||||
struct gnttab_copy tx_copy_ops[MAX_PENDING_REQS];
|
||||
struct gnttab_copy tx_copy_ops[2 * MAX_PENDING_REQS];
|
||||
struct gnttab_map_grant_ref tx_map_ops[MAX_PENDING_REQS];
|
||||
struct gnttab_unmap_grant_ref tx_unmap_ops[MAX_PENDING_REQS];
|
||||
/* passed to gnttab_[un]map_refs with pages under (un)mapping */
|
||||
|
@ -334,6 +334,7 @@ static int xenvif_count_requests(struct xenvif_queue *queue,
|
||||
struct xenvif_tx_cb {
|
||||
u16 copy_pending_idx[XEN_NETBK_LEGACY_SLOTS_MAX + 1];
|
||||
u8 copy_count;
|
||||
u32 split_mask;
|
||||
};
|
||||
|
||||
#define XENVIF_TX_CB(skb) ((struct xenvif_tx_cb *)(skb)->cb)
|
||||
@ -361,6 +362,8 @@ static inline struct sk_buff *xenvif_alloc_skb(unsigned int size)
|
||||
struct sk_buff *skb =
|
||||
alloc_skb(size + NET_SKB_PAD + NET_IP_ALIGN,
|
||||
GFP_ATOMIC | __GFP_NOWARN);
|
||||
|
||||
BUILD_BUG_ON(sizeof(*XENVIF_TX_CB(skb)) > sizeof(skb->cb));
|
||||
if (unlikely(skb == NULL))
|
||||
return NULL;
|
||||
|
||||
@ -396,11 +399,13 @@ static void xenvif_get_requests(struct xenvif_queue *queue,
|
||||
nr_slots = shinfo->nr_frags + 1;
|
||||
|
||||
copy_count(skb) = 0;
|
||||
XENVIF_TX_CB(skb)->split_mask = 0;
|
||||
|
||||
/* Create copy ops for exactly data_len bytes into the skb head. */
|
||||
__skb_put(skb, data_len);
|
||||
while (data_len > 0) {
|
||||
int amount = data_len > txp->size ? txp->size : data_len;
|
||||
bool split = false;
|
||||
|
||||
cop->source.u.ref = txp->gref;
|
||||
cop->source.domid = queue->vif->domid;
|
||||
@ -413,6 +418,13 @@ static void xenvif_get_requests(struct xenvif_queue *queue,
|
||||
cop->dest.u.gmfn = virt_to_gfn(skb->data + skb_headlen(skb)
|
||||
- data_len);
|
||||
|
||||
/* Don't cross local page boundary! */
|
||||
if (cop->dest.offset + amount > XEN_PAGE_SIZE) {
|
||||
amount = XEN_PAGE_SIZE - cop->dest.offset;
|
||||
XENVIF_TX_CB(skb)->split_mask |= 1U << copy_count(skb);
|
||||
split = true;
|
||||
}
|
||||
|
||||
cop->len = amount;
|
||||
cop->flags = GNTCOPY_source_gref;
|
||||
|
||||
@ -420,6 +432,7 @@ static void xenvif_get_requests(struct xenvif_queue *queue,
|
||||
pending_idx = queue->pending_ring[index];
|
||||
callback_param(queue, pending_idx).ctx = NULL;
|
||||
copy_pending_idx(skb, copy_count(skb)) = pending_idx;
|
||||
if (!split)
|
||||
copy_count(skb)++;
|
||||
|
||||
cop++;
|
||||
@ -441,7 +454,8 @@ static void xenvif_get_requests(struct xenvif_queue *queue,
|
||||
nr_slots--;
|
||||
} else {
|
||||
/* The copy op partially covered the tx_request.
|
||||
* The remainder will be mapped.
|
||||
* The remainder will be mapped or copied in the next
|
||||
* iteration.
|
||||
*/
|
||||
txp->offset += amount;
|
||||
txp->size -= amount;
|
||||
@ -539,6 +553,13 @@ static int xenvif_tx_check_gop(struct xenvif_queue *queue,
|
||||
pending_idx = copy_pending_idx(skb, i);
|
||||
|
||||
newerr = (*gopp_copy)->status;
|
||||
|
||||
/* Split copies need to be handled together. */
|
||||
if (XENVIF_TX_CB(skb)->split_mask & (1U << i)) {
|
||||
(*gopp_copy)++;
|
||||
if (!newerr)
|
||||
newerr = (*gopp_copy)->status;
|
||||
}
|
||||
if (likely(!newerr)) {
|
||||
/* The first frag might still have this slot mapped */
|
||||
if (i < copy_count(skb) - 1 || !sharedslot)
|
||||
@ -973,10 +994,8 @@ static void xenvif_tx_build_gops(struct xenvif_queue *queue,
|
||||
|
||||
/* No crossing a page as the payload mustn't fragment. */
|
||||
if (unlikely((txreq.offset + txreq.size) > XEN_PAGE_SIZE)) {
|
||||
netdev_err(queue->vif->dev,
|
||||
"txreq.offset: %u, size: %u, end: %lu\n",
|
||||
txreq.offset, txreq.size,
|
||||
(unsigned long)(txreq.offset&~XEN_PAGE_MASK) + txreq.size);
|
||||
netdev_err(queue->vif->dev, "Cross page boundary, txreq.offset: %u, size: %u\n",
|
||||
txreq.offset, txreq.size);
|
||||
xenvif_fatal_tx_err(queue->vif);
|
||||
break;
|
||||
}
|
||||
@ -1061,10 +1080,6 @@ static void xenvif_tx_build_gops(struct xenvif_queue *queue,
|
||||
__skb_queue_tail(&queue->tx_queue, skb);
|
||||
|
||||
queue->tx.req_cons = idx;
|
||||
|
||||
if ((*map_ops >= ARRAY_SIZE(queue->tx_map_ops)) ||
|
||||
(*copy_ops >= ARRAY_SIZE(queue->tx_copy_ops)))
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
|
@ -637,7 +637,7 @@ static int ptp_qoriq_probe(struct platform_device *dev)
|
||||
return 0;
|
||||
|
||||
no_clock:
|
||||
iounmap(ptp_qoriq->base);
|
||||
iounmap(base);
|
||||
no_ioremap:
|
||||
release_resource(ptp_qoriq->rsrc);
|
||||
no_resource:
|
||||
|
@ -1547,7 +1547,7 @@ int fwnode_get_phy_id(struct fwnode_handle *fwnode, u32 *phy_id);
|
||||
struct mdio_device *fwnode_mdio_find_device(struct fwnode_handle *fwnode);
|
||||
struct phy_device *fwnode_phy_find_device(struct fwnode_handle *phy_fwnode);
|
||||
struct phy_device *device_phy_find_device(struct device *dev);
|
||||
struct fwnode_handle *fwnode_get_phy_node(struct fwnode_handle *fwnode);
|
||||
struct fwnode_handle *fwnode_get_phy_node(const struct fwnode_handle *fwnode);
|
||||
struct phy_device *get_phy_device(struct mii_bus *bus, int addr, bool is_c45);
|
||||
int phy_device_register(struct phy_device *phy);
|
||||
void phy_device_free(struct phy_device *phydev);
|
||||
|
@ -557,7 +557,7 @@ int sfp_get_module_eeprom_by_page(struct sfp_bus *bus,
|
||||
void sfp_upstream_start(struct sfp_bus *bus);
|
||||
void sfp_upstream_stop(struct sfp_bus *bus);
|
||||
void sfp_bus_put(struct sfp_bus *bus);
|
||||
struct sfp_bus *sfp_bus_find_fwnode(struct fwnode_handle *fwnode);
|
||||
struct sfp_bus *sfp_bus_find_fwnode(const struct fwnode_handle *fwnode);
|
||||
int sfp_bus_add_upstream(struct sfp_bus *bus, void *upstream,
|
||||
const struct sfp_upstream_ops *ops);
|
||||
void sfp_bus_del_upstream(struct sfp_bus *bus);
|
||||
@ -619,7 +619,8 @@ static inline void sfp_bus_put(struct sfp_bus *bus)
|
||||
{
|
||||
}
|
||||
|
||||
static inline struct sfp_bus *sfp_bus_find_fwnode(struct fwnode_handle *fwnode)
|
||||
static inline struct sfp_bus *
|
||||
sfp_bus_find_fwnode(const struct fwnode_handle *fwnode)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
@ -941,6 +941,8 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
|
||||
|
||||
cf = op->frames + op->cfsiz * i;
|
||||
err = memcpy_from_msg((u8 *)cf, msg, op->cfsiz);
|
||||
if (err < 0)
|
||||
goto free_op;
|
||||
|
||||
if (op->flags & CAN_FD_FRAME) {
|
||||
if (cf->len > 64)
|
||||
@ -950,12 +952,8 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
|
||||
err = -EINVAL;
|
||||
}
|
||||
|
||||
if (err < 0) {
|
||||
if (op->frames != &op->sframe)
|
||||
kfree(op->frames);
|
||||
kfree(op);
|
||||
return err;
|
||||
}
|
||||
if (err < 0)
|
||||
goto free_op;
|
||||
|
||||
if (msg_head->flags & TX_CP_CAN_ID) {
|
||||
/* copy can_id into frame */
|
||||
@ -1026,6 +1024,12 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
|
||||
bcm_tx_start_timer(op);
|
||||
|
||||
return msg_head->nframes * op->cfsiz + MHSIZ;
|
||||
|
||||
free_op:
|
||||
if (op->frames != &op->sframe)
|
||||
kfree(op->frames);
|
||||
kfree(op);
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1124,8 +1124,6 @@ static void __j1939_session_cancel(struct j1939_session *session,
|
||||
|
||||
if (session->sk)
|
||||
j1939_sk_send_loop_abort(session->sk, session->err);
|
||||
else
|
||||
j1939_sk_errqueue(session, J1939_ERRQUEUE_RX_ABORT);
|
||||
}
|
||||
|
||||
static void j1939_session_cancel(struct j1939_session *session,
|
||||
@ -1140,6 +1138,9 @@ static void j1939_session_cancel(struct j1939_session *session,
|
||||
}
|
||||
|
||||
j1939_session_list_unlock(session->priv);
|
||||
|
||||
if (!session->sk)
|
||||
j1939_sk_errqueue(session, J1939_ERRQUEUE_RX_ABORT);
|
||||
}
|
||||
|
||||
static enum hrtimer_restart j1939_tp_txtimer(struct hrtimer *hrtimer)
|
||||
@ -1253,6 +1254,9 @@ static enum hrtimer_restart j1939_tp_rxtimer(struct hrtimer *hrtimer)
|
||||
__j1939_session_cancel(session, J1939_XTP_ABORT_TIMEOUT);
|
||||
}
|
||||
j1939_session_list_unlock(session->priv);
|
||||
|
||||
if (!session->sk)
|
||||
j1939_sk_errqueue(session, J1939_ERRQUEUE_RX_ABORT);
|
||||
}
|
||||
|
||||
j1939_session_put(session);
|
||||
|
121
net/dsa/slave.c
121
net/dsa/slave.c
@ -57,6 +57,12 @@ struct dsa_standalone_event_work {
|
||||
u16 vid;
|
||||
};
|
||||
|
||||
struct dsa_host_vlan_rx_filtering_ctx {
|
||||
struct net_device *dev;
|
||||
const unsigned char *addr;
|
||||
enum dsa_standalone_event event;
|
||||
};
|
||||
|
||||
static bool dsa_switch_supports_uc_filtering(struct dsa_switch *ds)
|
||||
{
|
||||
return ds->ops->port_fdb_add && ds->ops->port_fdb_del &&
|
||||
@ -155,18 +161,37 @@ static int dsa_slave_schedule_standalone_work(struct net_device *dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dsa_slave_host_vlan_rx_filtering(struct net_device *vdev, int vid,
|
||||
void *arg)
|
||||
{
|
||||
struct dsa_host_vlan_rx_filtering_ctx *ctx = arg;
|
||||
|
||||
return dsa_slave_schedule_standalone_work(ctx->dev, ctx->event,
|
||||
ctx->addr, vid);
|
||||
}
|
||||
|
||||
static int dsa_slave_sync_uc(struct net_device *dev,
|
||||
const unsigned char *addr)
|
||||
{
|
||||
struct net_device *master = dsa_slave_to_master(dev);
|
||||
struct dsa_port *dp = dsa_slave_to_port(dev);
|
||||
struct dsa_host_vlan_rx_filtering_ctx ctx = {
|
||||
.dev = dev,
|
||||
.addr = addr,
|
||||
.event = DSA_UC_ADD,
|
||||
};
|
||||
int err;
|
||||
|
||||
dev_uc_add(master, addr);
|
||||
|
||||
if (!dsa_switch_supports_uc_filtering(dp->ds))
|
||||
return 0;
|
||||
|
||||
return dsa_slave_schedule_standalone_work(dev, DSA_UC_ADD, addr, 0);
|
||||
err = dsa_slave_schedule_standalone_work(dev, DSA_UC_ADD, addr, 0);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return vlan_for_each(dev, dsa_slave_host_vlan_rx_filtering, &ctx);
|
||||
}
|
||||
|
||||
static int dsa_slave_unsync_uc(struct net_device *dev,
|
||||
@ -174,13 +199,23 @@ static int dsa_slave_unsync_uc(struct net_device *dev,
|
||||
{
|
||||
struct net_device *master = dsa_slave_to_master(dev);
|
||||
struct dsa_port *dp = dsa_slave_to_port(dev);
|
||||
struct dsa_host_vlan_rx_filtering_ctx ctx = {
|
||||
.dev = dev,
|
||||
.addr = addr,
|
||||
.event = DSA_UC_DEL,
|
||||
};
|
||||
int err;
|
||||
|
||||
dev_uc_del(master, addr);
|
||||
|
||||
if (!dsa_switch_supports_uc_filtering(dp->ds))
|
||||
return 0;
|
||||
|
||||
return dsa_slave_schedule_standalone_work(dev, DSA_UC_DEL, addr, 0);
|
||||
err = dsa_slave_schedule_standalone_work(dev, DSA_UC_DEL, addr, 0);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return vlan_for_each(dev, dsa_slave_host_vlan_rx_filtering, &ctx);
|
||||
}
|
||||
|
||||
static int dsa_slave_sync_mc(struct net_device *dev,
|
||||
@ -188,13 +223,23 @@ static int dsa_slave_sync_mc(struct net_device *dev,
|
||||
{
|
||||
struct net_device *master = dsa_slave_to_master(dev);
|
||||
struct dsa_port *dp = dsa_slave_to_port(dev);
|
||||
struct dsa_host_vlan_rx_filtering_ctx ctx = {
|
||||
.dev = dev,
|
||||
.addr = addr,
|
||||
.event = DSA_MC_ADD,
|
||||
};
|
||||
int err;
|
||||
|
||||
dev_mc_add(master, addr);
|
||||
|
||||
if (!dsa_switch_supports_mc_filtering(dp->ds))
|
||||
return 0;
|
||||
|
||||
return dsa_slave_schedule_standalone_work(dev, DSA_MC_ADD, addr, 0);
|
||||
err = dsa_slave_schedule_standalone_work(dev, DSA_MC_ADD, addr, 0);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return vlan_for_each(dev, dsa_slave_host_vlan_rx_filtering, &ctx);
|
||||
}
|
||||
|
||||
static int dsa_slave_unsync_mc(struct net_device *dev,
|
||||
@ -202,13 +247,23 @@ static int dsa_slave_unsync_mc(struct net_device *dev,
|
||||
{
|
||||
struct net_device *master = dsa_slave_to_master(dev);
|
||||
struct dsa_port *dp = dsa_slave_to_port(dev);
|
||||
struct dsa_host_vlan_rx_filtering_ctx ctx = {
|
||||
.dev = dev,
|
||||
.addr = addr,
|
||||
.event = DSA_MC_DEL,
|
||||
};
|
||||
int err;
|
||||
|
||||
dev_mc_del(master, addr);
|
||||
|
||||
if (!dsa_switch_supports_mc_filtering(dp->ds))
|
||||
return 0;
|
||||
|
||||
return dsa_slave_schedule_standalone_work(dev, DSA_MC_DEL, addr, 0);
|
||||
err = dsa_slave_schedule_standalone_work(dev, DSA_MC_DEL, addr, 0);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return vlan_for_each(dev, dsa_slave_host_vlan_rx_filtering, &ctx);
|
||||
}
|
||||
|
||||
void dsa_slave_sync_ha(struct net_device *dev)
|
||||
@ -1702,6 +1757,8 @@ static int dsa_slave_vlan_rx_add_vid(struct net_device *dev, __be16 proto,
|
||||
.flags = 0,
|
||||
};
|
||||
struct netlink_ext_ack extack = {0};
|
||||
struct dsa_switch *ds = dp->ds;
|
||||
struct netdev_hw_addr *ha;
|
||||
int ret;
|
||||
|
||||
/* User port... */
|
||||
@ -1721,6 +1778,30 @@ static int dsa_slave_vlan_rx_add_vid(struct net_device *dev, __be16 proto,
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!dsa_switch_supports_uc_filtering(ds) &&
|
||||
!dsa_switch_supports_mc_filtering(ds))
|
||||
return 0;
|
||||
|
||||
netif_addr_lock_bh(dev);
|
||||
|
||||
if (dsa_switch_supports_mc_filtering(ds)) {
|
||||
netdev_for_each_synced_mc_addr(ha, dev) {
|
||||
dsa_slave_schedule_standalone_work(dev, DSA_MC_ADD,
|
||||
ha->addr, vid);
|
||||
}
|
||||
}
|
||||
|
||||
if (dsa_switch_supports_uc_filtering(ds)) {
|
||||
netdev_for_each_synced_uc_addr(ha, dev) {
|
||||
dsa_slave_schedule_standalone_work(dev, DSA_UC_ADD,
|
||||
ha->addr, vid);
|
||||
}
|
||||
}
|
||||
|
||||
netif_addr_unlock_bh(dev);
|
||||
|
||||
dsa_flush_workqueue();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1733,13 +1814,43 @@ static int dsa_slave_vlan_rx_kill_vid(struct net_device *dev, __be16 proto,
|
||||
/* This API only allows programming tagged, non-PVID VIDs */
|
||||
.flags = 0,
|
||||
};
|
||||
struct dsa_switch *ds = dp->ds;
|
||||
struct netdev_hw_addr *ha;
|
||||
int err;
|
||||
|
||||
err = dsa_port_vlan_del(dp, &vlan);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return dsa_port_host_vlan_del(dp, &vlan);
|
||||
err = dsa_port_host_vlan_del(dp, &vlan);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (!dsa_switch_supports_uc_filtering(ds) &&
|
||||
!dsa_switch_supports_mc_filtering(ds))
|
||||
return 0;
|
||||
|
||||
netif_addr_lock_bh(dev);
|
||||
|
||||
if (dsa_switch_supports_mc_filtering(ds)) {
|
||||
netdev_for_each_synced_mc_addr(ha, dev) {
|
||||
dsa_slave_schedule_standalone_work(dev, DSA_MC_DEL,
|
||||
ha->addr, vid);
|
||||
}
|
||||
}
|
||||
|
||||
if (dsa_switch_supports_uc_filtering(ds)) {
|
||||
netdev_for_each_synced_uc_addr(ha, dev) {
|
||||
dsa_slave_schedule_standalone_work(dev, DSA_UC_DEL,
|
||||
ha->addr, vid);
|
||||
}
|
||||
}
|
||||
|
||||
netif_addr_unlock_bh(dev);
|
||||
|
||||
dsa_flush_workqueue();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dsa_slave_restore_vlan(struct net_device *vdev, int vid, void *arg)
|
||||
|
@ -2488,8 +2488,7 @@ static int nl802154_del_llsec_seclevel(struct sk_buff *skb,
|
||||
if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (!info->attrs[NL802154_ATTR_SEC_LEVEL] ||
|
||||
llsec_parse_seclevel(info->attrs[NL802154_ATTR_SEC_LEVEL],
|
||||
if (llsec_parse_seclevel(info->attrs[NL802154_ATTR_SEC_LEVEL],
|
||||
&sl) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -363,6 +363,13 @@ virtio_transport_stream_do_dequeue(struct vsock_sock *vsk,
|
||||
u32 free_space;
|
||||
|
||||
spin_lock_bh(&vvs->rx_lock);
|
||||
|
||||
if (WARN_ONCE(skb_queue_empty(&vvs->rx_queue) && vvs->rx_bytes,
|
||||
"rx_queue is empty, but rx_bytes is non-zero\n")) {
|
||||
spin_unlock_bh(&vvs->rx_lock);
|
||||
return err;
|
||||
}
|
||||
|
||||
while (total < len && !skb_queue_empty(&vvs->rx_queue)) {
|
||||
skb = skb_peek(&vvs->rx_queue);
|
||||
|
||||
@ -1068,7 +1075,7 @@ virtio_transport_recv_enqueue(struct vsock_sock *vsk,
|
||||
memcpy(skb_put(last_skb, skb->len), skb->data, skb->len);
|
||||
free_pkt = true;
|
||||
last_hdr->flags |= hdr->flags;
|
||||
last_hdr->len = cpu_to_le32(last_skb->len);
|
||||
le32_add_cpu(&last_hdr->len, len);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,6 @@
|
||||
struct vsock_loopback {
|
||||
struct workqueue_struct *workqueue;
|
||||
|
||||
spinlock_t pkt_list_lock; /* protects pkt_list */
|
||||
struct sk_buff_head pkt_queue;
|
||||
struct work_struct pkt_work;
|
||||
};
|
||||
@ -32,9 +31,7 @@ static int vsock_loopback_send_pkt(struct sk_buff *skb)
|
||||
struct vsock_loopback *vsock = &the_vsock_loopback;
|
||||
int len = skb->len;
|
||||
|
||||
spin_lock_bh(&vsock->pkt_list_lock);
|
||||
skb_queue_tail(&vsock->pkt_queue, skb);
|
||||
spin_unlock_bh(&vsock->pkt_list_lock);
|
||||
|
||||
queue_work(vsock->workqueue, &vsock->pkt_work);
|
||||
|
||||
@ -113,9 +110,9 @@ static void vsock_loopback_work(struct work_struct *work)
|
||||
|
||||
skb_queue_head_init(&pkts);
|
||||
|
||||
spin_lock_bh(&vsock->pkt_list_lock);
|
||||
spin_lock_bh(&vsock->pkt_queue.lock);
|
||||
skb_queue_splice_init(&vsock->pkt_queue, &pkts);
|
||||
spin_unlock_bh(&vsock->pkt_list_lock);
|
||||
spin_unlock_bh(&vsock->pkt_queue.lock);
|
||||
|
||||
while ((skb = __skb_dequeue(&pkts))) {
|
||||
virtio_transport_deliver_tap_pkt(skb);
|
||||
@ -132,7 +129,6 @@ static int __init vsock_loopback_init(void)
|
||||
if (!vsock->workqueue)
|
||||
return -ENOMEM;
|
||||
|
||||
spin_lock_init(&vsock->pkt_list_lock);
|
||||
skb_queue_head_init(&vsock->pkt_queue);
|
||||
INIT_WORK(&vsock->pkt_work, vsock_loopback_work);
|
||||
|
||||
@ -156,9 +152,7 @@ static void __exit vsock_loopback_exit(void)
|
||||
|
||||
flush_work(&vsock->pkt_work);
|
||||
|
||||
spin_lock_bh(&vsock->pkt_list_lock);
|
||||
virtio_vsock_skb_queue_purge(&vsock->pkt_queue);
|
||||
spin_unlock_bh(&vsock->pkt_list_lock);
|
||||
|
||||
destroy_workqueue(vsock->workqueue);
|
||||
}
|
||||
|
@ -968,6 +968,91 @@ static void test_seqpacket_inv_buf_server(const struct test_opts *opts)
|
||||
test_inv_buf_server(opts, false);
|
||||
}
|
||||
|
||||
#define HELLO_STR "HELLO"
|
||||
#define WORLD_STR "WORLD"
|
||||
|
||||
static void test_stream_virtio_skb_merge_client(const struct test_opts *opts)
|
||||
{
|
||||
ssize_t res;
|
||||
int fd;
|
||||
|
||||
fd = vsock_stream_connect(opts->peer_cid, 1234);
|
||||
if (fd < 0) {
|
||||
perror("connect");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Send first skbuff. */
|
||||
res = send(fd, HELLO_STR, strlen(HELLO_STR), 0);
|
||||
if (res != strlen(HELLO_STR)) {
|
||||
fprintf(stderr, "unexpected send(2) result %zi\n", res);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
control_writeln("SEND0");
|
||||
/* Peer reads part of first skbuff. */
|
||||
control_expectln("REPLY0");
|
||||
|
||||
/* Send second skbuff, it will be appended to the first. */
|
||||
res = send(fd, WORLD_STR, strlen(WORLD_STR), 0);
|
||||
if (res != strlen(WORLD_STR)) {
|
||||
fprintf(stderr, "unexpected send(2) result %zi\n", res);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
control_writeln("SEND1");
|
||||
/* Peer reads merged skbuff packet. */
|
||||
control_expectln("REPLY1");
|
||||
|
||||
close(fd);
|
||||
}
|
||||
|
||||
static void test_stream_virtio_skb_merge_server(const struct test_opts *opts)
|
||||
{
|
||||
unsigned char buf[64];
|
||||
ssize_t res;
|
||||
int fd;
|
||||
|
||||
fd = vsock_stream_accept(VMADDR_CID_ANY, 1234, NULL);
|
||||
if (fd < 0) {
|
||||
perror("accept");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
control_expectln("SEND0");
|
||||
|
||||
/* Read skbuff partially. */
|
||||
res = recv(fd, buf, 2, 0);
|
||||
if (res != 2) {
|
||||
fprintf(stderr, "expected recv(2) returns 2 bytes, got %zi\n", res);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
control_writeln("REPLY0");
|
||||
control_expectln("SEND1");
|
||||
|
||||
res = recv(fd, buf + 2, sizeof(buf) - 2, 0);
|
||||
if (res != 8) {
|
||||
fprintf(stderr, "expected recv(2) returns 8 bytes, got %zi\n", res);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
res = recv(fd, buf, sizeof(buf) - 8 - 2, MSG_DONTWAIT);
|
||||
if (res != -1) {
|
||||
fprintf(stderr, "expected recv(2) failure, got %zi\n", res);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (memcmp(buf, HELLO_STR WORLD_STR, strlen(HELLO_STR WORLD_STR))) {
|
||||
fprintf(stderr, "pattern mismatch\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
control_writeln("REPLY1");
|
||||
|
||||
close(fd);
|
||||
}
|
||||
|
||||
static struct test_case test_cases[] = {
|
||||
{
|
||||
.name = "SOCK_STREAM connection reset",
|
||||
@ -1038,6 +1123,11 @@ static struct test_case test_cases[] = {
|
||||
.run_client = test_seqpacket_inv_buf_client,
|
||||
.run_server = test_seqpacket_inv_buf_server,
|
||||
},
|
||||
{
|
||||
.name = "SOCK_STREAM virtio skb merge",
|
||||
.run_client = test_stream_virtio_skb_merge_client,
|
||||
.run_server = test_stream_virtio_skb_merge_server,
|
||||
},
|
||||
{},
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user