forked from Minki/linux
Networking fixes for 5.16-rc1, including fixes from bpf, can
and netfilter. Current release - regressions: - bpf: do not reject when the stack read size is different from the tracked scalar size - net: fix premature exit from NAPI state polling in napi_disable() - riscv, bpf: fix RV32 broken build, and silence RV64 warning Current release - new code bugs: - net: fix possible NULL deref in sock_reserve_memory - amt: fix error return code in amt_init(); fix stopping the workqueue - ax88796c: use the correct ioctl callback Previous releases - always broken: - bpf: stop caching subprog index in the bpf_pseudo_func insn - security: fixups for the security hooks in sctp - nfc: add necessary privilege flags in netlink layer, limit operations to admin only - vsock: prevent unnecessary refcnt inc for non-blocking connect - net/smc: fix sk_refcnt underflow on link down and fallback - nfnetlink_queue: fix OOB when mac header was cleared - can: j1939: ignore invalid messages per standard - bpf, sockmap: - fix race in ingress receive verdict with redirect to self - fix incorrect sk_skb data_end access when src_reg = dst_reg - strparser, and tls are reusing qdisc_skb_cb and colliding - ethtool: fix ethtool msg len calculation for pause stats - vlan: fix a UAF in vlan_dev_real_dev() when ref-holder tries to access an unregistering real_dev - udp6: make encap_rcv() bump the v6 not v4 stats - drv: prestera: add explicit padding to fix m68k build - drv: felix: fix broken VLAN-tagged PTP under VLAN-aware bridge - drv: mvpp2: fix wrong SerDes reconfiguration order Misc & small latecomers: - ipvs: auto-load ipvs on genl access - mctp: sanity check the struct sockaddr_mctp padding fields - libfs: support RENAME_EXCHANGE in simple_rename() - avoid double accounting for pure zerocopy skbs Signed-off-by: Jakub Kicinski <kuba@kernel.org> -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEE6jPA+I1ugmIBA4hXMUZtbf5SIrsFAmGNQdwACgkQMUZtbf5S IrsiMQ//f66lTJ8PJ5Qj70hX9dC897olx7uGHB9eiKoyOcJI459hFlfXwRU2T4Tf fPNwPNUQ9Mynw9tX/jWEi+7zd6r6TSHGXK49U9/rIbQ95QjKY4LHowIE63x+vPl2 5Cpf+80zXC3DUX1fijgyG1ujnU3kBaqopTxDLmlsHw2PGkwT5Ox1DUwkhc370eEL xlpq3PYGWA8/AQNyhSVBkG/UmoLaq0jYNP5yVcOj4jGjgcgLe1SLrqczENr35QHZ cRkuBsFBMBZF7wSX2f9qQIB/+b1pcLlD9IO+K3S7Ruq+rUd7qfL/tmwNxEh0axYK AyIun1Bxcy7QJGjtpGAz+Ku7jS9T3HxzyxhqilQo3co8jAW0WJ1YwHl+XPgQXyjV DLG6Vxt4syiwsoSXGn8MQugs4nlBT+0qWl8YamIR+o7KkAYPc2QWkXlzEDfNeIW8 JNCZA3sy7VGi1ytorZGx16sQsEWnyRG9a6/WV20Dr+HVs1SKPcFzIfG6mVngR07T mQMHnbAF6Z5d8VTcPQfMxd7UH48s1bHtk5lcSTa3j0Cw+GkA6ytTmjPdJ1qRcdkH dl9jAfADe4O6frG+9XH7FEFqhmkghVI7bOCA4ZOhClVaIcDGgEZc2y7sY9/oZ7P4 KXBD2R5X1caCUM0UtzwL7/8ddOtPtHIrFnhY+7+I6ijt9qmI0BY= =Ttgq -----END PGP SIGNATURE----- Merge tag 'net-5.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net Pull networking fixes from Jakub Kicinski: "Including fixes from bpf, can and netfilter. Current release - regressions: - bpf: do not reject when the stack read size is different from the tracked scalar size - net: fix premature exit from NAPI state polling in napi_disable() - riscv, bpf: fix RV32 broken build, and silence RV64 warning Current release - new code bugs: - net: fix possible NULL deref in sock_reserve_memory - amt: fix error return code in amt_init(); fix stopping the workqueue - ax88796c: use the correct ioctl callback Previous releases - always broken: - bpf: stop caching subprog index in the bpf_pseudo_func insn - security: fixups for the security hooks in sctp - nfc: add necessary privilege flags in netlink layer, limit operations to admin only - vsock: prevent unnecessary refcnt inc for non-blocking connect - net/smc: fix sk_refcnt underflow on link down and fallback - nfnetlink_queue: fix OOB when mac header was cleared - can: j1939: ignore invalid messages per standard - bpf, sockmap: - fix race in ingress receive verdict with redirect to self - fix incorrect sk_skb data_end access when src_reg = dst_reg - strparser, and tls are reusing qdisc_skb_cb and colliding - ethtool: fix ethtool msg len calculation for pause stats - vlan: fix a UAF in vlan_dev_real_dev() when ref-holder tries to access an unregistering real_dev - udp6: make encap_rcv() bump the v6 not v4 stats - drv: prestera: add explicit padding to fix m68k build - drv: felix: fix broken VLAN-tagged PTP under VLAN-aware bridge - drv: mvpp2: fix wrong SerDes reconfiguration order Misc & small latecomers: - ipvs: auto-load ipvs on genl access - mctp: sanity check the struct sockaddr_mctp padding fields - libfs: support RENAME_EXCHANGE in simple_rename() - avoid double accounting for pure zerocopy skbs" * tag 'net-5.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (123 commits) selftests/net: udpgso_bench_rx: fix port argument net: wwan: iosm: fix compilation warning cxgb4: fix eeprom len when diagnostics not implemented net: fix premature exit from NAPI state polling in napi_disable() net/smc: fix sk_refcnt underflow on linkdown and fallback net/mlx5: Lag, fix a potential Oops with mlx5_lag_create_definer() gve: fix unmatched u64_stats_update_end() net: ethernet: lantiq_etop: Fix compilation error selftests: forwarding: Fix packet matching in mirroring selftests vsock: prevent unnecessary refcnt inc for nonblocking connect net: marvell: mvpp2: Fix wrong SerDes reconfiguration order net: ethernet: ti: cpsw_ale: Fix access to un-initialized memory net: stmmac: allow a tc-taprio base-time of zero selftests: net: test_vxlan_under_vrf: fix HV connectivity test net: hns3: allow configure ETS bandwidth of all TCs net: hns3: remove check VF uc mac exist when set by PF net: hns3: fix some mac statistics is always 0 in device version V2 net: hns3: fix kernel crash when unload VF while it is being reset net: hns3: sync rx ring head in echo common pull net: hns3: fix pfc packet number incorrect after querying pfc parameters ...
This commit is contained in:
commit
f54ca91fe6
@ -1004,13 +1004,11 @@ udp_l3mdev_accept - BOOLEAN
|
||||
udp_mem - vector of 3 INTEGERs: min, pressure, max
|
||||
Number of pages allowed for queueing by all UDP sockets.
|
||||
|
||||
min: Below this number of pages UDP is not bothered about its
|
||||
memory appetite. When amount of memory allocated by UDP exceeds
|
||||
this number, UDP starts to moderate memory usage.
|
||||
min: Number of pages allowed for queueing by all UDP sockets.
|
||||
|
||||
pressure: This value was introduced to follow format of tcp_mem.
|
||||
|
||||
max: Number of pages allowed for queueing by all UDP sockets.
|
||||
max: This value was introduced to follow format of tcp_mem.
|
||||
|
||||
Default is calculated at boot time from amount of available memory.
|
||||
|
||||
|
@ -15,10 +15,7 @@ For security module support, three SCTP specific hooks have been implemented::
|
||||
security_sctp_assoc_request()
|
||||
security_sctp_bind_connect()
|
||||
security_sctp_sk_clone()
|
||||
|
||||
Also the following security hook has been utilised::
|
||||
|
||||
security_inet_conn_established()
|
||||
security_sctp_assoc_established()
|
||||
|
||||
The usage of these hooks are described below with the SELinux implementation
|
||||
described in the `SCTP SELinux Support`_ chapter.
|
||||
@ -26,11 +23,11 @@ described in the `SCTP SELinux Support`_ chapter.
|
||||
|
||||
security_sctp_assoc_request()
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Passes the ``@ep`` and ``@chunk->skb`` of the association INIT packet to the
|
||||
Passes the ``@asoc`` and ``@chunk->skb`` of the association INIT packet to the
|
||||
security module. Returns 0 on success, error on failure.
|
||||
::
|
||||
|
||||
@ep - pointer to sctp endpoint structure.
|
||||
@asoc - pointer to sctp association structure.
|
||||
@skb - pointer to skbuff of association packet.
|
||||
|
||||
|
||||
@ -117,16 +114,17 @@ Called whenever a new socket is created by **accept**\(2)
|
||||
calls **sctp_peeloff**\(3).
|
||||
::
|
||||
|
||||
@ep - pointer to current sctp endpoint structure.
|
||||
@asoc - pointer to current sctp association structure.
|
||||
@sk - pointer to current sock structure.
|
||||
@sk - pointer to new sock structure.
|
||||
@newsk - pointer to new sock structure.
|
||||
|
||||
|
||||
security_inet_conn_established()
|
||||
security_sctp_assoc_established()
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Called when a COOKIE ACK is received::
|
||||
Called when a COOKIE ACK is received, and the peer secid will be
|
||||
saved into ``@asoc->peer_secid`` for client::
|
||||
|
||||
@sk - pointer to sock structure.
|
||||
@asoc - pointer to sctp association structure.
|
||||
@skb - pointer to skbuff of the COOKIE ACK packet.
|
||||
|
||||
|
||||
@ -134,7 +132,7 @@ Security Hooks used for Association Establishment
|
||||
-------------------------------------------------
|
||||
|
||||
The following diagram shows the use of ``security_sctp_bind_connect()``,
|
||||
``security_sctp_assoc_request()``, ``security_inet_conn_established()`` when
|
||||
``security_sctp_assoc_request()``, ``security_sctp_assoc_established()`` when
|
||||
establishing an association.
|
||||
::
|
||||
|
||||
@ -151,9 +149,9 @@ establishing an association.
|
||||
INIT --------------------------------------------->
|
||||
sctp_sf_do_5_1B_init()
|
||||
Respond to an INIT chunk.
|
||||
SCTP peer endpoint "A" is
|
||||
asking for an association. Call
|
||||
security_sctp_assoc_request()
|
||||
SCTP peer endpoint "A" is asking
|
||||
for a temporary association.
|
||||
Call security_sctp_assoc_request()
|
||||
to set the peer label if first
|
||||
association.
|
||||
If not first association, check
|
||||
@ -163,13 +161,16 @@ establishing an association.
|
||||
| discard the packet.
|
||||
|
|
||||
COOKIE ECHO ------------------------------------------>
|
||||
|
|
||||
|
|
||||
|
|
||||
sctp_sf_do_5_1D_ce()
|
||||
Respond to an COOKIE ECHO chunk.
|
||||
Confirm the cookie and create a
|
||||
permanent association.
|
||||
Call security_sctp_assoc_request() to
|
||||
do the same as for INIT chunk Response.
|
||||
<------------------------------------------- COOKIE ACK
|
||||
| |
|
||||
sctp_sf_do_5_1E_ca |
|
||||
Call security_inet_conn_established() |
|
||||
Call security_sctp_assoc_established() |
|
||||
to set the peer label. |
|
||||
| |
|
||||
| If SCTP_SOCKET_TCP or peeled off
|
||||
@ -195,27 +196,27 @@ hooks with the SELinux specifics expanded below::
|
||||
security_sctp_assoc_request()
|
||||
security_sctp_bind_connect()
|
||||
security_sctp_sk_clone()
|
||||
security_inet_conn_established()
|
||||
security_sctp_assoc_established()
|
||||
|
||||
|
||||
security_sctp_assoc_request()
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Passes the ``@ep`` and ``@chunk->skb`` of the association INIT packet to the
|
||||
Passes the ``@asoc`` and ``@chunk->skb`` of the association INIT packet to the
|
||||
security module. Returns 0 on success, error on failure.
|
||||
::
|
||||
|
||||
@ep - pointer to sctp endpoint structure.
|
||||
@asoc - pointer to sctp association structure.
|
||||
@skb - pointer to skbuff of association packet.
|
||||
|
||||
The security module performs the following operations:
|
||||
IF this is the first association on ``@ep->base.sk``, then set the peer
|
||||
IF this is the first association on ``@asoc->base.sk``, then set the peer
|
||||
sid to that in ``@skb``. This will ensure there is only one peer sid
|
||||
assigned to ``@ep->base.sk`` that may support multiple associations.
|
||||
assigned to ``@asoc->base.sk`` that may support multiple associations.
|
||||
|
||||
ELSE validate the ``@ep->base.sk peer_sid`` against the ``@skb peer sid``
|
||||
ELSE validate the ``@asoc->base.sk peer_sid`` against the ``@skb peer sid``
|
||||
to determine whether the association should be allowed or denied.
|
||||
|
||||
Set the sctp ``@ep sid`` to socket's sid (from ``ep->base.sk``) with
|
||||
Set the sctp ``@asoc sid`` to socket's sid (from ``asoc->base.sk``) with
|
||||
MLS portion taken from ``@skb peer sid``. This will be used by SCTP
|
||||
TCP style sockets and peeled off connections as they cause a new socket
|
||||
to be generated.
|
||||
@ -259,21 +260,21 @@ security_sctp_sk_clone()
|
||||
Called whenever a new socket is created by **accept**\(2) (i.e. a TCP style
|
||||
socket) or when a socket is 'peeled off' e.g userspace calls
|
||||
**sctp_peeloff**\(3). ``security_sctp_sk_clone()`` will set the new
|
||||
sockets sid and peer sid to that contained in the ``@ep sid`` and
|
||||
``@ep peer sid`` respectively.
|
||||
sockets sid and peer sid to that contained in the ``@asoc sid`` and
|
||||
``@asoc peer sid`` respectively.
|
||||
::
|
||||
|
||||
@ep - pointer to current sctp endpoint structure.
|
||||
@asoc - pointer to current sctp association structure.
|
||||
@sk - pointer to current sock structure.
|
||||
@sk - pointer to new sock structure.
|
||||
@newsk - pointer to new sock structure.
|
||||
|
||||
|
||||
security_inet_conn_established()
|
||||
security_sctp_assoc_established()
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Called when a COOKIE ACK is received where it sets the connection's peer sid
|
||||
to that in ``@skb``::
|
||||
|
||||
@sk - pointer to sock structure.
|
||||
@asoc - pointer to sctp association structure.
|
||||
@skb - pointer to skbuff of the COOKIE ACK packet.
|
||||
|
||||
|
||||
|
@ -872,9 +872,10 @@ F: Documentation/devicetree/bindings/thermal/amazon,al-thermal.txt
|
||||
F: drivers/thermal/thermal_mmio.c
|
||||
|
||||
AMAZON ETHERNET DRIVERS
|
||||
M: Netanel Belgazal <netanel@amazon.com>
|
||||
M: Shay Agroskin <shayagr@amazon.com>
|
||||
M: Arthur Kiyanovski <akiyano@amazon.com>
|
||||
R: Guy Tzalik <gtzalik@amazon.com>
|
||||
R: David Arinzon <darinzon@amazon.com>
|
||||
R: Noam Dagan <ndagan@amazon.com>
|
||||
R: Saeed Bishara <saeedb@amazon.com>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Supported
|
||||
|
@ -11,7 +11,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
#ifdef CONFIG_BPF_JIT
|
||||
#if defined(CONFIG_BPF_JIT) && defined(CONFIG_ARCH_RV64I)
|
||||
int rv_bpf_fixup_exception(const struct exception_table_entry *ex, struct pt_regs *regs);
|
||||
#endif
|
||||
|
||||
@ -23,7 +23,7 @@ int fixup_exception(struct pt_regs *regs)
|
||||
if (!fixup)
|
||||
return 0;
|
||||
|
||||
#ifdef CONFIG_BPF_JIT
|
||||
#if defined(CONFIG_BPF_JIT) && defined(CONFIG_ARCH_RV64I)
|
||||
if (regs->epc >= BPF_JIT_REGION_START && regs->epc < BPF_JIT_REGION_END)
|
||||
return rv_bpf_fixup_exception(fixup, regs);
|
||||
#endif
|
||||
|
@ -459,6 +459,8 @@ static int emit_call(bool fixed, u64 addr, struct rv_jit_context *ctx)
|
||||
#define BPF_FIXUP_OFFSET_MASK GENMASK(26, 0)
|
||||
#define BPF_FIXUP_REG_MASK GENMASK(31, 27)
|
||||
|
||||
int rv_bpf_fixup_exception(const struct exception_table_entry *ex,
|
||||
struct pt_regs *regs);
|
||||
int rv_bpf_fixup_exception(const struct exception_table_entry *ex,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
|
@ -294,6 +294,7 @@ config GTP
|
||||
config AMT
|
||||
tristate "Automatic Multicast Tunneling (AMT)"
|
||||
depends on INET && IP_MULTICAST
|
||||
depends on IPV6 || !IPV6
|
||||
select NET_UDP_TUNNEL
|
||||
help
|
||||
This allows one to create AMT(Automatic Multicast Tunneling)
|
||||
|
@ -12,7 +12,6 @@
|
||||
#include <linux/igmp.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <net/net_namespace.h>
|
||||
#include <net/protocol.h>
|
||||
#include <net/ip.h>
|
||||
#include <net/udp.h>
|
||||
#include <net/udp_tunnel.h>
|
||||
@ -23,7 +22,6 @@
|
||||
#include <linux/security.h>
|
||||
#include <net/gro_cells.h>
|
||||
#include <net/ipv6.h>
|
||||
#include <net/protocol.h>
|
||||
#include <net/if_inet6.h>
|
||||
#include <net/ndisc.h>
|
||||
#include <net/addrconf.h>
|
||||
@ -2767,7 +2765,7 @@ static int amt_err_lookup(struct sock *sk, struct sk_buff *skb)
|
||||
rcu_read_lock_bh();
|
||||
amt = rcu_dereference_sk_user_data(sk);
|
||||
if (!amt)
|
||||
goto drop;
|
||||
goto out;
|
||||
|
||||
if (amt->mode != AMT_MODE_GATEWAY)
|
||||
goto drop;
|
||||
@ -2789,6 +2787,7 @@ static int amt_err_lookup(struct sock *sk, struct sk_buff *skb)
|
||||
default:
|
||||
goto drop;
|
||||
}
|
||||
out:
|
||||
rcu_read_unlock_bh();
|
||||
return 0;
|
||||
drop:
|
||||
@ -3259,8 +3258,10 @@ static int __init amt_init(void)
|
||||
goto unregister_notifier;
|
||||
|
||||
amt_wq = alloc_workqueue("amt", WQ_UNBOUND, 1);
|
||||
if (!amt_wq)
|
||||
if (!amt_wq) {
|
||||
err = -ENOMEM;
|
||||
goto rtnl_unregister;
|
||||
}
|
||||
|
||||
spin_lock_init(&source_gc_lock);
|
||||
spin_lock_bh(&source_gc_lock);
|
||||
@ -3285,7 +3286,7 @@ static void __exit amt_fini(void)
|
||||
{
|
||||
rtnl_link_unregister(&amt_link_ops);
|
||||
unregister_netdevice_notifier(&amt_notifier_block);
|
||||
flush_delayed_work(&source_gc_wq);
|
||||
cancel_delayed_work(&source_gc_wq);
|
||||
__amt_source_gc_work();
|
||||
destroy_workqueue(amt_wq);
|
||||
}
|
||||
|
@ -108,15 +108,15 @@ static ssize_t ad_partner_oper_port_state_show(struct slave *slave, char *buf)
|
||||
}
|
||||
static SLAVE_ATTR_RO(ad_partner_oper_port_state);
|
||||
|
||||
static const struct slave_attribute *slave_attrs[] = {
|
||||
&slave_attr_state,
|
||||
&slave_attr_mii_status,
|
||||
&slave_attr_link_failure_count,
|
||||
&slave_attr_perm_hwaddr,
|
||||
&slave_attr_queue_id,
|
||||
&slave_attr_ad_aggregator_id,
|
||||
&slave_attr_ad_actor_oper_port_state,
|
||||
&slave_attr_ad_partner_oper_port_state,
|
||||
static const struct attribute *slave_attrs[] = {
|
||||
&slave_attr_state.attr,
|
||||
&slave_attr_mii_status.attr,
|
||||
&slave_attr_link_failure_count.attr,
|
||||
&slave_attr_perm_hwaddr.attr,
|
||||
&slave_attr_queue_id.attr,
|
||||
&slave_attr_ad_aggregator_id.attr,
|
||||
&slave_attr_ad_actor_oper_port_state.attr,
|
||||
&slave_attr_ad_partner_oper_port_state.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
@ -137,24 +137,10 @@ const struct sysfs_ops slave_sysfs_ops = {
|
||||
|
||||
int bond_sysfs_slave_add(struct slave *slave)
|
||||
{
|
||||
const struct slave_attribute **a;
|
||||
int err;
|
||||
|
||||
for (a = slave_attrs; *a; ++a) {
|
||||
err = sysfs_create_file(&slave->kobj, &((*a)->attr));
|
||||
if (err) {
|
||||
kobject_put(&slave->kobj);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return sysfs_create_files(&slave->kobj, slave_attrs);
|
||||
}
|
||||
|
||||
void bond_sysfs_slave_del(struct slave *slave)
|
||||
{
|
||||
const struct slave_attribute **a;
|
||||
|
||||
for (a = slave_attrs; *a; ++a)
|
||||
sysfs_remove_file(&slave->kobj, &((*a)->attr));
|
||||
sysfs_remove_files(&slave->kobj, slave_attrs);
|
||||
}
|
||||
|
@ -1092,7 +1092,7 @@ static int mcp251xfd_chip_start(struct mcp251xfd_priv *priv)
|
||||
|
||||
err = mcp251xfd_chip_rx_int_enable(priv);
|
||||
if (err)
|
||||
return err;
|
||||
goto out_chip_stop;
|
||||
|
||||
err = mcp251xfd_chip_ecc_init(priv);
|
||||
if (err)
|
||||
@ -2290,8 +2290,10 @@ static irqreturn_t mcp251xfd_irq(int irq, void *dev_id)
|
||||
* check will fail, too. So leave IRQ handler
|
||||
* directly.
|
||||
*/
|
||||
if (priv->can.state == CAN_STATE_BUS_OFF)
|
||||
if (priv->can.state == CAN_STATE_BUS_OFF) {
|
||||
can_rx_offload_threaded_irq_finish(&priv->offload);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
}
|
||||
|
||||
handled = IRQ_HANDLED;
|
||||
|
@ -664,7 +664,7 @@ int es58x_rx_err_msg(struct net_device *netdev, enum es58x_err error,
|
||||
struct can_device_stats *can_stats = &can->can_stats;
|
||||
struct can_frame *cf = NULL;
|
||||
struct sk_buff *skb;
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
if (!netif_running(netdev)) {
|
||||
if (net_ratelimit())
|
||||
@ -823,8 +823,6 @@ int es58x_rx_err_msg(struct net_device *netdev, enum es58x_err error,
|
||||
can->state = CAN_STATE_BUS_OFF;
|
||||
can_bus_off(netdev);
|
||||
ret = can->do_set_mode(netdev, CAN_MODE_STOP);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -881,7 +879,7 @@ int es58x_rx_err_msg(struct net_device *netdev, enum es58x_err error,
|
||||
ES58X_EVENT_BUSOFF, timestamp);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -841,14 +841,14 @@ static int pcan_usb_start(struct peak_usb_device *dev)
|
||||
pdev->bec.rxerr = 0;
|
||||
pdev->bec.txerr = 0;
|
||||
|
||||
/* be notified on error counter changes (if requested by user) */
|
||||
if (dev->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) {
|
||||
err = pcan_usb_set_err_frame(dev, PCAN_USB_BERR_MASK);
|
||||
if (err)
|
||||
netdev_warn(dev->netdev,
|
||||
"Asking for BERR reporting error %u\n",
|
||||
err);
|
||||
}
|
||||
/* always ask the device for BERR reporting, to be able to switch from
|
||||
* WARNING to PASSIVE state
|
||||
*/
|
||||
err = pcan_usb_set_err_frame(dev, PCAN_USB_BERR_MASK);
|
||||
if (err)
|
||||
netdev_warn(dev->netdev,
|
||||
"Asking for BERR reporting error %u\n",
|
||||
err);
|
||||
|
||||
/* if revision greater than 3, can put silent mode on/off */
|
||||
if (dev->device_rev > 3) {
|
||||
@ -883,6 +883,11 @@ static int pcan_usb_init(struct peak_usb_device *dev)
|
||||
return err;
|
||||
}
|
||||
|
||||
dev_info(dev->netdev->dev.parent,
|
||||
"PEAK-System %s adapter hwrev %u serial %08X (%u channel)\n",
|
||||
pcan_usb.name, dev->device_rev, serial_number,
|
||||
pcan_usb.ctrl_count);
|
||||
|
||||
/* Since rev 4.1, PCAN-USB is able to make single-shot as well as
|
||||
* looped back frames.
|
||||
*/
|
||||
@ -896,11 +901,6 @@ static int pcan_usb_init(struct peak_usb_device *dev)
|
||||
"Firmware update available. Please contact support@peak-system.com\n");
|
||||
}
|
||||
|
||||
dev_info(dev->netdev->dev.parent,
|
||||
"PEAK-System %s adapter hwrev %u serial %08X (%u channel)\n",
|
||||
pcan_usb.name, dev->device_rev, serial_number,
|
||||
pcan_usb.ctrl_count);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -986,7 +986,6 @@ const struct peak_usb_adapter pcan_usb = {
|
||||
.device_id = PCAN_USB_PRODUCT_ID,
|
||||
.ctrl_count = 1,
|
||||
.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES | CAN_CTRLMODE_LISTENONLY |
|
||||
CAN_CTRLMODE_BERR_REPORTING |
|
||||
CAN_CTRLMODE_CC_LEN8_DLC,
|
||||
.clock = {
|
||||
.freq = PCAN_USB_CRYSTAL_HZ / 2,
|
||||
|
@ -640,7 +640,10 @@ static void mv88e6393x_phylink_validate(struct mv88e6xxx_chip *chip, int port,
|
||||
unsigned long *mask,
|
||||
struct phylink_link_state *state)
|
||||
{
|
||||
if (port == 0 || port == 9 || port == 10) {
|
||||
bool is_6191x =
|
||||
chip->info->prod_num == MV88E6XXX_PORT_SWITCH_ID_PROD_6191X;
|
||||
|
||||
if (((port == 0 || port == 9) && !is_6191x) || port == 10) {
|
||||
phylink_set(mask, 10000baseT_Full);
|
||||
phylink_set(mask, 10000baseKR_Full);
|
||||
phylink_set(mask, 10000baseCR_Full);
|
||||
|
@ -1370,12 +1370,12 @@ out:
|
||||
static bool felix_rxtstamp(struct dsa_switch *ds, int port,
|
||||
struct sk_buff *skb, unsigned int type)
|
||||
{
|
||||
u8 *extraction = skb->data - ETH_HLEN - OCELOT_TAG_LEN;
|
||||
u32 tstamp_lo = OCELOT_SKB_CB(skb)->tstamp_lo;
|
||||
struct skb_shared_hwtstamps *shhwtstamps;
|
||||
struct ocelot *ocelot = ds->priv;
|
||||
u32 tstamp_lo, tstamp_hi;
|
||||
struct timespec64 ts;
|
||||
u64 tstamp, val;
|
||||
u32 tstamp_hi;
|
||||
u64 tstamp;
|
||||
|
||||
/* If the "no XTR IRQ" workaround is in use, tell DSA to defer this skb
|
||||
* for RX timestamping. Then free it, and poll for its copy through
|
||||
@ -1390,9 +1390,6 @@ static bool felix_rxtstamp(struct dsa_switch *ds, int port,
|
||||
ocelot_ptp_gettime64(&ocelot->ptp_info, &ts);
|
||||
tstamp = ktime_set(ts.tv_sec, ts.tv_nsec);
|
||||
|
||||
ocelot_xfh_get_rew_val(extraction, &val);
|
||||
tstamp_lo = (u32)val;
|
||||
|
||||
tstamp_hi = tstamp >> 32;
|
||||
if ((tstamp & 0xffffffff) < tstamp_lo)
|
||||
tstamp_hi--;
|
||||
|
@ -1109,6 +1109,14 @@ qca8k_setup(struct dsa_switch *ds)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Make sure MAC06 is disabled */
|
||||
ret = qca8k_reg_clear(priv, QCA8K_REG_PORT0_PAD_CTRL,
|
||||
QCA8K_PORT0_PAD_MAC06_EXCHANGE_EN);
|
||||
if (ret) {
|
||||
dev_err(priv->dev, "failed disabling MAC06 exchange");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Enable CPU Port */
|
||||
ret = qca8k_reg_set(priv, QCA8K_REG_GLOBAL_FW_CTRL0,
|
||||
QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN);
|
||||
|
@ -34,6 +34,7 @@
|
||||
#define QCA8K_MASK_CTRL_DEVICE_ID_MASK GENMASK(15, 8)
|
||||
#define QCA8K_MASK_CTRL_DEVICE_ID(x) ((x) >> 8)
|
||||
#define QCA8K_REG_PORT0_PAD_CTRL 0x004
|
||||
#define QCA8K_PORT0_PAD_MAC06_EXCHANGE_EN BIT(31)
|
||||
#define QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE BIT(19)
|
||||
#define QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE BIT(18)
|
||||
#define QCA8K_REG_PORT5_PAD_CTRL 0x008
|
||||
|
@ -934,7 +934,7 @@ static const struct net_device_ops ax88796c_netdev_ops = {
|
||||
.ndo_stop = ax88796c_close,
|
||||
.ndo_start_xmit = ax88796c_start_xmit,
|
||||
.ndo_get_stats64 = ax88796c_get_stats64,
|
||||
.ndo_do_ioctl = ax88796c_ioctl,
|
||||
.ndo_eth_ioctl = ax88796c_ioctl,
|
||||
.ndo_set_mac_address = eth_mac_addr,
|
||||
.ndo_set_features = ax88796c_set_features,
|
||||
};
|
||||
@ -1114,11 +1114,13 @@ static int ax88796c_remove(struct spi_device *spi)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id ax88796c_dt_ids[] = {
|
||||
{ .compatible = "asix,ax88796c" },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, ax88796c_dt_ids);
|
||||
#endif
|
||||
|
||||
static const struct spi_device_id asix_id[] = {
|
||||
{ "ax88796c", 0 },
|
||||
|
@ -443,7 +443,7 @@ static int bnxt_dl_reload_down(struct devlink *dl, bool netns_change,
|
||||
case DEVLINK_RELOAD_ACTION_DRIVER_REINIT: {
|
||||
if (BNXT_PF(bp) && bp->pf.active_vfs) {
|
||||
NL_SET_ERR_MSG_MOD(extack,
|
||||
"reload is unsupported when VFs are allocated\n");
|
||||
"reload is unsupported when VFs are allocated");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
rtnl_lock();
|
||||
|
@ -5503,7 +5503,6 @@ static bool tg3_setup_fiber_hw_autoneg(struct tg3 *tp, u32 mac_status)
|
||||
int workaround, port_a;
|
||||
|
||||
serdes_cfg = 0;
|
||||
expected_sg_dig_ctrl = 0;
|
||||
workaround = 0;
|
||||
port_a = 1;
|
||||
current_link_up = false;
|
||||
|
@ -2015,12 +2015,15 @@ static int cxgb4_get_module_info(struct net_device *dev,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!sff8472_comp || (sff_diag_type & 4)) {
|
||||
if (!sff8472_comp || (sff_diag_type & SFP_DIAG_ADDRMODE)) {
|
||||
modinfo->type = ETH_MODULE_SFF_8079;
|
||||
modinfo->eeprom_len = ETH_MODULE_SFF_8079_LEN;
|
||||
} else {
|
||||
modinfo->type = ETH_MODULE_SFF_8472;
|
||||
modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN;
|
||||
if (sff_diag_type & SFP_DIAG_IMPLEMENTED)
|
||||
modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN;
|
||||
else
|
||||
modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN / 2;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -293,6 +293,8 @@ enum {
|
||||
#define I2C_PAGE_SIZE 0x100
|
||||
#define SFP_DIAG_TYPE_ADDR 0x5c
|
||||
#define SFP_DIAG_TYPE_LEN 0x1
|
||||
#define SFP_DIAG_ADDRMODE BIT(2)
|
||||
#define SFP_DIAG_IMPLEMENTED BIT(6)
|
||||
#define SFF_8472_COMP_ADDR 0x5e
|
||||
#define SFF_8472_COMP_LEN 0x1
|
||||
#define SFF_REV_ADDR 0x1
|
||||
|
@ -1137,7 +1137,7 @@ static void gve_tx_timeout(struct net_device *dev, unsigned int txqueue)
|
||||
goto reset;
|
||||
|
||||
ntfy_idx = gve_tx_idx_to_ntfy(priv, txqueue);
|
||||
if (ntfy_idx > priv->num_ntfy_blks)
|
||||
if (ntfy_idx >= priv->num_ntfy_blks)
|
||||
goto reset;
|
||||
|
||||
block = &priv->ntfy_blocks[ntfy_idx];
|
||||
|
@ -500,7 +500,8 @@ static struct sk_buff *gve_rx_skb(struct gve_priv *priv, struct gve_rx_ring *rx,
|
||||
rx->rx_copied_pkt++;
|
||||
rx->rx_frag_copy_cnt++;
|
||||
rx->rx_copybreak_pkt++;
|
||||
} u64_stats_update_end(&rx->statss);
|
||||
u64_stats_update_end(&rx->statss);
|
||||
}
|
||||
} else {
|
||||
if (rx->data.raw_addressing) {
|
||||
int recycle = gve_rx_can_recycle_buffer(page_info);
|
||||
|
@ -4210,6 +4210,13 @@ int hns3_clean_rx_ring(struct hns3_enet_ring *ring, int budget,
|
||||
}
|
||||
|
||||
out:
|
||||
/* sync head pointer before exiting, since hardware will calculate
|
||||
* FBD number with head pointer
|
||||
*/
|
||||
if (unused_count > 0)
|
||||
failure = failure ||
|
||||
hns3_nic_alloc_rx_buffers(ring, unused_count);
|
||||
|
||||
return failure ? budget : recv_pkts;
|
||||
}
|
||||
|
||||
|
@ -238,9 +238,11 @@ static void hns3_lb_clear_tx_ring(struct hns3_nic_priv *priv, u32 start_ringid,
|
||||
}
|
||||
|
||||
/**
|
||||
* hns3_lp_run_test - run loopback test
|
||||
* hns3_lp_run_test - run loopback test
|
||||
* @ndev: net device
|
||||
* @mode: loopback type
|
||||
*
|
||||
* Return: %0 for success or a NIC loopback test error code on failure
|
||||
*/
|
||||
static int hns3_lp_run_test(struct net_device *ndev, enum hnae3_loop mode)
|
||||
{
|
||||
@ -398,7 +400,7 @@ static void hns3_do_selftest(struct net_device *ndev, int (*st_param)[2],
|
||||
}
|
||||
|
||||
/**
|
||||
* hns3_nic_self_test - self test
|
||||
* hns3_self_test - self test
|
||||
* @ndev: net device
|
||||
* @eth_test: test cmd
|
||||
* @data: test result
|
||||
|
@ -483,6 +483,7 @@ static int hclge_firmware_compat_config(struct hclge_dev *hdev, bool en)
|
||||
if (hnae3_dev_phy_imp_supported(hdev))
|
||||
hnae3_set_bit(compat, HCLGE_PHY_IMP_EN_B, 1);
|
||||
hnae3_set_bit(compat, HCLGE_MAC_STATS_EXT_EN_B, 1);
|
||||
hnae3_set_bit(compat, HCLGE_SYNC_RX_RING_HEAD_EN_B, 1);
|
||||
|
||||
req->compat = cpu_to_le32(compat);
|
||||
}
|
||||
|
@ -1151,6 +1151,7 @@ struct hclge_query_ppu_pf_other_int_dfx_cmd {
|
||||
#define HCLGE_NCSI_ERROR_REPORT_EN_B 1
|
||||
#define HCLGE_PHY_IMP_EN_B 2
|
||||
#define HCLGE_MAC_STATS_EXT_EN_B 3
|
||||
#define HCLGE_SYNC_RX_RING_HEAD_EN_B 4
|
||||
struct hclge_firmware_compat_cmd {
|
||||
__le32 compat;
|
||||
u8 rsv[20];
|
||||
|
@ -129,7 +129,7 @@ static int hclge_ets_sch_mode_validate(struct hclge_dev *hdev,
|
||||
u32 total_ets_bw = 0;
|
||||
u8 i;
|
||||
|
||||
for (i = 0; i < hdev->tc_max; i++) {
|
||||
for (i = 0; i < HNAE3_MAX_TC; i++) {
|
||||
switch (ets->tc_tsa[i]) {
|
||||
case IEEE_8021QAZ_TSA_STRICT:
|
||||
if (hdev->tm_info.tc_info[i].tc_sch_mode !=
|
||||
@ -286,28 +286,24 @@ err_out:
|
||||
|
||||
static int hclge_ieee_getpfc(struct hnae3_handle *h, struct ieee_pfc *pfc)
|
||||
{
|
||||
u64 requests[HNAE3_MAX_TC], indications[HNAE3_MAX_TC];
|
||||
struct hclge_vport *vport = hclge_get_vport(h);
|
||||
struct hclge_dev *hdev = vport->back;
|
||||
int ret;
|
||||
u8 i;
|
||||
|
||||
memset(pfc, 0, sizeof(*pfc));
|
||||
pfc->pfc_cap = hdev->pfc_max;
|
||||
pfc->pfc_en = hdev->tm_info.pfc_en;
|
||||
|
||||
ret = hclge_pfc_tx_stats_get(hdev, requests);
|
||||
if (ret)
|
||||
ret = hclge_mac_update_stats(hdev);
|
||||
if (ret) {
|
||||
dev_err(&hdev->pdev->dev,
|
||||
"failed to update MAC stats, ret = %d.\n", ret);
|
||||
return ret;
|
||||
|
||||
ret = hclge_pfc_rx_stats_get(hdev, indications);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
for (i = 0; i < HCLGE_MAX_TC_NUM; i++) {
|
||||
pfc->requests[i] = requests[i];
|
||||
pfc->indications[i] = indications[i];
|
||||
}
|
||||
|
||||
hclge_pfc_tx_stats_get(hdev, pfc->requests);
|
||||
hclge_pfc_rx_stats_get(hdev, pfc->indications);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -26,8 +26,6 @@
|
||||
#include "hclge_devlink.h"
|
||||
|
||||
#define HCLGE_NAME "hclge"
|
||||
#define HCLGE_STATS_READ(p, offset) (*(u64 *)((u8 *)(p) + (offset)))
|
||||
#define HCLGE_MAC_STATS_FIELD_OFF(f) (offsetof(struct hclge_mac_stats, f))
|
||||
|
||||
#define HCLGE_BUF_SIZE_UNIT 256U
|
||||
#define HCLGE_BUF_MUL_BY 2
|
||||
@ -568,6 +566,16 @@ static int hclge_mac_query_reg_num(struct hclge_dev *hdev, u32 *reg_num)
|
||||
struct hclge_desc desc;
|
||||
int ret;
|
||||
|
||||
/* Driver needs total register number of both valid registers and
|
||||
* reserved registers, but the old firmware only returns number
|
||||
* of valid registers in device V2. To be compatible with these
|
||||
* devices, driver uses a fixed value.
|
||||
*/
|
||||
if (hdev->ae_dev->dev_version == HNAE3_DEVICE_VERSION_V2) {
|
||||
*reg_num = HCLGE_MAC_STATS_MAX_NUM_V1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_QUERY_MAC_REG_NUM, true);
|
||||
ret = hclge_cmd_send(&hdev->hw, &desc, 1);
|
||||
if (ret) {
|
||||
@ -587,7 +595,7 @@ static int hclge_mac_query_reg_num(struct hclge_dev *hdev, u32 *reg_num)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hclge_mac_update_stats(struct hclge_dev *hdev)
|
||||
int hclge_mac_update_stats(struct hclge_dev *hdev)
|
||||
{
|
||||
/* The firmware supports the new statistics acquisition method */
|
||||
if (hdev->ae_dev->dev_specs.mac_stats_num)
|
||||
@ -2581,7 +2589,7 @@ static int hclge_init_roce_base_info(struct hclge_vport *vport)
|
||||
if (hdev->num_msi < hdev->num_nic_msi + hdev->num_roce_msi)
|
||||
return -EINVAL;
|
||||
|
||||
roce->rinfo.base_vector = hdev->roce_base_vector;
|
||||
roce->rinfo.base_vector = hdev->num_nic_msi;
|
||||
|
||||
roce->rinfo.netdev = nic->kinfo.netdev;
|
||||
roce->rinfo.roce_io_base = hdev->hw.io_base;
|
||||
@ -2617,10 +2625,6 @@ static int hclge_init_msi(struct hclge_dev *hdev)
|
||||
hdev->num_msi = vectors;
|
||||
hdev->num_msi_left = vectors;
|
||||
|
||||
hdev->base_msi_vector = pdev->irq;
|
||||
hdev->roce_base_vector = hdev->base_msi_vector +
|
||||
hdev->num_nic_msi;
|
||||
|
||||
hdev->vector_status = devm_kcalloc(&pdev->dev, hdev->num_msi,
|
||||
sizeof(u16), GFP_KERNEL);
|
||||
if (!hdev->vector_status) {
|
||||
@ -8949,8 +8953,11 @@ int hclge_add_mc_addr_common(struct hclge_vport *vport,
|
||||
|
||||
err_no_space:
|
||||
/* if already overflow, not to print each time */
|
||||
if (!(vport->overflow_promisc_flags & HNAE3_OVERFLOW_MPE))
|
||||
if (!(vport->overflow_promisc_flags & HNAE3_OVERFLOW_MPE)) {
|
||||
vport->overflow_promisc_flags |= HNAE3_OVERFLOW_MPE;
|
||||
dev_err(&hdev->pdev->dev, "mc mac vlan table is full\n");
|
||||
}
|
||||
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
@ -9006,12 +9013,17 @@ int hclge_rm_mc_addr_common(struct hclge_vport *vport,
|
||||
|
||||
static void hclge_sync_vport_mac_list(struct hclge_vport *vport,
|
||||
struct list_head *list,
|
||||
int (*sync)(struct hclge_vport *,
|
||||
const unsigned char *))
|
||||
enum HCLGE_MAC_ADDR_TYPE mac_type)
|
||||
{
|
||||
int (*sync)(struct hclge_vport *vport, const unsigned char *addr);
|
||||
struct hclge_mac_node *mac_node, *tmp;
|
||||
int ret;
|
||||
|
||||
if (mac_type == HCLGE_MAC_ADDR_UC)
|
||||
sync = hclge_add_uc_addr_common;
|
||||
else
|
||||
sync = hclge_add_mc_addr_common;
|
||||
|
||||
list_for_each_entry_safe(mac_node, tmp, list, node) {
|
||||
ret = sync(vport, mac_node->mac_addr);
|
||||
if (!ret) {
|
||||
@ -9023,8 +9035,13 @@ static void hclge_sync_vport_mac_list(struct hclge_vport *vport,
|
||||
/* If one unicast mac address is existing in hardware,
|
||||
* we need to try whether other unicast mac addresses
|
||||
* are new addresses that can be added.
|
||||
* Multicast mac address can be reusable, even though
|
||||
* there is no space to add new multicast mac address,
|
||||
* we should check whether other mac addresses are
|
||||
* existing in hardware for reuse.
|
||||
*/
|
||||
if (ret != -EEXIST)
|
||||
if ((mac_type == HCLGE_MAC_ADDR_UC && ret != -EEXIST) ||
|
||||
(mac_type == HCLGE_MAC_ADDR_MC && ret != -ENOSPC))
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -9032,12 +9049,17 @@ static void hclge_sync_vport_mac_list(struct hclge_vport *vport,
|
||||
|
||||
static void hclge_unsync_vport_mac_list(struct hclge_vport *vport,
|
||||
struct list_head *list,
|
||||
int (*unsync)(struct hclge_vport *,
|
||||
const unsigned char *))
|
||||
enum HCLGE_MAC_ADDR_TYPE mac_type)
|
||||
{
|
||||
int (*unsync)(struct hclge_vport *vport, const unsigned char *addr);
|
||||
struct hclge_mac_node *mac_node, *tmp;
|
||||
int ret;
|
||||
|
||||
if (mac_type == HCLGE_MAC_ADDR_UC)
|
||||
unsync = hclge_rm_uc_addr_common;
|
||||
else
|
||||
unsync = hclge_rm_mc_addr_common;
|
||||
|
||||
list_for_each_entry_safe(mac_node, tmp, list, node) {
|
||||
ret = unsync(vport, mac_node->mac_addr);
|
||||
if (!ret || ret == -ENOENT) {
|
||||
@ -9168,17 +9190,8 @@ stop_traverse:
|
||||
spin_unlock_bh(&vport->mac_list_lock);
|
||||
|
||||
/* delete first, in order to get max mac table space for adding */
|
||||
if (mac_type == HCLGE_MAC_ADDR_UC) {
|
||||
hclge_unsync_vport_mac_list(vport, &tmp_del_list,
|
||||
hclge_rm_uc_addr_common);
|
||||
hclge_sync_vport_mac_list(vport, &tmp_add_list,
|
||||
hclge_add_uc_addr_common);
|
||||
} else {
|
||||
hclge_unsync_vport_mac_list(vport, &tmp_del_list,
|
||||
hclge_rm_mc_addr_common);
|
||||
hclge_sync_vport_mac_list(vport, &tmp_add_list,
|
||||
hclge_add_mc_addr_common);
|
||||
}
|
||||
hclge_unsync_vport_mac_list(vport, &tmp_del_list, mac_type);
|
||||
hclge_sync_vport_mac_list(vport, &tmp_add_list, mac_type);
|
||||
|
||||
/* if some mac addresses were added/deleted fail, move back to the
|
||||
* mac_list, and retry at next time.
|
||||
@ -9337,12 +9350,7 @@ static void hclge_uninit_vport_mac_list(struct hclge_vport *vport,
|
||||
|
||||
spin_unlock_bh(&vport->mac_list_lock);
|
||||
|
||||
if (mac_type == HCLGE_MAC_ADDR_UC)
|
||||
hclge_unsync_vport_mac_list(vport, &tmp_del_list,
|
||||
hclge_rm_uc_addr_common);
|
||||
else
|
||||
hclge_unsync_vport_mac_list(vport, &tmp_del_list,
|
||||
hclge_rm_mc_addr_common);
|
||||
hclge_unsync_vport_mac_list(vport, &tmp_del_list, mac_type);
|
||||
|
||||
if (!list_empty(&tmp_del_list))
|
||||
dev_warn(&hdev->pdev->dev,
|
||||
@ -9410,36 +9418,6 @@ static int hclge_get_mac_ethertype_cmd_status(struct hclge_dev *hdev,
|
||||
return return_status;
|
||||
}
|
||||
|
||||
static bool hclge_check_vf_mac_exist(struct hclge_vport *vport, int vf_idx,
|
||||
u8 *mac_addr)
|
||||
{
|
||||
struct hclge_mac_vlan_tbl_entry_cmd req;
|
||||
struct hclge_dev *hdev = vport->back;
|
||||
struct hclge_desc desc;
|
||||
u16 egress_port = 0;
|
||||
int i;
|
||||
|
||||
if (is_zero_ether_addr(mac_addr))
|
||||
return false;
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
hnae3_set_field(egress_port, HCLGE_MAC_EPORT_VFID_M,
|
||||
HCLGE_MAC_EPORT_VFID_S, vport->vport_id);
|
||||
req.egress_port = cpu_to_le16(egress_port);
|
||||
hclge_prepare_mac_addr(&req, mac_addr, false);
|
||||
|
||||
if (hclge_lookup_mac_vlan_tbl(vport, &req, &desc, false) != -ENOENT)
|
||||
return true;
|
||||
|
||||
vf_idx += HCLGE_VF_VPORT_START_NUM;
|
||||
for (i = HCLGE_VF_VPORT_START_NUM; i < hdev->num_alloc_vport; i++)
|
||||
if (i != vf_idx &&
|
||||
ether_addr_equal(mac_addr, hdev->vport[i].vf_info.mac))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int hclge_set_vf_mac(struct hnae3_handle *handle, int vf,
|
||||
u8 *mac_addr)
|
||||
{
|
||||
@ -9457,12 +9435,6 @@ static int hclge_set_vf_mac(struct hnae3_handle *handle, int vf,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (hclge_check_vf_mac_exist(vport, vf, mac_addr)) {
|
||||
dev_err(&hdev->pdev->dev, "Specified MAC(=%pM) exists!\n",
|
||||
mac_addr);
|
||||
return -EEXIST;
|
||||
}
|
||||
|
||||
ether_addr_copy(vport->vf_info.mac, mac_addr);
|
||||
|
||||
if (test_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state)) {
|
||||
|
@ -404,7 +404,7 @@ struct hclge_tm_info {
|
||||
};
|
||||
|
||||
/* max number of mac statistics on each version */
|
||||
#define HCLGE_MAC_STATS_MAX_NUM_V1 84
|
||||
#define HCLGE_MAC_STATS_MAX_NUM_V1 87
|
||||
#define HCLGE_MAC_STATS_MAX_NUM_V2 105
|
||||
|
||||
struct hclge_comm_stats_str {
|
||||
@ -852,6 +852,9 @@ struct hclge_vf_vlan_cfg {
|
||||
(y) = (_k_ ^ ~_v_) & (_k_); \
|
||||
} while (0)
|
||||
|
||||
#define HCLGE_MAC_STATS_FIELD_OFF(f) (offsetof(struct hclge_mac_stats, f))
|
||||
#define HCLGE_STATS_READ(p, offset) (*(u64 *)((u8 *)(p) + (offset)))
|
||||
|
||||
#define HCLGE_MAC_TNL_LOG_SIZE 8
|
||||
#define HCLGE_VPORT_NUM 256
|
||||
struct hclge_dev {
|
||||
@ -904,12 +907,10 @@ struct hclge_dev {
|
||||
u16 num_msi;
|
||||
u16 num_msi_left;
|
||||
u16 num_msi_used;
|
||||
u32 base_msi_vector;
|
||||
u16 *vector_status;
|
||||
int *vector_irq;
|
||||
u16 num_nic_msi; /* Num of nic vectors for this PF */
|
||||
u16 num_roce_msi; /* Num of roce vectors for this PF */
|
||||
int roce_base_vector;
|
||||
|
||||
unsigned long service_timer_period;
|
||||
unsigned long service_timer_previous;
|
||||
@ -1168,4 +1169,5 @@ void hclge_inform_vf_promisc_info(struct hclge_vport *vport);
|
||||
int hclge_dbg_dump_rst_info(struct hclge_dev *hdev, char *buf, int len);
|
||||
int hclge_push_vf_link_status(struct hclge_vport *vport);
|
||||
int hclge_enable_vport_vlan_filter(struct hclge_vport *vport, bool request_en);
|
||||
int hclge_mac_update_stats(struct hclge_dev *hdev);
|
||||
#endif
|
||||
|
@ -113,50 +113,50 @@ static int hclge_shaper_para_calc(u32 ir, u8 shaper_level,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hclge_pfc_stats_get(struct hclge_dev *hdev,
|
||||
enum hclge_opcode_type opcode, u64 *stats)
|
||||
static const u16 hclge_pfc_tx_stats_offset[] = {
|
||||
HCLGE_MAC_STATS_FIELD_OFF(mac_tx_pfc_pri0_pkt_num),
|
||||
HCLGE_MAC_STATS_FIELD_OFF(mac_tx_pfc_pri1_pkt_num),
|
||||
HCLGE_MAC_STATS_FIELD_OFF(mac_tx_pfc_pri2_pkt_num),
|
||||
HCLGE_MAC_STATS_FIELD_OFF(mac_tx_pfc_pri3_pkt_num),
|
||||
HCLGE_MAC_STATS_FIELD_OFF(mac_tx_pfc_pri4_pkt_num),
|
||||
HCLGE_MAC_STATS_FIELD_OFF(mac_tx_pfc_pri5_pkt_num),
|
||||
HCLGE_MAC_STATS_FIELD_OFF(mac_tx_pfc_pri6_pkt_num),
|
||||
HCLGE_MAC_STATS_FIELD_OFF(mac_tx_pfc_pri7_pkt_num)
|
||||
};
|
||||
|
||||
static const u16 hclge_pfc_rx_stats_offset[] = {
|
||||
HCLGE_MAC_STATS_FIELD_OFF(mac_rx_pfc_pri0_pkt_num),
|
||||
HCLGE_MAC_STATS_FIELD_OFF(mac_rx_pfc_pri1_pkt_num),
|
||||
HCLGE_MAC_STATS_FIELD_OFF(mac_rx_pfc_pri2_pkt_num),
|
||||
HCLGE_MAC_STATS_FIELD_OFF(mac_rx_pfc_pri3_pkt_num),
|
||||
HCLGE_MAC_STATS_FIELD_OFF(mac_rx_pfc_pri4_pkt_num),
|
||||
HCLGE_MAC_STATS_FIELD_OFF(mac_rx_pfc_pri5_pkt_num),
|
||||
HCLGE_MAC_STATS_FIELD_OFF(mac_rx_pfc_pri6_pkt_num),
|
||||
HCLGE_MAC_STATS_FIELD_OFF(mac_rx_pfc_pri7_pkt_num)
|
||||
};
|
||||
|
||||
static void hclge_pfc_stats_get(struct hclge_dev *hdev, bool tx, u64 *stats)
|
||||
{
|
||||
struct hclge_desc desc[HCLGE_TM_PFC_PKT_GET_CMD_NUM];
|
||||
int ret, i, j;
|
||||
const u16 *offset;
|
||||
int i;
|
||||
|
||||
if (!(opcode == HCLGE_OPC_QUERY_PFC_RX_PKT_CNT ||
|
||||
opcode == HCLGE_OPC_QUERY_PFC_TX_PKT_CNT))
|
||||
return -EINVAL;
|
||||
if (tx)
|
||||
offset = hclge_pfc_tx_stats_offset;
|
||||
else
|
||||
offset = hclge_pfc_rx_stats_offset;
|
||||
|
||||
for (i = 0; i < HCLGE_TM_PFC_PKT_GET_CMD_NUM - 1; i++) {
|
||||
hclge_cmd_setup_basic_desc(&desc[i], opcode, true);
|
||||
desc[i].flag |= cpu_to_le16(HCLGE_CMD_FLAG_NEXT);
|
||||
}
|
||||
|
||||
hclge_cmd_setup_basic_desc(&desc[i], opcode, true);
|
||||
|
||||
ret = hclge_cmd_send(&hdev->hw, desc, HCLGE_TM_PFC_PKT_GET_CMD_NUM);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
for (i = 0; i < HCLGE_TM_PFC_PKT_GET_CMD_NUM; i++) {
|
||||
struct hclge_pfc_stats_cmd *pfc_stats =
|
||||
(struct hclge_pfc_stats_cmd *)desc[i].data;
|
||||
|
||||
for (j = 0; j < HCLGE_TM_PFC_NUM_GET_PER_CMD; j++) {
|
||||
u32 index = i * HCLGE_TM_PFC_PKT_GET_CMD_NUM + j;
|
||||
|
||||
if (index < HCLGE_MAX_TC_NUM)
|
||||
stats[index] =
|
||||
le64_to_cpu(pfc_stats->pkt_num[j]);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
for (i = 0; i < HCLGE_MAX_TC_NUM; i++)
|
||||
stats[i] = HCLGE_STATS_READ(&hdev->mac_stats, offset[i]);
|
||||
}
|
||||
|
||||
int hclge_pfc_rx_stats_get(struct hclge_dev *hdev, u64 *stats)
|
||||
void hclge_pfc_rx_stats_get(struct hclge_dev *hdev, u64 *stats)
|
||||
{
|
||||
return hclge_pfc_stats_get(hdev, HCLGE_OPC_QUERY_PFC_RX_PKT_CNT, stats);
|
||||
hclge_pfc_stats_get(hdev, false, stats);
|
||||
}
|
||||
|
||||
int hclge_pfc_tx_stats_get(struct hclge_dev *hdev, u64 *stats)
|
||||
void hclge_pfc_tx_stats_get(struct hclge_dev *hdev, u64 *stats)
|
||||
{
|
||||
return hclge_pfc_stats_get(hdev, HCLGE_OPC_QUERY_PFC_TX_PKT_CNT, stats);
|
||||
hclge_pfc_stats_get(hdev, true, stats);
|
||||
}
|
||||
|
||||
int hclge_mac_pause_en_cfg(struct hclge_dev *hdev, bool tx, bool rx)
|
||||
@ -1123,7 +1123,6 @@ static int hclge_tm_pri_tc_base_dwrr_cfg(struct hclge_dev *hdev)
|
||||
|
||||
static int hclge_tm_ets_tc_dwrr_cfg(struct hclge_dev *hdev)
|
||||
{
|
||||
#define DEFAULT_TC_WEIGHT 1
|
||||
#define DEFAULT_TC_OFFSET 14
|
||||
|
||||
struct hclge_ets_tc_weight_cmd *ets_weight;
|
||||
@ -1136,13 +1135,7 @@ static int hclge_tm_ets_tc_dwrr_cfg(struct hclge_dev *hdev)
|
||||
for (i = 0; i < HNAE3_MAX_TC; i++) {
|
||||
struct hclge_pg_info *pg_info;
|
||||
|
||||
ets_weight->tc_weight[i] = DEFAULT_TC_WEIGHT;
|
||||
|
||||
if (!(hdev->hw_tc_map & BIT(i)))
|
||||
continue;
|
||||
|
||||
pg_info =
|
||||
&hdev->tm_info.pg_info[hdev->tm_info.tc_info[i].pgid];
|
||||
pg_info = &hdev->tm_info.pg_info[hdev->tm_info.tc_info[i].pgid];
|
||||
ets_weight->tc_weight[i] = pg_info->tc_dwrr[i];
|
||||
}
|
||||
|
||||
|
@ -228,8 +228,8 @@ int hclge_tm_dwrr_cfg(struct hclge_dev *hdev);
|
||||
int hclge_tm_init_hw(struct hclge_dev *hdev, bool init);
|
||||
int hclge_mac_pause_en_cfg(struct hclge_dev *hdev, bool tx, bool rx);
|
||||
int hclge_pause_addr_cfg(struct hclge_dev *hdev, const u8 *mac_addr);
|
||||
int hclge_pfc_rx_stats_get(struct hclge_dev *hdev, u64 *stats);
|
||||
int hclge_pfc_tx_stats_get(struct hclge_dev *hdev, u64 *stats);
|
||||
void hclge_pfc_rx_stats_get(struct hclge_dev *hdev, u64 *stats);
|
||||
void hclge_pfc_tx_stats_get(struct hclge_dev *hdev, u64 *stats);
|
||||
int hclge_tm_qs_shaper_cfg(struct hclge_vport *vport, int max_tx_rate);
|
||||
int hclge_tm_get_qset_num(struct hclge_dev *hdev, u16 *qset_num);
|
||||
int hclge_tm_get_pri_num(struct hclge_dev *hdev, u8 *pri_num);
|
||||
|
@ -434,8 +434,28 @@ err_csq:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int hclgevf_firmware_compat_config(struct hclgevf_dev *hdev, bool en)
|
||||
{
|
||||
struct hclgevf_firmware_compat_cmd *req;
|
||||
struct hclgevf_desc desc;
|
||||
u32 compat = 0;
|
||||
|
||||
hclgevf_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_IMP_COMPAT_CFG, false);
|
||||
|
||||
if (en) {
|
||||
req = (struct hclgevf_firmware_compat_cmd *)desc.data;
|
||||
|
||||
hnae3_set_bit(compat, HCLGEVF_SYNC_RX_RING_HEAD_EN_B, 1);
|
||||
|
||||
req->compat = cpu_to_le32(compat);
|
||||
}
|
||||
|
||||
return hclgevf_cmd_send(&hdev->hw, &desc, 1);
|
||||
}
|
||||
|
||||
int hclgevf_cmd_init(struct hclgevf_dev *hdev)
|
||||
{
|
||||
struct hnae3_ae_dev *ae_dev = pci_get_drvdata(hdev->pdev);
|
||||
int ret;
|
||||
|
||||
spin_lock_bh(&hdev->hw.cmq.csq.lock);
|
||||
@ -484,6 +504,17 @@ int hclgevf_cmd_init(struct hclgevf_dev *hdev)
|
||||
hnae3_get_field(hdev->fw_version, HNAE3_FW_VERSION_BYTE0_MASK,
|
||||
HNAE3_FW_VERSION_BYTE0_SHIFT));
|
||||
|
||||
if (ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V3) {
|
||||
/* ask the firmware to enable some features, driver can work
|
||||
* without it.
|
||||
*/
|
||||
ret = hclgevf_firmware_compat_config(hdev, true);
|
||||
if (ret)
|
||||
dev_warn(&hdev->pdev->dev,
|
||||
"Firmware compatible features not enabled(%d).\n",
|
||||
ret);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_cmd_init:
|
||||
@ -508,6 +539,7 @@ static void hclgevf_cmd_uninit_regs(struct hclgevf_hw *hw)
|
||||
|
||||
void hclgevf_cmd_uninit(struct hclgevf_dev *hdev)
|
||||
{
|
||||
hclgevf_firmware_compat_config(hdev, false);
|
||||
set_bit(HCLGEVF_STATE_CMD_DISABLE, &hdev->state);
|
||||
/* wait to ensure that the firmware completes the possible left
|
||||
* over commands.
|
||||
|
@ -15,6 +15,12 @@
|
||||
struct hclgevf_hw;
|
||||
struct hclgevf_dev;
|
||||
|
||||
#define HCLGEVF_SYNC_RX_RING_HEAD_EN_B 4
|
||||
struct hclgevf_firmware_compat_cmd {
|
||||
__le32 compat;
|
||||
u8 rsv[20];
|
||||
};
|
||||
|
||||
struct hclgevf_desc {
|
||||
__le16 opcode;
|
||||
__le16 flag;
|
||||
@ -107,6 +113,9 @@ enum hclgevf_opcode_type {
|
||||
HCLGEVF_OPC_RSS_TC_MODE = 0x0D08,
|
||||
/* Mailbox cmd */
|
||||
HCLGEVF_OPC_MBX_VF_TO_PF = 0x2001,
|
||||
|
||||
/* IMP stats command */
|
||||
HCLGEVF_OPC_IMP_COMPAT_CFG = 0x701A,
|
||||
};
|
||||
|
||||
#define HCLGEVF_TQP_REG_OFFSET 0x80000
|
||||
|
@ -2557,7 +2557,7 @@ static int hclgevf_init_roce_base_info(struct hclgevf_dev *hdev)
|
||||
hdev->num_msi_left == 0)
|
||||
return -EINVAL;
|
||||
|
||||
roce->rinfo.base_vector = hdev->roce_base_vector;
|
||||
roce->rinfo.base_vector = hdev->roce_base_msix_offset;
|
||||
|
||||
roce->rinfo.netdev = nic->kinfo.netdev;
|
||||
roce->rinfo.roce_io_base = hdev->hw.io_base;
|
||||
@ -2823,9 +2823,6 @@ static int hclgevf_init_msi(struct hclgevf_dev *hdev)
|
||||
hdev->num_msi = vectors;
|
||||
hdev->num_msi_left = vectors;
|
||||
|
||||
hdev->base_msi_vector = pdev->irq;
|
||||
hdev->roce_base_vector = pdev->irq + hdev->roce_base_msix_offset;
|
||||
|
||||
hdev->vector_status = devm_kcalloc(&pdev->dev, hdev->num_msi,
|
||||
sizeof(u16), GFP_KERNEL);
|
||||
if (!hdev->vector_status) {
|
||||
@ -3013,7 +3010,10 @@ static void hclgevf_uninit_client_instance(struct hnae3_client *client,
|
||||
|
||||
/* un-init roce, if it exists */
|
||||
if (hdev->roce_client) {
|
||||
while (test_bit(HCLGEVF_STATE_RST_HANDLING, &hdev->state))
|
||||
msleep(HCLGEVF_WAIT_RESET_DONE);
|
||||
clear_bit(HCLGEVF_STATE_ROCE_REGISTERED, &hdev->state);
|
||||
|
||||
hdev->roce_client->ops->uninit_instance(&hdev->roce, 0);
|
||||
hdev->roce_client = NULL;
|
||||
hdev->roce.client = NULL;
|
||||
@ -3022,6 +3022,8 @@ static void hclgevf_uninit_client_instance(struct hnae3_client *client,
|
||||
/* un-init nic/unic, if this was not called by roce client */
|
||||
if (client->ops->uninit_instance && hdev->nic_client &&
|
||||
client->type != HNAE3_CLIENT_ROCE) {
|
||||
while (test_bit(HCLGEVF_STATE_RST_HANDLING, &hdev->state))
|
||||
msleep(HCLGEVF_WAIT_RESET_DONE);
|
||||
clear_bit(HCLGEVF_STATE_NIC_REGISTERED, &hdev->state);
|
||||
|
||||
client->ops->uninit_instance(&hdev->nic, 0);
|
||||
|
@ -109,6 +109,8 @@
|
||||
#define HCLGEVF_VF_RST_ING 0x07008
|
||||
#define HCLGEVF_VF_RST_ING_BIT BIT(16)
|
||||
|
||||
#define HCLGEVF_WAIT_RESET_DONE 100
|
||||
|
||||
#define HCLGEVF_RSS_IND_TBL_SIZE 512
|
||||
#define HCLGEVF_RSS_SET_BITMAP_MSK 0xffff
|
||||
#define HCLGEVF_RSS_KEY_SIZE 40
|
||||
@ -308,8 +310,6 @@ struct hclgevf_dev {
|
||||
u16 num_nic_msix; /* Num of nic vectors for this VF */
|
||||
u16 num_roce_msix; /* Num of roce vectors for this VF */
|
||||
u16 roce_base_msix_offset;
|
||||
int roce_base_vector;
|
||||
u32 base_msi_vector;
|
||||
u16 *vector_status;
|
||||
int *vector_irq;
|
||||
|
||||
|
@ -165,13 +165,10 @@
|
||||
#define ice_for_each_chnl_tc(i) \
|
||||
for ((i) = ICE_CHNL_START_TC; (i) < ICE_CHNL_MAX_TC; (i)++)
|
||||
|
||||
#define ICE_UCAST_PROMISC_BITS (ICE_PROMISC_UCAST_TX | ICE_PROMISC_MCAST_TX | \
|
||||
ICE_PROMISC_UCAST_RX | ICE_PROMISC_MCAST_RX)
|
||||
#define ICE_UCAST_PROMISC_BITS (ICE_PROMISC_UCAST_TX | ICE_PROMISC_UCAST_RX)
|
||||
|
||||
#define ICE_UCAST_VLAN_PROMISC_BITS (ICE_PROMISC_UCAST_TX | \
|
||||
ICE_PROMISC_MCAST_TX | \
|
||||
ICE_PROMISC_UCAST_RX | \
|
||||
ICE_PROMISC_MCAST_RX | \
|
||||
ICE_PROMISC_VLAN_TX | \
|
||||
ICE_PROMISC_VLAN_RX)
|
||||
|
||||
|
@ -962,7 +962,7 @@ ice_vsi_stop_tx_ring(struct ice_vsi *vsi, enum ice_disq_rst_src rst_src,
|
||||
} else if (status == ICE_ERR_DOES_NOT_EXIST) {
|
||||
dev_dbg(ice_pf_to_dev(vsi->back), "LAN Tx queues do not exist, nothing to disable\n");
|
||||
} else if (status) {
|
||||
dev_err(ice_pf_to_dev(vsi->back), "Failed to disable LAN Tx queues, error: %s\n",
|
||||
dev_dbg(ice_pf_to_dev(vsi->back), "Failed to disable LAN Tx queues, error: %s\n",
|
||||
ice_stat_str(status));
|
||||
return -ENODEV;
|
||||
}
|
||||
|
@ -638,8 +638,7 @@ void ice_free_vfs(struct ice_pf *pf)
|
||||
|
||||
/* Avoid wait time by stopping all VFs at the same time */
|
||||
ice_for_each_vf(pf, i)
|
||||
if (test_bit(ICE_VF_STATE_QS_ENA, pf->vf[i].vf_states))
|
||||
ice_dis_vf_qs(&pf->vf[i]);
|
||||
ice_dis_vf_qs(&pf->vf[i]);
|
||||
|
||||
tmp = pf->num_alloc_vfs;
|
||||
pf->num_qps_per_vf = 0;
|
||||
@ -651,6 +650,8 @@ void ice_free_vfs(struct ice_pf *pf)
|
||||
set_bit(ICE_VF_STATE_DIS, pf->vf[i].vf_states);
|
||||
ice_free_vf_res(&pf->vf[i]);
|
||||
}
|
||||
|
||||
mutex_destroy(&pf->vf[i].cfg_lock);
|
||||
}
|
||||
|
||||
if (ice_sriov_free_msix_res(pf))
|
||||
@ -1695,8 +1696,7 @@ bool ice_reset_vf(struct ice_vf *vf, bool is_vflr)
|
||||
|
||||
vsi = ice_get_vf_vsi(vf);
|
||||
|
||||
if (test_bit(ICE_VF_STATE_QS_ENA, vf->vf_states))
|
||||
ice_dis_vf_qs(vf);
|
||||
ice_dis_vf_qs(vf);
|
||||
|
||||
/* Call Disable LAN Tx queue AQ whether or not queues are
|
||||
* enabled. This is needed for successful completion of VFR.
|
||||
@ -1948,6 +1948,8 @@ static void ice_set_dflt_settings_vfs(struct ice_pf *pf)
|
||||
ice_vf_fdir_init(vf);
|
||||
|
||||
ice_vc_set_dflt_vf_ops(&vf->vc_ops);
|
||||
|
||||
mutex_init(&vf->cfg_lock);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3013,6 +3015,7 @@ bool ice_is_any_vf_in_promisc(struct ice_pf *pf)
|
||||
static int ice_vc_cfg_promiscuous_mode_msg(struct ice_vf *vf, u8 *msg)
|
||||
{
|
||||
enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS;
|
||||
enum ice_status mcast_status = 0, ucast_status = 0;
|
||||
bool rm_promisc, alluni = false, allmulti = false;
|
||||
struct virtchnl_promisc_info *info =
|
||||
(struct virtchnl_promisc_info *)msg;
|
||||
@ -3054,24 +3057,6 @@ static int ice_vc_cfg_promiscuous_mode_msg(struct ice_vf *vf, u8 *msg)
|
||||
rm_promisc = !allmulti && !alluni;
|
||||
|
||||
if (vsi->num_vlan || vf->port_vlan_info) {
|
||||
struct ice_vsi *pf_vsi = ice_get_main_vsi(pf);
|
||||
struct net_device *pf_netdev;
|
||||
|
||||
if (!pf_vsi) {
|
||||
v_ret = VIRTCHNL_STATUS_ERR_PARAM;
|
||||
goto error_param;
|
||||
}
|
||||
|
||||
pf_netdev = pf_vsi->netdev;
|
||||
|
||||
ret = ice_set_vf_spoofchk(pf_netdev, vf->vf_id, rm_promisc);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to update spoofchk to %s for VF %d VSI %d when setting promiscuous mode\n",
|
||||
rm_promisc ? "ON" : "OFF", vf->vf_id,
|
||||
vsi->vsi_num);
|
||||
v_ret = VIRTCHNL_STATUS_ERR_PARAM;
|
||||
}
|
||||
|
||||
if (rm_promisc)
|
||||
ret = ice_cfg_vlan_pruning(vsi, true);
|
||||
else
|
||||
@ -3105,52 +3090,51 @@ static int ice_vc_cfg_promiscuous_mode_msg(struct ice_vf *vf, u8 *msg)
|
||||
goto error_param;
|
||||
}
|
||||
} else {
|
||||
enum ice_status status;
|
||||
u8 promisc_m;
|
||||
u8 mcast_m, ucast_m;
|
||||
|
||||
if (alluni) {
|
||||
if (vf->port_vlan_info || vsi->num_vlan)
|
||||
promisc_m = ICE_UCAST_VLAN_PROMISC_BITS;
|
||||
else
|
||||
promisc_m = ICE_UCAST_PROMISC_BITS;
|
||||
} else if (allmulti) {
|
||||
if (vf->port_vlan_info || vsi->num_vlan)
|
||||
promisc_m = ICE_MCAST_VLAN_PROMISC_BITS;
|
||||
else
|
||||
promisc_m = ICE_MCAST_PROMISC_BITS;
|
||||
if (vf->port_vlan_info || vsi->num_vlan > 1) {
|
||||
mcast_m = ICE_MCAST_VLAN_PROMISC_BITS;
|
||||
ucast_m = ICE_UCAST_VLAN_PROMISC_BITS;
|
||||
} else {
|
||||
if (vf->port_vlan_info || vsi->num_vlan)
|
||||
promisc_m = ICE_UCAST_VLAN_PROMISC_BITS;
|
||||
else
|
||||
promisc_m = ICE_UCAST_PROMISC_BITS;
|
||||
mcast_m = ICE_MCAST_PROMISC_BITS;
|
||||
ucast_m = ICE_UCAST_PROMISC_BITS;
|
||||
}
|
||||
|
||||
/* Configure multicast/unicast with or without VLAN promiscuous
|
||||
* mode
|
||||
*/
|
||||
status = ice_vf_set_vsi_promisc(vf, vsi, promisc_m, rm_promisc);
|
||||
if (status) {
|
||||
dev_err(dev, "%sable Tx/Rx filter promiscuous mode on VF-%d failed, error: %s\n",
|
||||
rm_promisc ? "dis" : "en", vf->vf_id,
|
||||
ice_stat_str(status));
|
||||
v_ret = ice_err_to_virt_err(status);
|
||||
goto error_param;
|
||||
} else {
|
||||
dev_dbg(dev, "%sable Tx/Rx filter promiscuous mode on VF-%d succeeded\n",
|
||||
rm_promisc ? "dis" : "en", vf->vf_id);
|
||||
ucast_status = ice_vf_set_vsi_promisc(vf, vsi, ucast_m,
|
||||
!alluni);
|
||||
if (ucast_status) {
|
||||
dev_err(dev, "%sable Tx/Rx filter promiscuous mode on VF-%d failed\n",
|
||||
alluni ? "en" : "dis", vf->vf_id);
|
||||
v_ret = ice_err_to_virt_err(ucast_status);
|
||||
}
|
||||
|
||||
mcast_status = ice_vf_set_vsi_promisc(vf, vsi, mcast_m,
|
||||
!allmulti);
|
||||
if (mcast_status) {
|
||||
dev_err(dev, "%sable Tx/Rx filter promiscuous mode on VF-%d failed\n",
|
||||
allmulti ? "en" : "dis", vf->vf_id);
|
||||
v_ret = ice_err_to_virt_err(mcast_status);
|
||||
}
|
||||
}
|
||||
|
||||
if (allmulti &&
|
||||
!test_and_set_bit(ICE_VF_STATE_MC_PROMISC, vf->vf_states))
|
||||
dev_info(dev, "VF %u successfully set multicast promiscuous mode\n", vf->vf_id);
|
||||
else if (!allmulti && test_and_clear_bit(ICE_VF_STATE_MC_PROMISC, vf->vf_states))
|
||||
dev_info(dev, "VF %u successfully unset multicast promiscuous mode\n", vf->vf_id);
|
||||
if (!mcast_status) {
|
||||
if (allmulti &&
|
||||
!test_and_set_bit(ICE_VF_STATE_MC_PROMISC, vf->vf_states))
|
||||
dev_info(dev, "VF %u successfully set multicast promiscuous mode\n",
|
||||
vf->vf_id);
|
||||
else if (!allmulti && test_and_clear_bit(ICE_VF_STATE_MC_PROMISC, vf->vf_states))
|
||||
dev_info(dev, "VF %u successfully unset multicast promiscuous mode\n",
|
||||
vf->vf_id);
|
||||
}
|
||||
|
||||
if (alluni && !test_and_set_bit(ICE_VF_STATE_UC_PROMISC, vf->vf_states))
|
||||
dev_info(dev, "VF %u successfully set unicast promiscuous mode\n", vf->vf_id);
|
||||
else if (!alluni && test_and_clear_bit(ICE_VF_STATE_UC_PROMISC, vf->vf_states))
|
||||
dev_info(dev, "VF %u successfully unset unicast promiscuous mode\n", vf->vf_id);
|
||||
if (!ucast_status) {
|
||||
if (alluni && !test_and_set_bit(ICE_VF_STATE_UC_PROMISC, vf->vf_states))
|
||||
dev_info(dev, "VF %u successfully set unicast promiscuous mode\n",
|
||||
vf->vf_id);
|
||||
else if (!alluni && test_and_clear_bit(ICE_VF_STATE_UC_PROMISC, vf->vf_states))
|
||||
dev_info(dev, "VF %u successfully unset unicast promiscuous mode\n",
|
||||
vf->vf_id);
|
||||
}
|
||||
|
||||
error_param:
|
||||
return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE,
|
||||
@ -3824,6 +3808,7 @@ ice_vc_add_mac_addr(struct ice_vf *vf, struct ice_vsi *vsi,
|
||||
struct device *dev = ice_pf_to_dev(vf->pf);
|
||||
u8 *mac_addr = vc_ether_addr->addr;
|
||||
enum ice_status status;
|
||||
int ret = 0;
|
||||
|
||||
/* device MAC already added */
|
||||
if (ether_addr_equal(mac_addr, vf->dev_lan_addr.addr))
|
||||
@ -3836,20 +3821,23 @@ ice_vc_add_mac_addr(struct ice_vf *vf, struct ice_vsi *vsi,
|
||||
|
||||
status = ice_fltr_add_mac(vsi, mac_addr, ICE_FWD_TO_VSI);
|
||||
if (status == ICE_ERR_ALREADY_EXISTS) {
|
||||
dev_err(dev, "MAC %pM already exists for VF %d\n", mac_addr,
|
||||
dev_dbg(dev, "MAC %pM already exists for VF %d\n", mac_addr,
|
||||
vf->vf_id);
|
||||
return -EEXIST;
|
||||
/* don't return since we might need to update
|
||||
* the primary MAC in ice_vfhw_mac_add() below
|
||||
*/
|
||||
ret = -EEXIST;
|
||||
} else if (status) {
|
||||
dev_err(dev, "Failed to add MAC %pM for VF %d\n, error %s\n",
|
||||
mac_addr, vf->vf_id, ice_stat_str(status));
|
||||
return -EIO;
|
||||
} else {
|
||||
vf->num_mac++;
|
||||
}
|
||||
|
||||
ice_vfhw_mac_add(vf, vc_ether_addr);
|
||||
|
||||
vf->num_mac++;
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -4151,6 +4139,8 @@ ice_set_vf_port_vlan(struct net_device *netdev, int vf_id, u16 vlan_id, u8 qos,
|
||||
return 0;
|
||||
}
|
||||
|
||||
mutex_lock(&vf->cfg_lock);
|
||||
|
||||
vf->port_vlan_info = vlanprio;
|
||||
|
||||
if (vf->port_vlan_info)
|
||||
@ -4160,6 +4150,7 @@ ice_set_vf_port_vlan(struct net_device *netdev, int vf_id, u16 vlan_id, u8 qos,
|
||||
dev_info(dev, "Clearing port VLAN on VF %d\n", vf_id);
|
||||
|
||||
ice_vc_reset_vf(vf);
|
||||
mutex_unlock(&vf->cfg_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -4699,6 +4690,15 @@ error_handler:
|
||||
return;
|
||||
}
|
||||
|
||||
/* VF is being configured in another context that triggers a VFR, so no
|
||||
* need to process this message
|
||||
*/
|
||||
if (!mutex_trylock(&vf->cfg_lock)) {
|
||||
dev_info(dev, "VF %u is being configured in another context that will trigger a VFR, so there is no need to handle this message\n",
|
||||
vf->vf_id);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (v_opcode) {
|
||||
case VIRTCHNL_OP_VERSION:
|
||||
err = ops->get_ver_msg(vf, msg);
|
||||
@ -4787,6 +4787,8 @@ error_handler:
|
||||
dev_info(dev, "PF failed to honor VF %d, opcode %d, error %d\n",
|
||||
vf_id, v_opcode, err);
|
||||
}
|
||||
|
||||
mutex_unlock(&vf->cfg_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -4902,6 +4904,8 @@ int ice_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mutex_lock(&vf->cfg_lock);
|
||||
|
||||
/* VF is notified of its new MAC via the PF's response to the
|
||||
* VIRTCHNL_OP_GET_VF_RESOURCES message after the VF has been reset
|
||||
*/
|
||||
@ -4920,6 +4924,7 @@ int ice_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac)
|
||||
}
|
||||
|
||||
ice_vc_reset_vf(vf);
|
||||
mutex_unlock(&vf->cfg_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -4954,11 +4959,15 @@ int ice_set_vf_trust(struct net_device *netdev, int vf_id, bool trusted)
|
||||
if (trusted == vf->trusted)
|
||||
return 0;
|
||||
|
||||
mutex_lock(&vf->cfg_lock);
|
||||
|
||||
vf->trusted = trusted;
|
||||
ice_vc_reset_vf(vf);
|
||||
dev_info(ice_pf_to_dev(pf), "VF %u is now %strusted\n",
|
||||
vf_id, trusted ? "" : "un");
|
||||
|
||||
mutex_unlock(&vf->cfg_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -100,6 +100,11 @@ struct ice_vc_vf_ops {
|
||||
struct ice_vf {
|
||||
struct ice_pf *pf;
|
||||
|
||||
/* Used during virtchnl message handling and NDO ops against the VF
|
||||
* that will trigger a VFR
|
||||
*/
|
||||
struct mutex cfg_lock;
|
||||
|
||||
u16 vf_id; /* VF ID in the PF space */
|
||||
u16 lan_vsi_idx; /* index into PF struct */
|
||||
u16 ctrl_vsi_idx;
|
||||
|
@ -262,7 +262,7 @@ ltq_etop_hw_init(struct net_device *dev)
|
||||
/* enable crc generation */
|
||||
ltq_etop_w32(PPE32_CGEN, LQ_PPE32_ENET_MAC_CFG);
|
||||
|
||||
ltq_dma_init_port(DMA_PORT_ETOP, priv->tx_burst_len, rx_burst_len);
|
||||
ltq_dma_init_port(DMA_PORT_ETOP, priv->tx_burst_len, priv->rx_burst_len);
|
||||
|
||||
for (i = 0; i < MAX_DMA_CHAN; i++) {
|
||||
int irq = LTQ_DMA_CH0_INT + i;
|
||||
|
@ -242,10 +242,8 @@ static int liteeth_probe(struct platform_device *pdev)
|
||||
priv->dev = &pdev->dev;
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0) {
|
||||
dev_err(&pdev->dev, "Failed to get IRQ %d\n", irq);
|
||||
if (irq < 0)
|
||||
return irq;
|
||||
}
|
||||
netdev->irq = irq;
|
||||
|
||||
priv->base = devm_platform_ioremap_resource_byname(pdev, "mac");
|
||||
@ -289,7 +287,6 @@ static int liteeth_remove(struct platform_device *pdev)
|
||||
struct net_device *netdev = platform_get_drvdata(pdev);
|
||||
|
||||
unregister_netdev(netdev);
|
||||
free_netdev(netdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1605,7 +1605,7 @@ static void mvpp22_gop_fca_set_periodic_timer(struct mvpp2_port *port)
|
||||
mvpp22_gop_fca_enable_periodic(port, true);
|
||||
}
|
||||
|
||||
static int mvpp22_gop_init(struct mvpp2_port *port)
|
||||
static int mvpp22_gop_init(struct mvpp2_port *port, phy_interface_t interface)
|
||||
{
|
||||
struct mvpp2 *priv = port->priv;
|
||||
u32 val;
|
||||
@ -1613,7 +1613,7 @@ static int mvpp22_gop_init(struct mvpp2_port *port)
|
||||
if (!priv->sysctrl_base)
|
||||
return 0;
|
||||
|
||||
switch (port->phy_interface) {
|
||||
switch (interface) {
|
||||
case PHY_INTERFACE_MODE_RGMII:
|
||||
case PHY_INTERFACE_MODE_RGMII_ID:
|
||||
case PHY_INTERFACE_MODE_RGMII_RXID:
|
||||
@ -1743,15 +1743,15 @@ static void mvpp22_gop_setup_irq(struct mvpp2_port *port)
|
||||
* lanes by the physical layer. This is why configurations like
|
||||
* "PPv2 (2500BaseX) - COMPHY (2500SGMII)" are valid.
|
||||
*/
|
||||
static int mvpp22_comphy_init(struct mvpp2_port *port)
|
||||
static int mvpp22_comphy_init(struct mvpp2_port *port,
|
||||
phy_interface_t interface)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!port->comphy)
|
||||
return 0;
|
||||
|
||||
ret = phy_set_mode_ext(port->comphy, PHY_MODE_ETHERNET,
|
||||
port->phy_interface);
|
||||
ret = phy_set_mode_ext(port->comphy, PHY_MODE_ETHERNET, interface);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -2172,7 +2172,8 @@ static void mvpp22_pcs_reset_assert(struct mvpp2_port *port)
|
||||
writel(val & ~MVPP22_XPCS_CFG0_RESET_DIS, xpcs + MVPP22_XPCS_CFG0);
|
||||
}
|
||||
|
||||
static void mvpp22_pcs_reset_deassert(struct mvpp2_port *port)
|
||||
static void mvpp22_pcs_reset_deassert(struct mvpp2_port *port,
|
||||
phy_interface_t interface)
|
||||
{
|
||||
struct mvpp2 *priv = port->priv;
|
||||
void __iomem *mpcs, *xpcs;
|
||||
@ -2184,7 +2185,7 @@ static void mvpp22_pcs_reset_deassert(struct mvpp2_port *port)
|
||||
mpcs = priv->iface_base + MVPP22_MPCS_BASE(port->gop_id);
|
||||
xpcs = priv->iface_base + MVPP22_XPCS_BASE(port->gop_id);
|
||||
|
||||
switch (port->phy_interface) {
|
||||
switch (interface) {
|
||||
case PHY_INTERFACE_MODE_10GBASER:
|
||||
val = readl(mpcs + MVPP22_MPCS_CLK_RESET);
|
||||
val |= MAC_CLK_RESET_MAC | MAC_CLK_RESET_SD_RX |
|
||||
@ -4529,7 +4530,8 @@ static int mvpp2_poll(struct napi_struct *napi, int budget)
|
||||
return rx_done;
|
||||
}
|
||||
|
||||
static void mvpp22_mode_reconfigure(struct mvpp2_port *port)
|
||||
static void mvpp22_mode_reconfigure(struct mvpp2_port *port,
|
||||
phy_interface_t interface)
|
||||
{
|
||||
u32 ctrl3;
|
||||
|
||||
@ -4540,18 +4542,18 @@ static void mvpp22_mode_reconfigure(struct mvpp2_port *port)
|
||||
mvpp22_pcs_reset_assert(port);
|
||||
|
||||
/* comphy reconfiguration */
|
||||
mvpp22_comphy_init(port);
|
||||
mvpp22_comphy_init(port, interface);
|
||||
|
||||
/* gop reconfiguration */
|
||||
mvpp22_gop_init(port);
|
||||
mvpp22_gop_init(port, interface);
|
||||
|
||||
mvpp22_pcs_reset_deassert(port);
|
||||
mvpp22_pcs_reset_deassert(port, interface);
|
||||
|
||||
if (mvpp2_port_supports_xlg(port)) {
|
||||
ctrl3 = readl(port->base + MVPP22_XLG_CTRL3_REG);
|
||||
ctrl3 &= ~MVPP22_XLG_CTRL3_MACMODESELECT_MASK;
|
||||
|
||||
if (mvpp2_is_xlg(port->phy_interface))
|
||||
if (mvpp2_is_xlg(interface))
|
||||
ctrl3 |= MVPP22_XLG_CTRL3_MACMODESELECT_10G;
|
||||
else
|
||||
ctrl3 |= MVPP22_XLG_CTRL3_MACMODESELECT_GMAC;
|
||||
@ -4559,7 +4561,7 @@ static void mvpp22_mode_reconfigure(struct mvpp2_port *port)
|
||||
writel(ctrl3, port->base + MVPP22_XLG_CTRL3_REG);
|
||||
}
|
||||
|
||||
if (mvpp2_port_supports_xlg(port) && mvpp2_is_xlg(port->phy_interface))
|
||||
if (mvpp2_port_supports_xlg(port) && mvpp2_is_xlg(interface))
|
||||
mvpp2_xlg_max_rx_size_set(port);
|
||||
else
|
||||
mvpp2_gmac_max_rx_size_set(port);
|
||||
@ -4579,7 +4581,7 @@ static void mvpp2_start_dev(struct mvpp2_port *port)
|
||||
mvpp2_interrupts_enable(port);
|
||||
|
||||
if (port->priv->hw_version >= MVPP22)
|
||||
mvpp22_mode_reconfigure(port);
|
||||
mvpp22_mode_reconfigure(port, port->phy_interface);
|
||||
|
||||
if (port->phylink) {
|
||||
phylink_start(port->phylink);
|
||||
@ -6444,6 +6446,9 @@ static int mvpp2__mac_prepare(struct phylink_config *config, unsigned int mode,
|
||||
mvpp22_gop_mask_irq(port);
|
||||
|
||||
phy_power_off(port->comphy);
|
||||
|
||||
/* Reconfigure the serdes lanes */
|
||||
mvpp22_mode_reconfigure(port, interface);
|
||||
}
|
||||
}
|
||||
|
||||
@ -6498,9 +6503,6 @@ static int mvpp2_mac_finish(struct phylink_config *config, unsigned int mode,
|
||||
port->phy_interface != interface) {
|
||||
port->phy_interface = interface;
|
||||
|
||||
/* Reconfigure the serdes lanes */
|
||||
mvpp22_mode_reconfigure(port);
|
||||
|
||||
/* Unmask interrupts */
|
||||
mvpp22_gop_unmask_irq(port);
|
||||
}
|
||||
@ -6961,7 +6963,7 @@ static int mvpp2_port_probe(struct platform_device *pdev,
|
||||
* driver does this, we can remove this code.
|
||||
*/
|
||||
if (port->comphy) {
|
||||
err = mvpp22_comphy_init(port);
|
||||
err = mvpp22_comphy_init(port, port->phy_interface);
|
||||
if (err == 0)
|
||||
phy_power_off(port->comphy);
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ config NDC_DIS_DYNAMIC_CACHING
|
||||
config OCTEONTX2_PF
|
||||
tristate "Marvell OcteonTX2 NIC Physical Function driver"
|
||||
select OCTEONTX2_MBOX
|
||||
select NET_DEVLINK
|
||||
depends on (64BIT && COMPILE_TEST) || ARM64
|
||||
depends on PCI
|
||||
depends on PTP_1588_CLOCK_OPTIONAL
|
||||
|
@ -2450,9 +2450,7 @@ alloc:
|
||||
bmap = mcam->bmap_reverse;
|
||||
start = mcam->bmap_entries - start;
|
||||
end = mcam->bmap_entries - end;
|
||||
index = start;
|
||||
start = end;
|
||||
end = index;
|
||||
swap(start, end);
|
||||
} else {
|
||||
bmap = mcam->bmap;
|
||||
}
|
||||
|
@ -501,7 +501,7 @@ static const struct net_device_ops otx2vf_netdev_ops = {
|
||||
.ndo_set_features = otx2vf_set_features,
|
||||
.ndo_get_stats64 = otx2_get_stats64,
|
||||
.ndo_tx_timeout = otx2_tx_timeout,
|
||||
.ndo_do_ioctl = otx2_ioctl,
|
||||
.ndo_eth_ioctl = otx2_ioctl,
|
||||
};
|
||||
|
||||
static int otx2_wq_init(struct otx2_nic *vf)
|
||||
|
@ -499,7 +499,8 @@ static void prestera_port_mdix_get(struct ethtool_link_ksettings *ecmd,
|
||||
{
|
||||
struct prestera_port_phy_state *state = &port->state_phy;
|
||||
|
||||
if (prestera_hw_port_phy_mode_get(port, &state->mdix, NULL, NULL, NULL)) {
|
||||
if (prestera_hw_port_phy_mode_get(port,
|
||||
&state->mdix, NULL, NULL, NULL)) {
|
||||
netdev_warn(port->dev, "MDIX params get failed");
|
||||
state->mdix = ETH_TP_MDI_INVALID;
|
||||
}
|
||||
|
@ -180,108 +180,113 @@ struct prestera_msg_common_resp {
|
||||
struct prestera_msg_ret ret;
|
||||
};
|
||||
|
||||
union prestera_msg_switch_param {
|
||||
u8 mac[ETH_ALEN];
|
||||
__le32 ageing_timeout_ms;
|
||||
} __packed;
|
||||
|
||||
struct prestera_msg_switch_attr_req {
|
||||
struct prestera_msg_cmd cmd;
|
||||
__le32 attr;
|
||||
union prestera_msg_switch_param param;
|
||||
union {
|
||||
__le32 ageing_timeout_ms;
|
||||
struct {
|
||||
u8 mac[ETH_ALEN];
|
||||
u8 __pad[2];
|
||||
};
|
||||
} param;
|
||||
};
|
||||
|
||||
struct prestera_msg_switch_init_resp {
|
||||
struct prestera_msg_ret ret;
|
||||
__le32 port_count;
|
||||
__le32 mtu_max;
|
||||
u8 switch_id;
|
||||
u8 lag_max;
|
||||
u8 lag_member_max;
|
||||
__le32 size_tbl_router_nexthop;
|
||||
} __packed __aligned(4);
|
||||
u8 switch_id;
|
||||
u8 lag_max;
|
||||
u8 lag_member_max;
|
||||
};
|
||||
|
||||
struct prestera_msg_event_port_param {
|
||||
union {
|
||||
struct {
|
||||
u8 oper;
|
||||
__le32 mode;
|
||||
__le32 speed;
|
||||
u8 oper;
|
||||
u8 duplex;
|
||||
u8 fc;
|
||||
u8 fec;
|
||||
} __packed mac;
|
||||
} mac;
|
||||
struct {
|
||||
u8 mdix;
|
||||
__le64 lmode_bmap;
|
||||
u8 mdix;
|
||||
u8 fc;
|
||||
} __packed phy;
|
||||
} __packed;
|
||||
} __packed __aligned(4);
|
||||
u8 __pad[2];
|
||||
} __packed phy; /* make sure always 12 bytes size */
|
||||
};
|
||||
};
|
||||
|
||||
struct prestera_msg_port_cap_param {
|
||||
__le64 link_mode;
|
||||
u8 type;
|
||||
u8 fec;
|
||||
u8 fc;
|
||||
u8 transceiver;
|
||||
u8 type;
|
||||
u8 fec;
|
||||
u8 fc;
|
||||
u8 transceiver;
|
||||
};
|
||||
|
||||
struct prestera_msg_port_flood_param {
|
||||
u8 type;
|
||||
u8 enable;
|
||||
u8 __pad[2];
|
||||
};
|
||||
|
||||
union prestera_msg_port_param {
|
||||
__le32 mtu;
|
||||
__le32 speed;
|
||||
__le32 link_mode;
|
||||
u8 admin_state;
|
||||
u8 oper_state;
|
||||
__le32 mtu;
|
||||
u8 mac[ETH_ALEN];
|
||||
u8 accept_frm_type;
|
||||
__le32 speed;
|
||||
u8 learning;
|
||||
u8 flood;
|
||||
__le32 link_mode;
|
||||
u8 type;
|
||||
u8 duplex;
|
||||
u8 fec;
|
||||
u8 fc;
|
||||
|
||||
union {
|
||||
struct {
|
||||
u8 admin:1;
|
||||
u8 admin;
|
||||
u8 fc;
|
||||
u8 ap_enable;
|
||||
u8 __reserved[5];
|
||||
union {
|
||||
struct {
|
||||
__le32 mode;
|
||||
u8 inband:1;
|
||||
__le32 speed;
|
||||
u8 duplex;
|
||||
u8 fec;
|
||||
u8 fec_supp;
|
||||
} __packed reg_mode;
|
||||
u8 inband;
|
||||
u8 duplex;
|
||||
u8 fec;
|
||||
u8 fec_supp;
|
||||
} reg_mode;
|
||||
struct {
|
||||
__le32 mode;
|
||||
__le32 speed;
|
||||
u8 fec;
|
||||
u8 fec_supp;
|
||||
} __packed ap_modes[PRESTERA_AP_PORT_MAX];
|
||||
} __packed;
|
||||
} __packed mac;
|
||||
u8 fec;
|
||||
u8 fec_supp;
|
||||
u8 __pad[2];
|
||||
} ap_modes[PRESTERA_AP_PORT_MAX];
|
||||
};
|
||||
} mac;
|
||||
struct {
|
||||
u8 admin:1;
|
||||
u8 adv_enable;
|
||||
__le64 modes;
|
||||
__le32 mode;
|
||||
u8 admin;
|
||||
u8 adv_enable;
|
||||
u8 mdix;
|
||||
} __packed phy;
|
||||
} __packed link;
|
||||
u8 __pad;
|
||||
} phy;
|
||||
} link;
|
||||
|
||||
struct prestera_msg_port_cap_param cap;
|
||||
struct prestera_msg_port_flood_param flood_ext;
|
||||
struct prestera_msg_event_port_param link_evt;
|
||||
} __packed;
|
||||
};
|
||||
|
||||
struct prestera_msg_port_attr_req {
|
||||
struct prestera_msg_cmd cmd;
|
||||
@ -289,14 +294,12 @@ struct prestera_msg_port_attr_req {
|
||||
__le32 port;
|
||||
__le32 dev;
|
||||
union prestera_msg_port_param param;
|
||||
} __packed __aligned(4);
|
||||
|
||||
};
|
||||
|
||||
struct prestera_msg_port_attr_resp {
|
||||
struct prestera_msg_ret ret;
|
||||
union prestera_msg_port_param param;
|
||||
} __packed __aligned(4);
|
||||
|
||||
};
|
||||
|
||||
struct prestera_msg_port_stats_resp {
|
||||
struct prestera_msg_ret ret;
|
||||
@ -313,6 +316,7 @@ struct prestera_msg_port_info_resp {
|
||||
__le32 hw_id;
|
||||
__le32 dev_id;
|
||||
__le16 fp_id;
|
||||
u8 pad[2];
|
||||
};
|
||||
|
||||
struct prestera_msg_vlan_req {
|
||||
@ -320,13 +324,13 @@ struct prestera_msg_vlan_req {
|
||||
__le32 port;
|
||||
__le32 dev;
|
||||
__le16 vid;
|
||||
u8 is_member;
|
||||
u8 is_tagged;
|
||||
u8 is_member;
|
||||
u8 is_tagged;
|
||||
};
|
||||
|
||||
struct prestera_msg_fdb_req {
|
||||
struct prestera_msg_cmd cmd;
|
||||
u8 dest_type;
|
||||
__le32 flush_mode;
|
||||
union {
|
||||
struct {
|
||||
__le32 port;
|
||||
@ -334,22 +338,25 @@ struct prestera_msg_fdb_req {
|
||||
};
|
||||
__le16 lag_id;
|
||||
} dest;
|
||||
u8 mac[ETH_ALEN];
|
||||
__le16 vid;
|
||||
u8 dynamic;
|
||||
__le32 flush_mode;
|
||||
} __packed __aligned(4);
|
||||
u8 dest_type;
|
||||
u8 dynamic;
|
||||
u8 mac[ETH_ALEN];
|
||||
u8 __pad[2];
|
||||
};
|
||||
|
||||
struct prestera_msg_bridge_req {
|
||||
struct prestera_msg_cmd cmd;
|
||||
__le32 port;
|
||||
__le32 dev;
|
||||
__le16 bridge;
|
||||
u8 pad[2];
|
||||
};
|
||||
|
||||
struct prestera_msg_bridge_resp {
|
||||
struct prestera_msg_ret ret;
|
||||
__le16 bridge;
|
||||
u8 pad[2];
|
||||
};
|
||||
|
||||
struct prestera_msg_acl_action {
|
||||
@ -359,11 +366,12 @@ struct prestera_msg_acl_action {
|
||||
|
||||
struct prestera_msg_acl_match {
|
||||
__le32 type;
|
||||
__le32 __reserved;
|
||||
union {
|
||||
struct {
|
||||
u8 key;
|
||||
u8 mask;
|
||||
} __packed u8;
|
||||
} u8;
|
||||
struct {
|
||||
__le16 key;
|
||||
__le16 mask;
|
||||
@ -379,7 +387,7 @@ struct prestera_msg_acl_match {
|
||||
struct {
|
||||
u8 key[ETH_ALEN];
|
||||
u8 mask[ETH_ALEN];
|
||||
} __packed mac;
|
||||
} mac;
|
||||
} keymask;
|
||||
};
|
||||
|
||||
@ -408,16 +416,19 @@ struct prestera_msg_acl_ruleset_bind_req {
|
||||
__le32 port;
|
||||
__le32 dev;
|
||||
__le16 ruleset_id;
|
||||
u8 pad[2];
|
||||
};
|
||||
|
||||
struct prestera_msg_acl_ruleset_req {
|
||||
struct prestera_msg_cmd cmd;
|
||||
__le16 id;
|
||||
u8 pad[2];
|
||||
};
|
||||
|
||||
struct prestera_msg_acl_ruleset_resp {
|
||||
struct prestera_msg_ret ret;
|
||||
__le16 id;
|
||||
u8 pad[2];
|
||||
};
|
||||
|
||||
struct prestera_msg_span_req {
|
||||
@ -425,11 +436,13 @@ struct prestera_msg_span_req {
|
||||
__le32 port;
|
||||
__le32 dev;
|
||||
u8 id;
|
||||
u8 pad[3];
|
||||
};
|
||||
|
||||
struct prestera_msg_span_resp {
|
||||
struct prestera_msg_ret ret;
|
||||
u8 id;
|
||||
u8 pad[3];
|
||||
};
|
||||
|
||||
struct prestera_msg_stp_req {
|
||||
@ -437,12 +450,14 @@ struct prestera_msg_stp_req {
|
||||
__le32 port;
|
||||
__le32 dev;
|
||||
__le16 vid;
|
||||
u8 state;
|
||||
u8 state;
|
||||
u8 __pad;
|
||||
};
|
||||
|
||||
struct prestera_msg_rxtx_req {
|
||||
struct prestera_msg_cmd cmd;
|
||||
u8 use_sdma;
|
||||
u8 pad[3];
|
||||
};
|
||||
|
||||
struct prestera_msg_rxtx_resp {
|
||||
@ -455,12 +470,14 @@ struct prestera_msg_lag_req {
|
||||
__le32 port;
|
||||
__le32 dev;
|
||||
__le16 lag_id;
|
||||
u8 pad[2];
|
||||
};
|
||||
|
||||
struct prestera_msg_cpu_code_counter_req {
|
||||
struct prestera_msg_cmd cmd;
|
||||
u8 counter_type;
|
||||
u8 code;
|
||||
u8 pad[2];
|
||||
};
|
||||
|
||||
struct mvsw_msg_cpu_code_counter_ret {
|
||||
@ -485,21 +502,21 @@ union prestera_msg_event_fdb_param {
|
||||
|
||||
struct prestera_msg_event_fdb {
|
||||
struct prestera_msg_event id;
|
||||
u8 dest_type;
|
||||
__le32 vid;
|
||||
union {
|
||||
__le32 port_id;
|
||||
__le16 lag_id;
|
||||
} dest;
|
||||
__le32 vid;
|
||||
union prestera_msg_event_fdb_param param;
|
||||
} __packed __aligned(4);
|
||||
u8 dest_type;
|
||||
};
|
||||
|
||||
static inline void prestera_hw_build_tests(void)
|
||||
static void prestera_hw_build_tests(void)
|
||||
{
|
||||
/* check requests */
|
||||
BUILD_BUG_ON(sizeof(struct prestera_msg_common_req) != 4);
|
||||
BUILD_BUG_ON(sizeof(struct prestera_msg_switch_attr_req) != 16);
|
||||
BUILD_BUG_ON(sizeof(struct prestera_msg_port_attr_req) != 120);
|
||||
BUILD_BUG_ON(sizeof(struct prestera_msg_port_attr_req) != 144);
|
||||
BUILD_BUG_ON(sizeof(struct prestera_msg_port_info_req) != 8);
|
||||
BUILD_BUG_ON(sizeof(struct prestera_msg_vlan_req) != 16);
|
||||
BUILD_BUG_ON(sizeof(struct prestera_msg_fdb_req) != 28);
|
||||
@ -516,7 +533,7 @@ static inline void prestera_hw_build_tests(void)
|
||||
/* check responses */
|
||||
BUILD_BUG_ON(sizeof(struct prestera_msg_common_resp) != 8);
|
||||
BUILD_BUG_ON(sizeof(struct prestera_msg_switch_init_resp) != 24);
|
||||
BUILD_BUG_ON(sizeof(struct prestera_msg_port_attr_resp) != 112);
|
||||
BUILD_BUG_ON(sizeof(struct prestera_msg_port_attr_resp) != 136);
|
||||
BUILD_BUG_ON(sizeof(struct prestera_msg_port_stats_resp) != 248);
|
||||
BUILD_BUG_ON(sizeof(struct prestera_msg_port_info_resp) != 20);
|
||||
BUILD_BUG_ON(sizeof(struct prestera_msg_bridge_resp) != 12);
|
||||
@ -549,9 +566,9 @@ static int __prestera_cmd_ret(struct prestera_switch *sw,
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (__le32_to_cpu(ret->cmd.type) != PRESTERA_CMD_TYPE_ACK)
|
||||
if (ret->cmd.type != __cpu_to_le32(PRESTERA_CMD_TYPE_ACK))
|
||||
return -EBADE;
|
||||
if (__le32_to_cpu(ret->status) != PRESTERA_CMD_ACK_OK)
|
||||
if (ret->status != __cpu_to_le32(PRESTERA_CMD_ACK_OK))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
@ -1344,7 +1361,8 @@ int prestera_hw_port_speed_get(const struct prestera_port *port, u32 *speed)
|
||||
int prestera_hw_port_autoneg_restart(struct prestera_port *port)
|
||||
{
|
||||
struct prestera_msg_port_attr_req req = {
|
||||
.attr = __cpu_to_le32(PRESTERA_CMD_PORT_ATTR_PHY_AUTONEG_RESTART),
|
||||
.attr =
|
||||
__cpu_to_le32(PRESTERA_CMD_PORT_ATTR_PHY_AUTONEG_RESTART),
|
||||
.port = __cpu_to_le32(port->hw_id),
|
||||
.dev = __cpu_to_le32(port->dev_id),
|
||||
};
|
||||
|
@ -405,7 +405,8 @@ static int prestera_port_create(struct prestera_switch *sw, u32 id)
|
||||
|
||||
err = prestera_port_cfg_mac_write(port, &cfg_mac);
|
||||
if (err) {
|
||||
dev_err(prestera_dev(sw), "Failed to set port(%u) mac mode\n", id);
|
||||
dev_err(prestera_dev(sw),
|
||||
"Failed to set port(%u) mac mode\n", id);
|
||||
goto err_port_init;
|
||||
}
|
||||
|
||||
@ -418,7 +419,8 @@ static int prestera_port_create(struct prestera_switch *sw, u32 id)
|
||||
false, 0, 0,
|
||||
port->cfg_phy.mdix);
|
||||
if (err) {
|
||||
dev_err(prestera_dev(sw), "Failed to set port(%u) phy mode\n", id);
|
||||
dev_err(prestera_dev(sw),
|
||||
"Failed to set port(%u) phy mode\n", id);
|
||||
goto err_port_init;
|
||||
}
|
||||
}
|
||||
|
@ -411,7 +411,8 @@ static int prestera_fw_cmd_send(struct prestera_fw *fw, int qid,
|
||||
goto cmd_exit;
|
||||
}
|
||||
|
||||
memcpy_fromio(out_msg, prestera_fw_cmdq_buf(fw, qid) + in_size, ret_size);
|
||||
memcpy_fromio(out_msg,
|
||||
prestera_fw_cmdq_buf(fw, qid) + in_size, ret_size);
|
||||
|
||||
cmd_exit:
|
||||
prestera_fw_write(fw, PRESTERA_CMDQ_REQ_CTL_REG(qid),
|
||||
|
@ -289,7 +289,7 @@ mlx5_lag_create_definer(struct mlx5_lag *ldev, enum netdev_lag_hash hash,
|
||||
|
||||
lag_definer = kzalloc(sizeof(*lag_definer), GFP_KERNEL);
|
||||
if (!lag_definer)
|
||||
return ERR_PTR(ENOMEM);
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
match_definer_mask = kvzalloc(MLX5_FLD_SZ_BYTES(match_definer,
|
||||
match_mask),
|
||||
|
@ -1424,7 +1424,7 @@ static void mana_gd_shutdown(struct pci_dev *pdev)
|
||||
{
|
||||
struct gdma_context *gc = pci_get_drvdata(pdev);
|
||||
|
||||
dev_info(&pdev->dev, "Shutdown was calledd\n");
|
||||
dev_info(&pdev->dev, "Shutdown was called\n");
|
||||
|
||||
mana_remove(&gc->mana, true);
|
||||
|
||||
|
@ -817,9 +817,7 @@ ef4_realloc_channels(struct ef4_nic *efx, u32 rxq_entries, u32 txq_entries)
|
||||
efx->rxq_entries = rxq_entries;
|
||||
efx->txq_entries = txq_entries;
|
||||
for (i = 0; i < efx->n_channels; i++) {
|
||||
channel = efx->channel[i];
|
||||
efx->channel[i] = other_channel[i];
|
||||
other_channel[i] = channel;
|
||||
swap(efx->channel[i], other_channel[i]);
|
||||
}
|
||||
|
||||
/* Restart buffer table allocation */
|
||||
@ -863,9 +861,7 @@ rollback:
|
||||
efx->rxq_entries = old_rxq_entries;
|
||||
efx->txq_entries = old_txq_entries;
|
||||
for (i = 0; i < efx->n_channels; i++) {
|
||||
channel = efx->channel[i];
|
||||
efx->channel[i] = other_channel[i];
|
||||
other_channel[i] = channel;
|
||||
swap(efx->channel[i], other_channel[i]);
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
|
@ -786,8 +786,6 @@ static int tc_setup_taprio(struct stmmac_priv *priv,
|
||||
goto disable;
|
||||
if (qopt->num_entries >= dep)
|
||||
return -EINVAL;
|
||||
if (!qopt->base_time)
|
||||
return -ERANGE;
|
||||
if (!qopt->cycle_time)
|
||||
return -ERANGE;
|
||||
|
||||
|
@ -1299,10 +1299,8 @@ struct cpsw_ale *cpsw_ale_create(struct cpsw_ale_params *params)
|
||||
if (!ale)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
ale->p0_untag_vid_mask =
|
||||
devm_kmalloc_array(params->dev, BITS_TO_LONGS(VLAN_N_VID),
|
||||
sizeof(unsigned long),
|
||||
GFP_KERNEL);
|
||||
ale->p0_untag_vid_mask = devm_bitmap_zalloc(params->dev, VLAN_N_VID,
|
||||
GFP_KERNEL);
|
||||
if (!ale->p0_untag_vid_mask)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
|
@ -420,8 +420,20 @@ static int emac_set_coalesce(struct net_device *ndev,
|
||||
u32 int_ctrl, num_interrupts = 0;
|
||||
u32 prescale = 0, addnl_dvdr = 1, coal_intvl = 0;
|
||||
|
||||
if (!coal->rx_coalesce_usecs)
|
||||
return -EINVAL;
|
||||
if (!coal->rx_coalesce_usecs) {
|
||||
priv->coal_intvl = 0;
|
||||
|
||||
switch (priv->version) {
|
||||
case EMAC_VERSION_2:
|
||||
emac_ctrl_write(EMAC_DM646X_CMINTCTRL, 0);
|
||||
break;
|
||||
default:
|
||||
emac_ctrl_write(EMAC_CTRL_EWINTTCNT, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
coal_intvl = coal->rx_coalesce_usecs;
|
||||
|
||||
|
@ -672,11 +672,13 @@ static void sixpack_close(struct tty_struct *tty)
|
||||
del_timer_sync(&sp->tx_t);
|
||||
del_timer_sync(&sp->resync_t);
|
||||
|
||||
/* Free all 6pack frame buffers. */
|
||||
unregister_netdev(sp->dev);
|
||||
|
||||
/* Free all 6pack frame buffers after unreg. */
|
||||
kfree(sp->rbuff);
|
||||
kfree(sp->xbuff);
|
||||
|
||||
unregister_netdev(sp->dev);
|
||||
free_netdev(sp->dev);
|
||||
}
|
||||
|
||||
/* Perform I/O control on an active 6pack channel. */
|
||||
|
@ -792,13 +792,14 @@ static void mkiss_close(struct tty_struct *tty)
|
||||
*/
|
||||
netif_stop_queue(ax->dev);
|
||||
|
||||
/* Free all AX25 frame buffers. */
|
||||
kfree(ax->rbuff);
|
||||
kfree(ax->xbuff);
|
||||
|
||||
ax->tty = NULL;
|
||||
|
||||
unregister_netdev(ax->dev);
|
||||
|
||||
/* Free all AX25 frame buffers after unreg. */
|
||||
kfree(ax->rbuff);
|
||||
kfree(ax->xbuff);
|
||||
|
||||
free_netdev(ax->dev);
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,11 @@
|
||||
#define LAN87XX_MASK_LINK_UP (0x0004)
|
||||
#define LAN87XX_MASK_LINK_DOWN (0x0002)
|
||||
|
||||
/* MISC Control 1 Register */
|
||||
#define LAN87XX_CTRL_1 (0x11)
|
||||
#define LAN87XX_MASK_RGMII_TXC_DLY_EN (0x4000)
|
||||
#define LAN87XX_MASK_RGMII_RXC_DLY_EN (0x2000)
|
||||
|
||||
/* phyaccess nested types */
|
||||
#define PHYACC_ATTR_MODE_READ 0
|
||||
#define PHYACC_ATTR_MODE_WRITE 1
|
||||
@ -112,6 +117,43 @@ static int access_ereg_modify_changed(struct phy_device *phydev,
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int lan87xx_config_rgmii_delay(struct phy_device *phydev)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (!phy_interface_is_rgmii(phydev))
|
||||
return 0;
|
||||
|
||||
rc = access_ereg(phydev, PHYACC_ATTR_MODE_READ,
|
||||
PHYACC_ATTR_BANK_MISC, LAN87XX_CTRL_1, 0);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
switch (phydev->interface) {
|
||||
case PHY_INTERFACE_MODE_RGMII:
|
||||
rc &= ~LAN87XX_MASK_RGMII_TXC_DLY_EN;
|
||||
rc &= ~LAN87XX_MASK_RGMII_RXC_DLY_EN;
|
||||
break;
|
||||
case PHY_INTERFACE_MODE_RGMII_ID:
|
||||
rc |= LAN87XX_MASK_RGMII_TXC_DLY_EN;
|
||||
rc |= LAN87XX_MASK_RGMII_RXC_DLY_EN;
|
||||
break;
|
||||
case PHY_INTERFACE_MODE_RGMII_RXID:
|
||||
rc &= ~LAN87XX_MASK_RGMII_TXC_DLY_EN;
|
||||
rc |= LAN87XX_MASK_RGMII_RXC_DLY_EN;
|
||||
break;
|
||||
case PHY_INTERFACE_MODE_RGMII_TXID:
|
||||
rc |= LAN87XX_MASK_RGMII_TXC_DLY_EN;
|
||||
rc &= ~LAN87XX_MASK_RGMII_RXC_DLY_EN;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
return access_ereg(phydev, PHYACC_ATTR_MODE_WRITE,
|
||||
PHYACC_ATTR_BANK_MISC, LAN87XX_CTRL_1, rc);
|
||||
}
|
||||
|
||||
static int lan87xx_phy_init(struct phy_device *phydev)
|
||||
{
|
||||
static const struct access_ereg_val init[] = {
|
||||
@ -185,7 +227,7 @@ static int lan87xx_phy_init(struct phy_device *phydev)
|
||||
return rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return lan87xx_config_rgmii_delay(phydev);
|
||||
}
|
||||
|
||||
static int lan87xx_phy_config_intr(struct phy_device *phydev)
|
||||
|
@ -815,7 +815,12 @@ int phy_ethtool_ksettings_set(struct phy_device *phydev,
|
||||
phydev->mdix_ctrl = cmd->base.eth_tp_mdix_ctrl;
|
||||
|
||||
/* Restart the PHY */
|
||||
_phy_start_aneg(phydev);
|
||||
if (phy_is_started(phydev)) {
|
||||
phydev->state = PHY_UP;
|
||||
phy_trigger_machine(phydev);
|
||||
} else {
|
||||
_phy_start_aneg(phydev);
|
||||
}
|
||||
|
||||
mutex_unlock(&phydev->lock);
|
||||
return 0;
|
||||
|
@ -409,7 +409,7 @@ static int genmii_read_link(struct mii_phy *phy)
|
||||
* though magic-aneg shouldn't prevent this case from occurring
|
||||
*/
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int generic_suspend(struct mii_phy* phy)
|
||||
|
@ -394,12 +394,10 @@ void ipc_imem_sys_devlink_close(struct iosm_devlink *ipc_devlink)
|
||||
int boot_check_timeout = BOOT_CHECK_DEFAULT_TIMEOUT;
|
||||
enum ipc_mem_exec_stage exec_stage;
|
||||
struct ipc_mem_channel *channel;
|
||||
enum ipc_phase curr_phase;
|
||||
int status = 0;
|
||||
u32 tail = 0;
|
||||
|
||||
channel = ipc_imem->ipc_devlink->devlink_sio.channel;
|
||||
curr_phase = ipc_imem->phase;
|
||||
/* Increase the total wait time to boot_check_timeout */
|
||||
do {
|
||||
exec_stage = ipc_mmio_get_exec_stage(ipc_imem->mmio);
|
||||
|
@ -2216,7 +2216,7 @@ static int pn533_fill_fragment_skbs(struct pn533 *dev, struct sk_buff *skb)
|
||||
frag = pn533_alloc_skb(dev, frag_size);
|
||||
if (!frag) {
|
||||
skb_queue_purge(&dev->fragment_skb);
|
||||
break;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (!dev->tgt_mode) {
|
||||
@ -2285,7 +2285,7 @@ static int pn533_transceive(struct nfc_dev *nfc_dev,
|
||||
/* jumbo frame ? */
|
||||
if (skb->len > PN533_CMD_DATAEXCH_DATA_MAXLEN) {
|
||||
rc = pn533_fill_fragment_skbs(dev, skb);
|
||||
if (rc <= 0)
|
||||
if (rc < 0)
|
||||
goto error;
|
||||
|
||||
skb = skb_dequeue(&dev->fragment_skb);
|
||||
@ -2353,7 +2353,7 @@ static int pn533_tm_send(struct nfc_dev *nfc_dev, struct sk_buff *skb)
|
||||
/* let's split in multiple chunks if size's too big */
|
||||
if (skb->len > PN533_CMD_DATAEXCH_DATA_MAXLEN) {
|
||||
rc = pn533_fill_fragment_skbs(dev, skb);
|
||||
if (rc <= 0)
|
||||
if (rc < 0)
|
||||
goto error;
|
||||
|
||||
/* get the first skb */
|
||||
|
@ -624,7 +624,7 @@ static void port100_recv_response(struct urb *urb)
|
||||
break; /* success */
|
||||
case -ECONNRESET:
|
||||
case -ENOENT:
|
||||
nfc_err(&dev->interface->dev,
|
||||
nfc_dbg(&dev->interface->dev,
|
||||
"The urb has been canceled (status %d)\n", urb->status);
|
||||
goto sched_wq;
|
||||
case -ESHUTDOWN:
|
||||
@ -678,7 +678,7 @@ static void port100_recv_ack(struct urb *urb)
|
||||
break; /* success */
|
||||
case -ECONNRESET:
|
||||
case -ENOENT:
|
||||
nfc_err(&dev->interface->dev,
|
||||
nfc_dbg(&dev->interface->dev,
|
||||
"The urb has been stopped (status %d)\n", urb->status);
|
||||
goto sched_wq;
|
||||
case -ESHUTDOWN:
|
||||
@ -942,7 +942,7 @@ static void port100_send_complete(struct urb *urb)
|
||||
break; /* success */
|
||||
case -ECONNRESET:
|
||||
case -ENOENT:
|
||||
nfc_err(&dev->interface->dev,
|
||||
nfc_dbg(&dev->interface->dev,
|
||||
"The urb has been stopped (status %d)\n", urb->status);
|
||||
break;
|
||||
case -ESHUTDOWN:
|
||||
|
29
fs/libfs.c
29
fs/libfs.c
@ -448,6 +448,30 @@ int simple_rmdir(struct inode *dir, struct dentry *dentry)
|
||||
}
|
||||
EXPORT_SYMBOL(simple_rmdir);
|
||||
|
||||
int simple_rename_exchange(struct inode *old_dir, struct dentry *old_dentry,
|
||||
struct inode *new_dir, struct dentry *new_dentry)
|
||||
{
|
||||
bool old_is_dir = d_is_dir(old_dentry);
|
||||
bool new_is_dir = d_is_dir(new_dentry);
|
||||
|
||||
if (old_dir != new_dir && old_is_dir != new_is_dir) {
|
||||
if (old_is_dir) {
|
||||
drop_nlink(old_dir);
|
||||
inc_nlink(new_dir);
|
||||
} else {
|
||||
drop_nlink(new_dir);
|
||||
inc_nlink(old_dir);
|
||||
}
|
||||
}
|
||||
old_dir->i_ctime = old_dir->i_mtime =
|
||||
new_dir->i_ctime = new_dir->i_mtime =
|
||||
d_inode(old_dentry)->i_ctime =
|
||||
d_inode(new_dentry)->i_ctime = current_time(old_dir);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(simple_rename_exchange);
|
||||
|
||||
int simple_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
|
||||
struct dentry *old_dentry, struct inode *new_dir,
|
||||
struct dentry *new_dentry, unsigned int flags)
|
||||
@ -455,9 +479,12 @@ int simple_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
|
||||
struct inode *inode = d_inode(old_dentry);
|
||||
int they_are_dirs = d_is_dir(old_dentry);
|
||||
|
||||
if (flags & ~RENAME_NOREPLACE)
|
||||
if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE))
|
||||
return -EINVAL;
|
||||
|
||||
if (flags & RENAME_EXCHANGE)
|
||||
return simple_rename_exchange(old_dir, old_dentry, new_dir, new_dentry);
|
||||
|
||||
if (!simple_empty(new_dentry))
|
||||
return -ENOTEMPTY;
|
||||
|
||||
|
@ -484,6 +484,12 @@ bpf_ctx_record_field_size(struct bpf_insn_access_aux *aux, u32 size)
|
||||
aux->ctx_field_size = size;
|
||||
}
|
||||
|
||||
static inline bool bpf_pseudo_func(const struct bpf_insn *insn)
|
||||
{
|
||||
return insn->code == (BPF_LD | BPF_IMM | BPF_DW) &&
|
||||
insn->src_reg == BPF_PSEUDO_FUNC;
|
||||
}
|
||||
|
||||
struct bpf_prog_ops {
|
||||
int (*test_run)(struct bpf_prog *prog, const union bpf_attr *kattr,
|
||||
union bpf_attr __user *uattr);
|
||||
|
@ -12,6 +12,7 @@
|
||||
struct ocelot_skb_cb {
|
||||
struct sk_buff *clone;
|
||||
unsigned int ptp_class; /* valid only for clones */
|
||||
u32 tstamp_lo;
|
||||
u8 ptp_cmd;
|
||||
u8 ts_id;
|
||||
};
|
||||
|
@ -10,6 +10,9 @@
|
||||
#define __ETHTOOL_LINK_MODE_MASK_NWORDS \
|
||||
DIV_ROUND_UP(__ETHTOOL_LINK_MODE_MASK_NBITS, 32)
|
||||
|
||||
#define ETHTOOL_PAUSE_STAT_CNT (__ETHTOOL_A_PAUSE_STAT_CNT - \
|
||||
ETHTOOL_A_PAUSE_STAT_TX_FRAMES)
|
||||
|
||||
enum ethtool_multicast_groups {
|
||||
ETHNL_MCGRP_MONITOR,
|
||||
};
|
||||
|
@ -3385,6 +3385,8 @@ extern int simple_open(struct inode *inode, struct file *file);
|
||||
extern int simple_link(struct dentry *, struct inode *, struct dentry *);
|
||||
extern int simple_unlink(struct inode *, struct dentry *);
|
||||
extern int simple_rmdir(struct inode *, struct dentry *);
|
||||
extern int simple_rename_exchange(struct inode *old_dir, struct dentry *old_dentry,
|
||||
struct inode *new_dir, struct dentry *new_dentry);
|
||||
extern int simple_rename(struct user_namespace *, struct inode *,
|
||||
struct dentry *, struct inode *, struct dentry *,
|
||||
unsigned int);
|
||||
|
@ -329,12 +329,14 @@ LSM_HOOK(int, 0, tun_dev_create, void)
|
||||
LSM_HOOK(int, 0, tun_dev_attach_queue, void *security)
|
||||
LSM_HOOK(int, 0, tun_dev_attach, struct sock *sk, void *security)
|
||||
LSM_HOOK(int, 0, tun_dev_open, void *security)
|
||||
LSM_HOOK(int, 0, sctp_assoc_request, struct sctp_endpoint *ep,
|
||||
LSM_HOOK(int, 0, sctp_assoc_request, struct sctp_association *asoc,
|
||||
struct sk_buff *skb)
|
||||
LSM_HOOK(int, 0, sctp_bind_connect, struct sock *sk, int optname,
|
||||
struct sockaddr *address, int addrlen)
|
||||
LSM_HOOK(void, LSM_RET_VOID, sctp_sk_clone, struct sctp_endpoint *ep,
|
||||
LSM_HOOK(void, LSM_RET_VOID, sctp_sk_clone, struct sctp_association *asoc,
|
||||
struct sock *sk, struct sock *newsk)
|
||||
LSM_HOOK(void, LSM_RET_VOID, sctp_assoc_established, struct sctp_association *asoc,
|
||||
struct sk_buff *skb)
|
||||
#endif /* CONFIG_SECURITY_NETWORK */
|
||||
|
||||
#ifdef CONFIG_SECURITY_INFINIBAND
|
||||
|
@ -1027,9 +1027,9 @@
|
||||
* Security hooks for SCTP
|
||||
*
|
||||
* @sctp_assoc_request:
|
||||
* Passes the @ep and @chunk->skb of the association INIT packet to
|
||||
* Passes the @asoc and @chunk->skb of the association INIT packet to
|
||||
* the security module.
|
||||
* @ep pointer to sctp endpoint structure.
|
||||
* @asoc pointer to sctp association structure.
|
||||
* @skb pointer to skbuff of association packet.
|
||||
* Return 0 on success, error on failure.
|
||||
* @sctp_bind_connect:
|
||||
@ -1047,9 +1047,14 @@
|
||||
* Called whenever a new socket is created by accept(2) (i.e. a TCP
|
||||
* style socket) or when a socket is 'peeled off' e.g userspace
|
||||
* calls sctp_peeloff(3).
|
||||
* @ep pointer to current sctp endpoint structure.
|
||||
* @asoc pointer to current sctp association structure.
|
||||
* @sk pointer to current sock structure.
|
||||
* @sk pointer to new sock structure.
|
||||
* @newsk pointer to new sock structure.
|
||||
* @sctp_assoc_established:
|
||||
* Passes the @asoc and @chunk->skb of the association COOKIE_ACK packet
|
||||
* to the security module.
|
||||
* @asoc pointer to sctp association structure.
|
||||
* @skb pointer to skbuff of association packet.
|
||||
*
|
||||
* Security hooks for Infiniband
|
||||
*
|
||||
|
@ -179,7 +179,7 @@ struct xfrm_policy;
|
||||
struct xfrm_state;
|
||||
struct xfrm_user_sec_ctx;
|
||||
struct seq_file;
|
||||
struct sctp_endpoint;
|
||||
struct sctp_association;
|
||||
|
||||
#ifdef CONFIG_MMU
|
||||
extern unsigned long mmap_min_addr;
|
||||
@ -1425,11 +1425,13 @@ int security_tun_dev_create(void);
|
||||
int security_tun_dev_attach_queue(void *security);
|
||||
int security_tun_dev_attach(struct sock *sk, void *security);
|
||||
int security_tun_dev_open(void *security);
|
||||
int security_sctp_assoc_request(struct sctp_endpoint *ep, struct sk_buff *skb);
|
||||
int security_sctp_assoc_request(struct sctp_association *asoc, struct sk_buff *skb);
|
||||
int security_sctp_bind_connect(struct sock *sk, int optname,
|
||||
struct sockaddr *address, int addrlen);
|
||||
void security_sctp_sk_clone(struct sctp_endpoint *ep, struct sock *sk,
|
||||
void security_sctp_sk_clone(struct sctp_association *asoc, struct sock *sk,
|
||||
struct sock *newsk);
|
||||
void security_sctp_assoc_established(struct sctp_association *asoc,
|
||||
struct sk_buff *skb);
|
||||
|
||||
#else /* CONFIG_SECURITY_NETWORK */
|
||||
static inline int security_unix_stream_connect(struct sock *sock,
|
||||
@ -1631,7 +1633,7 @@ static inline int security_tun_dev_open(void *security)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int security_sctp_assoc_request(struct sctp_endpoint *ep,
|
||||
static inline int security_sctp_assoc_request(struct sctp_association *asoc,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
return 0;
|
||||
@ -1644,11 +1646,16 @@ static inline int security_sctp_bind_connect(struct sock *sk, int optname,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void security_sctp_sk_clone(struct sctp_endpoint *ep,
|
||||
static inline void security_sctp_sk_clone(struct sctp_association *asoc,
|
||||
struct sock *sk,
|
||||
struct sock *newsk)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void security_sctp_assoc_established(struct sctp_association *asoc,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
}
|
||||
#endif /* CONFIG_SECURITY_NETWORK */
|
||||
|
||||
#ifdef CONFIG_SECURITY_INFINIBAND
|
||||
|
@ -454,9 +454,15 @@ enum {
|
||||
* all frags to avoid possible bad checksum
|
||||
*/
|
||||
SKBFL_SHARED_FRAG = BIT(1),
|
||||
|
||||
/* segment contains only zerocopy data and should not be
|
||||
* charged to the kernel memory.
|
||||
*/
|
||||
SKBFL_PURE_ZEROCOPY = BIT(2),
|
||||
};
|
||||
|
||||
#define SKBFL_ZEROCOPY_FRAG (SKBFL_ZEROCOPY_ENABLE | SKBFL_SHARED_FRAG)
|
||||
#define SKBFL_ALL_ZEROCOPY (SKBFL_ZEROCOPY_FRAG | SKBFL_PURE_ZEROCOPY)
|
||||
|
||||
/*
|
||||
* The callback notifies userspace to release buffers when skb DMA is done in
|
||||
@ -1464,6 +1470,17 @@ static inline struct ubuf_info *skb_zcopy(struct sk_buff *skb)
|
||||
return is_zcopy ? skb_uarg(skb) : NULL;
|
||||
}
|
||||
|
||||
static inline bool skb_zcopy_pure(const struct sk_buff *skb)
|
||||
{
|
||||
return skb_shinfo(skb)->flags & SKBFL_PURE_ZEROCOPY;
|
||||
}
|
||||
|
||||
static inline bool skb_pure_zcopy_same(const struct sk_buff *skb1,
|
||||
const struct sk_buff *skb2)
|
||||
{
|
||||
return skb_zcopy_pure(skb1) == skb_zcopy_pure(skb2);
|
||||
}
|
||||
|
||||
static inline void net_zcopy_get(struct ubuf_info *uarg)
|
||||
{
|
||||
refcount_inc(&uarg->refcnt);
|
||||
@ -1528,7 +1545,7 @@ static inline void skb_zcopy_clear(struct sk_buff *skb, bool zerocopy_success)
|
||||
if (!skb_zcopy_is_nouarg(skb))
|
||||
uarg->callback(skb, uarg, zerocopy_success);
|
||||
|
||||
skb_shinfo(skb)->flags &= ~SKBFL_ZEROCOPY_FRAG;
|
||||
skb_shinfo(skb)->flags &= ~SKBFL_ALL_ZEROCOPY;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1675,6 +1692,22 @@ static inline int skb_unclone(struct sk_buff *skb, gfp_t pri)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This variant of skb_unclone() makes sure skb->truesize is not changed */
|
||||
static inline int skb_unclone_keeptruesize(struct sk_buff *skb, gfp_t pri)
|
||||
{
|
||||
might_sleep_if(gfpflags_allow_blocking(pri));
|
||||
|
||||
if (skb_cloned(skb)) {
|
||||
unsigned int save = skb->truesize;
|
||||
int res;
|
||||
|
||||
res = pskb_expand_head(skb, 0, 0, pri);
|
||||
skb->truesize = save;
|
||||
return res;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* skb_header_cloned - is the header a clone
|
||||
* @skb: buffer to check
|
||||
|
@ -507,6 +507,18 @@ static inline bool sk_psock_strp_enabled(struct sk_psock *psock)
|
||||
return !!psock->saved_data_ready;
|
||||
}
|
||||
|
||||
static inline bool sk_is_tcp(const struct sock *sk)
|
||||
{
|
||||
return sk->sk_type == SOCK_STREAM &&
|
||||
sk->sk_protocol == IPPROTO_TCP;
|
||||
}
|
||||
|
||||
static inline bool sk_is_udp(const struct sock *sk)
|
||||
{
|
||||
return sk->sk_type == SOCK_DGRAM &&
|
||||
sk->sk_protocol == IPPROTO_UDP;
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_NET_SOCK_MSG)
|
||||
|
||||
#define BPF_F_STRPARSER (1UL << 1)
|
||||
|
@ -72,7 +72,9 @@ struct llc_sap {
|
||||
static inline
|
||||
struct hlist_head *llc_sk_dev_hash(struct llc_sap *sap, int ifindex)
|
||||
{
|
||||
return &sap->sk_dev_hash[ifindex % LLC_SK_DEV_HASH_ENTRIES];
|
||||
u32 bucket = hash_32(ifindex, LLC_SK_DEV_HASH_BITS);
|
||||
|
||||
return &sap->sk_dev_hash[bucket];
|
||||
}
|
||||
|
||||
static inline
|
||||
|
@ -1355,16 +1355,6 @@ struct sctp_endpoint {
|
||||
reconf_enable:1;
|
||||
|
||||
__u8 strreset_enable;
|
||||
|
||||
/* Security identifiers from incoming (INIT). These are set by
|
||||
* security_sctp_assoc_request(). These will only be used by
|
||||
* SCTP TCP type sockets and peeled off connections as they
|
||||
* cause a new socket to be generated. security_sctp_sk_clone()
|
||||
* will then plug these into the new socket.
|
||||
*/
|
||||
|
||||
u32 secid;
|
||||
u32 peer_secid;
|
||||
};
|
||||
|
||||
/* Recover the outter endpoint structure. */
|
||||
@ -2104,6 +2094,16 @@ struct sctp_association {
|
||||
__u64 abandoned_unsent[SCTP_PR_INDEX(MAX) + 1];
|
||||
__u64 abandoned_sent[SCTP_PR_INDEX(MAX) + 1];
|
||||
|
||||
/* Security identifiers from incoming (INIT). These are set by
|
||||
* security_sctp_assoc_request(). These will only be used by
|
||||
* SCTP TCP type sockets and peeled off connections as they
|
||||
* cause a new socket to be generated. security_sctp_sk_clone()
|
||||
* will then plug these into the new socket.
|
||||
*/
|
||||
|
||||
u32 secid;
|
||||
u32 peer_secid;
|
||||
|
||||
struct rcu_head rcu;
|
||||
};
|
||||
|
||||
|
@ -54,10 +54,28 @@ struct strp_msg {
|
||||
int offset;
|
||||
};
|
||||
|
||||
struct _strp_msg {
|
||||
/* Internal cb structure. struct strp_msg must be first for passing
|
||||
* to upper layer.
|
||||
*/
|
||||
struct strp_msg strp;
|
||||
int accum_len;
|
||||
};
|
||||
|
||||
struct sk_skb_cb {
|
||||
#define SK_SKB_CB_PRIV_LEN 20
|
||||
unsigned char data[SK_SKB_CB_PRIV_LEN];
|
||||
struct _strp_msg strp;
|
||||
/* temp_reg is a temporary register used for bpf_convert_data_end_access
|
||||
* when dst_reg == src_reg.
|
||||
*/
|
||||
u64 temp_reg;
|
||||
};
|
||||
|
||||
static inline struct strp_msg *strp_msg(struct sk_buff *skb)
|
||||
{
|
||||
return (struct strp_msg *)((void *)skb->cb +
|
||||
offsetof(struct qdisc_skb_cb, data));
|
||||
offsetof(struct sk_skb_cb, strp));
|
||||
}
|
||||
|
||||
/* Structure for an attached lower socket */
|
||||
|
@ -293,7 +293,10 @@ static inline bool tcp_out_of_memory(struct sock *sk)
|
||||
static inline void tcp_wmem_free_skb(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
sk_wmem_queued_add(sk, -skb->truesize);
|
||||
sk_mem_uncharge(sk, skb->truesize);
|
||||
if (!skb_zcopy_pure(skb))
|
||||
sk_mem_uncharge(sk, skb->truesize);
|
||||
else
|
||||
sk_mem_uncharge(sk, SKB_TRUESIZE(skb_end_offset(skb)));
|
||||
__kfree_skb(skb);
|
||||
}
|
||||
|
||||
@ -974,7 +977,8 @@ static inline bool tcp_skb_can_collapse(const struct sk_buff *to,
|
||||
const struct sk_buff *from)
|
||||
{
|
||||
return likely(tcp_skb_can_collapse_to(to) &&
|
||||
mptcp_skb_can_collapse(to, from));
|
||||
mptcp_skb_can_collapse(to, from) &&
|
||||
skb_pure_zcopy_same(to, from));
|
||||
}
|
||||
|
||||
/* Events passed to congestion control interface */
|
||||
|
@ -411,7 +411,9 @@ enum {
|
||||
ETHTOOL_A_PAUSE_STAT_TX_FRAMES,
|
||||
ETHTOOL_A_PAUSE_STAT_RX_FRAMES,
|
||||
|
||||
/* add new constants above here */
|
||||
/* add new constants above here
|
||||
* adjust ETHTOOL_PAUSE_STAT_CNT if adding non-stats!
|
||||
*/
|
||||
__ETHTOOL_A_PAUSE_STAT_CNT,
|
||||
ETHTOOL_A_PAUSE_STAT_MAX = (__ETHTOOL_A_PAUSE_STAT_CNT - 1)
|
||||
};
|
||||
|
@ -390,6 +390,13 @@ static int bpf_adj_branches(struct bpf_prog *prog, u32 pos, s32 end_old,
|
||||
i = end_new;
|
||||
insn = prog->insnsi + end_old;
|
||||
}
|
||||
if (bpf_pseudo_func(insn)) {
|
||||
ret = bpf_adj_delta_to_imm(insn, pos, end_old,
|
||||
end_new, i, probe_pass);
|
||||
if (ret)
|
||||
return ret;
|
||||
continue;
|
||||
}
|
||||
code = insn->code;
|
||||
if ((BPF_CLASS(code) != BPF_JMP &&
|
||||
BPF_CLASS(code) != BPF_JMP32) ||
|
||||
|
@ -240,12 +240,6 @@ static bool bpf_pseudo_kfunc_call(const struct bpf_insn *insn)
|
||||
insn->src_reg == BPF_PSEUDO_KFUNC_CALL;
|
||||
}
|
||||
|
||||
static bool bpf_pseudo_func(const struct bpf_insn *insn)
|
||||
{
|
||||
return insn->code == (BPF_LD | BPF_IMM | BPF_DW) &&
|
||||
insn->src_reg == BPF_PSEUDO_FUNC;
|
||||
}
|
||||
|
||||
struct bpf_call_arg_meta {
|
||||
struct bpf_map *map_ptr;
|
||||
bool raw_mode;
|
||||
@ -1960,16 +1954,10 @@ static int add_subprog_and_kfunc(struct bpf_verifier_env *env)
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
if (bpf_pseudo_func(insn)) {
|
||||
if (bpf_pseudo_func(insn) || bpf_pseudo_call(insn))
|
||||
ret = add_subprog(env, i + insn->imm + 1);
|
||||
if (ret >= 0)
|
||||
/* remember subprog */
|
||||
insn[1].imm = ret;
|
||||
} else if (bpf_pseudo_call(insn)) {
|
||||
ret = add_subprog(env, i + insn->imm + 1);
|
||||
} else {
|
||||
else
|
||||
ret = add_kfunc_call(env, insn->imm, insn->off);
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
@ -3088,9 +3076,12 @@ static int check_stack_read_fixed_off(struct bpf_verifier_env *env,
|
||||
reg = ®_state->stack[spi].spilled_ptr;
|
||||
|
||||
if (is_spilled_reg(®_state->stack[spi])) {
|
||||
if (size != BPF_REG_SIZE) {
|
||||
u8 scalar_size = 0;
|
||||
u8 spill_size = 1;
|
||||
|
||||
for (i = BPF_REG_SIZE - 1; i > 0 && stype[i - 1] == STACK_SPILL; i--)
|
||||
spill_size++;
|
||||
|
||||
if (size != BPF_REG_SIZE || spill_size != BPF_REG_SIZE) {
|
||||
if (reg->type != SCALAR_VALUE) {
|
||||
verbose_linfo(env, env->insn_idx, "; ");
|
||||
verbose(env, "invalid size of register fill\n");
|
||||
@ -3101,10 +3092,7 @@ static int check_stack_read_fixed_off(struct bpf_verifier_env *env,
|
||||
if (dst_regno < 0)
|
||||
return 0;
|
||||
|
||||
for (i = BPF_REG_SIZE; i > 0 && stype[i - 1] == STACK_SPILL; i--)
|
||||
scalar_size++;
|
||||
|
||||
if (!(off % BPF_REG_SIZE) && size == scalar_size) {
|
||||
if (!(off % BPF_REG_SIZE) && size == spill_size) {
|
||||
/* The earlier check_reg_arg() has decided the
|
||||
* subreg_def for this insn. Save it first.
|
||||
*/
|
||||
@ -3128,12 +3116,6 @@ static int check_stack_read_fixed_off(struct bpf_verifier_env *env,
|
||||
state->regs[dst_regno].live |= REG_LIVE_WRITTEN;
|
||||
return 0;
|
||||
}
|
||||
for (i = 1; i < BPF_REG_SIZE; i++) {
|
||||
if (stype[(slot - i) % BPF_REG_SIZE] != STACK_SPILL) {
|
||||
verbose(env, "corrupted spill memory\n");
|
||||
return -EACCES;
|
||||
}
|
||||
}
|
||||
|
||||
if (dst_regno >= 0) {
|
||||
/* restore register state from stack */
|
||||
@ -9393,7 +9375,8 @@ static int check_ld_imm(struct bpf_verifier_env *env, struct bpf_insn *insn)
|
||||
|
||||
if (insn->src_reg == BPF_PSEUDO_FUNC) {
|
||||
struct bpf_prog_aux *aux = env->prog->aux;
|
||||
u32 subprogno = insn[1].imm;
|
||||
u32 subprogno = find_subprog(env,
|
||||
env->insn_idx + insn->imm + 1);
|
||||
|
||||
if (!aux->func_info) {
|
||||
verbose(env, "missing btf func_info\n");
|
||||
@ -12563,14 +12546,9 @@ static int jit_subprogs(struct bpf_verifier_env *env)
|
||||
return 0;
|
||||
|
||||
for (i = 0, insn = prog->insnsi; i < prog->len; i++, insn++) {
|
||||
if (bpf_pseudo_func(insn)) {
|
||||
env->insn_aux_data[i].call_imm = insn->imm;
|
||||
/* subprog is encoded in insn[1].imm */
|
||||
if (!bpf_pseudo_func(insn) && !bpf_pseudo_call(insn))
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!bpf_pseudo_call(insn))
|
||||
continue;
|
||||
/* Upon error here we cannot fall back to interpreter but
|
||||
* need a hard reject of the program. Thus -EFAULT is
|
||||
* propagated in any case.
|
||||
@ -12591,6 +12569,12 @@ static int jit_subprogs(struct bpf_verifier_env *env)
|
||||
env->insn_aux_data[i].call_imm = insn->imm;
|
||||
/* point imm to __bpf_call_base+1 from JITs point of view */
|
||||
insn->imm = 1;
|
||||
if (bpf_pseudo_func(insn))
|
||||
/* jit (e.g. x86_64) may emit fewer instructions
|
||||
* if it learns a u32 imm is the same as a u64 imm.
|
||||
* Force a non zero here.
|
||||
*/
|
||||
insn[1].imm = 1;
|
||||
}
|
||||
|
||||
err = bpf_prog_alloc_jited_linfo(prog);
|
||||
@ -12675,7 +12659,7 @@ static int jit_subprogs(struct bpf_verifier_env *env)
|
||||
insn = func[i]->insnsi;
|
||||
for (j = 0; j < func[i]->len; j++, insn++) {
|
||||
if (bpf_pseudo_func(insn)) {
|
||||
subprog = insn[1].imm;
|
||||
subprog = insn->off;
|
||||
insn[0].imm = (u32)(long)func[subprog]->bpf_func;
|
||||
insn[1].imm = ((u64)(long)func[subprog]->bpf_func) >> 32;
|
||||
continue;
|
||||
@ -12726,7 +12710,8 @@ static int jit_subprogs(struct bpf_verifier_env *env)
|
||||
for (i = 0, insn = prog->insnsi; i < prog->len; i++, insn++) {
|
||||
if (bpf_pseudo_func(insn)) {
|
||||
insn[0].imm = env->insn_aux_data[i].call_imm;
|
||||
insn[1].imm = find_subprog(env, i + insn[0].imm + 1);
|
||||
insn[1].imm = insn->off;
|
||||
insn->off = 0;
|
||||
continue;
|
||||
}
|
||||
if (!bpf_pseudo_call(insn))
|
||||
|
24
mm/shmem.c
24
mm/shmem.c
@ -2960,28 +2960,6 @@ static int shmem_rmdir(struct inode *dir, struct dentry *dentry)
|
||||
return shmem_unlink(dir, dentry);
|
||||
}
|
||||
|
||||
static int shmem_exchange(struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry)
|
||||
{
|
||||
bool old_is_dir = d_is_dir(old_dentry);
|
||||
bool new_is_dir = d_is_dir(new_dentry);
|
||||
|
||||
if (old_dir != new_dir && old_is_dir != new_is_dir) {
|
||||
if (old_is_dir) {
|
||||
drop_nlink(old_dir);
|
||||
inc_nlink(new_dir);
|
||||
} else {
|
||||
drop_nlink(new_dir);
|
||||
inc_nlink(old_dir);
|
||||
}
|
||||
}
|
||||
old_dir->i_ctime = old_dir->i_mtime =
|
||||
new_dir->i_ctime = new_dir->i_mtime =
|
||||
d_inode(old_dentry)->i_ctime =
|
||||
d_inode(new_dentry)->i_ctime = current_time(old_dir);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int shmem_whiteout(struct user_namespace *mnt_userns,
|
||||
struct inode *old_dir, struct dentry *old_dentry)
|
||||
{
|
||||
@ -3027,7 +3005,7 @@ static int shmem_rename2(struct user_namespace *mnt_userns,
|
||||
return -EINVAL;
|
||||
|
||||
if (flags & RENAME_EXCHANGE)
|
||||
return shmem_exchange(old_dir, old_dentry, new_dir, new_dentry);
|
||||
return simple_rename_exchange(old_dir, old_dentry, new_dir, new_dentry);
|
||||
|
||||
if (!simple_empty(new_dentry))
|
||||
return -ENOTEMPTY;
|
||||
|
@ -123,9 +123,6 @@ void unregister_vlan_dev(struct net_device *dev, struct list_head *head)
|
||||
}
|
||||
|
||||
vlan_vid_del(real_dev, vlan->vlan_proto, vlan_id);
|
||||
|
||||
/* Get rid of the vlan's reference to real_dev */
|
||||
dev_put(real_dev);
|
||||
}
|
||||
|
||||
int vlan_check_real_dev(struct net_device *real_dev,
|
||||
|
@ -843,6 +843,9 @@ static void vlan_dev_free(struct net_device *dev)
|
||||
|
||||
free_percpu(vlan->vlan_pcpu_stats);
|
||||
vlan->vlan_pcpu_stats = NULL;
|
||||
|
||||
/* Get rid of the vlan's reference to real_dev */
|
||||
dev_put(vlan->real_dev);
|
||||
}
|
||||
|
||||
void vlan_setup(struct net_device *dev)
|
||||
|
@ -75,6 +75,13 @@ static void j1939_can_recv(struct sk_buff *iskb, void *data)
|
||||
skcb->addr.pgn = (cf->can_id >> 8) & J1939_PGN_MAX;
|
||||
/* set default message type */
|
||||
skcb->addr.type = J1939_TP;
|
||||
|
||||
if (!j1939_address_is_valid(skcb->addr.sa)) {
|
||||
netdev_err_once(priv->ndev, "%s: sa is broadcast address, ignoring!\n",
|
||||
__func__);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (j1939_pgn_is_pdu1(skcb->addr.pgn)) {
|
||||
/* Type 1: with destination address */
|
||||
skcb->addr.da = skcb->addr.pgn;
|
||||
|
@ -2023,6 +2023,11 @@ static void j1939_tp_cmd_recv(struct j1939_priv *priv, struct sk_buff *skb)
|
||||
extd = J1939_ETP;
|
||||
fallthrough;
|
||||
case J1939_TP_CMD_BAM:
|
||||
if (cmd == J1939_TP_CMD_BAM && !j1939_cb_is_broadcast(skcb)) {
|
||||
netdev_err_once(priv->ndev, "%s: BAM to unicast (%02x), ignoring!\n",
|
||||
__func__, skcb->addr.sa);
|
||||
return;
|
||||
}
|
||||
fallthrough;
|
||||
case J1939_TP_CMD_RTS:
|
||||
if (skcb->addr.type != extd)
|
||||
@ -2085,6 +2090,12 @@ static void j1939_tp_cmd_recv(struct j1939_priv *priv, struct sk_buff *skb)
|
||||
break;
|
||||
|
||||
case J1939_ETP_CMD_ABORT: /* && J1939_TP_CMD_ABORT */
|
||||
if (j1939_cb_is_broadcast(skcb)) {
|
||||
netdev_err_once(priv->ndev, "%s: abort to broadcast (%02x), ignoring!\n",
|
||||
__func__, skcb->addr.sa);
|
||||
return;
|
||||
}
|
||||
|
||||
if (j1939_tp_im_transmitter(skcb))
|
||||
j1939_xtp_rx_abort(priv, skb, true);
|
||||
|
||||
|
@ -646,7 +646,8 @@ int __zerocopy_sg_from_iter(struct sock *sk, struct sk_buff *skb,
|
||||
skb->truesize += truesize;
|
||||
if (sk && sk->sk_type == SOCK_STREAM) {
|
||||
sk_wmem_queued_add(sk, truesize);
|
||||
sk_mem_charge(sk, truesize);
|
||||
if (!skb_zcopy_pure(skb))
|
||||
sk_mem_charge(sk, truesize);
|
||||
} else {
|
||||
refcount_add(truesize, &skb->sk->sk_wmem_alloc);
|
||||
}
|
||||
|
@ -6928,7 +6928,7 @@ void napi_disable(struct napi_struct *n)
|
||||
might_sleep();
|
||||
set_bit(NAPI_STATE_DISABLE, &n->state);
|
||||
|
||||
do {
|
||||
for ( ; ; ) {
|
||||
val = READ_ONCE(n->state);
|
||||
if (val & (NAPIF_STATE_SCHED | NAPIF_STATE_NPSVC)) {
|
||||
usleep_range(20, 200);
|
||||
@ -6937,7 +6937,10 @@ void napi_disable(struct napi_struct *n)
|
||||
|
||||
new = val | NAPIF_STATE_SCHED | NAPIF_STATE_NPSVC;
|
||||
new &= ~(NAPIF_STATE_THREADED | NAPIF_STATE_PREFER_BUSY_POLL);
|
||||
} while (cmpxchg(&n->state, val, new) != val);
|
||||
|
||||
if (cmpxchg(&n->state, val, new) == val)
|
||||
break;
|
||||
}
|
||||
|
||||
hrtimer_cancel(&n->timer);
|
||||
|
||||
|
@ -66,7 +66,7 @@ struct devlink {
|
||||
u8 reload_failed:1;
|
||||
refcount_t refcount;
|
||||
struct completion comp;
|
||||
char priv[0] __aligned(NETDEV_ALIGN);
|
||||
char priv[] __aligned(NETDEV_ALIGN);
|
||||
};
|
||||
|
||||
void *devlink_priv(struct devlink *devlink)
|
||||
|
@ -9756,22 +9756,46 @@ static u32 sock_ops_convert_ctx_access(enum bpf_access_type type,
|
||||
static struct bpf_insn *bpf_convert_data_end_access(const struct bpf_insn *si,
|
||||
struct bpf_insn *insn)
|
||||
{
|
||||
/* si->dst_reg = skb->data */
|
||||
int reg;
|
||||
int temp_reg_off = offsetof(struct sk_buff, cb) +
|
||||
offsetof(struct sk_skb_cb, temp_reg);
|
||||
|
||||
if (si->src_reg == si->dst_reg) {
|
||||
/* We need an extra register, choose and save a register. */
|
||||
reg = BPF_REG_9;
|
||||
if (si->src_reg == reg || si->dst_reg == reg)
|
||||
reg--;
|
||||
if (si->src_reg == reg || si->dst_reg == reg)
|
||||
reg--;
|
||||
*insn++ = BPF_STX_MEM(BPF_DW, si->src_reg, reg, temp_reg_off);
|
||||
} else {
|
||||
reg = si->dst_reg;
|
||||
}
|
||||
|
||||
/* reg = skb->data */
|
||||
*insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct sk_buff, data),
|
||||
si->dst_reg, si->src_reg,
|
||||
reg, si->src_reg,
|
||||
offsetof(struct sk_buff, data));
|
||||
/* AX = skb->len */
|
||||
*insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct sk_buff, len),
|
||||
BPF_REG_AX, si->src_reg,
|
||||
offsetof(struct sk_buff, len));
|
||||
/* si->dst_reg = skb->data + skb->len */
|
||||
*insn++ = BPF_ALU64_REG(BPF_ADD, si->dst_reg, BPF_REG_AX);
|
||||
/* reg = skb->data + skb->len */
|
||||
*insn++ = BPF_ALU64_REG(BPF_ADD, reg, BPF_REG_AX);
|
||||
/* AX = skb->data_len */
|
||||
*insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct sk_buff, data_len),
|
||||
BPF_REG_AX, si->src_reg,
|
||||
offsetof(struct sk_buff, data_len));
|
||||
/* si->dst_reg = skb->data + skb->len - skb->data_len */
|
||||
*insn++ = BPF_ALU64_REG(BPF_SUB, si->dst_reg, BPF_REG_AX);
|
||||
|
||||
/* reg = skb->data + skb->len - skb->data_len */
|
||||
*insn++ = BPF_ALU64_REG(BPF_SUB, reg, BPF_REG_AX);
|
||||
|
||||
if (si->src_reg == si->dst_reg) {
|
||||
/* Restore the saved register */
|
||||
*insn++ = BPF_MOV64_REG(BPF_REG_AX, si->src_reg);
|
||||
*insn++ = BPF_MOV64_REG(si->dst_reg, reg);
|
||||
*insn++ = BPF_LDX_MEM(BPF_DW, reg, BPF_REG_AX, temp_reg_off);
|
||||
}
|
||||
|
||||
return insn;
|
||||
}
|
||||
@ -9782,11 +9806,33 @@ static u32 sk_skb_convert_ctx_access(enum bpf_access_type type,
|
||||
struct bpf_prog *prog, u32 *target_size)
|
||||
{
|
||||
struct bpf_insn *insn = insn_buf;
|
||||
int off;
|
||||
|
||||
switch (si->off) {
|
||||
case offsetof(struct __sk_buff, data_end):
|
||||
insn = bpf_convert_data_end_access(si, insn);
|
||||
break;
|
||||
case offsetof(struct __sk_buff, cb[0]) ...
|
||||
offsetofend(struct __sk_buff, cb[4]) - 1:
|
||||
BUILD_BUG_ON(sizeof_field(struct sk_skb_cb, data) < 20);
|
||||
BUILD_BUG_ON((offsetof(struct sk_buff, cb) +
|
||||
offsetof(struct sk_skb_cb, data)) %
|
||||
sizeof(__u64));
|
||||
|
||||
prog->cb_access = 1;
|
||||
off = si->off;
|
||||
off -= offsetof(struct __sk_buff, cb[0]);
|
||||
off += offsetof(struct sk_buff, cb);
|
||||
off += offsetof(struct sk_skb_cb, data);
|
||||
if (type == BPF_WRITE)
|
||||
*insn++ = BPF_STX_MEM(BPF_SIZE(si->code), si->dst_reg,
|
||||
si->src_reg, off);
|
||||
else
|
||||
*insn++ = BPF_LDX_MEM(BPF_SIZE(si->code), si->dst_reg,
|
||||
si->src_reg, off);
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
return bpf_convert_ctx_access(type, si, insn_buf, prog,
|
||||
target_size);
|
||||
@ -10423,8 +10469,10 @@ BPF_CALL_3(bpf_sk_lookup_assign, struct bpf_sk_lookup_kern *, ctx,
|
||||
return -EINVAL;
|
||||
if (unlikely(sk && sk_is_refcounted(sk)))
|
||||
return -ESOCKTNOSUPPORT; /* reject non-RCU freed sockets */
|
||||
if (unlikely(sk && sk->sk_state == TCP_ESTABLISHED))
|
||||
return -ESOCKTNOSUPPORT; /* reject connected sockets */
|
||||
if (unlikely(sk && sk_is_tcp(sk) && sk->sk_state != TCP_LISTEN))
|
||||
return -ESOCKTNOSUPPORT; /* only accept TCP socket in LISTEN */
|
||||
if (unlikely(sk && sk_is_udp(sk) && sk->sk_state != TCP_CLOSE))
|
||||
return -ESOCKTNOSUPPORT; /* only accept UDP socket in CLOSE */
|
||||
|
||||
/* Check if socket is suitable for packet L3/L4 protocol */
|
||||
if (sk && sk->sk_protocol != ctx->protocol)
|
||||
|
@ -3433,8 +3433,9 @@ static inline void skb_split_no_header(struct sk_buff *skb,
|
||||
void skb_split(struct sk_buff *skb, struct sk_buff *skb1, const u32 len)
|
||||
{
|
||||
int pos = skb_headlen(skb);
|
||||
const int zc_flags = SKBFL_SHARED_FRAG | SKBFL_PURE_ZEROCOPY;
|
||||
|
||||
skb_shinfo(skb1)->flags |= skb_shinfo(skb)->flags & SKBFL_SHARED_FRAG;
|
||||
skb_shinfo(skb1)->flags |= skb_shinfo(skb)->flags & zc_flags;
|
||||
skb_zerocopy_clone(skb1, skb, 0);
|
||||
if (len < pos) /* Split line is inside header. */
|
||||
skb_split_inside_header(skb, skb1, len, pos);
|
||||
@ -3449,19 +3450,7 @@ EXPORT_SYMBOL(skb_split);
|
||||
*/
|
||||
static int skb_prepare_for_shift(struct sk_buff *skb)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (skb_cloned(skb)) {
|
||||
/* Save and restore truesize: pskb_expand_head() may reallocate
|
||||
* memory where ksize(kmalloc(S)) != ksize(kmalloc(S)), but we
|
||||
* cannot change truesize at this point.
|
||||
*/
|
||||
unsigned int save_truesize = skb->truesize;
|
||||
|
||||
ret = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
|
||||
skb->truesize = save_truesize;
|
||||
}
|
||||
return ret;
|
||||
return skb_unclone_keeptruesize(skb, GFP_ATOMIC);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -976,7 +976,7 @@ static int sock_reserve_memory(struct sock *sk, int bytes)
|
||||
bool charged;
|
||||
int pages;
|
||||
|
||||
if (!mem_cgroup_sockets_enabled || !sk->sk_memcg)
|
||||
if (!mem_cgroup_sockets_enabled || !sk->sk_memcg || !sk_has_account(sk))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (!bytes)
|
||||
|
@ -511,12 +511,6 @@ static bool sock_map_op_okay(const struct bpf_sock_ops_kern *ops)
|
||||
ops->op == BPF_SOCK_OPS_TCP_LISTEN_CB;
|
||||
}
|
||||
|
||||
static bool sk_is_tcp(const struct sock *sk)
|
||||
{
|
||||
return sk->sk_type == SOCK_STREAM &&
|
||||
sk->sk_protocol == IPPROTO_TCP;
|
||||
}
|
||||
|
||||
static bool sock_map_redirect_allowed(const struct sock *sk)
|
||||
{
|
||||
if (sk_is_tcp(sk))
|
||||
|
@ -101,6 +101,7 @@ static struct sk_buff *ocelot_rcv(struct sk_buff *skb,
|
||||
struct dsa_port *dp;
|
||||
u8 *extraction;
|
||||
u16 vlan_tpid;
|
||||
u64 rew_val;
|
||||
|
||||
/* Revert skb->data by the amount consumed by the DSA master,
|
||||
* so it points to the beginning of the frame.
|
||||
@ -130,6 +131,7 @@ static struct sk_buff *ocelot_rcv(struct sk_buff *skb,
|
||||
ocelot_xfh_get_qos_class(extraction, &qos_class);
|
||||
ocelot_xfh_get_tag_type(extraction, &tag_type);
|
||||
ocelot_xfh_get_vlan_tci(extraction, &vlan_tci);
|
||||
ocelot_xfh_get_rew_val(extraction, &rew_val);
|
||||
|
||||
skb->dev = dsa_master_find_slave(netdev, 0, src_port);
|
||||
if (!skb->dev)
|
||||
@ -143,6 +145,7 @@ static struct sk_buff *ocelot_rcv(struct sk_buff *skb,
|
||||
|
||||
dsa_default_offload_fwd_mark(skb);
|
||||
skb->priority = qos_class;
|
||||
OCELOT_SKB_CB(skb)->tstamp_lo = rew_val;
|
||||
|
||||
/* Ocelot switches copy frames unmodified to the CPU. However, it is
|
||||
* possible for the user to request a VLAN modification through
|
||||
|
@ -56,8 +56,7 @@ static int pause_reply_size(const struct ethnl_req_info *req_base,
|
||||
|
||||
if (req_base->flags & ETHTOOL_FLAG_STATS)
|
||||
n += nla_total_size(0) + /* _PAUSE_STATS */
|
||||
nla_total_size_64bit(sizeof(u64)) *
|
||||
(ETHTOOL_A_PAUSE_STAT_MAX - 2);
|
||||
nla_total_size_64bit(sizeof(u64)) * ETHTOOL_PAUSE_STAT_CNT;
|
||||
return n;
|
||||
}
|
||||
|
||||
|
@ -862,6 +862,7 @@ struct sk_buff *tcp_stream_alloc_skb(struct sock *sk, int size, gfp_t gfp,
|
||||
if (likely(skb)) {
|
||||
bool mem_scheduled;
|
||||
|
||||
skb->truesize = SKB_TRUESIZE(skb_end_offset(skb));
|
||||
if (force_schedule) {
|
||||
mem_scheduled = true;
|
||||
sk_forced_mem_schedule(sk, skb->truesize);
|
||||
@ -1318,6 +1319,15 @@ new_segment:
|
||||
|
||||
copy = min_t(int, copy, pfrag->size - pfrag->offset);
|
||||
|
||||
/* skb changing from pure zc to mixed, must charge zc */
|
||||
if (unlikely(skb_zcopy_pure(skb))) {
|
||||
if (!sk_wmem_schedule(sk, skb->data_len))
|
||||
goto wait_for_space;
|
||||
|
||||
sk_mem_charge(sk, skb->data_len);
|
||||
skb_shinfo(skb)->flags &= ~SKBFL_PURE_ZEROCOPY;
|
||||
}
|
||||
|
||||
if (!sk_wmem_schedule(sk, copy))
|
||||
goto wait_for_space;
|
||||
|
||||
@ -1338,8 +1348,16 @@ new_segment:
|
||||
}
|
||||
pfrag->offset += copy;
|
||||
} else {
|
||||
if (!sk_wmem_schedule(sk, copy))
|
||||
goto wait_for_space;
|
||||
/* First append to a fragless skb builds initial
|
||||
* pure zerocopy skb
|
||||
*/
|
||||
if (!skb->len)
|
||||
skb_shinfo(skb)->flags |= SKBFL_PURE_ZEROCOPY;
|
||||
|
||||
if (!skb_zcopy_pure(skb)) {
|
||||
if (!sk_wmem_schedule(sk, copy))
|
||||
goto wait_for_space;
|
||||
}
|
||||
|
||||
err = skb_zerocopy_iter_stream(sk, skb, msg, copy, uarg);
|
||||
if (err == -EMSGSIZE || err == -EEXIST) {
|
||||
|
@ -172,6 +172,41 @@ static int tcp_msg_wait_data(struct sock *sk, struct sk_psock *psock,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int tcp_bpf_recvmsg_parser(struct sock *sk,
|
||||
struct msghdr *msg,
|
||||
size_t len,
|
||||
int nonblock,
|
||||
int flags,
|
||||
int *addr_len)
|
||||
{
|
||||
struct sk_psock *psock;
|
||||
int copied;
|
||||
|
||||
if (unlikely(flags & MSG_ERRQUEUE))
|
||||
return inet_recv_error(sk, msg, len, addr_len);
|
||||
|
||||
psock = sk_psock_get(sk);
|
||||
if (unlikely(!psock))
|
||||
return tcp_recvmsg(sk, msg, len, nonblock, flags, addr_len);
|
||||
|
||||
lock_sock(sk);
|
||||
msg_bytes_ready:
|
||||
copied = sk_msg_recvmsg(sk, psock, msg, len, flags);
|
||||
if (!copied) {
|
||||
long timeo;
|
||||
int data;
|
||||
|
||||
timeo = sock_rcvtimeo(sk, nonblock);
|
||||
data = tcp_msg_wait_data(sk, psock, timeo);
|
||||
if (data && !sk_psock_queue_empty(psock))
|
||||
goto msg_bytes_ready;
|
||||
copied = -EAGAIN;
|
||||
}
|
||||
release_sock(sk);
|
||||
sk_psock_put(sk, psock);
|
||||
return copied;
|
||||
}
|
||||
|
||||
static int tcp_bpf_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
|
||||
int nonblock, int flags, int *addr_len)
|
||||
{
|
||||
@ -464,6 +499,8 @@ enum {
|
||||
enum {
|
||||
TCP_BPF_BASE,
|
||||
TCP_BPF_TX,
|
||||
TCP_BPF_RX,
|
||||
TCP_BPF_TXRX,
|
||||
TCP_BPF_NUM_CFGS,
|
||||
};
|
||||
|
||||
@ -475,7 +512,6 @@ static void tcp_bpf_rebuild_protos(struct proto prot[TCP_BPF_NUM_CFGS],
|
||||
struct proto *base)
|
||||
{
|
||||
prot[TCP_BPF_BASE] = *base;
|
||||
prot[TCP_BPF_BASE].unhash = sock_map_unhash;
|
||||
prot[TCP_BPF_BASE].close = sock_map_close;
|
||||
prot[TCP_BPF_BASE].recvmsg = tcp_bpf_recvmsg;
|
||||
prot[TCP_BPF_BASE].sock_is_readable = sk_msg_is_readable;
|
||||
@ -483,6 +519,12 @@ static void tcp_bpf_rebuild_protos(struct proto prot[TCP_BPF_NUM_CFGS],
|
||||
prot[TCP_BPF_TX] = prot[TCP_BPF_BASE];
|
||||
prot[TCP_BPF_TX].sendmsg = tcp_bpf_sendmsg;
|
||||
prot[TCP_BPF_TX].sendpage = tcp_bpf_sendpage;
|
||||
|
||||
prot[TCP_BPF_RX] = prot[TCP_BPF_BASE];
|
||||
prot[TCP_BPF_RX].recvmsg = tcp_bpf_recvmsg_parser;
|
||||
|
||||
prot[TCP_BPF_TXRX] = prot[TCP_BPF_TX];
|
||||
prot[TCP_BPF_TXRX].recvmsg = tcp_bpf_recvmsg_parser;
|
||||
}
|
||||
|
||||
static void tcp_bpf_check_v6_needs_rebuild(struct proto *ops)
|
||||
@ -520,6 +562,10 @@ int tcp_bpf_update_proto(struct sock *sk, struct sk_psock *psock, bool restore)
|
||||
int family = sk->sk_family == AF_INET6 ? TCP_BPF_IPV6 : TCP_BPF_IPV4;
|
||||
int config = psock->progs.msg_parser ? TCP_BPF_TX : TCP_BPF_BASE;
|
||||
|
||||
if (psock->progs.stream_verdict || psock->progs.skb_verdict) {
|
||||
config = (config == TCP_BPF_TX) ? TCP_BPF_TXRX : TCP_BPF_RX;
|
||||
}
|
||||
|
||||
if (restore) {
|
||||
if (inet_csk_has_ulp(sk)) {
|
||||
/* TLS does not have an unhash proto in SW cases,
|
||||
|
@ -408,13 +408,13 @@ static inline bool tcp_urg_mode(const struct tcp_sock *tp)
|
||||
return tp->snd_una != tp->snd_up;
|
||||
}
|
||||
|
||||
#define OPTION_SACK_ADVERTISE (1 << 0)
|
||||
#define OPTION_TS (1 << 1)
|
||||
#define OPTION_MD5 (1 << 2)
|
||||
#define OPTION_WSCALE (1 << 3)
|
||||
#define OPTION_FAST_OPEN_COOKIE (1 << 8)
|
||||
#define OPTION_SMC (1 << 9)
|
||||
#define OPTION_MPTCP (1 << 10)
|
||||
#define OPTION_SACK_ADVERTISE BIT(0)
|
||||
#define OPTION_TS BIT(1)
|
||||
#define OPTION_MD5 BIT(2)
|
||||
#define OPTION_WSCALE BIT(3)
|
||||
#define OPTION_FAST_OPEN_COOKIE BIT(8)
|
||||
#define OPTION_SMC BIT(9)
|
||||
#define OPTION_MPTCP BIT(10)
|
||||
|
||||
static void smc_options_write(__be32 *ptr, u16 *options)
|
||||
{
|
||||
@ -1559,7 +1559,7 @@ int tcp_fragment(struct sock *sk, enum tcp_queue tcp_queue,
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (skb_unclone(skb, gfp))
|
||||
if (skb_unclone_keeptruesize(skb, gfp))
|
||||
return -ENOMEM;
|
||||
|
||||
/* Get a new skb... force flag on. */
|
||||
@ -1667,7 +1667,7 @@ int tcp_trim_head(struct sock *sk, struct sk_buff *skb, u32 len)
|
||||
{
|
||||
u32 delta_truesize;
|
||||
|
||||
if (skb_unclone(skb, GFP_ATOMIC))
|
||||
if (skb_unclone_keeptruesize(skb, GFP_ATOMIC))
|
||||
return -ENOMEM;
|
||||
|
||||
delta_truesize = __pskb_trim_head(skb, len);
|
||||
@ -1677,7 +1677,8 @@ int tcp_trim_head(struct sock *sk, struct sk_buff *skb, u32 len)
|
||||
if (delta_truesize) {
|
||||
skb->truesize -= delta_truesize;
|
||||
sk_wmem_queued_add(sk, -delta_truesize);
|
||||
sk_mem_uncharge(sk, delta_truesize);
|
||||
if (!skb_zcopy_pure(skb))
|
||||
sk_mem_uncharge(sk, delta_truesize);
|
||||
}
|
||||
|
||||
/* Any change of skb->len requires recalculation of tso factor. */
|
||||
@ -2295,7 +2296,9 @@ static bool tcp_can_coalesce_send_queue_head(struct sock *sk, int len)
|
||||
if (len <= skb->len)
|
||||
break;
|
||||
|
||||
if (unlikely(TCP_SKB_CB(skb)->eor) || tcp_has_tx_tstamp(skb))
|
||||
if (unlikely(TCP_SKB_CB(skb)->eor) ||
|
||||
tcp_has_tx_tstamp(skb) ||
|
||||
!skb_pure_zcopy_same(skb, next))
|
||||
return false;
|
||||
|
||||
len -= skb->len;
|
||||
@ -3166,7 +3169,7 @@ int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb, int segs)
|
||||
cur_mss, GFP_ATOMIC))
|
||||
return -ENOMEM; /* We'll try again later. */
|
||||
} else {
|
||||
if (skb_unclone(skb, GFP_ATOMIC))
|
||||
if (skb_unclone_keeptruesize(skb, GFP_ATOMIC))
|
||||
return -ENOMEM;
|
||||
|
||||
diff = tcp_skb_pcount(skb);
|
||||
|
@ -378,7 +378,7 @@ static int __net_init seg6_net_init(struct net *net)
|
||||
kfree(rcu_dereference_raw(sdata->tun_src));
|
||||
kfree(sdata);
|
||||
return -ENOMEM;
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
@ -1263,7 +1263,6 @@ static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *
|
||||
|
||||
inet_sk(newsk)->pinet6 = tcp_inet6_sk(newsk);
|
||||
|
||||
newinet = inet_sk(newsk);
|
||||
newnp = tcp_inet6_sk(newsk);
|
||||
newtp = tcp_sk(newsk);
|
||||
|
||||
|
@ -700,9 +700,9 @@ static int udpv6_queue_rcv_one_skb(struct sock *sk, struct sk_buff *skb)
|
||||
|
||||
ret = encap_rcv(sk, skb);
|
||||
if (ret <= 0) {
|
||||
__UDP_INC_STATS(sock_net(sk),
|
||||
UDP_MIB_INDATAGRAMS,
|
||||
is_udplite);
|
||||
__UDP6_INC_STATS(sock_net(sk),
|
||||
UDP_MIB_INDATAGRAMS,
|
||||
is_udplite);
|
||||
return -ret;
|
||||
}
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user