forked from Minki/linux
Including fixes from wifi, netfilter and can.
A handful of awaited fixes here - revert of the FEC changes, bluetooth fix, fixes for iwlwifi spew. We added a warning in PHY/MDIO code which is triggering on a couple of platforms in a false-positive-ish way. If we can't iron that out over the week we'll drop it and re-add for 6.1. I've added a new "follow up fixes" section for fixes to fixes in 6.0-rcs but it may actually give the false impression that those are problematic or that more testing time would have caught them. So likely a one time thing. Follow up fixes: - nf_tables_addchain: fix nft_counters_enabled underflow - ebtables: fix memory leak when blob is malformed - nf_ct_ftp: fix deadlock when nat rewrite is needed Current release - regressions: - Revert "fec: Restart PPS after link state change" - Revert "net: fec: Use a spinlock to guard `fep->ptp_clk_on`" - Bluetooth: fix HCIGETDEVINFO regression - wifi: mt76: fix 5 GHz connection regression on mt76x0/mt76x2 - mptcp: fix fwd memory accounting on coalesce - rwlock removal fall out: - ipmr: always call ip{,6}_mr_forward() from RCU read-side critical section - ipv6: fix crash when IPv6 is administratively disabled - tcp: read multiple skbs in tcp_read_skb() - mdio_bus_phy_resume state warning fallout: - eth: ravb: fix PHY state warning splat during system resume - eth: sh_eth: fix PHY state warning splat during system resume Current release - new code bugs: - wifi: iwlwifi: don't spam logs with NSS>2 messages - eth: mtk_eth_soc: enable XDP support just for MT7986 SoC Previous releases - regressions: - bonding: fix NULL deref in bond_rr_gen_slave_id - wifi: iwlwifi: mark IWLMEI as broken Previous releases - always broken: - nf_conntrack helpers: - irc: tighten matching on DCC message - sip: fix ct_sip_walk_headers - osf: fix possible bogus match in nf_osf_find() - ipvlan: fix out-of-bound bugs caused by unset skb->mac_header - core: fix flow symmetric hash - bonding, team: unsync device addresses on ndo_stop - phy: micrel: fix shared interrupt on LAN8814 Signed-off-by: Jakub Kicinski <kuba@kernel.org> -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEE6jPA+I1ugmIBA4hXMUZtbf5SIrsFAmMsj3EACgkQMUZtbf5S IrsUgQ//eXxuUZeGTg7cgJKPFJelrZ3iL16B1+s2qX94GPIqXRAShgC78iM7IbSe y3vR/7YVE7sKXm88wnLefMQVXPp0cE2p0+8++E/j4zcRZsM5sHb2+d3gW6nos2ed U8Ldm7LzWUNt/o1ZHDqZWBSoreFkmbFyHO6FVPCuH11tFUJqxJ/SP860mwo6tbuT HOoVphKis41IMEXCgybs2V0DAQewba0gejzAmySDy8epNhOj2F4Vo6aadnUCI68U HrIFYe2wiEi6MZDsB9zpRXc9seb6ZBKbBjgQnTK7MwfBEQCzxtR2lkNobJM1WbdL nYwHBOJ16yX0BnlSpUEepv6iJYY5Q7FS35Wk3Rq5Mik6DaEir6vVSBdRxHpYOkO2 KPIyyMMAA5E8mAtqH3PcpnwDK+9c3KlZYYKXxIp2IjQm87DpOZJFynwsC3Crmbzo C7UTMav2nkHljoapMLUwzqyw2ip+Qo14XA043FDPUru1sXY9CY6q50XZa5GmrNKh xyaBdp4Ckj1kOuXUR9jz3Rq8skOZ8lNGHtiCdgPZitWhNKW1YORJihC7/9zdieCR 1gOE7Dpz/MhVmFn2e8S5O3TkU5lXfALfPDJi4QiML5VLHXd/nCE5sHPiOBWcoo4w 2djKbIGpLRnO6qMs4NkWNmPbG+/ouvpM+lewqn+xU4TGyn/NTbI= =wrep -----END PGP SIGNATURE----- Merge tag 'net-6.0-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net Pull networking fixes from Jakub Kicinski: "Including fixes from wifi, netfilter and can. A handful of awaited fixes here - revert of the FEC changes, bluetooth fix, fixes for iwlwifi spew. We added a warning in PHY/MDIO code which is triggering on a couple of platforms in a false-positive-ish way. If we can't iron that out over the week we'll drop it and re-add for 6.1. I've added a new "follow up fixes" section for fixes to fixes in 6.0-rcs but it may actually give the false impression that those are problematic or that more testing time would have caught them. So likely a one time thing. Follow up fixes: - nf_tables_addchain: fix nft_counters_enabled underflow - ebtables: fix memory leak when blob is malformed - nf_ct_ftp: fix deadlock when nat rewrite is needed Current release - regressions: - Revert "fec: Restart PPS after link state change" and the related "net: fec: Use a spinlock to guard `fep->ptp_clk_on`" - Bluetooth: fix HCIGETDEVINFO regression - wifi: mt76: fix 5 GHz connection regression on mt76x0/mt76x2 - mptcp: fix fwd memory accounting on coalesce - rwlock removal fall out: - ipmr: always call ip{,6}_mr_forward() from RCU read-side critical section - ipv6: fix crash when IPv6 is administratively disabled - tcp: read multiple skbs in tcp_read_skb() - mdio_bus_phy_resume state warning fallout: - eth: ravb: fix PHY state warning splat during system resume - eth: sh_eth: fix PHY state warning splat during system resume Current release - new code bugs: - wifi: iwlwifi: don't spam logs with NSS>2 messages - eth: mtk_eth_soc: enable XDP support just for MT7986 SoC Previous releases - regressions: - bonding: fix NULL deref in bond_rr_gen_slave_id - wifi: iwlwifi: mark IWLMEI as broken Previous releases - always broken: - nf_conntrack helpers: - irc: tighten matching on DCC message - sip: fix ct_sip_walk_headers - osf: fix possible bogus match in nf_osf_find() - ipvlan: fix out-of-bound bugs caused by unset skb->mac_header - core: fix flow symmetric hash - bonding, team: unsync device addresses on ndo_stop - phy: micrel: fix shared interrupt on LAN8814" * tag 'net-6.0-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (83 commits) selftests: forwarding: add shebang for sch_red.sh bnxt: prevent skb UAF after handing over to PTP worker net: marvell: Fix refcounting bugs in prestera_port_sfp_bind() net: sched: fix possible refcount leak in tc_new_tfilter() net: sunhme: Fix packet reception for len < RX_COPY_THRESHOLD udp: Use WARN_ON_ONCE() in udp_read_skb() selftests: bonding: cause oops in bond_rr_gen_slave_id bonding: fix NULL deref in bond_rr_gen_slave_id net: phy: micrel: fix shared interrupt on LAN8814 net/smc: Stop the CLC flow if no link to map buffers on ice: Fix ice_xdp_xmit() when XDP TX queue number is not sufficient net: atlantic: fix potential memory leak in aq_ndev_close() can: gs_usb: gs_usb_set_phys_id(): return with error if identify is not supported can: gs_usb: gs_can_open(): fix race dev->can.state condition can: flexcan: flexcan_mailbox_read() fix return value for drop = true net: sh_eth: Fix PHY state warning splat during system resume net: ravb: Fix PHY state warning splat during system resume netfilter: nf_ct_ftp: fix deadlock when nat rewrite is needed netfilter: ebtables: fix memory leak when blob is malformed netfilter: nf_tables: fix percpu memory leak at nf_tables_addchain() ...
This commit is contained in:
commit
504c25cb76
@ -47,7 +47,6 @@ allow_join_initial_addr_port - BOOLEAN
|
|||||||
Default: 1
|
Default: 1
|
||||||
|
|
||||||
pm_type - INTEGER
|
pm_type - INTEGER
|
||||||
|
|
||||||
Set the default path manager type to use for each new MPTCP
|
Set the default path manager type to use for each new MPTCP
|
||||||
socket. In-kernel path management will control subflow
|
socket. In-kernel path management will control subflow
|
||||||
connections and address advertisements according to
|
connections and address advertisements according to
|
||||||
|
@ -70,15 +70,6 @@ nf_conntrack_generic_timeout - INTEGER (seconds)
|
|||||||
Default for generic timeout. This refers to layer 4 unknown/unsupported
|
Default for generic timeout. This refers to layer 4 unknown/unsupported
|
||||||
protocols.
|
protocols.
|
||||||
|
|
||||||
nf_conntrack_helper - BOOLEAN
|
|
||||||
- 0 - disabled (default)
|
|
||||||
- not 0 - enabled
|
|
||||||
|
|
||||||
Enable automatic conntrack helper assignment.
|
|
||||||
If disabled it is required to set up iptables rules to assign
|
|
||||||
helpers to connections. See the CT target description in the
|
|
||||||
iptables-extensions(8) man page for further information.
|
|
||||||
|
|
||||||
nf_conntrack_icmp_timeout - INTEGER (seconds)
|
nf_conntrack_icmp_timeout - INTEGER (seconds)
|
||||||
default 30
|
default 30
|
||||||
|
|
||||||
|
@ -8652,8 +8652,8 @@ F: drivers/input/touchscreen/goodix*
|
|||||||
|
|
||||||
GOOGLE ETHERNET DRIVERS
|
GOOGLE ETHERNET DRIVERS
|
||||||
M: Jeroen de Borst <jeroendb@google.com>
|
M: Jeroen de Borst <jeroendb@google.com>
|
||||||
R: Catherine Sullivan <csully@google.com>
|
M: Catherine Sullivan <csully@google.com>
|
||||||
R: David Awogbemila <awogbemila@google.com>
|
R: Shailend Chand <shailend@google.com>
|
||||||
L: netdev@vger.kernel.org
|
L: netdev@vger.kernel.org
|
||||||
S: Supported
|
S: Supported
|
||||||
F: Documentation/networking/device_drivers/ethernet/google/gve.rst
|
F: Documentation/networking/device_drivers/ethernet/google/gve.rst
|
||||||
@ -16857,6 +16857,7 @@ F: drivers/net/ethernet/qualcomm/emac/
|
|||||||
|
|
||||||
QUALCOMM ETHQOS ETHERNET DRIVER
|
QUALCOMM ETHQOS ETHERNET DRIVER
|
||||||
M: Vinod Koul <vkoul@kernel.org>
|
M: Vinod Koul <vkoul@kernel.org>
|
||||||
|
R: Bhupesh Sharma <bhupesh.sharma@linaro.org>
|
||||||
L: netdev@vger.kernel.org
|
L: netdev@vger.kernel.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: Documentation/devicetree/bindings/net/qcom,ethqos.txt
|
F: Documentation/devicetree/bindings/net/qcom,ethqos.txt
|
||||||
@ -19959,6 +19960,7 @@ S: Supported
|
|||||||
F: drivers/net/team/
|
F: drivers/net/team/
|
||||||
F: include/linux/if_team.h
|
F: include/linux/if_team.h
|
||||||
F: include/uapi/linux/if_team.h
|
F: include/uapi/linux/if_team.h
|
||||||
|
F: tools/testing/selftests/net/team/
|
||||||
|
|
||||||
TECHNOLOGIC SYSTEMS TS-5500 PLATFORM SUPPORT
|
TECHNOLOGIC SYSTEMS TS-5500 PLATFORM SUPPORT
|
||||||
M: "Savoir-faire Linux Inc." <kernel@savoirfairelinux.com>
|
M: "Savoir-faire Linux Inc." <kernel@savoirfairelinux.com>
|
||||||
|
@ -88,8 +88,9 @@ static const u8 null_mac_addr[ETH_ALEN + 2] __long_aligned = {
|
|||||||
static const u16 ad_ticks_per_sec = 1000 / AD_TIMER_INTERVAL;
|
static const u16 ad_ticks_per_sec = 1000 / AD_TIMER_INTERVAL;
|
||||||
static const int ad_delta_in_ticks = (AD_TIMER_INTERVAL * HZ) / 1000;
|
static const int ad_delta_in_ticks = (AD_TIMER_INTERVAL * HZ) / 1000;
|
||||||
|
|
||||||
static const u8 lacpdu_mcast_addr[ETH_ALEN + 2] __long_aligned =
|
const u8 lacpdu_mcast_addr[ETH_ALEN + 2] __long_aligned = {
|
||||||
MULTICAST_LACPDU_ADDR;
|
0x01, 0x80, 0xC2, 0x00, 0x00, 0x02
|
||||||
|
};
|
||||||
|
|
||||||
/* ================= main 802.3ad protocol functions ================== */
|
/* ================= main 802.3ad protocol functions ================== */
|
||||||
static int ad_lacpdu_send(struct port *port);
|
static int ad_lacpdu_send(struct port *port);
|
||||||
|
@ -865,12 +865,8 @@ static void bond_hw_addr_flush(struct net_device *bond_dev,
|
|||||||
dev_uc_unsync(slave_dev, bond_dev);
|
dev_uc_unsync(slave_dev, bond_dev);
|
||||||
dev_mc_unsync(slave_dev, bond_dev);
|
dev_mc_unsync(slave_dev, bond_dev);
|
||||||
|
|
||||||
if (BOND_MODE(bond) == BOND_MODE_8023AD) {
|
if (BOND_MODE(bond) == BOND_MODE_8023AD)
|
||||||
/* del lacpdu mc addr from mc list */
|
dev_mc_del(slave_dev, lacpdu_mcast_addr);
|
||||||
u8 lacpdu_multicast[ETH_ALEN] = MULTICAST_LACPDU_ADDR;
|
|
||||||
|
|
||||||
dev_mc_del(slave_dev, lacpdu_multicast);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*--------------------------- Active slave change ---------------------------*/
|
/*--------------------------- Active slave change ---------------------------*/
|
||||||
@ -890,7 +886,8 @@ static void bond_hw_addr_swap(struct bonding *bond, struct slave *new_active,
|
|||||||
if (bond->dev->flags & IFF_ALLMULTI)
|
if (bond->dev->flags & IFF_ALLMULTI)
|
||||||
dev_set_allmulti(old_active->dev, -1);
|
dev_set_allmulti(old_active->dev, -1);
|
||||||
|
|
||||||
bond_hw_addr_flush(bond->dev, old_active->dev);
|
if (bond->dev->flags & IFF_UP)
|
||||||
|
bond_hw_addr_flush(bond->dev, old_active->dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (new_active) {
|
if (new_active) {
|
||||||
@ -901,10 +898,12 @@ static void bond_hw_addr_swap(struct bonding *bond, struct slave *new_active,
|
|||||||
if (bond->dev->flags & IFF_ALLMULTI)
|
if (bond->dev->flags & IFF_ALLMULTI)
|
||||||
dev_set_allmulti(new_active->dev, 1);
|
dev_set_allmulti(new_active->dev, 1);
|
||||||
|
|
||||||
netif_addr_lock_bh(bond->dev);
|
if (bond->dev->flags & IFF_UP) {
|
||||||
dev_uc_sync(new_active->dev, bond->dev);
|
netif_addr_lock_bh(bond->dev);
|
||||||
dev_mc_sync(new_active->dev, bond->dev);
|
dev_uc_sync(new_active->dev, bond->dev);
|
||||||
netif_addr_unlock_bh(bond->dev);
|
dev_mc_sync(new_active->dev, bond->dev);
|
||||||
|
netif_addr_unlock_bh(bond->dev);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2166,16 +2165,14 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
netif_addr_lock_bh(bond_dev);
|
if (bond_dev->flags & IFF_UP) {
|
||||||
dev_mc_sync_multiple(slave_dev, bond_dev);
|
netif_addr_lock_bh(bond_dev);
|
||||||
dev_uc_sync_multiple(slave_dev, bond_dev);
|
dev_mc_sync_multiple(slave_dev, bond_dev);
|
||||||
netif_addr_unlock_bh(bond_dev);
|
dev_uc_sync_multiple(slave_dev, bond_dev);
|
||||||
|
netif_addr_unlock_bh(bond_dev);
|
||||||
|
|
||||||
if (BOND_MODE(bond) == BOND_MODE_8023AD) {
|
if (BOND_MODE(bond) == BOND_MODE_8023AD)
|
||||||
/* add lacpdu mc addr to mc list */
|
dev_mc_add(slave_dev, lacpdu_mcast_addr);
|
||||||
u8 lacpdu_multicast[ETH_ALEN] = MULTICAST_LACPDU_ADDR;
|
|
||||||
|
|
||||||
dev_mc_add(slave_dev, lacpdu_multicast);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2447,7 +2444,8 @@ static int __bond_release_one(struct net_device *bond_dev,
|
|||||||
if (old_flags & IFF_ALLMULTI)
|
if (old_flags & IFF_ALLMULTI)
|
||||||
dev_set_allmulti(slave_dev, -1);
|
dev_set_allmulti(slave_dev, -1);
|
||||||
|
|
||||||
bond_hw_addr_flush(bond_dev, slave_dev);
|
if (old_flags & IFF_UP)
|
||||||
|
bond_hw_addr_flush(bond_dev, slave_dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
slave_disable_netpoll(slave);
|
slave_disable_netpoll(slave);
|
||||||
@ -4184,6 +4182,12 @@ static int bond_open(struct net_device *bond_dev)
|
|||||||
struct list_head *iter;
|
struct list_head *iter;
|
||||||
struct slave *slave;
|
struct slave *slave;
|
||||||
|
|
||||||
|
if (BOND_MODE(bond) == BOND_MODE_ROUNDROBIN && !bond->rr_tx_counter) {
|
||||||
|
bond->rr_tx_counter = alloc_percpu(u32);
|
||||||
|
if (!bond->rr_tx_counter)
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
/* reset slave->backup and slave->inactive */
|
/* reset slave->backup and slave->inactive */
|
||||||
if (bond_has_slaves(bond)) {
|
if (bond_has_slaves(bond)) {
|
||||||
bond_for_each_slave(bond, slave, iter) {
|
bond_for_each_slave(bond, slave, iter) {
|
||||||
@ -4221,6 +4225,9 @@ static int bond_open(struct net_device *bond_dev)
|
|||||||
/* register to receive LACPDUs */
|
/* register to receive LACPDUs */
|
||||||
bond->recv_probe = bond_3ad_lacpdu_recv;
|
bond->recv_probe = bond_3ad_lacpdu_recv;
|
||||||
bond_3ad_initiate_agg_selection(bond, 1);
|
bond_3ad_initiate_agg_selection(bond, 1);
|
||||||
|
|
||||||
|
bond_for_each_slave(bond, slave, iter)
|
||||||
|
dev_mc_add(slave->dev, lacpdu_mcast_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bond_mode_can_use_xmit_hash(bond))
|
if (bond_mode_can_use_xmit_hash(bond))
|
||||||
@ -4232,6 +4239,7 @@ static int bond_open(struct net_device *bond_dev)
|
|||||||
static int bond_close(struct net_device *bond_dev)
|
static int bond_close(struct net_device *bond_dev)
|
||||||
{
|
{
|
||||||
struct bonding *bond = netdev_priv(bond_dev);
|
struct bonding *bond = netdev_priv(bond_dev);
|
||||||
|
struct slave *slave;
|
||||||
|
|
||||||
bond_work_cancel_all(bond);
|
bond_work_cancel_all(bond);
|
||||||
bond->send_peer_notif = 0;
|
bond->send_peer_notif = 0;
|
||||||
@ -4239,6 +4247,19 @@ static int bond_close(struct net_device *bond_dev)
|
|||||||
bond_alb_deinitialize(bond);
|
bond_alb_deinitialize(bond);
|
||||||
bond->recv_probe = NULL;
|
bond->recv_probe = NULL;
|
||||||
|
|
||||||
|
if (bond_uses_primary(bond)) {
|
||||||
|
rcu_read_lock();
|
||||||
|
slave = rcu_dereference(bond->curr_active_slave);
|
||||||
|
if (slave)
|
||||||
|
bond_hw_addr_flush(bond_dev, slave->dev);
|
||||||
|
rcu_read_unlock();
|
||||||
|
} else {
|
||||||
|
struct list_head *iter;
|
||||||
|
|
||||||
|
bond_for_each_slave(bond, slave, iter)
|
||||||
|
bond_hw_addr_flush(bond_dev, slave->dev);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6228,15 +6249,6 @@ static int bond_init(struct net_device *bond_dev)
|
|||||||
if (!bond->wq)
|
if (!bond->wq)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
if (BOND_MODE(bond) == BOND_MODE_ROUNDROBIN) {
|
|
||||||
bond->rr_tx_counter = alloc_percpu(u32);
|
|
||||||
if (!bond->rr_tx_counter) {
|
|
||||||
destroy_workqueue(bond->wq);
|
|
||||||
bond->wq = NULL;
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
spin_lock_init(&bond->stats_lock);
|
spin_lock_init(&bond->stats_lock);
|
||||||
netdev_lockdep_set_classes(bond_dev);
|
netdev_lockdep_set_classes(bond_dev);
|
||||||
|
|
||||||
|
@ -941,11 +941,6 @@ static struct sk_buff *flexcan_mailbox_read(struct can_rx_offload *offload,
|
|||||||
u32 reg_ctrl, reg_id, reg_iflag1;
|
u32 reg_ctrl, reg_id, reg_iflag1;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (unlikely(drop)) {
|
|
||||||
skb = ERR_PTR(-ENOBUFS);
|
|
||||||
goto mark_as_read;
|
|
||||||
}
|
|
||||||
|
|
||||||
mb = flexcan_get_mb(priv, n);
|
mb = flexcan_get_mb(priv, n);
|
||||||
|
|
||||||
if (priv->devtype_data.quirks & FLEXCAN_QUIRK_USE_RX_MAILBOX) {
|
if (priv->devtype_data.quirks & FLEXCAN_QUIRK_USE_RX_MAILBOX) {
|
||||||
@ -974,6 +969,11 @@ static struct sk_buff *flexcan_mailbox_read(struct can_rx_offload *offload,
|
|||||||
reg_ctrl = priv->read(&mb->can_ctrl);
|
reg_ctrl = priv->read(&mb->can_ctrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (unlikely(drop)) {
|
||||||
|
skb = ERR_PTR(-ENOBUFS);
|
||||||
|
goto mark_as_read;
|
||||||
|
}
|
||||||
|
|
||||||
if (reg_ctrl & FLEXCAN_MB_CNT_EDL)
|
if (reg_ctrl & FLEXCAN_MB_CNT_EDL)
|
||||||
skb = alloc_canfd_skb(offload->dev, &cfd);
|
skb = alloc_canfd_skb(offload->dev, &cfd);
|
||||||
else
|
else
|
||||||
|
@ -824,6 +824,7 @@ static int gs_can_open(struct net_device *netdev)
|
|||||||
flags |= GS_CAN_MODE_TRIPLE_SAMPLE;
|
flags |= GS_CAN_MODE_TRIPLE_SAMPLE;
|
||||||
|
|
||||||
/* finally start device */
|
/* finally start device */
|
||||||
|
dev->can.state = CAN_STATE_ERROR_ACTIVE;
|
||||||
dm->mode = cpu_to_le32(GS_CAN_MODE_START);
|
dm->mode = cpu_to_le32(GS_CAN_MODE_START);
|
||||||
dm->flags = cpu_to_le32(flags);
|
dm->flags = cpu_to_le32(flags);
|
||||||
rc = usb_control_msg(interface_to_usbdev(dev->iface),
|
rc = usb_control_msg(interface_to_usbdev(dev->iface),
|
||||||
@ -835,13 +836,12 @@ static int gs_can_open(struct net_device *netdev)
|
|||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
netdev_err(netdev, "Couldn't start device (err=%d)\n", rc);
|
netdev_err(netdev, "Couldn't start device (err=%d)\n", rc);
|
||||||
kfree(dm);
|
kfree(dm);
|
||||||
|
dev->can.state = CAN_STATE_STOPPED;
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
kfree(dm);
|
kfree(dm);
|
||||||
|
|
||||||
dev->can.state = CAN_STATE_ERROR_ACTIVE;
|
|
||||||
|
|
||||||
parent->active_channels++;
|
parent->active_channels++;
|
||||||
if (!(dev->can.ctrlmode & CAN_CTRLMODE_LISTENONLY))
|
if (!(dev->can.ctrlmode & CAN_CTRLMODE_LISTENONLY))
|
||||||
netif_start_queue(netdev);
|
netif_start_queue(netdev);
|
||||||
@ -925,17 +925,21 @@ static int gs_usb_set_identify(struct net_device *netdev, bool do_identify)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* blink LED's for finding the this interface */
|
/* blink LED's for finding the this interface */
|
||||||
static int gs_usb_set_phys_id(struct net_device *dev,
|
static int gs_usb_set_phys_id(struct net_device *netdev,
|
||||||
enum ethtool_phys_id_state state)
|
enum ethtool_phys_id_state state)
|
||||||
{
|
{
|
||||||
|
const struct gs_can *dev = netdev_priv(netdev);
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
|
if (!(dev->feature & GS_CAN_FEATURE_IDENTIFY))
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case ETHTOOL_ID_ACTIVE:
|
case ETHTOOL_ID_ACTIVE:
|
||||||
rc = gs_usb_set_identify(dev, GS_CAN_IDENTIFY_ON);
|
rc = gs_usb_set_identify(netdev, GS_CAN_IDENTIFY_ON);
|
||||||
break;
|
break;
|
||||||
case ETHTOOL_ID_INACTIVE:
|
case ETHTOOL_ID_INACTIVE:
|
||||||
rc = gs_usb_set_identify(dev, GS_CAN_IDENTIFY_OFF);
|
rc = gs_usb_set_identify(netdev, GS_CAN_IDENTIFY_OFF);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -1072,9 +1076,10 @@ static struct gs_can *gs_make_candev(unsigned int channel,
|
|||||||
dev->feature |= GS_CAN_FEATURE_REQ_USB_QUIRK_LPC546XX |
|
dev->feature |= GS_CAN_FEATURE_REQ_USB_QUIRK_LPC546XX |
|
||||||
GS_CAN_FEATURE_QUIRK_BREQ_CANTACT_PRO;
|
GS_CAN_FEATURE_QUIRK_BREQ_CANTACT_PRO;
|
||||||
|
|
||||||
if (le32_to_cpu(dconf->sw_version) > 1)
|
/* GS_CAN_FEATURE_IDENTIFY is only supported for sw_version > 1 */
|
||||||
if (feature & GS_CAN_FEATURE_IDENTIFY)
|
if (!(le32_to_cpu(dconf->sw_version) > 1 &&
|
||||||
netdev->ethtool_ops = &gs_usb_ethtool_ops;
|
feature & GS_CAN_FEATURE_IDENTIFY))
|
||||||
|
dev->feature &= ~GS_CAN_FEATURE_IDENTIFY;
|
||||||
|
|
||||||
kfree(bt_const);
|
kfree(bt_const);
|
||||||
|
|
||||||
|
@ -244,10 +244,6 @@ void lan937x_port_setup(struct ksz_device *dev, int port, bool cpu_port)
|
|||||||
lan937x_port_cfg(dev, port, REG_PORT_CTRL_0,
|
lan937x_port_cfg(dev, port, REG_PORT_CTRL_0,
|
||||||
PORT_TAIL_TAG_ENABLE, true);
|
PORT_TAIL_TAG_ENABLE, true);
|
||||||
|
|
||||||
/* disable frame check length field */
|
|
||||||
lan937x_port_cfg(dev, port, REG_PORT_MAC_CTRL_0, PORT_CHECK_LENGTH,
|
|
||||||
false);
|
|
||||||
|
|
||||||
/* set back pressure for half duplex */
|
/* set back pressure for half duplex */
|
||||||
lan937x_port_cfg(dev, port, REG_PORT_MAC_CTRL_1, PORT_BACK_PRESSURE,
|
lan937x_port_cfg(dev, port, REG_PORT_MAC_CTRL_1, PORT_BACK_PRESSURE,
|
||||||
true);
|
true);
|
||||||
|
@ -94,11 +94,8 @@ static int aq_ndev_close(struct net_device *ndev)
|
|||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
err = aq_nic_stop(aq_nic);
|
err = aq_nic_stop(aq_nic);
|
||||||
if (err < 0)
|
|
||||||
goto err_exit;
|
|
||||||
aq_nic_deinit(aq_nic, true);
|
aq_nic_deinit(aq_nic, true);
|
||||||
|
|
||||||
err_exit:
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -659,7 +659,6 @@ static void bnxt_tx_int(struct bnxt *bp, struct bnxt_napi *bnapi, int nr_pkts)
|
|||||||
|
|
||||||
for (i = 0; i < nr_pkts; i++) {
|
for (i = 0; i < nr_pkts; i++) {
|
||||||
struct bnxt_sw_tx_bd *tx_buf;
|
struct bnxt_sw_tx_bd *tx_buf;
|
||||||
bool compl_deferred = false;
|
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
int j, last;
|
int j, last;
|
||||||
|
|
||||||
@ -668,6 +667,8 @@ static void bnxt_tx_int(struct bnxt *bp, struct bnxt_napi *bnapi, int nr_pkts)
|
|||||||
skb = tx_buf->skb;
|
skb = tx_buf->skb;
|
||||||
tx_buf->skb = NULL;
|
tx_buf->skb = NULL;
|
||||||
|
|
||||||
|
tx_bytes += skb->len;
|
||||||
|
|
||||||
if (tx_buf->is_push) {
|
if (tx_buf->is_push) {
|
||||||
tx_buf->is_push = 0;
|
tx_buf->is_push = 0;
|
||||||
goto next_tx_int;
|
goto next_tx_int;
|
||||||
@ -688,8 +689,9 @@ static void bnxt_tx_int(struct bnxt *bp, struct bnxt_napi *bnapi, int nr_pkts)
|
|||||||
}
|
}
|
||||||
if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)) {
|
if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)) {
|
||||||
if (bp->flags & BNXT_FLAG_CHIP_P5) {
|
if (bp->flags & BNXT_FLAG_CHIP_P5) {
|
||||||
|
/* PTP worker takes ownership of the skb */
|
||||||
if (!bnxt_get_tx_ts_p5(bp, skb))
|
if (!bnxt_get_tx_ts_p5(bp, skb))
|
||||||
compl_deferred = true;
|
skb = NULL;
|
||||||
else
|
else
|
||||||
atomic_inc(&bp->ptp_cfg->tx_avail);
|
atomic_inc(&bp->ptp_cfg->tx_avail);
|
||||||
}
|
}
|
||||||
@ -698,9 +700,7 @@ static void bnxt_tx_int(struct bnxt *bp, struct bnxt_napi *bnapi, int nr_pkts)
|
|||||||
next_tx_int:
|
next_tx_int:
|
||||||
cons = NEXT_TX(cons);
|
cons = NEXT_TX(cons);
|
||||||
|
|
||||||
tx_bytes += skb->len;
|
dev_kfree_skb_any(skb);
|
||||||
if (!compl_deferred)
|
|
||||||
dev_kfree_skb_any(skb);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
netdev_tx_completed_queue(txq, nr_pkts, tx_bytes);
|
netdev_tx_completed_queue(txq, nr_pkts, tx_bytes);
|
||||||
|
@ -317,9 +317,9 @@ void bnxt_ptp_cfg_tstamp_filters(struct bnxt *bp)
|
|||||||
|
|
||||||
if (!(bp->fw_cap & BNXT_FW_CAP_RX_ALL_PKT_TS) && (ptp->tstamp_filters &
|
if (!(bp->fw_cap & BNXT_FW_CAP_RX_ALL_PKT_TS) && (ptp->tstamp_filters &
|
||||||
(PORT_MAC_CFG_REQ_FLAGS_ALL_RX_TS_CAPTURE_ENABLE |
|
(PORT_MAC_CFG_REQ_FLAGS_ALL_RX_TS_CAPTURE_ENABLE |
|
||||||
PORT_MAC_CFG_REQ_FLAGS_PTP_RX_TS_CAPTURE_DISABLE))) {
|
PORT_MAC_CFG_REQ_FLAGS_ALL_RX_TS_CAPTURE_DISABLE))) {
|
||||||
ptp->tstamp_filters &= ~(PORT_MAC_CFG_REQ_FLAGS_ALL_RX_TS_CAPTURE_ENABLE |
|
ptp->tstamp_filters &= ~(PORT_MAC_CFG_REQ_FLAGS_ALL_RX_TS_CAPTURE_ENABLE |
|
||||||
PORT_MAC_CFG_REQ_FLAGS_PTP_RX_TS_CAPTURE_DISABLE);
|
PORT_MAC_CFG_REQ_FLAGS_ALL_RX_TS_CAPTURE_DISABLE);
|
||||||
netdev_warn(bp->dev, "Unsupported FW for all RX pkts timestamp filter\n");
|
netdev_warn(bp->dev, "Unsupported FW for all RX pkts timestamp filter\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,7 +9,6 @@ fsl-enetc-$(CONFIG_FSL_ENETC_QOS) += enetc_qos.o
|
|||||||
|
|
||||||
obj-$(CONFIG_FSL_ENETC_VF) += fsl-enetc-vf.o
|
obj-$(CONFIG_FSL_ENETC_VF) += fsl-enetc-vf.o
|
||||||
fsl-enetc-vf-y := enetc_vf.o $(common-objs)
|
fsl-enetc-vf-y := enetc_vf.o $(common-objs)
|
||||||
fsl-enetc-vf-$(CONFIG_FSL_ENETC_QOS) += enetc_qos.o
|
|
||||||
|
|
||||||
obj-$(CONFIG_FSL_ENETC_IERB) += fsl-enetc-ierb.o
|
obj-$(CONFIG_FSL_ENETC_IERB) += fsl-enetc-ierb.o
|
||||||
fsl-enetc-ierb-y := enetc_ierb.o
|
fsl-enetc-ierb-y := enetc_ierb.o
|
||||||
|
@ -2432,7 +2432,7 @@ int enetc_close(struct net_device *ndev)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int enetc_setup_tc_mqprio(struct net_device *ndev, void *type_data)
|
int enetc_setup_tc_mqprio(struct net_device *ndev, void *type_data)
|
||||||
{
|
{
|
||||||
struct enetc_ndev_priv *priv = netdev_priv(ndev);
|
struct enetc_ndev_priv *priv = netdev_priv(ndev);
|
||||||
struct tc_mqprio_qopt *mqprio = type_data;
|
struct tc_mqprio_qopt *mqprio = type_data;
|
||||||
@ -2486,25 +2486,6 @@ static int enetc_setup_tc_mqprio(struct net_device *ndev, void *type_data)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int enetc_setup_tc(struct net_device *ndev, enum tc_setup_type type,
|
|
||||||
void *type_data)
|
|
||||||
{
|
|
||||||
switch (type) {
|
|
||||||
case TC_SETUP_QDISC_MQPRIO:
|
|
||||||
return enetc_setup_tc_mqprio(ndev, type_data);
|
|
||||||
case TC_SETUP_QDISC_TAPRIO:
|
|
||||||
return enetc_setup_tc_taprio(ndev, type_data);
|
|
||||||
case TC_SETUP_QDISC_CBS:
|
|
||||||
return enetc_setup_tc_cbs(ndev, type_data);
|
|
||||||
case TC_SETUP_QDISC_ETF:
|
|
||||||
return enetc_setup_tc_txtime(ndev, type_data);
|
|
||||||
case TC_SETUP_BLOCK:
|
|
||||||
return enetc_setup_tc_psfp(ndev, type_data);
|
|
||||||
default:
|
|
||||||
return -EOPNOTSUPP;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int enetc_setup_xdp_prog(struct net_device *dev, struct bpf_prog *prog,
|
static int enetc_setup_xdp_prog(struct net_device *dev, struct bpf_prog *prog,
|
||||||
struct netlink_ext_ack *extack)
|
struct netlink_ext_ack *extack)
|
||||||
{
|
{
|
||||||
@ -2600,29 +2581,6 @@ static int enetc_set_rss(struct net_device *ndev, int en)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int enetc_set_psfp(struct net_device *ndev, int en)
|
|
||||||
{
|
|
||||||
struct enetc_ndev_priv *priv = netdev_priv(ndev);
|
|
||||||
int err;
|
|
||||||
|
|
||||||
if (en) {
|
|
||||||
err = enetc_psfp_enable(priv);
|
|
||||||
if (err)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
priv->active_offloads |= ENETC_F_QCI;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = enetc_psfp_disable(priv);
|
|
||||||
if (err)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
priv->active_offloads &= ~ENETC_F_QCI;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void enetc_enable_rxvlan(struct net_device *ndev, bool en)
|
static void enetc_enable_rxvlan(struct net_device *ndev, bool en)
|
||||||
{
|
{
|
||||||
struct enetc_ndev_priv *priv = netdev_priv(ndev);
|
struct enetc_ndev_priv *priv = netdev_priv(ndev);
|
||||||
@ -2641,11 +2599,9 @@ static void enetc_enable_txvlan(struct net_device *ndev, bool en)
|
|||||||
enetc_bdr_enable_txvlan(&priv->si->hw, i, en);
|
enetc_bdr_enable_txvlan(&priv->si->hw, i, en);
|
||||||
}
|
}
|
||||||
|
|
||||||
int enetc_set_features(struct net_device *ndev,
|
void enetc_set_features(struct net_device *ndev, netdev_features_t features)
|
||||||
netdev_features_t features)
|
|
||||||
{
|
{
|
||||||
netdev_features_t changed = ndev->features ^ features;
|
netdev_features_t changed = ndev->features ^ features;
|
||||||
int err = 0;
|
|
||||||
|
|
||||||
if (changed & NETIF_F_RXHASH)
|
if (changed & NETIF_F_RXHASH)
|
||||||
enetc_set_rss(ndev, !!(features & NETIF_F_RXHASH));
|
enetc_set_rss(ndev, !!(features & NETIF_F_RXHASH));
|
||||||
@ -2657,11 +2613,6 @@ int enetc_set_features(struct net_device *ndev,
|
|||||||
if (changed & NETIF_F_HW_VLAN_CTAG_TX)
|
if (changed & NETIF_F_HW_VLAN_CTAG_TX)
|
||||||
enetc_enable_txvlan(ndev,
|
enetc_enable_txvlan(ndev,
|
||||||
!!(features & NETIF_F_HW_VLAN_CTAG_TX));
|
!!(features & NETIF_F_HW_VLAN_CTAG_TX));
|
||||||
|
|
||||||
if (changed & NETIF_F_HW_TC)
|
|
||||||
err = enetc_set_psfp(ndev, !!(features & NETIF_F_HW_TC));
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_FSL_ENETC_PTP_CLOCK
|
#ifdef CONFIG_FSL_ENETC_PTP_CLOCK
|
||||||
|
@ -393,11 +393,9 @@ void enetc_start(struct net_device *ndev);
|
|||||||
void enetc_stop(struct net_device *ndev);
|
void enetc_stop(struct net_device *ndev);
|
||||||
netdev_tx_t enetc_xmit(struct sk_buff *skb, struct net_device *ndev);
|
netdev_tx_t enetc_xmit(struct sk_buff *skb, struct net_device *ndev);
|
||||||
struct net_device_stats *enetc_get_stats(struct net_device *ndev);
|
struct net_device_stats *enetc_get_stats(struct net_device *ndev);
|
||||||
int enetc_set_features(struct net_device *ndev,
|
void enetc_set_features(struct net_device *ndev, netdev_features_t features);
|
||||||
netdev_features_t features);
|
|
||||||
int enetc_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd);
|
int enetc_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd);
|
||||||
int enetc_setup_tc(struct net_device *ndev, enum tc_setup_type type,
|
int enetc_setup_tc_mqprio(struct net_device *ndev, void *type_data);
|
||||||
void *type_data);
|
|
||||||
int enetc_setup_bpf(struct net_device *dev, struct netdev_bpf *xdp);
|
int enetc_setup_bpf(struct net_device *dev, struct netdev_bpf *xdp);
|
||||||
int enetc_xdp_xmit(struct net_device *ndev, int num_frames,
|
int enetc_xdp_xmit(struct net_device *ndev, int num_frames,
|
||||||
struct xdp_frame **frames, u32 flags);
|
struct xdp_frame **frames, u32 flags);
|
||||||
@ -465,6 +463,7 @@ int enetc_setup_tc_block_cb(enum tc_setup_type type, void *type_data,
|
|||||||
int enetc_setup_tc_psfp(struct net_device *ndev, void *type_data);
|
int enetc_setup_tc_psfp(struct net_device *ndev, void *type_data);
|
||||||
int enetc_psfp_init(struct enetc_ndev_priv *priv);
|
int enetc_psfp_init(struct enetc_ndev_priv *priv);
|
||||||
int enetc_psfp_clean(struct enetc_ndev_priv *priv);
|
int enetc_psfp_clean(struct enetc_ndev_priv *priv);
|
||||||
|
int enetc_set_psfp(struct net_device *ndev, bool en);
|
||||||
|
|
||||||
static inline void enetc_get_max_cap(struct enetc_ndev_priv *priv)
|
static inline void enetc_get_max_cap(struct enetc_ndev_priv *priv)
|
||||||
{
|
{
|
||||||
@ -540,4 +539,9 @@ static inline int enetc_psfp_disable(struct enetc_ndev_priv *priv)
|
|||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int enetc_set_psfp(struct net_device *ndev, bool en)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -709,6 +709,13 @@ static int enetc_pf_set_features(struct net_device *ndev,
|
|||||||
{
|
{
|
||||||
netdev_features_t changed = ndev->features ^ features;
|
netdev_features_t changed = ndev->features ^ features;
|
||||||
struct enetc_ndev_priv *priv = netdev_priv(ndev);
|
struct enetc_ndev_priv *priv = netdev_priv(ndev);
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (changed & NETIF_F_HW_TC) {
|
||||||
|
err = enetc_set_psfp(ndev, !!(features & NETIF_F_HW_TC));
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
if (changed & NETIF_F_HW_VLAN_CTAG_FILTER) {
|
if (changed & NETIF_F_HW_VLAN_CTAG_FILTER) {
|
||||||
struct enetc_pf *pf = enetc_si_priv(priv->si);
|
struct enetc_pf *pf = enetc_si_priv(priv->si);
|
||||||
@ -722,7 +729,28 @@ static int enetc_pf_set_features(struct net_device *ndev,
|
|||||||
if (changed & NETIF_F_LOOPBACK)
|
if (changed & NETIF_F_LOOPBACK)
|
||||||
enetc_set_loopback(ndev, !!(features & NETIF_F_LOOPBACK));
|
enetc_set_loopback(ndev, !!(features & NETIF_F_LOOPBACK));
|
||||||
|
|
||||||
return enetc_set_features(ndev, features);
|
enetc_set_features(ndev, features);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int enetc_pf_setup_tc(struct net_device *ndev, enum tc_setup_type type,
|
||||||
|
void *type_data)
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
case TC_SETUP_QDISC_MQPRIO:
|
||||||
|
return enetc_setup_tc_mqprio(ndev, type_data);
|
||||||
|
case TC_SETUP_QDISC_TAPRIO:
|
||||||
|
return enetc_setup_tc_taprio(ndev, type_data);
|
||||||
|
case TC_SETUP_QDISC_CBS:
|
||||||
|
return enetc_setup_tc_cbs(ndev, type_data);
|
||||||
|
case TC_SETUP_QDISC_ETF:
|
||||||
|
return enetc_setup_tc_txtime(ndev, type_data);
|
||||||
|
case TC_SETUP_BLOCK:
|
||||||
|
return enetc_setup_tc_psfp(ndev, type_data);
|
||||||
|
default:
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct net_device_ops enetc_ndev_ops = {
|
static const struct net_device_ops enetc_ndev_ops = {
|
||||||
@ -739,7 +767,7 @@ static const struct net_device_ops enetc_ndev_ops = {
|
|||||||
.ndo_set_vf_spoofchk = enetc_pf_set_vf_spoofchk,
|
.ndo_set_vf_spoofchk = enetc_pf_set_vf_spoofchk,
|
||||||
.ndo_set_features = enetc_pf_set_features,
|
.ndo_set_features = enetc_pf_set_features,
|
||||||
.ndo_eth_ioctl = enetc_ioctl,
|
.ndo_eth_ioctl = enetc_ioctl,
|
||||||
.ndo_setup_tc = enetc_setup_tc,
|
.ndo_setup_tc = enetc_pf_setup_tc,
|
||||||
.ndo_bpf = enetc_setup_bpf,
|
.ndo_bpf = enetc_setup_bpf,
|
||||||
.ndo_xdp_xmit = enetc_xdp_xmit,
|
.ndo_xdp_xmit = enetc_xdp_xmit,
|
||||||
};
|
};
|
||||||
|
@ -1517,6 +1517,29 @@ int enetc_setup_tc_block_cb(enum tc_setup_type type, void *type_data,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int enetc_set_psfp(struct net_device *ndev, bool en)
|
||||||
|
{
|
||||||
|
struct enetc_ndev_priv *priv = netdev_priv(ndev);
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (en) {
|
||||||
|
err = enetc_psfp_enable(priv);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
priv->active_offloads |= ENETC_F_QCI;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = enetc_psfp_disable(priv);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
priv->active_offloads &= ~ENETC_F_QCI;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int enetc_psfp_init(struct enetc_ndev_priv *priv)
|
int enetc_psfp_init(struct enetc_ndev_priv *priv)
|
||||||
{
|
{
|
||||||
if (epsfp.psfp_sfi_bitmap)
|
if (epsfp.psfp_sfi_bitmap)
|
||||||
|
@ -88,7 +88,20 @@ static int enetc_vf_set_mac_addr(struct net_device *ndev, void *addr)
|
|||||||
static int enetc_vf_set_features(struct net_device *ndev,
|
static int enetc_vf_set_features(struct net_device *ndev,
|
||||||
netdev_features_t features)
|
netdev_features_t features)
|
||||||
{
|
{
|
||||||
return enetc_set_features(ndev, features);
|
enetc_set_features(ndev, features);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int enetc_vf_setup_tc(struct net_device *ndev, enum tc_setup_type type,
|
||||||
|
void *type_data)
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
case TC_SETUP_QDISC_MQPRIO:
|
||||||
|
return enetc_setup_tc_mqprio(ndev, type_data);
|
||||||
|
default:
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Probing/ Init */
|
/* Probing/ Init */
|
||||||
@ -100,7 +113,7 @@ static const struct net_device_ops enetc_ndev_ops = {
|
|||||||
.ndo_set_mac_address = enetc_vf_set_mac_addr,
|
.ndo_set_mac_address = enetc_vf_set_mac_addr,
|
||||||
.ndo_set_features = enetc_vf_set_features,
|
.ndo_set_features = enetc_vf_set_features,
|
||||||
.ndo_eth_ioctl = enetc_ioctl,
|
.ndo_eth_ioctl = enetc_ioctl,
|
||||||
.ndo_setup_tc = enetc_setup_tc,
|
.ndo_setup_tc = enetc_vf_setup_tc,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void enetc_vf_netdev_setup(struct enetc_si *si, struct net_device *ndev,
|
static void enetc_vf_netdev_setup(struct enetc_si *si, struct net_device *ndev,
|
||||||
|
@ -561,6 +561,7 @@ struct fec_enet_private {
|
|||||||
struct clk *clk_2x_txclk;
|
struct clk *clk_2x_txclk;
|
||||||
|
|
||||||
bool ptp_clk_on;
|
bool ptp_clk_on;
|
||||||
|
struct mutex ptp_clk_mutex;
|
||||||
unsigned int num_tx_queues;
|
unsigned int num_tx_queues;
|
||||||
unsigned int num_rx_queues;
|
unsigned int num_rx_queues;
|
||||||
|
|
||||||
@ -638,13 +639,6 @@ struct fec_enet_private {
|
|||||||
int pps_enable;
|
int pps_enable;
|
||||||
unsigned int next_counter;
|
unsigned int next_counter;
|
||||||
|
|
||||||
struct {
|
|
||||||
struct timespec64 ts_phc;
|
|
||||||
u64 ns_sys;
|
|
||||||
u32 at_corr;
|
|
||||||
u8 at_inc_corr;
|
|
||||||
} ptp_saved_state;
|
|
||||||
|
|
||||||
u64 ethtool_stats[];
|
u64 ethtool_stats[];
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -655,8 +649,5 @@ void fec_ptp_disable_hwts(struct net_device *ndev);
|
|||||||
int fec_ptp_set(struct net_device *ndev, struct ifreq *ifr);
|
int fec_ptp_set(struct net_device *ndev, struct ifreq *ifr);
|
||||||
int fec_ptp_get(struct net_device *ndev, struct ifreq *ifr);
|
int fec_ptp_get(struct net_device *ndev, struct ifreq *ifr);
|
||||||
|
|
||||||
void fec_ptp_save_state(struct fec_enet_private *fep);
|
|
||||||
int fec_ptp_restore_state(struct fec_enet_private *fep);
|
|
||||||
|
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
#endif /* FEC_H */
|
#endif /* FEC_H */
|
||||||
|
@ -286,11 +286,8 @@ MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address");
|
|||||||
#define FEC_MMFR_TA (2 << 16)
|
#define FEC_MMFR_TA (2 << 16)
|
||||||
#define FEC_MMFR_DATA(v) (v & 0xffff)
|
#define FEC_MMFR_DATA(v) (v & 0xffff)
|
||||||
/* FEC ECR bits definition */
|
/* FEC ECR bits definition */
|
||||||
#define FEC_ECR_RESET BIT(0)
|
#define FEC_ECR_MAGICEN (1 << 2)
|
||||||
#define FEC_ECR_ETHEREN BIT(1)
|
#define FEC_ECR_SLEEP (1 << 3)
|
||||||
#define FEC_ECR_MAGICEN BIT(2)
|
|
||||||
#define FEC_ECR_SLEEP BIT(3)
|
|
||||||
#define FEC_ECR_EN1588 BIT(4)
|
|
||||||
|
|
||||||
#define FEC_MII_TIMEOUT 30000 /* us */
|
#define FEC_MII_TIMEOUT 30000 /* us */
|
||||||
|
|
||||||
@ -986,9 +983,6 @@ fec_restart(struct net_device *ndev)
|
|||||||
u32 temp_mac[2];
|
u32 temp_mac[2];
|
||||||
u32 rcntl = OPT_FRAME_SIZE | 0x04;
|
u32 rcntl = OPT_FRAME_SIZE | 0x04;
|
||||||
u32 ecntl = 0x2; /* ETHEREN */
|
u32 ecntl = 0x2; /* ETHEREN */
|
||||||
struct ptp_clock_request ptp_rq = { .type = PTP_CLK_REQ_PPS };
|
|
||||||
|
|
||||||
fec_ptp_save_state(fep);
|
|
||||||
|
|
||||||
/* Whack a reset. We should wait for this.
|
/* Whack a reset. We should wait for this.
|
||||||
* For i.MX6SX SOC, enet use AXI bus, we use disable MAC
|
* For i.MX6SX SOC, enet use AXI bus, we use disable MAC
|
||||||
@ -1142,7 +1136,7 @@ fec_restart(struct net_device *ndev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (fep->bufdesc_ex)
|
if (fep->bufdesc_ex)
|
||||||
ecntl |= FEC_ECR_EN1588;
|
ecntl |= (1 << 4);
|
||||||
|
|
||||||
if (fep->quirks & FEC_QUIRK_DELAYED_CLKS_SUPPORT &&
|
if (fep->quirks & FEC_QUIRK_DELAYED_CLKS_SUPPORT &&
|
||||||
fep->rgmii_txc_dly)
|
fep->rgmii_txc_dly)
|
||||||
@ -1163,14 +1157,6 @@ fec_restart(struct net_device *ndev)
|
|||||||
if (fep->bufdesc_ex)
|
if (fep->bufdesc_ex)
|
||||||
fec_ptp_start_cyclecounter(ndev);
|
fec_ptp_start_cyclecounter(ndev);
|
||||||
|
|
||||||
/* Restart PPS if needed */
|
|
||||||
if (fep->pps_enable) {
|
|
||||||
/* Clear flag so fec_ptp_enable_pps() doesn't return immediately */
|
|
||||||
fep->pps_enable = 0;
|
|
||||||
fec_ptp_restore_state(fep);
|
|
||||||
fep->ptp_caps.enable(&fep->ptp_caps, &ptp_rq, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Enable interrupts we wish to service */
|
/* Enable interrupts we wish to service */
|
||||||
if (fep->link)
|
if (fep->link)
|
||||||
writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK);
|
writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK);
|
||||||
@ -1221,8 +1207,6 @@ fec_stop(struct net_device *ndev)
|
|||||||
struct fec_enet_private *fep = netdev_priv(ndev);
|
struct fec_enet_private *fep = netdev_priv(ndev);
|
||||||
u32 rmii_mode = readl(fep->hwp + FEC_R_CNTRL) & (1 << 8);
|
u32 rmii_mode = readl(fep->hwp + FEC_R_CNTRL) & (1 << 8);
|
||||||
u32 val;
|
u32 val;
|
||||||
struct ptp_clock_request ptp_rq = { .type = PTP_CLK_REQ_PPS };
|
|
||||||
u32 ecntl = 0;
|
|
||||||
|
|
||||||
/* We cannot expect a graceful transmit stop without link !!! */
|
/* We cannot expect a graceful transmit stop without link !!! */
|
||||||
if (fep->link) {
|
if (fep->link) {
|
||||||
@ -1232,8 +1216,6 @@ fec_stop(struct net_device *ndev)
|
|||||||
netdev_err(ndev, "Graceful transmit stop did not complete!\n");
|
netdev_err(ndev, "Graceful transmit stop did not complete!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
fec_ptp_save_state(fep);
|
|
||||||
|
|
||||||
/* Whack a reset. We should wait for this.
|
/* Whack a reset. We should wait for this.
|
||||||
* For i.MX6SX SOC, enet use AXI bus, we use disable MAC
|
* For i.MX6SX SOC, enet use AXI bus, we use disable MAC
|
||||||
* instead of reset MAC itself.
|
* instead of reset MAC itself.
|
||||||
@ -1253,28 +1235,12 @@ fec_stop(struct net_device *ndev)
|
|||||||
writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
|
writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
|
||||||
writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK);
|
writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK);
|
||||||
|
|
||||||
if (fep->bufdesc_ex)
|
|
||||||
ecntl |= FEC_ECR_EN1588;
|
|
||||||
|
|
||||||
/* We have to keep ENET enabled to have MII interrupt stay working */
|
/* We have to keep ENET enabled to have MII interrupt stay working */
|
||||||
if (fep->quirks & FEC_QUIRK_ENET_MAC &&
|
if (fep->quirks & FEC_QUIRK_ENET_MAC &&
|
||||||
!(fep->wol_flag & FEC_WOL_FLAG_SLEEP_ON)) {
|
!(fep->wol_flag & FEC_WOL_FLAG_SLEEP_ON)) {
|
||||||
ecntl |= FEC_ECR_ETHEREN;
|
writel(2, fep->hwp + FEC_ECNTRL);
|
||||||
writel(rmii_mode, fep->hwp + FEC_R_CNTRL);
|
writel(rmii_mode, fep->hwp + FEC_R_CNTRL);
|
||||||
}
|
}
|
||||||
|
|
||||||
writel(ecntl, fep->hwp + FEC_ECNTRL);
|
|
||||||
|
|
||||||
if (fep->bufdesc_ex)
|
|
||||||
fec_ptp_start_cyclecounter(ndev);
|
|
||||||
|
|
||||||
/* Restart PPS if needed */
|
|
||||||
if (fep->pps_enable) {
|
|
||||||
/* Clear flag so fec_ptp_enable_pps() doesn't return immediately */
|
|
||||||
fep->pps_enable = 0;
|
|
||||||
fec_ptp_restore_state(fep);
|
|
||||||
fep->ptp_caps.enable(&fep->ptp_caps, &ptp_rq, 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2029,7 +1995,6 @@ static void fec_enet_phy_reset_after_clk_enable(struct net_device *ndev)
|
|||||||
static int fec_enet_clk_enable(struct net_device *ndev, bool enable)
|
static int fec_enet_clk_enable(struct net_device *ndev, bool enable)
|
||||||
{
|
{
|
||||||
struct fec_enet_private *fep = netdev_priv(ndev);
|
struct fec_enet_private *fep = netdev_priv(ndev);
|
||||||
unsigned long flags;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (enable) {
|
if (enable) {
|
||||||
@ -2038,15 +2003,15 @@ static int fec_enet_clk_enable(struct net_device *ndev, bool enable)
|
|||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if (fep->clk_ptp) {
|
if (fep->clk_ptp) {
|
||||||
spin_lock_irqsave(&fep->tmreg_lock, flags);
|
mutex_lock(&fep->ptp_clk_mutex);
|
||||||
ret = clk_prepare_enable(fep->clk_ptp);
|
ret = clk_prepare_enable(fep->clk_ptp);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
spin_unlock_irqrestore(&fep->tmreg_lock, flags);
|
mutex_unlock(&fep->ptp_clk_mutex);
|
||||||
goto failed_clk_ptp;
|
goto failed_clk_ptp;
|
||||||
} else {
|
} else {
|
||||||
fep->ptp_clk_on = true;
|
fep->ptp_clk_on = true;
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&fep->tmreg_lock, flags);
|
mutex_unlock(&fep->ptp_clk_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = clk_prepare_enable(fep->clk_ref);
|
ret = clk_prepare_enable(fep->clk_ref);
|
||||||
@ -2061,10 +2026,10 @@ static int fec_enet_clk_enable(struct net_device *ndev, bool enable)
|
|||||||
} else {
|
} else {
|
||||||
clk_disable_unprepare(fep->clk_enet_out);
|
clk_disable_unprepare(fep->clk_enet_out);
|
||||||
if (fep->clk_ptp) {
|
if (fep->clk_ptp) {
|
||||||
spin_lock_irqsave(&fep->tmreg_lock, flags);
|
mutex_lock(&fep->ptp_clk_mutex);
|
||||||
clk_disable_unprepare(fep->clk_ptp);
|
clk_disable_unprepare(fep->clk_ptp);
|
||||||
fep->ptp_clk_on = false;
|
fep->ptp_clk_on = false;
|
||||||
spin_unlock_irqrestore(&fep->tmreg_lock, flags);
|
mutex_unlock(&fep->ptp_clk_mutex);
|
||||||
}
|
}
|
||||||
clk_disable_unprepare(fep->clk_ref);
|
clk_disable_unprepare(fep->clk_ref);
|
||||||
clk_disable_unprepare(fep->clk_2x_txclk);
|
clk_disable_unprepare(fep->clk_2x_txclk);
|
||||||
@ -2077,10 +2042,10 @@ failed_clk_2x_txclk:
|
|||||||
clk_disable_unprepare(fep->clk_ref);
|
clk_disable_unprepare(fep->clk_ref);
|
||||||
failed_clk_ref:
|
failed_clk_ref:
|
||||||
if (fep->clk_ptp) {
|
if (fep->clk_ptp) {
|
||||||
spin_lock_irqsave(&fep->tmreg_lock, flags);
|
mutex_lock(&fep->ptp_clk_mutex);
|
||||||
clk_disable_unprepare(fep->clk_ptp);
|
clk_disable_unprepare(fep->clk_ptp);
|
||||||
fep->ptp_clk_on = false;
|
fep->ptp_clk_on = false;
|
||||||
spin_unlock_irqrestore(&fep->tmreg_lock, flags);
|
mutex_unlock(&fep->ptp_clk_mutex);
|
||||||
}
|
}
|
||||||
failed_clk_ptp:
|
failed_clk_ptp:
|
||||||
clk_disable_unprepare(fep->clk_enet_out);
|
clk_disable_unprepare(fep->clk_enet_out);
|
||||||
@ -3915,7 +3880,7 @@ fec_probe(struct platform_device *pdev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
fep->ptp_clk_on = false;
|
fep->ptp_clk_on = false;
|
||||||
spin_lock_init(&fep->tmreg_lock);
|
mutex_init(&fep->ptp_clk_mutex);
|
||||||
|
|
||||||
/* clk_ref is optional, depends on board */
|
/* clk_ref is optional, depends on board */
|
||||||
fep->clk_ref = devm_clk_get_optional(&pdev->dev, "enet_clk_ref");
|
fep->clk_ref = devm_clk_get_optional(&pdev->dev, "enet_clk_ref");
|
||||||
|
@ -365,19 +365,21 @@ static int fec_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
|
|||||||
*/
|
*/
|
||||||
static int fec_ptp_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts)
|
static int fec_ptp_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts)
|
||||||
{
|
{
|
||||||
struct fec_enet_private *fep =
|
struct fec_enet_private *adapter =
|
||||||
container_of(ptp, struct fec_enet_private, ptp_caps);
|
container_of(ptp, struct fec_enet_private, ptp_caps);
|
||||||
u64 ns;
|
u64 ns;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
spin_lock_irqsave(&fep->tmreg_lock, flags);
|
mutex_lock(&adapter->ptp_clk_mutex);
|
||||||
/* Check the ptp clock */
|
/* Check the ptp clock */
|
||||||
if (!fep->ptp_clk_on) {
|
if (!adapter->ptp_clk_on) {
|
||||||
spin_unlock_irqrestore(&fep->tmreg_lock, flags);
|
mutex_unlock(&adapter->ptp_clk_mutex);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
ns = timecounter_read(&fep->tc);
|
spin_lock_irqsave(&adapter->tmreg_lock, flags);
|
||||||
spin_unlock_irqrestore(&fep->tmreg_lock, flags);
|
ns = timecounter_read(&adapter->tc);
|
||||||
|
spin_unlock_irqrestore(&adapter->tmreg_lock, flags);
|
||||||
|
mutex_unlock(&adapter->ptp_clk_mutex);
|
||||||
|
|
||||||
*ts = ns_to_timespec64(ns);
|
*ts = ns_to_timespec64(ns);
|
||||||
|
|
||||||
@ -402,10 +404,10 @@ static int fec_ptp_settime(struct ptp_clock_info *ptp,
|
|||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
u32 counter;
|
u32 counter;
|
||||||
|
|
||||||
spin_lock_irqsave(&fep->tmreg_lock, flags);
|
mutex_lock(&fep->ptp_clk_mutex);
|
||||||
/* Check the ptp clock */
|
/* Check the ptp clock */
|
||||||
if (!fep->ptp_clk_on) {
|
if (!fep->ptp_clk_on) {
|
||||||
spin_unlock_irqrestore(&fep->tmreg_lock, flags);
|
mutex_unlock(&fep->ptp_clk_mutex);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -415,9 +417,11 @@ static int fec_ptp_settime(struct ptp_clock_info *ptp,
|
|||||||
*/
|
*/
|
||||||
counter = ns & fep->cc.mask;
|
counter = ns & fep->cc.mask;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&fep->tmreg_lock, flags);
|
||||||
writel(counter, fep->hwp + FEC_ATIME);
|
writel(counter, fep->hwp + FEC_ATIME);
|
||||||
timecounter_init(&fep->tc, &fep->cc, ns);
|
timecounter_init(&fep->tc, &fep->cc, ns);
|
||||||
spin_unlock_irqrestore(&fep->tmreg_lock, flags);
|
spin_unlock_irqrestore(&fep->tmreg_lock, flags);
|
||||||
|
mutex_unlock(&fep->ptp_clk_mutex);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -514,11 +518,13 @@ static void fec_time_keep(struct work_struct *work)
|
|||||||
struct fec_enet_private *fep = container_of(dwork, struct fec_enet_private, time_keep);
|
struct fec_enet_private *fep = container_of(dwork, struct fec_enet_private, time_keep);
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
spin_lock_irqsave(&fep->tmreg_lock, flags);
|
mutex_lock(&fep->ptp_clk_mutex);
|
||||||
if (fep->ptp_clk_on) {
|
if (fep->ptp_clk_on) {
|
||||||
|
spin_lock_irqsave(&fep->tmreg_lock, flags);
|
||||||
timecounter_read(&fep->tc);
|
timecounter_read(&fep->tc);
|
||||||
|
spin_unlock_irqrestore(&fep->tmreg_lock, flags);
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&fep->tmreg_lock, flags);
|
mutex_unlock(&fep->ptp_clk_mutex);
|
||||||
|
|
||||||
schedule_delayed_work(&fep->time_keep, HZ);
|
schedule_delayed_work(&fep->time_keep, HZ);
|
||||||
}
|
}
|
||||||
@ -593,6 +599,8 @@ void fec_ptp_init(struct platform_device *pdev, int irq_idx)
|
|||||||
}
|
}
|
||||||
fep->ptp_inc = NSEC_PER_SEC / fep->cycle_speed;
|
fep->ptp_inc = NSEC_PER_SEC / fep->cycle_speed;
|
||||||
|
|
||||||
|
spin_lock_init(&fep->tmreg_lock);
|
||||||
|
|
||||||
fec_ptp_start_cyclecounter(ndev);
|
fec_ptp_start_cyclecounter(ndev);
|
||||||
|
|
||||||
INIT_DELAYED_WORK(&fep->time_keep, fec_time_keep);
|
INIT_DELAYED_WORK(&fep->time_keep, fec_time_keep);
|
||||||
@ -625,36 +633,7 @@ void fec_ptp_stop(struct platform_device *pdev)
|
|||||||
struct net_device *ndev = platform_get_drvdata(pdev);
|
struct net_device *ndev = platform_get_drvdata(pdev);
|
||||||
struct fec_enet_private *fep = netdev_priv(ndev);
|
struct fec_enet_private *fep = netdev_priv(ndev);
|
||||||
|
|
||||||
if (fep->pps_enable)
|
|
||||||
fec_ptp_enable_pps(fep, 0);
|
|
||||||
|
|
||||||
cancel_delayed_work_sync(&fep->time_keep);
|
cancel_delayed_work_sync(&fep->time_keep);
|
||||||
if (fep->ptp_clock)
|
if (fep->ptp_clock)
|
||||||
ptp_clock_unregister(fep->ptp_clock);
|
ptp_clock_unregister(fep->ptp_clock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fec_ptp_save_state(struct fec_enet_private *fep)
|
|
||||||
{
|
|
||||||
u32 atime_inc_corr;
|
|
||||||
|
|
||||||
fec_ptp_gettime(&fep->ptp_caps, &fep->ptp_saved_state.ts_phc);
|
|
||||||
fep->ptp_saved_state.ns_sys = ktime_get_ns();
|
|
||||||
|
|
||||||
fep->ptp_saved_state.at_corr = readl(fep->hwp + FEC_ATIME_CORR);
|
|
||||||
atime_inc_corr = readl(fep->hwp + FEC_ATIME_INC) & FEC_T_INC_CORR_MASK;
|
|
||||||
fep->ptp_saved_state.at_inc_corr = (u8)(atime_inc_corr >> FEC_T_INC_CORR_OFFSET);
|
|
||||||
}
|
|
||||||
|
|
||||||
int fec_ptp_restore_state(struct fec_enet_private *fep)
|
|
||||||
{
|
|
||||||
u32 atime_inc = readl(fep->hwp + FEC_ATIME_INC) & FEC_T_INC_MASK;
|
|
||||||
u64 ns_sys;
|
|
||||||
|
|
||||||
writel(fep->ptp_saved_state.at_corr, fep->hwp + FEC_ATIME_CORR);
|
|
||||||
atime_inc |= ((u32)fep->ptp_saved_state.at_inc_corr) << FEC_T_INC_CORR_OFFSET;
|
|
||||||
writel(atime_inc, fep->hwp + FEC_ATIME_INC);
|
|
||||||
|
|
||||||
ns_sys = ktime_get_ns() - fep->ptp_saved_state.ns_sys;
|
|
||||||
timespec64_add_ns(&fep->ptp_saved_state.ts_phc, ns_sys);
|
|
||||||
return fec_ptp_settime(&fep->ptp_caps, &fep->ptp_saved_state.ts_phc);
|
|
||||||
}
|
|
||||||
|
@ -157,7 +157,7 @@ static int gve_alloc_page_dqo(struct gve_priv *priv,
|
|||||||
int err;
|
int err;
|
||||||
|
|
||||||
err = gve_alloc_page(priv, &priv->pdev->dev, &buf_state->page_info.page,
|
err = gve_alloc_page(priv, &priv->pdev->dev, &buf_state->page_info.page,
|
||||||
&buf_state->addr, DMA_FROM_DEVICE, GFP_KERNEL);
|
&buf_state->addr, DMA_FROM_DEVICE, GFP_ATOMIC);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
@ -5908,6 +5908,26 @@ static int i40e_get_link_speed(struct i40e_vsi *vsi)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* i40e_bw_bytes_to_mbits - Convert max_tx_rate from bytes to mbits
|
||||||
|
* @vsi: Pointer to vsi structure
|
||||||
|
* @max_tx_rate: max TX rate in bytes to be converted into Mbits
|
||||||
|
*
|
||||||
|
* Helper function to convert units before send to set BW limit
|
||||||
|
**/
|
||||||
|
static u64 i40e_bw_bytes_to_mbits(struct i40e_vsi *vsi, u64 max_tx_rate)
|
||||||
|
{
|
||||||
|
if (max_tx_rate < I40E_BW_MBPS_DIVISOR) {
|
||||||
|
dev_warn(&vsi->back->pdev->dev,
|
||||||
|
"Setting max tx rate to minimum usable value of 50Mbps.\n");
|
||||||
|
max_tx_rate = I40E_BW_CREDIT_DIVISOR;
|
||||||
|
} else {
|
||||||
|
do_div(max_tx_rate, I40E_BW_MBPS_DIVISOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
return max_tx_rate;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* i40e_set_bw_limit - setup BW limit for Tx traffic based on max_tx_rate
|
* i40e_set_bw_limit - setup BW limit for Tx traffic based on max_tx_rate
|
||||||
* @vsi: VSI to be configured
|
* @vsi: VSI to be configured
|
||||||
@ -5930,10 +5950,10 @@ int i40e_set_bw_limit(struct i40e_vsi *vsi, u16 seid, u64 max_tx_rate)
|
|||||||
max_tx_rate, seid);
|
max_tx_rate, seid);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
if (max_tx_rate && max_tx_rate < 50) {
|
if (max_tx_rate && max_tx_rate < I40E_BW_CREDIT_DIVISOR) {
|
||||||
dev_warn(&pf->pdev->dev,
|
dev_warn(&pf->pdev->dev,
|
||||||
"Setting max tx rate to minimum usable value of 50Mbps.\n");
|
"Setting max tx rate to minimum usable value of 50Mbps.\n");
|
||||||
max_tx_rate = 50;
|
max_tx_rate = I40E_BW_CREDIT_DIVISOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Tx rate credits are in values of 50Mbps, 0 is disabled */
|
/* Tx rate credits are in values of 50Mbps, 0 is disabled */
|
||||||
@ -8224,9 +8244,9 @@ config_tc:
|
|||||||
|
|
||||||
if (i40e_is_tc_mqprio_enabled(pf)) {
|
if (i40e_is_tc_mqprio_enabled(pf)) {
|
||||||
if (vsi->mqprio_qopt.max_rate[0]) {
|
if (vsi->mqprio_qopt.max_rate[0]) {
|
||||||
u64 max_tx_rate = vsi->mqprio_qopt.max_rate[0];
|
u64 max_tx_rate = i40e_bw_bytes_to_mbits(vsi,
|
||||||
|
vsi->mqprio_qopt.max_rate[0]);
|
||||||
|
|
||||||
do_div(max_tx_rate, I40E_BW_MBPS_DIVISOR);
|
|
||||||
ret = i40e_set_bw_limit(vsi, vsi->seid, max_tx_rate);
|
ret = i40e_set_bw_limit(vsi, vsi->seid, max_tx_rate);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
u64 credits = max_tx_rate;
|
u64 credits = max_tx_rate;
|
||||||
@ -10971,10 +10991,10 @@ static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (vsi->mqprio_qopt.max_rate[0]) {
|
if (vsi->mqprio_qopt.max_rate[0]) {
|
||||||
u64 max_tx_rate = vsi->mqprio_qopt.max_rate[0];
|
u64 max_tx_rate = i40e_bw_bytes_to_mbits(vsi,
|
||||||
|
vsi->mqprio_qopt.max_rate[0]);
|
||||||
u64 credits = 0;
|
u64 credits = 0;
|
||||||
|
|
||||||
do_div(max_tx_rate, I40E_BW_MBPS_DIVISOR);
|
|
||||||
ret = i40e_set_bw_limit(vsi, vsi->seid, max_tx_rate);
|
ret = i40e_set_bw_limit(vsi, vsi->seid, max_tx_rate);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto end_unlock;
|
goto end_unlock;
|
||||||
|
@ -2038,6 +2038,25 @@ static void i40e_del_qch(struct i40e_vf *vf)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* i40e_vc_get_max_frame_size
|
||||||
|
* @vf: pointer to the VF
|
||||||
|
*
|
||||||
|
* Max frame size is determined based on the current port's max frame size and
|
||||||
|
* whether a port VLAN is configured on this VF. The VF is not aware whether
|
||||||
|
* it's in a port VLAN so the PF needs to account for this in max frame size
|
||||||
|
* checks and sending the max frame size to the VF.
|
||||||
|
**/
|
||||||
|
static u16 i40e_vc_get_max_frame_size(struct i40e_vf *vf)
|
||||||
|
{
|
||||||
|
u16 max_frame_size = vf->pf->hw.phy.link_info.max_frame_size;
|
||||||
|
|
||||||
|
if (vf->port_vlan_id)
|
||||||
|
max_frame_size -= VLAN_HLEN;
|
||||||
|
|
||||||
|
return max_frame_size;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* i40e_vc_get_vf_resources_msg
|
* i40e_vc_get_vf_resources_msg
|
||||||
* @vf: pointer to the VF info
|
* @vf: pointer to the VF info
|
||||||
@ -2139,6 +2158,7 @@ static int i40e_vc_get_vf_resources_msg(struct i40e_vf *vf, u8 *msg)
|
|||||||
vfres->max_vectors = pf->hw.func_caps.num_msix_vectors_vf;
|
vfres->max_vectors = pf->hw.func_caps.num_msix_vectors_vf;
|
||||||
vfres->rss_key_size = I40E_HKEY_ARRAY_SIZE;
|
vfres->rss_key_size = I40E_HKEY_ARRAY_SIZE;
|
||||||
vfres->rss_lut_size = I40E_VF_HLUT_ARRAY_SIZE;
|
vfres->rss_lut_size = I40E_VF_HLUT_ARRAY_SIZE;
|
||||||
|
vfres->max_mtu = i40e_vc_get_max_frame_size(vf);
|
||||||
|
|
||||||
if (vf->lan_vsi_idx) {
|
if (vf->lan_vsi_idx) {
|
||||||
vfres->vsi_res[0].vsi_id = vf->lan_vsi_id;
|
vfres->vsi_res[0].vsi_id = vf->lan_vsi_id;
|
||||||
|
@ -1077,7 +1077,6 @@ static int iavf_set_mac(struct net_device *netdev, void *p)
|
|||||||
{
|
{
|
||||||
struct iavf_adapter *adapter = netdev_priv(netdev);
|
struct iavf_adapter *adapter = netdev_priv(netdev);
|
||||||
struct sockaddr *addr = p;
|
struct sockaddr *addr = p;
|
||||||
bool handle_mac = iavf_is_mac_set_handled(netdev, addr->sa_data);
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!is_valid_ether_addr(addr->sa_data))
|
if (!is_valid_ether_addr(addr->sa_data))
|
||||||
@ -1094,10 +1093,9 @@ static int iavf_set_mac(struct net_device *netdev, void *p)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (handle_mac)
|
ret = wait_event_interruptible_timeout(adapter->vc_waitqueue,
|
||||||
goto done;
|
iavf_is_mac_set_handled(netdev, addr->sa_data),
|
||||||
|
msecs_to_jiffies(2500));
|
||||||
ret = wait_event_interruptible_timeout(adapter->vc_waitqueue, false, msecs_to_jiffies(2500));
|
|
||||||
|
|
||||||
/* If ret < 0 then it means wait was interrupted.
|
/* If ret < 0 then it means wait was interrupted.
|
||||||
* If ret == 0 then it means we got a timeout.
|
* If ret == 0 then it means we got a timeout.
|
||||||
@ -1111,7 +1109,6 @@ static int iavf_set_mac(struct net_device *netdev, void *p)
|
|||||||
if (!ret)
|
if (!ret)
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
|
|
||||||
done:
|
|
||||||
if (!ether_addr_equal(netdev->dev_addr, addr->sa_data))
|
if (!ether_addr_equal(netdev->dev_addr, addr->sa_data))
|
||||||
return -EACCES;
|
return -EACCES;
|
||||||
|
|
||||||
|
@ -114,8 +114,11 @@ u32 iavf_get_tx_pending(struct iavf_ring *ring, bool in_sw)
|
|||||||
{
|
{
|
||||||
u32 head, tail;
|
u32 head, tail;
|
||||||
|
|
||||||
|
/* underlying hardware might not allow access and/or always return
|
||||||
|
* 0 for the head/tail registers so just use the cached values
|
||||||
|
*/
|
||||||
head = ring->next_to_clean;
|
head = ring->next_to_clean;
|
||||||
tail = readl(ring->tail);
|
tail = ring->next_to_use;
|
||||||
|
|
||||||
if (head != tail)
|
if (head != tail)
|
||||||
return (head < tail) ?
|
return (head < tail) ?
|
||||||
@ -1390,7 +1393,7 @@ static struct sk_buff *iavf_build_skb(struct iavf_ring *rx_ring,
|
|||||||
#endif
|
#endif
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
|
|
||||||
if (!rx_buffer)
|
if (!rx_buffer || !size)
|
||||||
return NULL;
|
return NULL;
|
||||||
/* prefetch first cache line of first page */
|
/* prefetch first cache line of first page */
|
||||||
va = page_address(rx_buffer->page) + rx_buffer->page_offset;
|
va = page_address(rx_buffer->page) + rx_buffer->page_offset;
|
||||||
@ -1548,7 +1551,7 @@ static int iavf_clean_rx_irq(struct iavf_ring *rx_ring, int budget)
|
|||||||
/* exit if we failed to retrieve a buffer */
|
/* exit if we failed to retrieve a buffer */
|
||||||
if (!skb) {
|
if (!skb) {
|
||||||
rx_ring->rx_stats.alloc_buff_failed++;
|
rx_ring->rx_stats.alloc_buff_failed++;
|
||||||
if (rx_buffer)
|
if (rx_buffer && size)
|
||||||
rx_buffer->pagecnt_bias++;
|
rx_buffer->pagecnt_bias++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -269,11 +269,14 @@ int iavf_get_vf_vlan_v2_caps(struct iavf_adapter *adapter)
|
|||||||
void iavf_configure_queues(struct iavf_adapter *adapter)
|
void iavf_configure_queues(struct iavf_adapter *adapter)
|
||||||
{
|
{
|
||||||
struct virtchnl_vsi_queue_config_info *vqci;
|
struct virtchnl_vsi_queue_config_info *vqci;
|
||||||
struct virtchnl_queue_pair_info *vqpi;
|
int i, max_frame = adapter->vf_res->max_mtu;
|
||||||
int pairs = adapter->num_active_queues;
|
int pairs = adapter->num_active_queues;
|
||||||
int i, max_frame = IAVF_MAX_RXBUFFER;
|
struct virtchnl_queue_pair_info *vqpi;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
|
if (max_frame > IAVF_MAX_RXBUFFER || !max_frame)
|
||||||
|
max_frame = IAVF_MAX_RXBUFFER;
|
||||||
|
|
||||||
if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
|
if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
|
||||||
/* bail because we already have a command pending */
|
/* bail because we already have a command pending */
|
||||||
dev_err(&adapter->pdev->dev, "Cannot configure queues, command %d pending\n",
|
dev_err(&adapter->pdev->dev, "Cannot configure queues, command %d pending\n",
|
||||||
|
@ -914,7 +914,7 @@ static void ice_set_dflt_vsi_ctx(struct ice_hw *hw, struct ice_vsi_ctx *ctxt)
|
|||||||
*/
|
*/
|
||||||
static int ice_vsi_setup_q_map(struct ice_vsi *vsi, struct ice_vsi_ctx *ctxt)
|
static int ice_vsi_setup_q_map(struct ice_vsi *vsi, struct ice_vsi_ctx *ctxt)
|
||||||
{
|
{
|
||||||
u16 offset = 0, qmap = 0, tx_count = 0, pow = 0;
|
u16 offset = 0, qmap = 0, tx_count = 0, rx_count = 0, pow = 0;
|
||||||
u16 num_txq_per_tc, num_rxq_per_tc;
|
u16 num_txq_per_tc, num_rxq_per_tc;
|
||||||
u16 qcount_tx = vsi->alloc_txq;
|
u16 qcount_tx = vsi->alloc_txq;
|
||||||
u16 qcount_rx = vsi->alloc_rxq;
|
u16 qcount_rx = vsi->alloc_rxq;
|
||||||
@ -981,22 +981,24 @@ static int ice_vsi_setup_q_map(struct ice_vsi *vsi, struct ice_vsi_ctx *ctxt)
|
|||||||
* at least 1)
|
* at least 1)
|
||||||
*/
|
*/
|
||||||
if (offset)
|
if (offset)
|
||||||
vsi->num_rxq = offset;
|
rx_count = offset;
|
||||||
else
|
else
|
||||||
vsi->num_rxq = num_rxq_per_tc;
|
rx_count = num_rxq_per_tc;
|
||||||
|
|
||||||
if (vsi->num_rxq > vsi->alloc_rxq) {
|
if (rx_count > vsi->alloc_rxq) {
|
||||||
dev_err(ice_pf_to_dev(vsi->back), "Trying to use more Rx queues (%u), than were allocated (%u)!\n",
|
dev_err(ice_pf_to_dev(vsi->back), "Trying to use more Rx queues (%u), than were allocated (%u)!\n",
|
||||||
vsi->num_rxq, vsi->alloc_rxq);
|
rx_count, vsi->alloc_rxq);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tx_count > vsi->alloc_txq) {
|
||||||
|
dev_err(ice_pf_to_dev(vsi->back), "Trying to use more Tx queues (%u), than were allocated (%u)!\n",
|
||||||
|
tx_count, vsi->alloc_txq);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
vsi->num_txq = tx_count;
|
vsi->num_txq = tx_count;
|
||||||
if (vsi->num_txq > vsi->alloc_txq) {
|
vsi->num_rxq = rx_count;
|
||||||
dev_err(ice_pf_to_dev(vsi->back), "Trying to use more Tx queues (%u), than were allocated (%u)!\n",
|
|
||||||
vsi->num_txq, vsi->alloc_txq);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vsi->type == ICE_VSI_VF && vsi->num_txq != vsi->num_rxq) {
|
if (vsi->type == ICE_VSI_VF && vsi->num_txq != vsi->num_rxq) {
|
||||||
dev_dbg(ice_pf_to_dev(vsi->back), "VF VSI should have same number of Tx and Rx queues. Hence making them equal\n");
|
dev_dbg(ice_pf_to_dev(vsi->back), "VF VSI should have same number of Tx and Rx queues. Hence making them equal\n");
|
||||||
@ -3490,6 +3492,7 @@ ice_vsi_setup_q_map_mqprio(struct ice_vsi *vsi, struct ice_vsi_ctx *ctxt,
|
|||||||
u16 pow, offset = 0, qcount_tx = 0, qcount_rx = 0, qmap;
|
u16 pow, offset = 0, qcount_tx = 0, qcount_rx = 0, qmap;
|
||||||
u16 tc0_offset = vsi->mqprio_qopt.qopt.offset[0];
|
u16 tc0_offset = vsi->mqprio_qopt.qopt.offset[0];
|
||||||
int tc0_qcount = vsi->mqprio_qopt.qopt.count[0];
|
int tc0_qcount = vsi->mqprio_qopt.qopt.count[0];
|
||||||
|
u16 new_txq, new_rxq;
|
||||||
u8 netdev_tc = 0;
|
u8 netdev_tc = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -3530,21 +3533,24 @@ ice_vsi_setup_q_map_mqprio(struct ice_vsi *vsi, struct ice_vsi_ctx *ctxt,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set actual Tx/Rx queue pairs */
|
new_txq = offset + qcount_tx;
|
||||||
vsi->num_txq = offset + qcount_tx;
|
if (new_txq > vsi->alloc_txq) {
|
||||||
if (vsi->num_txq > vsi->alloc_txq) {
|
|
||||||
dev_err(ice_pf_to_dev(vsi->back), "Trying to use more Tx queues (%u), than were allocated (%u)!\n",
|
dev_err(ice_pf_to_dev(vsi->back), "Trying to use more Tx queues (%u), than were allocated (%u)!\n",
|
||||||
vsi->num_txq, vsi->alloc_txq);
|
new_txq, vsi->alloc_txq);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
vsi->num_rxq = offset + qcount_rx;
|
new_rxq = offset + qcount_rx;
|
||||||
if (vsi->num_rxq > vsi->alloc_rxq) {
|
if (new_rxq > vsi->alloc_rxq) {
|
||||||
dev_err(ice_pf_to_dev(vsi->back), "Trying to use more Rx queues (%u), than were allocated (%u)!\n",
|
dev_err(ice_pf_to_dev(vsi->back), "Trying to use more Rx queues (%u), than were allocated (%u)!\n",
|
||||||
vsi->num_rxq, vsi->alloc_rxq);
|
new_rxq, vsi->alloc_rxq);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set actual Tx/Rx queue pairs */
|
||||||
|
vsi->num_txq = new_txq;
|
||||||
|
vsi->num_rxq = new_rxq;
|
||||||
|
|
||||||
/* Setup queue TC[0].qmap for given VSI context */
|
/* Setup queue TC[0].qmap for given VSI context */
|
||||||
ctxt->info.tc_mapping[0] = cpu_to_le16(qmap);
|
ctxt->info.tc_mapping[0] = cpu_to_le16(qmap);
|
||||||
ctxt->info.q_mapping[0] = cpu_to_le16(vsi->rxq_map[0]);
|
ctxt->info.q_mapping[0] = cpu_to_le16(vsi->rxq_map[0]);
|
||||||
@ -3576,6 +3582,7 @@ int ice_vsi_cfg_tc(struct ice_vsi *vsi, u8 ena_tc)
|
|||||||
{
|
{
|
||||||
u16 max_txqs[ICE_MAX_TRAFFIC_CLASS] = { 0 };
|
u16 max_txqs[ICE_MAX_TRAFFIC_CLASS] = { 0 };
|
||||||
struct ice_pf *pf = vsi->back;
|
struct ice_pf *pf = vsi->back;
|
||||||
|
struct ice_tc_cfg old_tc_cfg;
|
||||||
struct ice_vsi_ctx *ctx;
|
struct ice_vsi_ctx *ctx;
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
int i, ret = 0;
|
int i, ret = 0;
|
||||||
@ -3600,6 +3607,7 @@ int ice_vsi_cfg_tc(struct ice_vsi *vsi, u8 ena_tc)
|
|||||||
max_txqs[i] = vsi->num_txq;
|
max_txqs[i] = vsi->num_txq;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memcpy(&old_tc_cfg, &vsi->tc_cfg, sizeof(old_tc_cfg));
|
||||||
vsi->tc_cfg.ena_tc = ena_tc;
|
vsi->tc_cfg.ena_tc = ena_tc;
|
||||||
vsi->tc_cfg.numtc = num_tc;
|
vsi->tc_cfg.numtc = num_tc;
|
||||||
|
|
||||||
@ -3616,8 +3624,10 @@ int ice_vsi_cfg_tc(struct ice_vsi *vsi, u8 ena_tc)
|
|||||||
else
|
else
|
||||||
ret = ice_vsi_setup_q_map(vsi, ctx);
|
ret = ice_vsi_setup_q_map(vsi, ctx);
|
||||||
|
|
||||||
if (ret)
|
if (ret) {
|
||||||
|
memcpy(&vsi->tc_cfg, &old_tc_cfg, sizeof(vsi->tc_cfg));
|
||||||
goto out;
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
/* must to indicate which section of VSI context are being modified */
|
/* must to indicate which section of VSI context are being modified */
|
||||||
ctx->info.valid_sections = cpu_to_le16(ICE_AQ_VSI_PROP_RXQ_MAP_VALID);
|
ctx->info.valid_sections = cpu_to_le16(ICE_AQ_VSI_PROP_RXQ_MAP_VALID);
|
||||||
|
@ -2399,8 +2399,6 @@ int ice_schedule_reset(struct ice_pf *pf, enum ice_reset_req reset)
|
|||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
ice_unplug_aux_dev(pf);
|
|
||||||
|
|
||||||
switch (reset) {
|
switch (reset) {
|
||||||
case ICE_RESET_PFR:
|
case ICE_RESET_PFR:
|
||||||
set_bit(ICE_PFR_REQ, pf->state);
|
set_bit(ICE_PFR_REQ, pf->state);
|
||||||
@ -6651,7 +6649,7 @@ static void ice_napi_disable_all(struct ice_vsi *vsi)
|
|||||||
*/
|
*/
|
||||||
int ice_down(struct ice_vsi *vsi)
|
int ice_down(struct ice_vsi *vsi)
|
||||||
{
|
{
|
||||||
int i, tx_err, rx_err, link_err = 0, vlan_err = 0;
|
int i, tx_err, rx_err, vlan_err = 0;
|
||||||
|
|
||||||
WARN_ON(!test_bit(ICE_VSI_DOWN, vsi->state));
|
WARN_ON(!test_bit(ICE_VSI_DOWN, vsi->state));
|
||||||
|
|
||||||
@ -6685,20 +6683,13 @@ int ice_down(struct ice_vsi *vsi)
|
|||||||
|
|
||||||
ice_napi_disable_all(vsi);
|
ice_napi_disable_all(vsi);
|
||||||
|
|
||||||
if (test_bit(ICE_FLAG_LINK_DOWN_ON_CLOSE_ENA, vsi->back->flags)) {
|
|
||||||
link_err = ice_force_phys_link_state(vsi, false);
|
|
||||||
if (link_err)
|
|
||||||
netdev_err(vsi->netdev, "Failed to set physical link down, VSI %d error %d\n",
|
|
||||||
vsi->vsi_num, link_err);
|
|
||||||
}
|
|
||||||
|
|
||||||
ice_for_each_txq(vsi, i)
|
ice_for_each_txq(vsi, i)
|
||||||
ice_clean_tx_ring(vsi->tx_rings[i]);
|
ice_clean_tx_ring(vsi->tx_rings[i]);
|
||||||
|
|
||||||
ice_for_each_rxq(vsi, i)
|
ice_for_each_rxq(vsi, i)
|
||||||
ice_clean_rx_ring(vsi->rx_rings[i]);
|
ice_clean_rx_ring(vsi->rx_rings[i]);
|
||||||
|
|
||||||
if (tx_err || rx_err || link_err || vlan_err) {
|
if (tx_err || rx_err || vlan_err) {
|
||||||
netdev_err(vsi->netdev, "Failed to close VSI 0x%04X on switch 0x%04X\n",
|
netdev_err(vsi->netdev, "Failed to close VSI 0x%04X on switch 0x%04X\n",
|
||||||
vsi->vsi_num, vsi->vsw->sw_id);
|
vsi->vsi_num, vsi->vsw->sw_id);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
@ -6860,6 +6851,8 @@ int ice_vsi_open(struct ice_vsi *vsi)
|
|||||||
if (err)
|
if (err)
|
||||||
goto err_setup_rx;
|
goto err_setup_rx;
|
||||||
|
|
||||||
|
ice_vsi_cfg_netdev_tc(vsi, vsi->tc_cfg.ena_tc);
|
||||||
|
|
||||||
if (vsi->type == ICE_VSI_PF) {
|
if (vsi->type == ICE_VSI_PF) {
|
||||||
/* Notify the stack of the actual queue counts. */
|
/* Notify the stack of the actual queue counts. */
|
||||||
err = netif_set_real_num_tx_queues(vsi->netdev, vsi->num_txq);
|
err = netif_set_real_num_tx_queues(vsi->netdev, vsi->num_txq);
|
||||||
@ -8892,6 +8885,16 @@ int ice_stop(struct net_device *netdev)
|
|||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (test_bit(ICE_FLAG_LINK_DOWN_ON_CLOSE_ENA, vsi->back->flags)) {
|
||||||
|
int link_err = ice_force_phys_link_state(vsi, false);
|
||||||
|
|
||||||
|
if (link_err) {
|
||||||
|
netdev_err(vsi->netdev, "Failed to set physical link down, VSI %d error %d\n",
|
||||||
|
vsi->vsi_num, link_err);
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ice_vsi_close(vsi);
|
ice_vsi_close(vsi);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -610,7 +610,7 @@ ice_xdp_xmit(struct net_device *dev, int n, struct xdp_frame **frames,
|
|||||||
if (test_bit(ICE_VSI_DOWN, vsi->state))
|
if (test_bit(ICE_VSI_DOWN, vsi->state))
|
||||||
return -ENETDOWN;
|
return -ENETDOWN;
|
||||||
|
|
||||||
if (!ice_is_xdp_ena_vsi(vsi) || queue_index >= vsi->num_xdp_txq)
|
if (!ice_is_xdp_ena_vsi(vsi))
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
|
|
||||||
if (unlikely(flags & ~XDP_XMIT_FLAGS_MASK))
|
if (unlikely(flags & ~XDP_XMIT_FLAGS_MASK))
|
||||||
@ -621,6 +621,9 @@ ice_xdp_xmit(struct net_device *dev, int n, struct xdp_frame **frames,
|
|||||||
xdp_ring = vsi->xdp_rings[queue_index];
|
xdp_ring = vsi->xdp_rings[queue_index];
|
||||||
spin_lock(&xdp_ring->tx_lock);
|
spin_lock(&xdp_ring->tx_lock);
|
||||||
} else {
|
} else {
|
||||||
|
/* Generally, should not happen */
|
||||||
|
if (unlikely(queue_index >= vsi->num_xdp_txq))
|
||||||
|
return -ENXIO;
|
||||||
xdp_ring = vsi->xdp_rings[queue_index];
|
xdp_ring = vsi->xdp_rings[queue_index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -368,6 +368,7 @@ static int prestera_port_sfp_bind(struct prestera_port *port)
|
|||||||
if (!sw->np)
|
if (!sw->np)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
of_node_get(sw->np);
|
||||||
ports = of_find_node_by_name(sw->np, "ports");
|
ports = of_find_node_by_name(sw->np, "ports");
|
||||||
|
|
||||||
for_each_child_of_node(ports, node) {
|
for_each_child_of_node(ports, node) {
|
||||||
@ -417,6 +418,7 @@ static int prestera_port_sfp_bind(struct prestera_port *port)
|
|||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
of_node_put(node);
|
||||||
of_node_put(ports);
|
of_node_put(ports);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -872,6 +872,7 @@ static void prestera_pci_remove(struct pci_dev *pdev)
|
|||||||
static const struct pci_device_id prestera_pci_devices[] = {
|
static const struct pci_device_id prestera_pci_devices[] = {
|
||||||
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0xC804) },
|
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0xC804) },
|
||||||
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0xC80C) },
|
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0xC80C) },
|
||||||
|
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0xCC1E) },
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(pci, prestera_pci_devices);
|
MODULE_DEVICE_TABLE(pci, prestera_pci_devices);
|
||||||
|
@ -1458,7 +1458,7 @@ static void mtk_update_rx_cpu_idx(struct mtk_eth *eth)
|
|||||||
|
|
||||||
static bool mtk_page_pool_enabled(struct mtk_eth *eth)
|
static bool mtk_page_pool_enabled(struct mtk_eth *eth)
|
||||||
{
|
{
|
||||||
return !eth->hwlro;
|
return MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct page_pool *mtk_create_page_pool(struct mtk_eth *eth,
|
static struct page_pool *mtk_create_page_pool(struct mtk_eth *eth,
|
||||||
|
@ -179,6 +179,9 @@ static int mlxbf_gige_mdio_read(struct mii_bus *bus, int phy_add, int phy_reg)
|
|||||||
/* Only return ad bits of the gw register */
|
/* Only return ad bits of the gw register */
|
||||||
ret &= MLXBF_GIGE_MDIO_GW_AD_MASK;
|
ret &= MLXBF_GIGE_MDIO_GW_AD_MASK;
|
||||||
|
|
||||||
|
/* The MDIO lock is set on read. To release it, clear gw register */
|
||||||
|
writel(0, priv->mdio_io + MLXBF_GIGE_MDIO_GW_OFFSET);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,6 +206,9 @@ static int mlxbf_gige_mdio_write(struct mii_bus *bus, int phy_add,
|
|||||||
temp, !(temp & MLXBF_GIGE_MDIO_GW_BUSY_MASK),
|
temp, !(temp & MLXBF_GIGE_MDIO_GW_BUSY_MASK),
|
||||||
5, 1000000);
|
5, 1000000);
|
||||||
|
|
||||||
|
/* The MDIO lock is set on read. To release it, clear gw register */
|
||||||
|
writel(0, priv->mdio_io + MLXBF_GIGE_MDIO_GW_OFFSET);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -397,6 +397,11 @@ static void mana_gd_process_eq_events(void *arg)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Per GDMA spec, rmb is necessary after checking owner_bits, before
|
||||||
|
* reading eqe.
|
||||||
|
*/
|
||||||
|
rmb();
|
||||||
|
|
||||||
mana_gd_process_eqe(eq);
|
mana_gd_process_eqe(eq);
|
||||||
|
|
||||||
eq->head++;
|
eq->head++;
|
||||||
@ -1134,6 +1139,11 @@ static int mana_gd_read_cqe(struct gdma_queue *cq, struct gdma_comp *comp)
|
|||||||
if (WARN_ON_ONCE(owner_bits != new_bits))
|
if (WARN_ON_ONCE(owner_bits != new_bits))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
/* Per GDMA spec, rmb is necessary after checking owner_bits, before
|
||||||
|
* reading completion info
|
||||||
|
*/
|
||||||
|
rmb();
|
||||||
|
|
||||||
comp->wq_num = cqe->cqe_info.wq_num;
|
comp->wq_num = cqe->cqe_info.wq_num;
|
||||||
comp->is_sq = cqe->cqe_info.is_sq;
|
comp->is_sq = cqe->cqe_info.is_sq;
|
||||||
memcpy(comp->cqe_data, cqe->cqe_data, GDMA_COMP_DATA_SIZE);
|
memcpy(comp->cqe_data, cqe->cqe_data, GDMA_COMP_DATA_SIZE);
|
||||||
|
@ -1449,6 +1449,8 @@ static int ravb_phy_init(struct net_device *ndev)
|
|||||||
phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_100baseT_Half_BIT);
|
phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_100baseT_Half_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Indicate that the MAC is responsible for managing PHY PM */
|
||||||
|
phydev->mac_managed_pm = true;
|
||||||
phy_attached_info(phydev);
|
phy_attached_info(phydev);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2029,6 +2029,8 @@ static int sh_eth_phy_init(struct net_device *ndev)
|
|||||||
if (mdp->cd->register_type != SH_ETH_REG_GIGABIT)
|
if (mdp->cd->register_type != SH_ETH_REG_GIGABIT)
|
||||||
phy_set_max_speed(phydev, SPEED_100);
|
phy_set_max_speed(phydev, SPEED_100);
|
||||||
|
|
||||||
|
/* Indicate that the MAC is responsible for managing PHY PM */
|
||||||
|
phydev->mac_managed_pm = true;
|
||||||
phy_attached_info(phydev);
|
phy_attached_info(phydev);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -319,7 +319,7 @@ int efx_probe_interrupts(struct efx_nic *efx)
|
|||||||
efx->n_channels = 1 + (efx_separate_tx_channels ? 1 : 0);
|
efx->n_channels = 1 + (efx_separate_tx_channels ? 1 : 0);
|
||||||
efx->n_rx_channels = 1;
|
efx->n_rx_channels = 1;
|
||||||
efx->n_tx_channels = 1;
|
efx->n_tx_channels = 1;
|
||||||
efx->tx_channel_offset = 1;
|
efx->tx_channel_offset = efx_separate_tx_channels ? 1 : 0;
|
||||||
efx->n_xdp_channels = 0;
|
efx->n_xdp_channels = 0;
|
||||||
efx->xdp_channel_offset = efx->n_channels;
|
efx->xdp_channel_offset = efx->n_channels;
|
||||||
efx->legacy_irq = efx->pci_dev->irq;
|
efx->legacy_irq = efx->pci_dev->irq;
|
||||||
|
@ -320,7 +320,7 @@ int efx_siena_probe_interrupts(struct efx_nic *efx)
|
|||||||
efx->n_channels = 1 + (efx_siena_separate_tx_channels ? 1 : 0);
|
efx->n_channels = 1 + (efx_siena_separate_tx_channels ? 1 : 0);
|
||||||
efx->n_rx_channels = 1;
|
efx->n_rx_channels = 1;
|
||||||
efx->n_tx_channels = 1;
|
efx->n_tx_channels = 1;
|
||||||
efx->tx_channel_offset = 1;
|
efx->tx_channel_offset = efx_siena_separate_tx_channels ? 1 : 0;
|
||||||
efx->n_xdp_channels = 0;
|
efx->n_xdp_channels = 0;
|
||||||
efx->xdp_channel_offset = efx->n_channels;
|
efx->xdp_channel_offset = efx->n_channels;
|
||||||
efx->legacy_irq = efx->pci_dev->irq;
|
efx->legacy_irq = efx->pci_dev->irq;
|
||||||
|
@ -336,7 +336,7 @@ netdev_tx_t efx_siena_hard_start_xmit(struct sk_buff *skb,
|
|||||||
* previous packets out.
|
* previous packets out.
|
||||||
*/
|
*/
|
||||||
if (!netdev_xmit_more())
|
if (!netdev_xmit_more())
|
||||||
efx_tx_send_pending(tx_queue->channel);
|
efx_tx_send_pending(efx_get_tx_channel(efx, index));
|
||||||
return NETDEV_TX_OK;
|
return NETDEV_TX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -549,7 +549,7 @@ netdev_tx_t efx_hard_start_xmit(struct sk_buff *skb,
|
|||||||
* previous packets out.
|
* previous packets out.
|
||||||
*/
|
*/
|
||||||
if (!netdev_xmit_more())
|
if (!netdev_xmit_more())
|
||||||
efx_tx_send_pending(tx_queue->channel);
|
efx_tx_send_pending(efx_get_tx_channel(efx, index));
|
||||||
return NETDEV_TX_OK;
|
return NETDEV_TX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2020,9 +2020,9 @@ static void happy_meal_rx(struct happy_meal *hp, struct net_device *dev)
|
|||||||
|
|
||||||
skb_reserve(copy_skb, 2);
|
skb_reserve(copy_skb, 2);
|
||||||
skb_put(copy_skb, len);
|
skb_put(copy_skb, len);
|
||||||
dma_sync_single_for_cpu(hp->dma_dev, dma_addr, len, DMA_FROM_DEVICE);
|
dma_sync_single_for_cpu(hp->dma_dev, dma_addr, len + 2, DMA_FROM_DEVICE);
|
||||||
skb_copy_from_linear_data(skb, copy_skb->data, len);
|
skb_copy_from_linear_data(skb, copy_skb->data, len);
|
||||||
dma_sync_single_for_device(hp->dma_dev, dma_addr, len, DMA_FROM_DEVICE);
|
dma_sync_single_for_device(hp->dma_dev, dma_addr, len + 2, DMA_FROM_DEVICE);
|
||||||
/* Reuse original ring buffer. */
|
/* Reuse original ring buffer. */
|
||||||
hme_write_rxd(hp, this,
|
hme_write_rxd(hp, this,
|
||||||
(RXFLAG_OWN|((RX_BUF_ALLOC_SIZE-RX_OFFSET)<<16)),
|
(RXFLAG_OWN|((RX_BUF_ALLOC_SIZE-RX_OFFSET)<<16)),
|
||||||
|
@ -308,12 +308,12 @@ init_modem_driver_req(struct ipa_qmi *ipa_qmi)
|
|||||||
mem = ipa_mem_find(ipa, IPA_MEM_V4_ROUTE);
|
mem = ipa_mem_find(ipa, IPA_MEM_V4_ROUTE);
|
||||||
req.v4_route_tbl_info_valid = 1;
|
req.v4_route_tbl_info_valid = 1;
|
||||||
req.v4_route_tbl_info.start = ipa->mem_offset + mem->offset;
|
req.v4_route_tbl_info.start = ipa->mem_offset + mem->offset;
|
||||||
req.v4_route_tbl_info.count = mem->size / sizeof(__le64);
|
req.v4_route_tbl_info.end = IPA_ROUTE_MODEM_COUNT - 1;
|
||||||
|
|
||||||
mem = ipa_mem_find(ipa, IPA_MEM_V6_ROUTE);
|
mem = ipa_mem_find(ipa, IPA_MEM_V6_ROUTE);
|
||||||
req.v6_route_tbl_info_valid = 1;
|
req.v6_route_tbl_info_valid = 1;
|
||||||
req.v6_route_tbl_info.start = ipa->mem_offset + mem->offset;
|
req.v6_route_tbl_info.start = ipa->mem_offset + mem->offset;
|
||||||
req.v6_route_tbl_info.count = mem->size / sizeof(__le64);
|
req.v6_route_tbl_info.end = IPA_ROUTE_MODEM_COUNT - 1;
|
||||||
|
|
||||||
mem = ipa_mem_find(ipa, IPA_MEM_V4_FILTER);
|
mem = ipa_mem_find(ipa, IPA_MEM_V4_FILTER);
|
||||||
req.v4_filter_tbl_start_valid = 1;
|
req.v4_filter_tbl_start_valid = 1;
|
||||||
@ -352,7 +352,7 @@ init_modem_driver_req(struct ipa_qmi *ipa_qmi)
|
|||||||
req.v4_hash_route_tbl_info_valid = 1;
|
req.v4_hash_route_tbl_info_valid = 1;
|
||||||
req.v4_hash_route_tbl_info.start =
|
req.v4_hash_route_tbl_info.start =
|
||||||
ipa->mem_offset + mem->offset;
|
ipa->mem_offset + mem->offset;
|
||||||
req.v4_hash_route_tbl_info.count = mem->size / sizeof(__le64);
|
req.v4_hash_route_tbl_info.end = IPA_ROUTE_MODEM_COUNT - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
mem = ipa_mem_find(ipa, IPA_MEM_V6_ROUTE_HASHED);
|
mem = ipa_mem_find(ipa, IPA_MEM_V6_ROUTE_HASHED);
|
||||||
@ -360,7 +360,7 @@ init_modem_driver_req(struct ipa_qmi *ipa_qmi)
|
|||||||
req.v6_hash_route_tbl_info_valid = 1;
|
req.v6_hash_route_tbl_info_valid = 1;
|
||||||
req.v6_hash_route_tbl_info.start =
|
req.v6_hash_route_tbl_info.start =
|
||||||
ipa->mem_offset + mem->offset;
|
ipa->mem_offset + mem->offset;
|
||||||
req.v6_hash_route_tbl_info.count = mem->size / sizeof(__le64);
|
req.v6_hash_route_tbl_info.end = IPA_ROUTE_MODEM_COUNT - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
mem = ipa_mem_find(ipa, IPA_MEM_V4_FILTER_HASHED);
|
mem = ipa_mem_find(ipa, IPA_MEM_V4_FILTER_HASHED);
|
||||||
|
@ -311,7 +311,7 @@ struct qmi_elem_info ipa_init_modem_driver_req_ei[] = {
|
|||||||
.tlv_type = 0x12,
|
.tlv_type = 0x12,
|
||||||
.offset = offsetof(struct ipa_init_modem_driver_req,
|
.offset = offsetof(struct ipa_init_modem_driver_req,
|
||||||
v4_route_tbl_info),
|
v4_route_tbl_info),
|
||||||
.ei_array = ipa_mem_array_ei,
|
.ei_array = ipa_mem_bounds_ei,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.data_type = QMI_OPT_FLAG,
|
.data_type = QMI_OPT_FLAG,
|
||||||
@ -332,7 +332,7 @@ struct qmi_elem_info ipa_init_modem_driver_req_ei[] = {
|
|||||||
.tlv_type = 0x13,
|
.tlv_type = 0x13,
|
||||||
.offset = offsetof(struct ipa_init_modem_driver_req,
|
.offset = offsetof(struct ipa_init_modem_driver_req,
|
||||||
v6_route_tbl_info),
|
v6_route_tbl_info),
|
||||||
.ei_array = ipa_mem_array_ei,
|
.ei_array = ipa_mem_bounds_ei,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.data_type = QMI_OPT_FLAG,
|
.data_type = QMI_OPT_FLAG,
|
||||||
@ -496,7 +496,7 @@ struct qmi_elem_info ipa_init_modem_driver_req_ei[] = {
|
|||||||
.tlv_type = 0x1b,
|
.tlv_type = 0x1b,
|
||||||
.offset = offsetof(struct ipa_init_modem_driver_req,
|
.offset = offsetof(struct ipa_init_modem_driver_req,
|
||||||
v4_hash_route_tbl_info),
|
v4_hash_route_tbl_info),
|
||||||
.ei_array = ipa_mem_array_ei,
|
.ei_array = ipa_mem_bounds_ei,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.data_type = QMI_OPT_FLAG,
|
.data_type = QMI_OPT_FLAG,
|
||||||
@ -517,7 +517,7 @@ struct qmi_elem_info ipa_init_modem_driver_req_ei[] = {
|
|||||||
.tlv_type = 0x1c,
|
.tlv_type = 0x1c,
|
||||||
.offset = offsetof(struct ipa_init_modem_driver_req,
|
.offset = offsetof(struct ipa_init_modem_driver_req,
|
||||||
v6_hash_route_tbl_info),
|
v6_hash_route_tbl_info),
|
||||||
.ei_array = ipa_mem_array_ei,
|
.ei_array = ipa_mem_bounds_ei,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.data_type = QMI_OPT_FLAG,
|
.data_type = QMI_OPT_FLAG,
|
||||||
|
@ -86,9 +86,11 @@ enum ipa_platform_type {
|
|||||||
IPA_QMI_PLATFORM_TYPE_MSM_QNX_V01 = 0x5, /* QNX MSM */
|
IPA_QMI_PLATFORM_TYPE_MSM_QNX_V01 = 0x5, /* QNX MSM */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* This defines the start and end offset of a range of memory. Both
|
/* This defines the start and end offset of a range of memory. The start
|
||||||
* fields are offsets relative to the start of IPA shared memory.
|
* value is a byte offset relative to the start of IPA shared memory. The
|
||||||
* The end value is the last addressable byte *within* the range.
|
* end value is the last addressable unit *within* the range. Typically
|
||||||
|
* the end value is in units of bytes, however it can also be a maximum
|
||||||
|
* array index value.
|
||||||
*/
|
*/
|
||||||
struct ipa_mem_bounds {
|
struct ipa_mem_bounds {
|
||||||
u32 start;
|
u32 start;
|
||||||
@ -129,18 +131,19 @@ struct ipa_init_modem_driver_req {
|
|||||||
u8 hdr_tbl_info_valid;
|
u8 hdr_tbl_info_valid;
|
||||||
struct ipa_mem_bounds hdr_tbl_info;
|
struct ipa_mem_bounds hdr_tbl_info;
|
||||||
|
|
||||||
/* Routing table information. These define the location and size of
|
/* Routing table information. These define the location and maximum
|
||||||
* non-hashable IPv4 and IPv6 filter tables. The start values are
|
* *index* (not byte) for the modem portion of non-hashable IPv4 and
|
||||||
* offsets relative to the start of IPA shared memory.
|
* IPv6 routing tables. The start values are byte offsets relative
|
||||||
|
* to the start of IPA shared memory.
|
||||||
*/
|
*/
|
||||||
u8 v4_route_tbl_info_valid;
|
u8 v4_route_tbl_info_valid;
|
||||||
struct ipa_mem_array v4_route_tbl_info;
|
struct ipa_mem_bounds v4_route_tbl_info;
|
||||||
u8 v6_route_tbl_info_valid;
|
u8 v6_route_tbl_info_valid;
|
||||||
struct ipa_mem_array v6_route_tbl_info;
|
struct ipa_mem_bounds v6_route_tbl_info;
|
||||||
|
|
||||||
/* Filter table information. These define the location of the
|
/* Filter table information. These define the location of the
|
||||||
* non-hashable IPv4 and IPv6 filter tables. The start values are
|
* non-hashable IPv4 and IPv6 filter tables. The start values are
|
||||||
* offsets relative to the start of IPA shared memory.
|
* byte offsets relative to the start of IPA shared memory.
|
||||||
*/
|
*/
|
||||||
u8 v4_filter_tbl_start_valid;
|
u8 v4_filter_tbl_start_valid;
|
||||||
u32 v4_filter_tbl_start;
|
u32 v4_filter_tbl_start;
|
||||||
@ -181,18 +184,20 @@ struct ipa_init_modem_driver_req {
|
|||||||
u8 zip_tbl_info_valid;
|
u8 zip_tbl_info_valid;
|
||||||
struct ipa_mem_bounds zip_tbl_info;
|
struct ipa_mem_bounds zip_tbl_info;
|
||||||
|
|
||||||
/* Routing table information. These define the location and size
|
/* Routing table information. These define the location and maximum
|
||||||
* of hashable IPv4 and IPv6 filter tables. The start values are
|
* *index* (not byte) for the modem portion of hashable IPv4 and IPv6
|
||||||
* offsets relative to the start of IPA shared memory.
|
* routing tables (if supported by hardware). The start values are
|
||||||
|
* byte offsets relative to the start of IPA shared memory.
|
||||||
*/
|
*/
|
||||||
u8 v4_hash_route_tbl_info_valid;
|
u8 v4_hash_route_tbl_info_valid;
|
||||||
struct ipa_mem_array v4_hash_route_tbl_info;
|
struct ipa_mem_bounds v4_hash_route_tbl_info;
|
||||||
u8 v6_hash_route_tbl_info_valid;
|
u8 v6_hash_route_tbl_info_valid;
|
||||||
struct ipa_mem_array v6_hash_route_tbl_info;
|
struct ipa_mem_bounds v6_hash_route_tbl_info;
|
||||||
|
|
||||||
/* Filter table information. These define the location and size
|
/* Filter table information. These define the location and size
|
||||||
* of hashable IPv4 and IPv6 filter tables. The start values are
|
* of hashable IPv4 and IPv6 filter tables (if supported by hardware).
|
||||||
* offsets relative to the start of IPA shared memory.
|
* The start values are byte offsets relative to the start of IPA
|
||||||
|
* shared memory.
|
||||||
*/
|
*/
|
||||||
u8 v4_hash_filter_tbl_start_valid;
|
u8 v4_hash_filter_tbl_start_valid;
|
||||||
u32 v4_hash_filter_tbl_start;
|
u32 v4_hash_filter_tbl_start;
|
||||||
|
@ -108,8 +108,6 @@
|
|||||||
|
|
||||||
/* Assignment of route table entries to the modem and AP */
|
/* Assignment of route table entries to the modem and AP */
|
||||||
#define IPA_ROUTE_MODEM_MIN 0
|
#define IPA_ROUTE_MODEM_MIN 0
|
||||||
#define IPA_ROUTE_MODEM_COUNT 8
|
|
||||||
|
|
||||||
#define IPA_ROUTE_AP_MIN IPA_ROUTE_MODEM_COUNT
|
#define IPA_ROUTE_AP_MIN IPA_ROUTE_MODEM_COUNT
|
||||||
#define IPA_ROUTE_AP_COUNT \
|
#define IPA_ROUTE_AP_COUNT \
|
||||||
(IPA_ROUTE_COUNT_MAX - IPA_ROUTE_MODEM_COUNT)
|
(IPA_ROUTE_COUNT_MAX - IPA_ROUTE_MODEM_COUNT)
|
||||||
|
@ -13,6 +13,9 @@ struct ipa;
|
|||||||
/* The maximum number of filter table entries (IPv4, IPv6; hashed or not) */
|
/* The maximum number of filter table entries (IPv4, IPv6; hashed or not) */
|
||||||
#define IPA_FILTER_COUNT_MAX 14
|
#define IPA_FILTER_COUNT_MAX 14
|
||||||
|
|
||||||
|
/* The number of route table entries allotted to the modem */
|
||||||
|
#define IPA_ROUTE_MODEM_COUNT 8
|
||||||
|
|
||||||
/* The maximum number of route table entries (IPv4, IPv6; hashed or not) */
|
/* The maximum number of route table entries (IPv4, IPv6; hashed or not) */
|
||||||
#define IPA_ROUTE_COUNT_MAX 15
|
#define IPA_ROUTE_COUNT_MAX 15
|
||||||
|
|
||||||
|
@ -495,7 +495,6 @@ static int ipvlan_process_v6_outbound(struct sk_buff *skb)
|
|||||||
|
|
||||||
static int ipvlan_process_outbound(struct sk_buff *skb)
|
static int ipvlan_process_outbound(struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
struct ethhdr *ethh = eth_hdr(skb);
|
|
||||||
int ret = NET_XMIT_DROP;
|
int ret = NET_XMIT_DROP;
|
||||||
|
|
||||||
/* The ipvlan is a pseudo-L2 device, so the packets that we receive
|
/* The ipvlan is a pseudo-L2 device, so the packets that we receive
|
||||||
@ -505,6 +504,8 @@ static int ipvlan_process_outbound(struct sk_buff *skb)
|
|||||||
if (skb_mac_header_was_set(skb)) {
|
if (skb_mac_header_was_set(skb)) {
|
||||||
/* In this mode we dont care about
|
/* In this mode we dont care about
|
||||||
* multicast and broadcast traffic */
|
* multicast and broadcast traffic */
|
||||||
|
struct ethhdr *ethh = eth_hdr(skb);
|
||||||
|
|
||||||
if (is_multicast_ether_addr(ethh->h_dest)) {
|
if (is_multicast_ether_addr(ethh->h_dest)) {
|
||||||
pr_debug_ratelimited(
|
pr_debug_ratelimited(
|
||||||
"Dropped {multi|broad}cast of type=[%x]\n",
|
"Dropped {multi|broad}cast of type=[%x]\n",
|
||||||
@ -589,7 +590,7 @@ out:
|
|||||||
static int ipvlan_xmit_mode_l2(struct sk_buff *skb, struct net_device *dev)
|
static int ipvlan_xmit_mode_l2(struct sk_buff *skb, struct net_device *dev)
|
||||||
{
|
{
|
||||||
const struct ipvl_dev *ipvlan = netdev_priv(dev);
|
const struct ipvl_dev *ipvlan = netdev_priv(dev);
|
||||||
struct ethhdr *eth = eth_hdr(skb);
|
struct ethhdr *eth = skb_eth_hdr(skb);
|
||||||
struct ipvl_addr *addr;
|
struct ipvl_addr *addr;
|
||||||
void *lyr3h;
|
void *lyr3h;
|
||||||
int addr_type;
|
int addr_type;
|
||||||
@ -619,6 +620,7 @@ static int ipvlan_xmit_mode_l2(struct sk_buff *skb, struct net_device *dev)
|
|||||||
return dev_forward_skb(ipvlan->phy_dev, skb);
|
return dev_forward_skb(ipvlan->phy_dev, skb);
|
||||||
|
|
||||||
} else if (is_multicast_ether_addr(eth->h_dest)) {
|
} else if (is_multicast_ether_addr(eth->h_dest)) {
|
||||||
|
skb_reset_mac_header(skb);
|
||||||
ipvlan_skb_crossing_ns(skb, NULL);
|
ipvlan_skb_crossing_ns(skb, NULL);
|
||||||
ipvlan_multicast_enqueue(ipvlan->port, skb, true);
|
ipvlan_multicast_enqueue(ipvlan->port, skb, true);
|
||||||
return NET_XMIT_SUCCESS;
|
return NET_XMIT_SUCCESS;
|
||||||
|
@ -231,6 +231,7 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
unregister:
|
unregister:
|
||||||
|
of_node_put(child);
|
||||||
mdiobus_unregister(mdio);
|
mdiobus_unregister(mdio);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
@ -433,11 +433,11 @@ int nsim_dev_hwstats_init(struct nsim_dev *nsim_dev)
|
|||||||
goto err_remove_hwstats_recursive;
|
goto err_remove_hwstats_recursive;
|
||||||
}
|
}
|
||||||
|
|
||||||
debugfs_create_file("enable_ifindex", 0600, hwstats->l3_ddir, hwstats,
|
debugfs_create_file("enable_ifindex", 0200, hwstats->l3_ddir, hwstats,
|
||||||
&nsim_dev_hwstats_l3_enable_fops.fops);
|
&nsim_dev_hwstats_l3_enable_fops.fops);
|
||||||
debugfs_create_file("disable_ifindex", 0600, hwstats->l3_ddir, hwstats,
|
debugfs_create_file("disable_ifindex", 0200, hwstats->l3_ddir, hwstats,
|
||||||
&nsim_dev_hwstats_l3_disable_fops.fops);
|
&nsim_dev_hwstats_l3_disable_fops.fops);
|
||||||
debugfs_create_file("fail_next_enable", 0600, hwstats->l3_ddir, hwstats,
|
debugfs_create_file("fail_next_enable", 0200, hwstats->l3_ddir, hwstats,
|
||||||
&nsim_dev_hwstats_l3_fail_fops.fops);
|
&nsim_dev_hwstats_l3_fail_fops.fops);
|
||||||
|
|
||||||
INIT_DELAYED_WORK(&hwstats->traffic_dw,
|
INIT_DELAYED_WORK(&hwstats->traffic_dw,
|
||||||
|
@ -91,6 +91,9 @@
|
|||||||
#define VEND1_GLOBAL_FW_ID_MAJOR GENMASK(15, 8)
|
#define VEND1_GLOBAL_FW_ID_MAJOR GENMASK(15, 8)
|
||||||
#define VEND1_GLOBAL_FW_ID_MINOR GENMASK(7, 0)
|
#define VEND1_GLOBAL_FW_ID_MINOR GENMASK(7, 0)
|
||||||
|
|
||||||
|
#define VEND1_GLOBAL_GEN_STAT2 0xc831
|
||||||
|
#define VEND1_GLOBAL_GEN_STAT2_OP_IN_PROG BIT(15)
|
||||||
|
|
||||||
#define VEND1_GLOBAL_RSVD_STAT1 0xc885
|
#define VEND1_GLOBAL_RSVD_STAT1 0xc885
|
||||||
#define VEND1_GLOBAL_RSVD_STAT1_FW_BUILD_ID GENMASK(7, 4)
|
#define VEND1_GLOBAL_RSVD_STAT1_FW_BUILD_ID GENMASK(7, 4)
|
||||||
#define VEND1_GLOBAL_RSVD_STAT1_PROV_ID GENMASK(3, 0)
|
#define VEND1_GLOBAL_RSVD_STAT1_PROV_ID GENMASK(3, 0)
|
||||||
@ -125,6 +128,12 @@
|
|||||||
#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL2 BIT(1)
|
#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL2 BIT(1)
|
||||||
#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL3 BIT(0)
|
#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL3 BIT(0)
|
||||||
|
|
||||||
|
/* Sleep and timeout for checking if the Processor-Intensive
|
||||||
|
* MDIO operation is finished
|
||||||
|
*/
|
||||||
|
#define AQR107_OP_IN_PROG_SLEEP 1000
|
||||||
|
#define AQR107_OP_IN_PROG_TIMEOUT 100000
|
||||||
|
|
||||||
struct aqr107_hw_stat {
|
struct aqr107_hw_stat {
|
||||||
const char *name;
|
const char *name;
|
||||||
int reg;
|
int reg;
|
||||||
@ -597,16 +606,52 @@ static void aqr107_link_change_notify(struct phy_device *phydev)
|
|||||||
phydev_info(phydev, "Aquantia 1000Base-T2 mode active\n");
|
phydev_info(phydev, "Aquantia 1000Base-T2 mode active\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int aqr107_wait_processor_intensive_op(struct phy_device *phydev)
|
||||||
|
{
|
||||||
|
int val, err;
|
||||||
|
|
||||||
|
/* The datasheet notes to wait at least 1ms after issuing a
|
||||||
|
* processor intensive operation before checking.
|
||||||
|
* We cannot use the 'sleep_before_read' parameter of read_poll_timeout
|
||||||
|
* because that just determines the maximum time slept, not the minimum.
|
||||||
|
*/
|
||||||
|
usleep_range(1000, 5000);
|
||||||
|
|
||||||
|
err = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,
|
||||||
|
VEND1_GLOBAL_GEN_STAT2, val,
|
||||||
|
!(val & VEND1_GLOBAL_GEN_STAT2_OP_IN_PROG),
|
||||||
|
AQR107_OP_IN_PROG_SLEEP,
|
||||||
|
AQR107_OP_IN_PROG_TIMEOUT, false);
|
||||||
|
if (err) {
|
||||||
|
phydev_err(phydev, "timeout: processor-intensive MDIO operation\n");
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int aqr107_suspend(struct phy_device *phydev)
|
static int aqr107_suspend(struct phy_device *phydev)
|
||||||
{
|
{
|
||||||
return phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MDIO_CTRL1,
|
int err;
|
||||||
MDIO_CTRL1_LPOWER);
|
|
||||||
|
err = phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MDIO_CTRL1,
|
||||||
|
MDIO_CTRL1_LPOWER);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
return aqr107_wait_processor_intensive_op(phydev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int aqr107_resume(struct phy_device *phydev)
|
static int aqr107_resume(struct phy_device *phydev)
|
||||||
{
|
{
|
||||||
return phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MDIO_CTRL1,
|
int err;
|
||||||
MDIO_CTRL1_LPOWER);
|
|
||||||
|
err = phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MDIO_CTRL1,
|
||||||
|
MDIO_CTRL1_LPOWER);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
return aqr107_wait_processor_intensive_op(phydev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int aqr107_probe(struct phy_device *phydev)
|
static int aqr107_probe(struct phy_device *phydev)
|
||||||
|
@ -2679,16 +2679,19 @@ static int lan8804_config_init(struct phy_device *phydev)
|
|||||||
static irqreturn_t lan8814_handle_interrupt(struct phy_device *phydev)
|
static irqreturn_t lan8814_handle_interrupt(struct phy_device *phydev)
|
||||||
{
|
{
|
||||||
int irq_status, tsu_irq_status;
|
int irq_status, tsu_irq_status;
|
||||||
|
int ret = IRQ_NONE;
|
||||||
|
|
||||||
irq_status = phy_read(phydev, LAN8814_INTS);
|
irq_status = phy_read(phydev, LAN8814_INTS);
|
||||||
if (irq_status > 0 && (irq_status & LAN8814_INT_LINK))
|
|
||||||
phy_trigger_machine(phydev);
|
|
||||||
|
|
||||||
if (irq_status < 0) {
|
if (irq_status < 0) {
|
||||||
phy_error(phydev);
|
phy_error(phydev);
|
||||||
return IRQ_NONE;
|
return IRQ_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (irq_status & LAN8814_INT_LINK) {
|
||||||
|
phy_trigger_machine(phydev);
|
||||||
|
ret = IRQ_HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
tsu_irq_status = lanphy_read_page_reg(phydev, 4,
|
tsu_irq_status = lanphy_read_page_reg(phydev, 4,
|
||||||
LAN8814_INTR_STS_REG);
|
LAN8814_INTR_STS_REG);
|
||||||
@ -2697,12 +2700,15 @@ static irqreturn_t lan8814_handle_interrupt(struct phy_device *phydev)
|
|||||||
(tsu_irq_status & (LAN8814_INTR_STS_REG_1588_TSU0_ |
|
(tsu_irq_status & (LAN8814_INTR_STS_REG_1588_TSU0_ |
|
||||||
LAN8814_INTR_STS_REG_1588_TSU1_ |
|
LAN8814_INTR_STS_REG_1588_TSU1_ |
|
||||||
LAN8814_INTR_STS_REG_1588_TSU2_ |
|
LAN8814_INTR_STS_REG_1588_TSU2_ |
|
||||||
LAN8814_INTR_STS_REG_1588_TSU3_)))
|
LAN8814_INTR_STS_REG_1588_TSU3_))) {
|
||||||
lan8814_handle_ptp_interrupt(phydev);
|
lan8814_handle_ptp_interrupt(phydev);
|
||||||
else
|
ret = IRQ_HANDLED;
|
||||||
|
} else {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return IRQ_HANDLED;
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int lan8814_ack_interrupt(struct phy_device *phydev)
|
static int lan8814_ack_interrupt(struct phy_device *phydev)
|
||||||
|
@ -1275,10 +1275,12 @@ static int team_port_add(struct team *team, struct net_device *port_dev,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
netif_addr_lock_bh(dev);
|
if (dev->flags & IFF_UP) {
|
||||||
dev_uc_sync_multiple(port_dev, dev);
|
netif_addr_lock_bh(dev);
|
||||||
dev_mc_sync_multiple(port_dev, dev);
|
dev_uc_sync_multiple(port_dev, dev);
|
||||||
netif_addr_unlock_bh(dev);
|
dev_mc_sync_multiple(port_dev, dev);
|
||||||
|
netif_addr_unlock_bh(dev);
|
||||||
|
}
|
||||||
|
|
||||||
port->index = -1;
|
port->index = -1;
|
||||||
list_add_tail_rcu(&port->list, &team->port_list);
|
list_add_tail_rcu(&port->list, &team->port_list);
|
||||||
@ -1349,8 +1351,10 @@ static int team_port_del(struct team *team, struct net_device *port_dev)
|
|||||||
netdev_rx_handler_unregister(port_dev);
|
netdev_rx_handler_unregister(port_dev);
|
||||||
team_port_disable_netpoll(port);
|
team_port_disable_netpoll(port);
|
||||||
vlan_vids_del_by_dev(port_dev, dev);
|
vlan_vids_del_by_dev(port_dev, dev);
|
||||||
dev_uc_unsync(port_dev, dev);
|
if (dev->flags & IFF_UP) {
|
||||||
dev_mc_unsync(port_dev, dev);
|
dev_uc_unsync(port_dev, dev);
|
||||||
|
dev_mc_unsync(port_dev, dev);
|
||||||
|
}
|
||||||
dev_close(port_dev);
|
dev_close(port_dev);
|
||||||
team_port_leave(team, port);
|
team_port_leave(team, port);
|
||||||
|
|
||||||
@ -1700,6 +1704,14 @@ static int team_open(struct net_device *dev)
|
|||||||
|
|
||||||
static int team_close(struct net_device *dev)
|
static int team_close(struct net_device *dev)
|
||||||
{
|
{
|
||||||
|
struct team *team = netdev_priv(dev);
|
||||||
|
struct team_port *port;
|
||||||
|
|
||||||
|
list_for_each_entry(port, &team->port_list, list) {
|
||||||
|
dev_uc_unsync(port->dev, dev);
|
||||||
|
dev_mc_unsync(port->dev, dev);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -436,14 +436,13 @@ static int set_peer(struct wg_device *wg, struct nlattr **attrs)
|
|||||||
if (attrs[WGPEER_A_ENDPOINT]) {
|
if (attrs[WGPEER_A_ENDPOINT]) {
|
||||||
struct sockaddr *addr = nla_data(attrs[WGPEER_A_ENDPOINT]);
|
struct sockaddr *addr = nla_data(attrs[WGPEER_A_ENDPOINT]);
|
||||||
size_t len = nla_len(attrs[WGPEER_A_ENDPOINT]);
|
size_t len = nla_len(attrs[WGPEER_A_ENDPOINT]);
|
||||||
|
struct endpoint endpoint = { { { 0 } } };
|
||||||
|
|
||||||
if ((len == sizeof(struct sockaddr_in) &&
|
if (len == sizeof(struct sockaddr_in) && addr->sa_family == AF_INET) {
|
||||||
addr->sa_family == AF_INET) ||
|
endpoint.addr4 = *(struct sockaddr_in *)addr;
|
||||||
(len == sizeof(struct sockaddr_in6) &&
|
wg_socket_set_peer_endpoint(peer, &endpoint);
|
||||||
addr->sa_family == AF_INET6)) {
|
} else if (len == sizeof(struct sockaddr_in6) && addr->sa_family == AF_INET6) {
|
||||||
struct endpoint endpoint = { { { 0 } } };
|
endpoint.addr6 = *(struct sockaddr_in6 *)addr;
|
||||||
|
|
||||||
memcpy(&endpoint.addr, addr, len);
|
|
||||||
wg_socket_set_peer_endpoint(peer, &endpoint);
|
wg_socket_set_peer_endpoint(peer, &endpoint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,29 +6,28 @@
|
|||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
|
||||||
#include <linux/jiffies.h>
|
#include <linux/jiffies.h>
|
||||||
#include <linux/hrtimer.h>
|
|
||||||
|
|
||||||
static const struct {
|
static const struct {
|
||||||
bool result;
|
bool result;
|
||||||
u64 nsec_to_sleep_before;
|
unsigned int msec_to_sleep_before;
|
||||||
} expected_results[] __initconst = {
|
} expected_results[] __initconst = {
|
||||||
[0 ... PACKETS_BURSTABLE - 1] = { true, 0 },
|
[0 ... PACKETS_BURSTABLE - 1] = { true, 0 },
|
||||||
[PACKETS_BURSTABLE] = { false, 0 },
|
[PACKETS_BURSTABLE] = { false, 0 },
|
||||||
[PACKETS_BURSTABLE + 1] = { true, NSEC_PER_SEC / PACKETS_PER_SECOND },
|
[PACKETS_BURSTABLE + 1] = { true, MSEC_PER_SEC / PACKETS_PER_SECOND },
|
||||||
[PACKETS_BURSTABLE + 2] = { false, 0 },
|
[PACKETS_BURSTABLE + 2] = { false, 0 },
|
||||||
[PACKETS_BURSTABLE + 3] = { true, (NSEC_PER_SEC / PACKETS_PER_SECOND) * 2 },
|
[PACKETS_BURSTABLE + 3] = { true, (MSEC_PER_SEC / PACKETS_PER_SECOND) * 2 },
|
||||||
[PACKETS_BURSTABLE + 4] = { true, 0 },
|
[PACKETS_BURSTABLE + 4] = { true, 0 },
|
||||||
[PACKETS_BURSTABLE + 5] = { false, 0 }
|
[PACKETS_BURSTABLE + 5] = { false, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
static __init unsigned int maximum_jiffies_at_index(int index)
|
static __init unsigned int maximum_jiffies_at_index(int index)
|
||||||
{
|
{
|
||||||
u64 total_nsecs = 2 * NSEC_PER_SEC / PACKETS_PER_SECOND / 3;
|
unsigned int total_msecs = 2 * MSEC_PER_SEC / PACKETS_PER_SECOND / 3;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i <= index; ++i)
|
for (i = 0; i <= index; ++i)
|
||||||
total_nsecs += expected_results[i].nsec_to_sleep_before;
|
total_msecs += expected_results[i].msec_to_sleep_before;
|
||||||
return nsecs_to_jiffies(total_nsecs);
|
return msecs_to_jiffies(total_msecs);
|
||||||
}
|
}
|
||||||
|
|
||||||
static __init int timings_test(struct sk_buff *skb4, struct iphdr *hdr4,
|
static __init int timings_test(struct sk_buff *skb4, struct iphdr *hdr4,
|
||||||
@ -43,12 +42,8 @@ static __init int timings_test(struct sk_buff *skb4, struct iphdr *hdr4,
|
|||||||
loop_start_time = jiffies;
|
loop_start_time = jiffies;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(expected_results); ++i) {
|
for (i = 0; i < ARRAY_SIZE(expected_results); ++i) {
|
||||||
if (expected_results[i].nsec_to_sleep_before) {
|
if (expected_results[i].msec_to_sleep_before)
|
||||||
ktime_t timeout = ktime_add(ktime_add_ns(ktime_get_coarse_boottime(), TICK_NSEC * 4 / 3),
|
msleep(expected_results[i].msec_to_sleep_before);
|
||||||
ns_to_ktime(expected_results[i].nsec_to_sleep_before));
|
|
||||||
set_current_state(TASK_UNINTERRUPTIBLE);
|
|
||||||
schedule_hrtimeout_range_clock(&timeout, 0, HRTIMER_MODE_ABS, CLOCK_BOOTTIME);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (time_is_before_jiffies(loop_start_time +
|
if (time_is_before_jiffies(loop_start_time +
|
||||||
maximum_jiffies_at_index(i)))
|
maximum_jiffies_at_index(i)))
|
||||||
@ -132,7 +127,7 @@ bool __init wg_ratelimiter_selftest(void)
|
|||||||
if (IS_ENABLED(CONFIG_KASAN) || IS_ENABLED(CONFIG_UBSAN))
|
if (IS_ENABLED(CONFIG_KASAN) || IS_ENABLED(CONFIG_UBSAN))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
BUILD_BUG_ON(NSEC_PER_SEC % PACKETS_PER_SECOND != 0);
|
BUILD_BUG_ON(MSEC_PER_SEC % PACKETS_PER_SECOND != 0);
|
||||||
|
|
||||||
if (wg_ratelimiter_init())
|
if (wg_ratelimiter_init())
|
||||||
goto out;
|
goto out;
|
||||||
@ -172,7 +167,7 @@ bool __init wg_ratelimiter_selftest(void)
|
|||||||
++test;
|
++test;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (trials = TRIALS_BEFORE_GIVING_UP;;) {
|
for (trials = TRIALS_BEFORE_GIVING_UP; IS_ENABLED(DEBUG_RATELIMITER_TIMINGS);) {
|
||||||
int test_count = 0, ret;
|
int test_count = 0, ret;
|
||||||
|
|
||||||
ret = timings_test(skb4, hdr4, skb6, hdr6, &test_count);
|
ret = timings_test(skb4, hdr4, skb6, hdr6, &test_count);
|
||||||
|
@ -140,6 +140,7 @@ config IWLMEI
|
|||||||
depends on INTEL_MEI
|
depends on INTEL_MEI
|
||||||
depends on PM
|
depends on PM
|
||||||
depends on CFG80211
|
depends on CFG80211
|
||||||
|
depends on BROKEN
|
||||||
help
|
help
|
||||||
Enables the iwlmei kernel module.
|
Enables the iwlmei kernel module.
|
||||||
|
|
||||||
|
@ -1833,8 +1833,8 @@ static void iwl_mvm_parse_ppe(struct iwl_mvm *mvm,
|
|||||||
* If nss < MAX: we can set zeros in other streams
|
* If nss < MAX: we can set zeros in other streams
|
||||||
*/
|
*/
|
||||||
if (nss > MAX_HE_SUPP_NSS) {
|
if (nss > MAX_HE_SUPP_NSS) {
|
||||||
IWL_INFO(mvm, "Got NSS = %d - trimming to %d\n", nss,
|
IWL_DEBUG_INFO(mvm, "Got NSS = %d - trimming to %d\n", nss,
|
||||||
MAX_HE_SUPP_NSS);
|
MAX_HE_SUPP_NSS);
|
||||||
nss = MAX_HE_SUPP_NSS;
|
nss = MAX_HE_SUPP_NSS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -267,7 +267,8 @@ static void mt76_init_stream_cap(struct mt76_phy *phy,
|
|||||||
}
|
}
|
||||||
vht_cap->vht_mcs.rx_mcs_map = cpu_to_le16(mcs_map);
|
vht_cap->vht_mcs.rx_mcs_map = cpu_to_le16(mcs_map);
|
||||||
vht_cap->vht_mcs.tx_mcs_map = cpu_to_le16(mcs_map);
|
vht_cap->vht_mcs.tx_mcs_map = cpu_to_le16(mcs_map);
|
||||||
vht_cap->vht_mcs.tx_highest |=
|
if (ieee80211_hw_check(phy->hw, SUPPORTS_VHT_EXT_NSS_BW))
|
||||||
|
vht_cap->vht_mcs.tx_highest |=
|
||||||
cpu_to_le16(IEEE80211_VHT_EXT_NSS_BW_CAPABLE);
|
cpu_to_le16(IEEE80211_VHT_EXT_NSS_BW_CAPABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1088,7 +1088,7 @@ u32 mt7615_mac_get_sta_tid_sn(struct mt7615_dev *dev, int wcid, u8 tid)
|
|||||||
offset %= 32;
|
offset %= 32;
|
||||||
|
|
||||||
val = mt76_rr(dev, addr);
|
val = mt76_rr(dev, addr);
|
||||||
val >>= (tid % 32);
|
val >>= offset;
|
||||||
|
|
||||||
if (offset > 20) {
|
if (offset > 20) {
|
||||||
addr += 4;
|
addr += 4;
|
||||||
|
@ -124,8 +124,6 @@ struct hci_dev_info {
|
|||||||
__u16 acl_pkts;
|
__u16 acl_pkts;
|
||||||
__u16 sco_mtu;
|
__u16 sco_mtu;
|
||||||
__u16 sco_pkts;
|
__u16 sco_pkts;
|
||||||
__u16 iso_mtu;
|
|
||||||
__u16 iso_pkts;
|
|
||||||
|
|
||||||
struct hci_dev_stats stat;
|
struct hci_dev_stats stat;
|
||||||
};
|
};
|
||||||
|
@ -15,8 +15,6 @@
|
|||||||
#define PKT_TYPE_LACPDU cpu_to_be16(ETH_P_SLOW)
|
#define PKT_TYPE_LACPDU cpu_to_be16(ETH_P_SLOW)
|
||||||
#define AD_TIMER_INTERVAL 100 /*msec*/
|
#define AD_TIMER_INTERVAL 100 /*msec*/
|
||||||
|
|
||||||
#define MULTICAST_LACPDU_ADDR {0x01, 0x80, 0xC2, 0x00, 0x00, 0x02}
|
|
||||||
|
|
||||||
#define AD_LACP_SLOW 0
|
#define AD_LACP_SLOW 0
|
||||||
#define AD_LACP_FAST 1
|
#define AD_LACP_FAST 1
|
||||||
|
|
||||||
|
@ -786,6 +786,9 @@ extern struct rtnl_link_ops bond_link_ops;
|
|||||||
/* exported from bond_sysfs_slave.c */
|
/* exported from bond_sysfs_slave.c */
|
||||||
extern const struct sysfs_ops slave_sysfs_ops;
|
extern const struct sysfs_ops slave_sysfs_ops;
|
||||||
|
|
||||||
|
/* exported from bond_3ad.c */
|
||||||
|
extern const u8 lacpdu_mcast_addr[];
|
||||||
|
|
||||||
static inline netdev_tx_t bond_tx_drop(struct net_device *dev, struct sk_buff *skb)
|
static inline netdev_tx_t bond_tx_drop(struct net_device *dev, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
dev_core_stats_tx_dropped_inc(dev);
|
dev_core_stats_tx_dropped_inc(dev);
|
||||||
|
@ -15,6 +15,22 @@
|
|||||||
#ifndef IEEE802154_NETDEVICE_H
|
#ifndef IEEE802154_NETDEVICE_H
|
||||||
#define IEEE802154_NETDEVICE_H
|
#define IEEE802154_NETDEVICE_H
|
||||||
|
|
||||||
|
#define IEEE802154_REQUIRED_SIZE(struct_type, member) \
|
||||||
|
(offsetof(typeof(struct_type), member) + \
|
||||||
|
sizeof(((typeof(struct_type) *)(NULL))->member))
|
||||||
|
|
||||||
|
#define IEEE802154_ADDR_OFFSET \
|
||||||
|
offsetof(typeof(struct sockaddr_ieee802154), addr)
|
||||||
|
|
||||||
|
#define IEEE802154_MIN_NAMELEN (IEEE802154_ADDR_OFFSET + \
|
||||||
|
IEEE802154_REQUIRED_SIZE(struct ieee802154_addr_sa, addr_type))
|
||||||
|
|
||||||
|
#define IEEE802154_NAMELEN_SHORT (IEEE802154_ADDR_OFFSET + \
|
||||||
|
IEEE802154_REQUIRED_SIZE(struct ieee802154_addr_sa, short_addr))
|
||||||
|
|
||||||
|
#define IEEE802154_NAMELEN_LONG (IEEE802154_ADDR_OFFSET + \
|
||||||
|
IEEE802154_REQUIRED_SIZE(struct ieee802154_addr_sa, hwaddr))
|
||||||
|
|
||||||
#include <net/af_ieee802154.h>
|
#include <net/af_ieee802154.h>
|
||||||
#include <linux/netdevice.h>
|
#include <linux/netdevice.h>
|
||||||
#include <linux/skbuff.h>
|
#include <linux/skbuff.h>
|
||||||
@ -165,6 +181,27 @@ static inline void ieee802154_devaddr_to_raw(void *raw, __le64 addr)
|
|||||||
memcpy(raw, &temp, IEEE802154_ADDR_LEN);
|
memcpy(raw, &temp, IEEE802154_ADDR_LEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
ieee802154_sockaddr_check_size(struct sockaddr_ieee802154 *daddr, int len)
|
||||||
|
{
|
||||||
|
struct ieee802154_addr_sa *sa;
|
||||||
|
|
||||||
|
sa = &daddr->addr;
|
||||||
|
if (len < IEEE802154_MIN_NAMELEN)
|
||||||
|
return -EINVAL;
|
||||||
|
switch (sa->addr_type) {
|
||||||
|
case IEEE802154_ADDR_SHORT:
|
||||||
|
if (len < IEEE802154_NAMELEN_SHORT)
|
||||||
|
return -EINVAL;
|
||||||
|
break;
|
||||||
|
case IEEE802154_ADDR_LONG:
|
||||||
|
if (len < IEEE802154_NAMELEN_LONG)
|
||||||
|
return -EINVAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static inline void ieee802154_addr_from_sa(struct ieee802154_addr *a,
|
static inline void ieee802154_addr_from_sa(struct ieee802154_addr *a,
|
||||||
const struct ieee802154_addr_sa *sa)
|
const struct ieee802154_addr_sa *sa)
|
||||||
{
|
{
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include <linux/atomic.h>
|
#include <linux/atomic.h>
|
||||||
#include <linux/byteorder/generic.h>
|
#include <linux/byteorder/generic.h>
|
||||||
#include <linux/container_of.h>
|
#include <linux/container_of.h>
|
||||||
|
#include <linux/errno.h>
|
||||||
#include <linux/gfp.h>
|
#include <linux/gfp.h>
|
||||||
#include <linux/if.h>
|
#include <linux/if.h>
|
||||||
#include <linux/if_arp.h>
|
#include <linux/if_arp.h>
|
||||||
@ -700,6 +701,9 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
|
|||||||
int max_header_len = batadv_max_header_len();
|
int max_header_len = batadv_max_header_len();
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
if (hard_iface->net_dev->mtu < ETH_MIN_MTU + max_header_len)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
if (hard_iface->if_status != BATADV_IF_NOT_IN_USE)
|
if (hard_iface->if_status != BATADV_IF_NOT_IN_USE)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
@ -1040,8 +1040,10 @@ static int do_replace_finish(struct net *net, struct ebt_replace *repl,
|
|||||||
goto free_iterate;
|
goto free_iterate;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (repl->valid_hooks != t->valid_hooks)
|
if (repl->valid_hooks != t->valid_hooks) {
|
||||||
|
ret = -EINVAL;
|
||||||
goto free_unlock;
|
goto free_unlock;
|
||||||
|
}
|
||||||
|
|
||||||
if (repl->num_counters && repl->num_counters != t->private->nentries) {
|
if (repl->num_counters && repl->num_counters != t->private->nentries) {
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
|
@ -52,6 +52,7 @@ int __get_compat_msghdr(struct msghdr *kmsg,
|
|||||||
kmsg->msg_namelen = sizeof(struct sockaddr_storage);
|
kmsg->msg_namelen = sizeof(struct sockaddr_storage);
|
||||||
|
|
||||||
kmsg->msg_control_is_user = true;
|
kmsg->msg_control_is_user = true;
|
||||||
|
kmsg->msg_get_inq = 0;
|
||||||
kmsg->msg_control_user = compat_ptr(msg->msg_control);
|
kmsg->msg_control_user = compat_ptr(msg->msg_control);
|
||||||
kmsg->msg_controllen = msg->msg_controllen;
|
kmsg->msg_controllen = msg->msg_controllen;
|
||||||
|
|
||||||
|
@ -1611,9 +1611,8 @@ static inline void __flow_hash_consistentify(struct flow_keys *keys)
|
|||||||
|
|
||||||
switch (keys->control.addr_type) {
|
switch (keys->control.addr_type) {
|
||||||
case FLOW_DISSECTOR_KEY_IPV4_ADDRS:
|
case FLOW_DISSECTOR_KEY_IPV4_ADDRS:
|
||||||
addr_diff = (__force u32)keys->addrs.v4addrs.dst -
|
if ((__force u32)keys->addrs.v4addrs.dst <
|
||||||
(__force u32)keys->addrs.v4addrs.src;
|
(__force u32)keys->addrs.v4addrs.src)
|
||||||
if (addr_diff < 0)
|
|
||||||
swap(keys->addrs.v4addrs.src, keys->addrs.v4addrs.dst);
|
swap(keys->addrs.v4addrs.src, keys->addrs.v4addrs.dst);
|
||||||
|
|
||||||
if ((__force u16)keys->ports.dst <
|
if ((__force u16)keys->ports.dst <
|
||||||
|
@ -200,8 +200,9 @@ static int raw_bind(struct sock *sk, struct sockaddr *_uaddr, int len)
|
|||||||
int err = 0;
|
int err = 0;
|
||||||
struct net_device *dev = NULL;
|
struct net_device *dev = NULL;
|
||||||
|
|
||||||
if (len < sizeof(*uaddr))
|
err = ieee802154_sockaddr_check_size(uaddr, len);
|
||||||
return -EINVAL;
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
uaddr = (struct sockaddr_ieee802154 *)_uaddr;
|
uaddr = (struct sockaddr_ieee802154 *)_uaddr;
|
||||||
if (uaddr->family != AF_IEEE802154)
|
if (uaddr->family != AF_IEEE802154)
|
||||||
@ -493,7 +494,8 @@ static int dgram_bind(struct sock *sk, struct sockaddr *uaddr, int len)
|
|||||||
|
|
||||||
ro->bound = 0;
|
ro->bound = 0;
|
||||||
|
|
||||||
if (len < sizeof(*addr))
|
err = ieee802154_sockaddr_check_size(addr, len);
|
||||||
|
if (err < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (addr->family != AF_IEEE802154)
|
if (addr->family != AF_IEEE802154)
|
||||||
@ -564,8 +566,9 @@ static int dgram_connect(struct sock *sk, struct sockaddr *uaddr,
|
|||||||
struct dgram_sock *ro = dgram_sk(sk);
|
struct dgram_sock *ro = dgram_sk(sk);
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
if (len < sizeof(*addr))
|
err = ieee802154_sockaddr_check_size(addr, len);
|
||||||
return -EINVAL;
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
if (addr->family != AF_IEEE802154)
|
if (addr->family != AF_IEEE802154)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@ -604,6 +607,7 @@ static int dgram_sendmsg(struct sock *sk, struct msghdr *msg, size_t size)
|
|||||||
struct ieee802154_mac_cb *cb;
|
struct ieee802154_mac_cb *cb;
|
||||||
struct dgram_sock *ro = dgram_sk(sk);
|
struct dgram_sock *ro = dgram_sk(sk);
|
||||||
struct ieee802154_addr dst_addr;
|
struct ieee802154_addr dst_addr;
|
||||||
|
DECLARE_SOCKADDR(struct sockaddr_ieee802154*, daddr, msg->msg_name);
|
||||||
int hlen, tlen;
|
int hlen, tlen;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
@ -612,10 +616,20 @@ static int dgram_sendmsg(struct sock *sk, struct msghdr *msg, size_t size)
|
|||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ro->connected && !msg->msg_name)
|
if (msg->msg_name) {
|
||||||
return -EDESTADDRREQ;
|
if (ro->connected)
|
||||||
else if (ro->connected && msg->msg_name)
|
return -EISCONN;
|
||||||
return -EISCONN;
|
if (msg->msg_namelen < IEEE802154_MIN_NAMELEN)
|
||||||
|
return -EINVAL;
|
||||||
|
err = ieee802154_sockaddr_check_size(daddr, msg->msg_namelen);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
ieee802154_addr_from_sa(&dst_addr, &daddr->addr);
|
||||||
|
} else {
|
||||||
|
if (!ro->connected)
|
||||||
|
return -EDESTADDRREQ;
|
||||||
|
dst_addr = ro->dst_addr;
|
||||||
|
}
|
||||||
|
|
||||||
if (!ro->bound)
|
if (!ro->bound)
|
||||||
dev = dev_getfirstbyhwtype(sock_net(sk), ARPHRD_IEEE802154);
|
dev = dev_getfirstbyhwtype(sock_net(sk), ARPHRD_IEEE802154);
|
||||||
@ -651,16 +665,6 @@ static int dgram_sendmsg(struct sock *sk, struct msghdr *msg, size_t size)
|
|||||||
cb = mac_cb_init(skb);
|
cb = mac_cb_init(skb);
|
||||||
cb->type = IEEE802154_FC_TYPE_DATA;
|
cb->type = IEEE802154_FC_TYPE_DATA;
|
||||||
cb->ackreq = ro->want_ack;
|
cb->ackreq = ro->want_ack;
|
||||||
|
|
||||||
if (msg->msg_name) {
|
|
||||||
DECLARE_SOCKADDR(struct sockaddr_ieee802154*,
|
|
||||||
daddr, msg->msg_name);
|
|
||||||
|
|
||||||
ieee802154_addr_from_sa(&dst_addr, &daddr->addr);
|
|
||||||
} else {
|
|
||||||
dst_addr = ro->dst_addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
cb->secen = ro->secen;
|
cb->secen = ro->secen;
|
||||||
cb->secen_override = ro->secen_override;
|
cb->secen_override = ro->secen_override;
|
||||||
cb->seclevel = ro->seclevel;
|
cb->seclevel = ro->seclevel;
|
||||||
|
@ -1004,7 +1004,9 @@ static void ipmr_cache_resolve(struct net *net, struct mr_table *mrt,
|
|||||||
|
|
||||||
rtnl_unicast(skb, net, NETLINK_CB(skb).portid);
|
rtnl_unicast(skb, net, NETLINK_CB(skb).portid);
|
||||||
} else {
|
} else {
|
||||||
|
rcu_read_lock();
|
||||||
ip_mr_forward(net, mrt, skb->dev, skb, c, 0);
|
ip_mr_forward(net, mrt, skb->dev, skb, c, 0);
|
||||||
|
rcu_read_unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1761,19 +1761,28 @@ int tcp_read_skb(struct sock *sk, skb_read_actor_t recv_actor)
|
|||||||
if (sk->sk_state == TCP_LISTEN)
|
if (sk->sk_state == TCP_LISTEN)
|
||||||
return -ENOTCONN;
|
return -ENOTCONN;
|
||||||
|
|
||||||
skb = tcp_recv_skb(sk, seq, &offset);
|
while ((skb = tcp_recv_skb(sk, seq, &offset)) != NULL) {
|
||||||
if (!skb)
|
u8 tcp_flags;
|
||||||
return 0;
|
int used;
|
||||||
|
|
||||||
__skb_unlink(skb, &sk->sk_receive_queue);
|
__skb_unlink(skb, &sk->sk_receive_queue);
|
||||||
WARN_ON(!skb_set_owner_sk_safe(skb, sk));
|
WARN_ON_ONCE(!skb_set_owner_sk_safe(skb, sk));
|
||||||
copied = recv_actor(sk, skb);
|
tcp_flags = TCP_SKB_CB(skb)->tcp_flags;
|
||||||
if (copied >= 0) {
|
used = recv_actor(sk, skb);
|
||||||
seq += copied;
|
consume_skb(skb);
|
||||||
if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN)
|
if (used < 0) {
|
||||||
|
if (!copied)
|
||||||
|
copied = used;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
seq += used;
|
||||||
|
copied += used;
|
||||||
|
|
||||||
|
if (tcp_flags & TCPHDR_FIN) {
|
||||||
++seq;
|
++seq;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
consume_skb(skb);
|
|
||||||
WRITE_ONCE(tp->copied_seq, seq);
|
WRITE_ONCE(tp->copied_seq, seq);
|
||||||
|
|
||||||
tcp_rcv_space_adjust(sk);
|
tcp_rcv_space_adjust(sk);
|
||||||
|
@ -1821,7 +1821,7 @@ int udp_read_skb(struct sock *sk, skb_read_actor_t recv_actor)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
WARN_ON(!skb_set_owner_sk_safe(skb, sk));
|
WARN_ON_ONCE(!skb_set_owner_sk_safe(skb, sk));
|
||||||
used = recv_actor(sk, skb);
|
used = recv_actor(sk, skb);
|
||||||
if (used <= 0) {
|
if (used <= 0) {
|
||||||
if (!copied)
|
if (!copied)
|
||||||
|
@ -1070,13 +1070,13 @@ static int __init inet6_init(void)
|
|||||||
for (r = &inetsw6[0]; r < &inetsw6[SOCK_MAX]; ++r)
|
for (r = &inetsw6[0]; r < &inetsw6[SOCK_MAX]; ++r)
|
||||||
INIT_LIST_HEAD(r);
|
INIT_LIST_HEAD(r);
|
||||||
|
|
||||||
|
raw_hashinfo_init(&raw_v6_hashinfo);
|
||||||
|
|
||||||
if (disable_ipv6_mod) {
|
if (disable_ipv6_mod) {
|
||||||
pr_info("Loaded, but administratively disabled, reboot required to enable\n");
|
pr_info("Loaded, but administratively disabled, reboot required to enable\n");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
raw_hashinfo_init(&raw_v6_hashinfo);
|
|
||||||
|
|
||||||
err = proto_register(&tcpv6_prot, 1);
|
err = proto_register(&tcpv6_prot, 1);
|
||||||
if (err)
|
if (err)
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -1028,8 +1028,11 @@ static void ip6mr_cache_resolve(struct net *net, struct mr_table *mrt,
|
|||||||
((struct nlmsgerr *)nlmsg_data(nlh))->error = -EMSGSIZE;
|
((struct nlmsgerr *)nlmsg_data(nlh))->error = -EMSGSIZE;
|
||||||
}
|
}
|
||||||
rtnl_unicast(skb, net, NETLINK_CB(skb).portid);
|
rtnl_unicast(skb, net, NETLINK_CB(skb).portid);
|
||||||
} else
|
} else {
|
||||||
|
rcu_read_lock();
|
||||||
ip6_mr_forward(net, mrt, skb->dev, skb, c);
|
ip6_mr_forward(net, mrt, skb->dev, skb, c);
|
||||||
|
rcu_read_unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,9 +150,15 @@ static bool mptcp_try_coalesce(struct sock *sk, struct sk_buff *to,
|
|||||||
MPTCP_SKB_CB(from)->map_seq, MPTCP_SKB_CB(to)->map_seq,
|
MPTCP_SKB_CB(from)->map_seq, MPTCP_SKB_CB(to)->map_seq,
|
||||||
to->len, MPTCP_SKB_CB(from)->end_seq);
|
to->len, MPTCP_SKB_CB(from)->end_seq);
|
||||||
MPTCP_SKB_CB(to)->end_seq = MPTCP_SKB_CB(from)->end_seq;
|
MPTCP_SKB_CB(to)->end_seq = MPTCP_SKB_CB(from)->end_seq;
|
||||||
kfree_skb_partial(from, fragstolen);
|
|
||||||
|
/* note the fwd memory can reach a negative value after accounting
|
||||||
|
* for the delta, but the later skb free will restore a non
|
||||||
|
* negative one
|
||||||
|
*/
|
||||||
atomic_add(delta, &sk->sk_rmem_alloc);
|
atomic_add(delta, &sk->sk_rmem_alloc);
|
||||||
mptcp_rmem_charge(sk, delta);
|
mptcp_rmem_charge(sk, delta);
|
||||||
|
kfree_skb_partial(from, fragstolen);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@ MODULE_AUTHOR("Rusty Russell <rusty@rustcorp.com.au>");
|
|||||||
MODULE_DESCRIPTION("ftp connection tracking helper");
|
MODULE_DESCRIPTION("ftp connection tracking helper");
|
||||||
MODULE_ALIAS("ip_conntrack_ftp");
|
MODULE_ALIAS("ip_conntrack_ftp");
|
||||||
MODULE_ALIAS_NFCT_HELPER(HELPER_NAME);
|
MODULE_ALIAS_NFCT_HELPER(HELPER_NAME);
|
||||||
|
static DEFINE_SPINLOCK(nf_ftp_lock);
|
||||||
|
|
||||||
#define MAX_PORTS 8
|
#define MAX_PORTS 8
|
||||||
static u_int16_t ports[MAX_PORTS];
|
static u_int16_t ports[MAX_PORTS];
|
||||||
@ -409,7 +410,8 @@ static int help(struct sk_buff *skb,
|
|||||||
}
|
}
|
||||||
datalen = skb->len - dataoff;
|
datalen = skb->len - dataoff;
|
||||||
|
|
||||||
spin_lock_bh(&ct->lock);
|
/* seqadj (nat) uses ct->lock internally, nf_nat_ftp would cause deadlock */
|
||||||
|
spin_lock_bh(&nf_ftp_lock);
|
||||||
fb_ptr = skb->data + dataoff;
|
fb_ptr = skb->data + dataoff;
|
||||||
|
|
||||||
ends_in_nl = (fb_ptr[datalen - 1] == '\n');
|
ends_in_nl = (fb_ptr[datalen - 1] == '\n');
|
||||||
@ -538,7 +540,7 @@ out_update_nl:
|
|||||||
if (ends_in_nl)
|
if (ends_in_nl)
|
||||||
update_nl_seq(ct, seq, ct_ftp_info, dir, skb);
|
update_nl_seq(ct, seq, ct_ftp_info, dir, skb);
|
||||||
out:
|
out:
|
||||||
spin_unlock_bh(&ct->lock);
|
spin_unlock_bh(&nf_ftp_lock);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,15 +157,37 @@ static int help(struct sk_buff *skb, unsigned int protoff,
|
|||||||
data = ib_ptr;
|
data = ib_ptr;
|
||||||
data_limit = ib_ptr + datalen;
|
data_limit = ib_ptr + datalen;
|
||||||
|
|
||||||
/* strlen("\1DCC SENT t AAAAAAAA P\1\n")=24
|
/* Skip any whitespace */
|
||||||
* 5+MINMATCHLEN+strlen("t AAAAAAAA P\1\n")=14 */
|
while (data < data_limit - 10) {
|
||||||
while (data < data_limit - (19 + MINMATCHLEN)) {
|
if (*data == ' ' || *data == '\r' || *data == '\n')
|
||||||
if (memcmp(data, "\1DCC ", 5)) {
|
data++;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* strlen("PRIVMSG x ")=10 */
|
||||||
|
if (data < data_limit - 10) {
|
||||||
|
if (strncasecmp("PRIVMSG ", data, 8))
|
||||||
|
goto out;
|
||||||
|
data += 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* strlen(" :\1DCC SENT t AAAAAAAA P\1\n")=26
|
||||||
|
* 7+MINMATCHLEN+strlen("t AAAAAAAA P\1\n")=26
|
||||||
|
*/
|
||||||
|
while (data < data_limit - (21 + MINMATCHLEN)) {
|
||||||
|
/* Find first " :", the start of message */
|
||||||
|
if (memcmp(data, " :", 2)) {
|
||||||
data++;
|
data++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
data += 2;
|
||||||
|
|
||||||
|
/* then check that place only for the DCC command */
|
||||||
|
if (memcmp(data, "\1DCC ", 5))
|
||||||
|
goto out;
|
||||||
data += 5;
|
data += 5;
|
||||||
/* we have at least (19+MINMATCHLEN)-5 bytes valid data left */
|
/* we have at least (21+MINMATCHLEN)-(2+5) bytes valid data left */
|
||||||
|
|
||||||
iph = ip_hdr(skb);
|
iph = ip_hdr(skb);
|
||||||
pr_debug("DCC found in master %pI4:%u %pI4:%u\n",
|
pr_debug("DCC found in master %pI4:%u %pI4:%u\n",
|
||||||
@ -181,7 +203,7 @@ static int help(struct sk_buff *skb, unsigned int protoff,
|
|||||||
pr_debug("DCC %s detected\n", dccprotos[i]);
|
pr_debug("DCC %s detected\n", dccprotos[i]);
|
||||||
|
|
||||||
/* we have at least
|
/* we have at least
|
||||||
* (19+MINMATCHLEN)-5-dccprotos[i].matchlen bytes valid
|
* (21+MINMATCHLEN)-7-dccprotos[i].matchlen bytes valid
|
||||||
* data left (== 14/13 bytes) */
|
* data left (== 14/13 bytes) */
|
||||||
if (parse_dcc(data, data_limit, &dcc_ip,
|
if (parse_dcc(data, data_limit, &dcc_ip,
|
||||||
&dcc_port, &addr_beg_p, &addr_end_p)) {
|
&dcc_port, &addr_beg_p, &addr_end_p)) {
|
||||||
|
@ -477,7 +477,7 @@ static int ct_sip_walk_headers(const struct nf_conn *ct, const char *dptr,
|
|||||||
return ret;
|
return ret;
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
break;
|
break;
|
||||||
dataoff += *matchoff;
|
dataoff = *matchoff;
|
||||||
}
|
}
|
||||||
*in_header = 0;
|
*in_header = 0;
|
||||||
}
|
}
|
||||||
@ -489,7 +489,7 @@ static int ct_sip_walk_headers(const struct nf_conn *ct, const char *dptr,
|
|||||||
break;
|
break;
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
return ret;
|
return ret;
|
||||||
dataoff += *matchoff;
|
dataoff = *matchoff;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (in_header)
|
if (in_header)
|
||||||
|
@ -2197,7 +2197,6 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask,
|
|||||||
struct netlink_ext_ack *extack)
|
struct netlink_ext_ack *extack)
|
||||||
{
|
{
|
||||||
const struct nlattr * const *nla = ctx->nla;
|
const struct nlattr * const *nla = ctx->nla;
|
||||||
struct nft_stats __percpu *stats = NULL;
|
|
||||||
struct nft_table *table = ctx->table;
|
struct nft_table *table = ctx->table;
|
||||||
struct nft_base_chain *basechain;
|
struct nft_base_chain *basechain;
|
||||||
struct net *net = ctx->net;
|
struct net *net = ctx->net;
|
||||||
@ -2212,6 +2211,7 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask,
|
|||||||
return -EOVERFLOW;
|
return -EOVERFLOW;
|
||||||
|
|
||||||
if (nla[NFTA_CHAIN_HOOK]) {
|
if (nla[NFTA_CHAIN_HOOK]) {
|
||||||
|
struct nft_stats __percpu *stats = NULL;
|
||||||
struct nft_chain_hook hook;
|
struct nft_chain_hook hook;
|
||||||
|
|
||||||
if (flags & NFT_CHAIN_BINDING)
|
if (flags & NFT_CHAIN_BINDING)
|
||||||
@ -2243,8 +2243,11 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask,
|
|||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
nft_chain_release_hook(&hook);
|
nft_chain_release_hook(&hook);
|
||||||
kfree(basechain);
|
kfree(basechain);
|
||||||
|
free_percpu(stats);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
if (stats)
|
||||||
|
static_branch_inc(&nft_counters_enabled);
|
||||||
} else {
|
} else {
|
||||||
if (flags & NFT_CHAIN_BASE)
|
if (flags & NFT_CHAIN_BASE)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@ -2319,9 +2322,6 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask,
|
|||||||
goto err_unregister_hook;
|
goto err_unregister_hook;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stats)
|
|
||||||
static_branch_inc(&nft_counters_enabled);
|
|
||||||
|
|
||||||
table->use++;
|
table->use++;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -269,6 +269,7 @@ bool nf_osf_find(const struct sk_buff *skb,
|
|||||||
struct nf_osf_hdr_ctx ctx;
|
struct nf_osf_hdr_ctx ctx;
|
||||||
const struct tcphdr *tcp;
|
const struct tcphdr *tcp;
|
||||||
struct tcphdr _tcph;
|
struct tcphdr _tcph;
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
memset(&ctx, 0, sizeof(ctx));
|
memset(&ctx, 0, sizeof(ctx));
|
||||||
|
|
||||||
@ -283,10 +284,11 @@ bool nf_osf_find(const struct sk_buff *skb,
|
|||||||
|
|
||||||
data->genre = f->genre;
|
data->genre = f->genre;
|
||||||
data->version = f->version;
|
data->version = f->version;
|
||||||
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return found;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(nf_osf_find);
|
EXPORT_SYMBOL_GPL(nf_osf_find);
|
||||||
|
|
||||||
|
@ -2137,6 +2137,7 @@ replay:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (chain->tmplt_ops && chain->tmplt_ops != tp->ops) {
|
if (chain->tmplt_ops && chain->tmplt_ops != tp->ops) {
|
||||||
|
tfilter_put(tp, fh);
|
||||||
NL_SET_ERR_MSG(extack, "Chain template is set to a different filter kind");
|
NL_SET_ERR_MSG(extack, "Chain template is set to a different filter kind");
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
goto errout;
|
goto errout;
|
||||||
|
@ -67,6 +67,7 @@ struct taprio_sched {
|
|||||||
u32 flags;
|
u32 flags;
|
||||||
enum tk_offsets tk_offset;
|
enum tk_offsets tk_offset;
|
||||||
int clockid;
|
int clockid;
|
||||||
|
bool offloaded;
|
||||||
atomic64_t picos_per_byte; /* Using picoseconds because for 10Gbps+
|
atomic64_t picos_per_byte; /* Using picoseconds because for 10Gbps+
|
||||||
* speeds it's sub-nanoseconds per byte
|
* speeds it's sub-nanoseconds per byte
|
||||||
*/
|
*/
|
||||||
@ -1279,6 +1280,8 @@ static int taprio_enable_offload(struct net_device *dev,
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
q->offloaded = true;
|
||||||
|
|
||||||
done:
|
done:
|
||||||
taprio_offload_free(offload);
|
taprio_offload_free(offload);
|
||||||
|
|
||||||
@ -1293,12 +1296,9 @@ static int taprio_disable_offload(struct net_device *dev,
|
|||||||
struct tc_taprio_qopt_offload *offload;
|
struct tc_taprio_qopt_offload *offload;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (!FULL_OFFLOAD_IS_ENABLED(q->flags))
|
if (!q->offloaded)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!ops->ndo_setup_tc)
|
|
||||||
return -EOPNOTSUPP;
|
|
||||||
|
|
||||||
offload = taprio_offload_alloc(0);
|
offload = taprio_offload_alloc(0);
|
||||||
if (!offload) {
|
if (!offload) {
|
||||||
NL_SET_ERR_MSG(extack,
|
NL_SET_ERR_MSG(extack,
|
||||||
@ -1314,6 +1314,8 @@ static int taprio_disable_offload(struct net_device *dev,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
q->offloaded = false;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
taprio_offload_free(offload);
|
taprio_offload_free(offload);
|
||||||
|
|
||||||
@ -1949,12 +1951,14 @@ start_error:
|
|||||||
|
|
||||||
static struct Qdisc *taprio_leaf(struct Qdisc *sch, unsigned long cl)
|
static struct Qdisc *taprio_leaf(struct Qdisc *sch, unsigned long cl)
|
||||||
{
|
{
|
||||||
struct netdev_queue *dev_queue = taprio_queue_get(sch, cl);
|
struct taprio_sched *q = qdisc_priv(sch);
|
||||||
|
struct net_device *dev = qdisc_dev(sch);
|
||||||
|
unsigned int ntx = cl - 1;
|
||||||
|
|
||||||
if (!dev_queue)
|
if (ntx >= dev->num_tx_queues)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return dev_queue->qdisc_sleeping;
|
return q->qdiscs[ntx];
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned long taprio_find(struct Qdisc *sch, u32 classid)
|
static unsigned long taprio_find(struct Qdisc *sch, u32 classid)
|
||||||
|
@ -2239,7 +2239,7 @@ out:
|
|||||||
static int smcr_buf_map_usable_links(struct smc_link_group *lgr,
|
static int smcr_buf_map_usable_links(struct smc_link_group *lgr,
|
||||||
struct smc_buf_desc *buf_desc, bool is_rmb)
|
struct smc_buf_desc *buf_desc, bool is_rmb)
|
||||||
{
|
{
|
||||||
int i, rc = 0;
|
int i, rc = 0, cnt = 0;
|
||||||
|
|
||||||
/* protect against parallel link reconfiguration */
|
/* protect against parallel link reconfiguration */
|
||||||
mutex_lock(&lgr->llc_conf_mutex);
|
mutex_lock(&lgr->llc_conf_mutex);
|
||||||
@ -2252,9 +2252,12 @@ static int smcr_buf_map_usable_links(struct smc_link_group *lgr,
|
|||||||
rc = -ENOMEM;
|
rc = -ENOMEM;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
cnt++;
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
mutex_unlock(&lgr->llc_conf_mutex);
|
mutex_unlock(&lgr->llc_conf_mutex);
|
||||||
|
if (!rc && !cnt)
|
||||||
|
rc = -EINVAL;
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ TARGETS += damon
|
|||||||
TARGETS += drivers/dma-buf
|
TARGETS += drivers/dma-buf
|
||||||
TARGETS += drivers/s390x/uvdevice
|
TARGETS += drivers/s390x/uvdevice
|
||||||
TARGETS += drivers/net/bonding
|
TARGETS += drivers/net/bonding
|
||||||
|
TARGETS += drivers/net/team
|
||||||
TARGETS += efivarfs
|
TARGETS += efivarfs
|
||||||
TARGETS += exec
|
TARGETS += exec
|
||||||
TARGETS += filesystems
|
TARGETS += filesystems
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
# SPDX-License-Identifier: GPL-2.0
|
# SPDX-License-Identifier: GPL-2.0
|
||||||
# Makefile for net selftests
|
# Makefile for net selftests
|
||||||
|
|
||||||
TEST_PROGS := bond-break-lacpdu-tx.sh
|
TEST_PROGS := bond-break-lacpdu-tx.sh \
|
||||||
|
dev_addr_lists.sh \
|
||||||
|
bond-arp-interval-causes-panic.sh
|
||||||
|
|
||||||
|
TEST_FILES := lag_lib.sh
|
||||||
|
|
||||||
include ../../../lib.mk
|
include ../../../lib.mk
|
||||||
|
@ -0,0 +1,49 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# SPDX-License-Identifier: GPL-2.0
|
||||||
|
#
|
||||||
|
# cause kernel oops in bond_rr_gen_slave_id
|
||||||
|
DEBUG=${DEBUG:-0}
|
||||||
|
|
||||||
|
set -e
|
||||||
|
test ${DEBUG} -ne 0 && set -x
|
||||||
|
|
||||||
|
finish()
|
||||||
|
{
|
||||||
|
ip netns delete server || true
|
||||||
|
ip netns delete client || true
|
||||||
|
ip link del link1_1 || true
|
||||||
|
}
|
||||||
|
|
||||||
|
trap finish EXIT
|
||||||
|
|
||||||
|
client_ip4=192.168.1.198
|
||||||
|
server_ip4=192.168.1.254
|
||||||
|
|
||||||
|
# setup kernel so it reboots after causing the panic
|
||||||
|
echo 180 >/proc/sys/kernel/panic
|
||||||
|
|
||||||
|
# build namespaces
|
||||||
|
ip link add dev link1_1 type veth peer name link1_2
|
||||||
|
|
||||||
|
ip netns add "server"
|
||||||
|
ip link set dev link1_2 netns server up name eth0
|
||||||
|
ip netns exec server ip addr add ${server_ip4}/24 dev eth0
|
||||||
|
|
||||||
|
ip netns add "client"
|
||||||
|
ip link set dev link1_1 netns client down name eth0
|
||||||
|
ip netns exec client ip link add dev bond0 down type bond mode 1 \
|
||||||
|
miimon 100 all_slaves_active 1
|
||||||
|
ip netns exec client ip link set dev eth0 down master bond0
|
||||||
|
ip netns exec client ip link set dev bond0 up
|
||||||
|
ip netns exec client ip addr add ${client_ip4}/24 dev bond0
|
||||||
|
ip netns exec client ping -c 5 $server_ip4 >/dev/null
|
||||||
|
|
||||||
|
ip netns exec client ip link set dev eth0 down nomaster
|
||||||
|
ip netns exec client ip link set dev bond0 down
|
||||||
|
ip netns exec client ip link set dev bond0 type bond mode 0 \
|
||||||
|
arp_interval 1000 arp_ip_target "+${server_ip4}"
|
||||||
|
ip netns exec client ip link set dev eth0 down master bond0
|
||||||
|
ip netns exec client ip link set dev bond0 up
|
||||||
|
ip netns exec client ping -c 5 $server_ip4 >/dev/null
|
||||||
|
|
||||||
|
exit 0
|
@ -1 +1,2 @@
|
|||||||
CONFIG_BONDING=y
|
CONFIG_BONDING=y
|
||||||
|
CONFIG_MACVLAN=y
|
||||||
|
109
tools/testing/selftests/drivers/net/bonding/dev_addr_lists.sh
Executable file
109
tools/testing/selftests/drivers/net/bonding/dev_addr_lists.sh
Executable file
@ -0,0 +1,109 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# SPDX-License-Identifier: GPL-2.0
|
||||||
|
#
|
||||||
|
# Test bond device handling of addr lists (dev->uc, mc)
|
||||||
|
#
|
||||||
|
|
||||||
|
ALL_TESTS="
|
||||||
|
bond_cleanup_mode1
|
||||||
|
bond_cleanup_mode4
|
||||||
|
bond_listen_lacpdu_multicast_case_down
|
||||||
|
bond_listen_lacpdu_multicast_case_up
|
||||||
|
"
|
||||||
|
|
||||||
|
REQUIRE_MZ=no
|
||||||
|
NUM_NETIFS=0
|
||||||
|
lib_dir=$(dirname "$0")
|
||||||
|
source "$lib_dir"/../../../net/forwarding/lib.sh
|
||||||
|
|
||||||
|
source "$lib_dir"/lag_lib.sh
|
||||||
|
|
||||||
|
|
||||||
|
destroy()
|
||||||
|
{
|
||||||
|
local ifnames=(dummy1 dummy2 bond1 mv0)
|
||||||
|
local ifname
|
||||||
|
|
||||||
|
for ifname in "${ifnames[@]}"; do
|
||||||
|
ip link del "$ifname" &>/dev/null
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup()
|
||||||
|
{
|
||||||
|
pre_cleanup
|
||||||
|
|
||||||
|
destroy
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# bond driver control paths vary between modes that have a primary slave
|
||||||
|
# (bond_uses_primary()) and others. Test both kinds of modes.
|
||||||
|
|
||||||
|
bond_cleanup_mode1()
|
||||||
|
{
|
||||||
|
RET=0
|
||||||
|
|
||||||
|
test_LAG_cleanup "bonding" "active-backup"
|
||||||
|
}
|
||||||
|
|
||||||
|
bond_cleanup_mode4() {
|
||||||
|
RET=0
|
||||||
|
|
||||||
|
test_LAG_cleanup "bonding" "802.3ad"
|
||||||
|
}
|
||||||
|
|
||||||
|
bond_listen_lacpdu_multicast()
|
||||||
|
{
|
||||||
|
# Initial state of bond device, up | down
|
||||||
|
local init_state=$1
|
||||||
|
local lacpdu_mc="01:80:c2:00:00:02"
|
||||||
|
|
||||||
|
ip link add dummy1 type dummy
|
||||||
|
ip link add bond1 "$init_state" type bond mode 802.3ad
|
||||||
|
ip link set dev dummy1 master bond1
|
||||||
|
if [ "$init_state" = "down" ]; then
|
||||||
|
ip link set dev bond1 up
|
||||||
|
fi
|
||||||
|
|
||||||
|
grep_bridge_fdb "$lacpdu_mc" bridge fdb show brport dummy1 >/dev/null
|
||||||
|
check_err $? "LACPDU multicast address not present on slave (1)"
|
||||||
|
|
||||||
|
ip link set dev bond1 down
|
||||||
|
|
||||||
|
not grep_bridge_fdb "$lacpdu_mc" bridge fdb show brport dummy1 >/dev/null
|
||||||
|
check_err $? "LACPDU multicast address still present on slave"
|
||||||
|
|
||||||
|
ip link set dev bond1 up
|
||||||
|
|
||||||
|
grep_bridge_fdb "$lacpdu_mc" bridge fdb show brport dummy1 >/dev/null
|
||||||
|
check_err $? "LACPDU multicast address not present on slave (2)"
|
||||||
|
|
||||||
|
cleanup
|
||||||
|
|
||||||
|
log_test "bonding LACPDU multicast address to slave (from bond $init_state)"
|
||||||
|
}
|
||||||
|
|
||||||
|
# The LACPDU mc addr is added by different paths depending on the initial state
|
||||||
|
# of the bond when enslaving a device. Test both cases.
|
||||||
|
|
||||||
|
bond_listen_lacpdu_multicast_case_down()
|
||||||
|
{
|
||||||
|
RET=0
|
||||||
|
|
||||||
|
bond_listen_lacpdu_multicast "down"
|
||||||
|
}
|
||||||
|
|
||||||
|
bond_listen_lacpdu_multicast_case_up()
|
||||||
|
{
|
||||||
|
RET=0
|
||||||
|
|
||||||
|
bond_listen_lacpdu_multicast "up"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
trap cleanup EXIT
|
||||||
|
|
||||||
|
tests_run
|
||||||
|
|
||||||
|
exit "$EXIT_STATUS"
|
61
tools/testing/selftests/drivers/net/bonding/lag_lib.sh
Normal file
61
tools/testing/selftests/drivers/net/bonding/lag_lib.sh
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# SPDX-License-Identifier: GPL-2.0
|
||||||
|
|
||||||
|
# Test that a link aggregation device (bonding, team) removes the hardware
|
||||||
|
# addresses that it adds on its underlying devices.
|
||||||
|
test_LAG_cleanup()
|
||||||
|
{
|
||||||
|
local driver=$1
|
||||||
|
local mode=$2
|
||||||
|
local ucaddr="02:00:00:12:34:56"
|
||||||
|
local addr6="fe80::78:9abc/64"
|
||||||
|
local mcaddr="33:33:ff:78:9a:bc"
|
||||||
|
local name
|
||||||
|
|
||||||
|
ip link add dummy1 type dummy
|
||||||
|
ip link add dummy2 type dummy
|
||||||
|
if [ "$driver" = "bonding" ]; then
|
||||||
|
name="bond1"
|
||||||
|
ip link add "$name" up type bond mode "$mode"
|
||||||
|
ip link set dev dummy1 master "$name"
|
||||||
|
ip link set dev dummy2 master "$name"
|
||||||
|
elif [ "$driver" = "team" ]; then
|
||||||
|
name="team0"
|
||||||
|
teamd -d -c '
|
||||||
|
{
|
||||||
|
"device": "'"$name"'",
|
||||||
|
"runner": {
|
||||||
|
"name": "'"$mode"'"
|
||||||
|
},
|
||||||
|
"ports": {
|
||||||
|
"dummy1":
|
||||||
|
{},
|
||||||
|
"dummy2":
|
||||||
|
{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
'
|
||||||
|
ip link set dev "$name" up
|
||||||
|
else
|
||||||
|
check_err 1
|
||||||
|
log_test test_LAG_cleanup ": unknown driver \"$driver\""
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Used to test dev->uc handling
|
||||||
|
ip link add mv0 link "$name" up address "$ucaddr" type macvlan
|
||||||
|
# Used to test dev->mc handling
|
||||||
|
ip address add "$addr6" dev "$name"
|
||||||
|
ip link set dev "$name" down
|
||||||
|
ip link del "$name"
|
||||||
|
|
||||||
|
not grep_bridge_fdb "$ucaddr" bridge fdb show >/dev/null
|
||||||
|
check_err $? "macvlan unicast address still present on a slave"
|
||||||
|
|
||||||
|
not grep_bridge_fdb "$mcaddr" bridge fdb show >/dev/null
|
||||||
|
check_err $? "IPv6 solicited-node multicast mac address still present on a slave"
|
||||||
|
|
||||||
|
cleanup
|
||||||
|
|
||||||
|
log_test "$driver cleanup mode $mode"
|
||||||
|
}
|
6
tools/testing/selftests/drivers/net/team/Makefile
Normal file
6
tools/testing/selftests/drivers/net/team/Makefile
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# SPDX-License-Identifier: GPL-2.0
|
||||||
|
# Makefile for net selftests
|
||||||
|
|
||||||
|
TEST_PROGS := dev_addr_lists.sh
|
||||||
|
|
||||||
|
include ../../../lib.mk
|
3
tools/testing/selftests/drivers/net/team/config
Normal file
3
tools/testing/selftests/drivers/net/team/config
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
CONFIG_NET_TEAM=y
|
||||||
|
CONFIG_NET_TEAM_MODE_LOADBALANCE=y
|
||||||
|
CONFIG_MACVLAN=y
|
51
tools/testing/selftests/drivers/net/team/dev_addr_lists.sh
Executable file
51
tools/testing/selftests/drivers/net/team/dev_addr_lists.sh
Executable file
@ -0,0 +1,51 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# SPDX-License-Identifier: GPL-2.0
|
||||||
|
#
|
||||||
|
# Test team device handling of addr lists (dev->uc, mc)
|
||||||
|
#
|
||||||
|
|
||||||
|
ALL_TESTS="
|
||||||
|
team_cleanup
|
||||||
|
"
|
||||||
|
|
||||||
|
REQUIRE_MZ=no
|
||||||
|
NUM_NETIFS=0
|
||||||
|
lib_dir=$(dirname "$0")
|
||||||
|
source "$lib_dir"/../../../net/forwarding/lib.sh
|
||||||
|
|
||||||
|
source "$lib_dir"/../bonding/lag_lib.sh
|
||||||
|
|
||||||
|
|
||||||
|
destroy()
|
||||||
|
{
|
||||||
|
local ifnames=(dummy0 dummy1 team0 mv0)
|
||||||
|
local ifname
|
||||||
|
|
||||||
|
for ifname in "${ifnames[@]}"; do
|
||||||
|
ip link del "$ifname" &>/dev/null
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup()
|
||||||
|
{
|
||||||
|
pre_cleanup
|
||||||
|
|
||||||
|
destroy
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
team_cleanup()
|
||||||
|
{
|
||||||
|
RET=0
|
||||||
|
|
||||||
|
test_LAG_cleanup "team" "lacp"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
require_command teamd
|
||||||
|
|
||||||
|
trap cleanup EXIT
|
||||||
|
|
||||||
|
tests_run
|
||||||
|
|
||||||
|
exit "$EXIT_STATUS"
|
@ -28,7 +28,7 @@
|
|||||||
# +------------------+ +------------------+
|
# +------------------+ +------------------+
|
||||||
#
|
#
|
||||||
|
|
||||||
ALL_TESTS="mcast_v4 mcast_v6 rpf_v4 rpf_v6"
|
ALL_TESTS="mcast_v4 mcast_v6 rpf_v4 rpf_v6 unres_v4 unres_v6"
|
||||||
NUM_NETIFS=6
|
NUM_NETIFS=6
|
||||||
source lib.sh
|
source lib.sh
|
||||||
source tc_common.sh
|
source tc_common.sh
|
||||||
@ -406,6 +406,96 @@ rpf_v6()
|
|||||||
log_test "RPF IPv6"
|
log_test "RPF IPv6"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unres_v4()
|
||||||
|
{
|
||||||
|
# Send a multicast packet not corresponding to an installed route,
|
||||||
|
# causing the kernel to queue the packet for resolution and emit an
|
||||||
|
# IGMPMSG_NOCACHE notification. smcrouted will react to this
|
||||||
|
# notification by consulting its (*, G) list and installing an (S, G)
|
||||||
|
# route, which will be used to forward the queued packet.
|
||||||
|
|
||||||
|
RET=0
|
||||||
|
|
||||||
|
tc filter add dev $h2 ingress protocol ip pref 1 handle 1 flower \
|
||||||
|
dst_ip 225.1.2.3 ip_proto udp dst_port 12345 action drop
|
||||||
|
tc filter add dev $h3 ingress protocol ip pref 1 handle 1 flower \
|
||||||
|
dst_ip 225.1.2.3 ip_proto udp dst_port 12345 action drop
|
||||||
|
|
||||||
|
# Forwarding should fail before installing a matching (*, G).
|
||||||
|
$MZ $h1 -c 1 -p 128 -t udp "ttl=10,sp=54321,dp=12345" \
|
||||||
|
-a 00:11:22:33:44:55 -b 01:00:5e:01:02:03 \
|
||||||
|
-A 198.51.100.2 -B 225.1.2.3 -q
|
||||||
|
|
||||||
|
tc_check_packets "dev $h2 ingress" 1 0
|
||||||
|
check_err $? "Multicast received on first host when should not"
|
||||||
|
tc_check_packets "dev $h3 ingress" 1 0
|
||||||
|
check_err $? "Multicast received on second host when should not"
|
||||||
|
|
||||||
|
# Create (*, G). Will not be installed in the kernel.
|
||||||
|
create_mcast_sg $rp1 0.0.0.0 225.1.2.3 $rp2 $rp3
|
||||||
|
|
||||||
|
$MZ $h1 -c 1 -p 128 -t udp "ttl=10,sp=54321,dp=12345" \
|
||||||
|
-a 00:11:22:33:44:55 -b 01:00:5e:01:02:03 \
|
||||||
|
-A 198.51.100.2 -B 225.1.2.3 -q
|
||||||
|
|
||||||
|
tc_check_packets "dev $h2 ingress" 1 1
|
||||||
|
check_err $? "Multicast not received on first host"
|
||||||
|
tc_check_packets "dev $h3 ingress" 1 1
|
||||||
|
check_err $? "Multicast not received on second host"
|
||||||
|
|
||||||
|
delete_mcast_sg $rp1 0.0.0.0 225.1.2.3 $rp2 $rp3
|
||||||
|
|
||||||
|
tc filter del dev $h3 ingress protocol ip pref 1 handle 1 flower
|
||||||
|
tc filter del dev $h2 ingress protocol ip pref 1 handle 1 flower
|
||||||
|
|
||||||
|
log_test "Unresolved queue IPv4"
|
||||||
|
}
|
||||||
|
|
||||||
|
unres_v6()
|
||||||
|
{
|
||||||
|
# Send a multicast packet not corresponding to an installed route,
|
||||||
|
# causing the kernel to queue the packet for resolution and emit an
|
||||||
|
# MRT6MSG_NOCACHE notification. smcrouted will react to this
|
||||||
|
# notification by consulting its (*, G) list and installing an (S, G)
|
||||||
|
# route, which will be used to forward the queued packet.
|
||||||
|
|
||||||
|
RET=0
|
||||||
|
|
||||||
|
tc filter add dev $h2 ingress protocol ipv6 pref 1 handle 1 flower \
|
||||||
|
dst_ip ff0e::3 ip_proto udp dst_port 12345 action drop
|
||||||
|
tc filter add dev $h3 ingress protocol ipv6 pref 1 handle 1 flower \
|
||||||
|
dst_ip ff0e::3 ip_proto udp dst_port 12345 action drop
|
||||||
|
|
||||||
|
# Forwarding should fail before installing a matching (*, G).
|
||||||
|
$MZ $h1 -6 -c 1 -p 128 -t udp "ttl=10,sp=54321,dp=12345" \
|
||||||
|
-a 00:11:22:33:44:55 -b 33:33:00:00:00:03 \
|
||||||
|
-A 2001:db8:1::2 -B ff0e::3 -q
|
||||||
|
|
||||||
|
tc_check_packets "dev $h2 ingress" 1 0
|
||||||
|
check_err $? "Multicast received on first host when should not"
|
||||||
|
tc_check_packets "dev $h3 ingress" 1 0
|
||||||
|
check_err $? "Multicast received on second host when should not"
|
||||||
|
|
||||||
|
# Create (*, G). Will not be installed in the kernel.
|
||||||
|
create_mcast_sg $rp1 :: ff0e::3 $rp2 $rp3
|
||||||
|
|
||||||
|
$MZ $h1 -6 -c 1 -p 128 -t udp "ttl=10,sp=54321,dp=12345" \
|
||||||
|
-a 00:11:22:33:44:55 -b 33:33:00:00:00:03 \
|
||||||
|
-A 2001:db8:1::2 -B ff0e::3 -q
|
||||||
|
|
||||||
|
tc_check_packets "dev $h2 ingress" 1 1
|
||||||
|
check_err $? "Multicast not received on first host"
|
||||||
|
tc_check_packets "dev $h3 ingress" 1 1
|
||||||
|
check_err $? "Multicast not received on second host"
|
||||||
|
|
||||||
|
delete_mcast_sg $rp1 :: ff0e::3 $rp2 $rp3
|
||||||
|
|
||||||
|
tc filter del dev $h3 ingress protocol ipv6 pref 1 handle 1 flower
|
||||||
|
tc filter del dev $h2 ingress protocol ipv6 pref 1 handle 1 flower
|
||||||
|
|
||||||
|
log_test "Unresolved queue IPv6"
|
||||||
|
}
|
||||||
|
|
||||||
trap cleanup EXIT
|
trap cleanup EXIT
|
||||||
|
|
||||||
setup_prepare
|
setup_prepare
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#!/bin/bash
|
||||||
# SPDX-License-Identifier: GPL-2.0
|
# SPDX-License-Identifier: GPL-2.0
|
||||||
|
|
||||||
# This test sends one stream of traffic from H1 through a TBF shaper, to a RED
|
# This test sends one stream of traffic from H1 through a TBF shaper, to a RED
|
||||||
|
@ -91,7 +91,7 @@ src
|
|||||||
start 1
|
start 1
|
||||||
count 5
|
count 5
|
||||||
src_delta 2000
|
src_delta 2000
|
||||||
tools sendip nc bash
|
tools sendip socat nc bash
|
||||||
proto udp
|
proto udp
|
||||||
|
|
||||||
race_repeat 3
|
race_repeat 3
|
||||||
@ -116,7 +116,7 @@ src
|
|||||||
start 10
|
start 10
|
||||||
count 5
|
count 5
|
||||||
src_delta 2000
|
src_delta 2000
|
||||||
tools sendip nc bash
|
tools sendip socat nc bash
|
||||||
proto udp6
|
proto udp6
|
||||||
|
|
||||||
race_repeat 3
|
race_repeat 3
|
||||||
@ -141,7 +141,7 @@ src
|
|||||||
start 1
|
start 1
|
||||||
count 5
|
count 5
|
||||||
src_delta 2000
|
src_delta 2000
|
||||||
tools sendip nc bash
|
tools sendip socat nc bash
|
||||||
proto udp
|
proto udp
|
||||||
|
|
||||||
race_repeat 0
|
race_repeat 0
|
||||||
@ -163,7 +163,7 @@ src mac
|
|||||||
start 10
|
start 10
|
||||||
count 5
|
count 5
|
||||||
src_delta 2000
|
src_delta 2000
|
||||||
tools sendip nc bash
|
tools sendip socat nc bash
|
||||||
proto udp6
|
proto udp6
|
||||||
|
|
||||||
race_repeat 0
|
race_repeat 0
|
||||||
@ -185,7 +185,7 @@ src mac proto
|
|||||||
start 10
|
start 10
|
||||||
count 5
|
count 5
|
||||||
src_delta 2000
|
src_delta 2000
|
||||||
tools sendip nc bash
|
tools sendip socat nc bash
|
||||||
proto udp6
|
proto udp6
|
||||||
|
|
||||||
race_repeat 0
|
race_repeat 0
|
||||||
@ -207,7 +207,7 @@ src addr4
|
|||||||
start 1
|
start 1
|
||||||
count 5
|
count 5
|
||||||
src_delta 2000
|
src_delta 2000
|
||||||
tools sendip nc bash
|
tools sendip socat nc bash
|
||||||
proto udp
|
proto udp
|
||||||
|
|
||||||
race_repeat 3
|
race_repeat 3
|
||||||
@ -227,7 +227,7 @@ src addr6 port
|
|||||||
start 10
|
start 10
|
||||||
count 5
|
count 5
|
||||||
src_delta 2000
|
src_delta 2000
|
||||||
tools sendip nc
|
tools sendip socat nc
|
||||||
proto udp6
|
proto udp6
|
||||||
|
|
||||||
race_repeat 3
|
race_repeat 3
|
||||||
@ -247,7 +247,7 @@ src mac proto addr4
|
|||||||
start 1
|
start 1
|
||||||
count 5
|
count 5
|
||||||
src_delta 2000
|
src_delta 2000
|
||||||
tools sendip nc bash
|
tools sendip socat nc bash
|
||||||
proto udp
|
proto udp
|
||||||
|
|
||||||
race_repeat 0
|
race_repeat 0
|
||||||
@ -264,7 +264,7 @@ src mac
|
|||||||
start 1
|
start 1
|
||||||
count 5
|
count 5
|
||||||
src_delta 2000
|
src_delta 2000
|
||||||
tools sendip nc bash
|
tools sendip socat nc bash
|
||||||
proto udp
|
proto udp
|
||||||
|
|
||||||
race_repeat 0
|
race_repeat 0
|
||||||
@ -286,7 +286,7 @@ src mac addr4
|
|||||||
start 1
|
start 1
|
||||||
count 5
|
count 5
|
||||||
src_delta 2000
|
src_delta 2000
|
||||||
tools sendip nc bash
|
tools sendip socat nc bash
|
||||||
proto udp
|
proto udp
|
||||||
|
|
||||||
race_repeat 0
|
race_repeat 0
|
||||||
@ -337,7 +337,7 @@ src addr4
|
|||||||
start 1
|
start 1
|
||||||
count 5
|
count 5
|
||||||
src_delta 2000
|
src_delta 2000
|
||||||
tools sendip nc
|
tools sendip socat nc
|
||||||
proto udp
|
proto udp
|
||||||
|
|
||||||
race_repeat 3
|
race_repeat 3
|
||||||
@ -363,7 +363,7 @@ src mac
|
|||||||
start 1
|
start 1
|
||||||
count 1
|
count 1
|
||||||
src_delta 2000
|
src_delta 2000
|
||||||
tools sendip nc bash
|
tools sendip socat nc bash
|
||||||
proto udp
|
proto udp
|
||||||
|
|
||||||
race_repeat 0
|
race_repeat 0
|
||||||
@ -541,6 +541,24 @@ setup_send_udp() {
|
|||||||
dst_port=
|
dst_port=
|
||||||
src_addr4=
|
src_addr4=
|
||||||
}
|
}
|
||||||
|
elif command -v socat -v >/dev/null; then
|
||||||
|
send_udp() {
|
||||||
|
if [ -n "${src_addr4}" ]; then
|
||||||
|
B ip addr add "${src_addr4}" dev veth_b
|
||||||
|
__socatbind=",bind=${src_addr4}"
|
||||||
|
if [ -n "${src_port}" ];then
|
||||||
|
__socatbind="${__socatbind}:${src_port}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
ip addr add "${dst_addr4}" dev veth_a 2>/dev/null
|
||||||
|
[ -z "${dst_port}" ] && dst_port=12345
|
||||||
|
|
||||||
|
echo "test4" | B socat -t 0.01 STDIN UDP4-DATAGRAM:${dst_addr4}:${dst_port}"${__socatbind}"
|
||||||
|
|
||||||
|
src_addr4=
|
||||||
|
src_port=
|
||||||
|
}
|
||||||
elif command -v nc >/dev/null; then
|
elif command -v nc >/dev/null; then
|
||||||
if nc -u -w0 1.1.1.1 1 2>/dev/null; then
|
if nc -u -w0 1.1.1.1 1 2>/dev/null; then
|
||||||
# OpenBSD netcat
|
# OpenBSD netcat
|
||||||
@ -606,6 +624,29 @@ setup_send_udp6() {
|
|||||||
dst_port=
|
dst_port=
|
||||||
src_addr6=
|
src_addr6=
|
||||||
}
|
}
|
||||||
|
elif command -v socat -v >/dev/null; then
|
||||||
|
send_udp6() {
|
||||||
|
ip -6 addr add "${dst_addr6}" dev veth_a nodad \
|
||||||
|
2>/dev/null
|
||||||
|
|
||||||
|
__socatbind6=
|
||||||
|
|
||||||
|
if [ -n "${src_addr6}" ]; then
|
||||||
|
if [ -n "${src_addr6} != "${src_addr6_added} ]; then
|
||||||
|
B ip addr add "${src_addr6}" dev veth_b nodad
|
||||||
|
|
||||||
|
src_addr6_added=${src_addr6}
|
||||||
|
fi
|
||||||
|
|
||||||
|
__socatbind6=",bind=[${src_addr6}]"
|
||||||
|
|
||||||
|
if [ -n "${src_port}" ] ;then
|
||||||
|
__socatbind6="${__socatbind6}:${src_port}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "test6" | B socat -t 0.01 STDIN UDP6-DATAGRAM:[${dst_addr6}]:${dst_port}"${__socatbind6}"
|
||||||
|
}
|
||||||
elif command -v nc >/dev/null && nc -u -w0 1.1.1.1 1 2>/dev/null; then
|
elif command -v nc >/dev/null && nc -u -w0 1.1.1.1 1 2>/dev/null; then
|
||||||
# GNU netcat might not work with IPv6, try next tool
|
# GNU netcat might not work with IPv6, try next tool
|
||||||
send_udp6() {
|
send_udp6() {
|
||||||
|
@ -343,8 +343,10 @@ $(KERNEL_BZIMAGE): $(TOOLCHAIN_PATH)/.installed $(KERNEL_BUILD_PATH)/.config $(B
|
|||||||
.PHONY: $(KERNEL_BZIMAGE)
|
.PHONY: $(KERNEL_BZIMAGE)
|
||||||
|
|
||||||
$(TOOLCHAIN_PATH)/$(CHOST)/include/linux/.installed: | $(KERNEL_BUILD_PATH)/.config $(TOOLCHAIN_PATH)/.installed
|
$(TOOLCHAIN_PATH)/$(CHOST)/include/linux/.installed: | $(KERNEL_BUILD_PATH)/.config $(TOOLCHAIN_PATH)/.installed
|
||||||
|
ifneq ($(ARCH),um)
|
||||||
rm -rf $(TOOLCHAIN_PATH)/$(CHOST)/include/linux
|
rm -rf $(TOOLCHAIN_PATH)/$(CHOST)/include/linux
|
||||||
$(MAKE) -C $(KERNEL_PATH) O=$(KERNEL_BUILD_PATH) INSTALL_HDR_PATH=$(TOOLCHAIN_PATH)/$(CHOST) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(CROSS_COMPILE) headers_install
|
$(MAKE) -C $(KERNEL_PATH) O=$(KERNEL_BUILD_PATH) INSTALL_HDR_PATH=$(TOOLCHAIN_PATH)/$(CHOST) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(CROSS_COMPILE) headers_install
|
||||||
|
endif
|
||||||
touch $@
|
touch $@
|
||||||
|
|
||||||
$(TOOLCHAIN_PATH)/.installed: $(TOOLCHAIN_TAR)
|
$(TOOLCHAIN_PATH)/.installed: $(TOOLCHAIN_TAR)
|
||||||
|
Loading…
Reference in New Issue
Block a user