The following commit has been merged in the master branch: commit 3793faad7b5b730941b2efbc252d14374b60843a Merge: ae1804de93f6f1626906567ae7deec8e0111259d a811c1fa0a02c062555b54651065899437bacdbe Author: David S. Miller davem@davemloft.net Date: Wed May 6 22:10:13 2020 -0700
Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
Conflicts were all overlapping changes.
Signed-off-by: David S. Miller davem@davemloft.net
diff --combined Documentation/admin-guide/kernel-parameters.txt index 398c34804bb8,7bc83f3d9bdf..a827ec820f73 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@@ -356,7 -356,7 +356,7 @@@ shot down by NMI
autoconf= [IPV6] - See Documentation/networking/ipv6.txt. + See Documentation/networking/ipv6.rst.
show_lapic= [APIC,X86] Advanced Programmable Interrupt Controller Limit apic dumping. The parameter defines the maximal @@@ -638,7 -638,7 +638,7 @@@
See Documentation/admin-guide/serial-console.rst for more information. See - Documentation/networking/netconsole.txt for an + Documentation/networking/netconsole.rst for an alternative.
uart[8250],io,<addr>[,options] @@@ -831,7 -831,7 +831,7 @@@
decnet.addr= [HW,NET] Format: <area>[,<node>] - See also Documentation/networking/decnet.txt. + See also Documentation/networking/decnet.rst.
default_hugepagesz= [same as hugepagesz=] The size of the default @@@ -872,7 -872,7 +872,7 @@@ miss to occur.
disable= [IPV6] - See Documentation/networking/ipv6.txt. + See Documentation/networking/ipv6.rst.
hardened_usercopy= [KNL] Under CONFIG_HARDENED_USERCOPY, whether @@@ -912,7 -912,7 +912,7 @@@ to workaround buggy firmware.
disable_ipv6= [IPV6] - See Documentation/networking/ipv6.txt. + See Documentation/networking/ipv6.rst.
disable_mtrr_cleanup [X86] The kernel tries to adjust MTRR layout from continuous @@@ -4910,7 -4910,7 +4910,7 @@@ Set the number of tcp_metrics_hash slots. Default value is 8192 or 16384 depending on total ram pages. This is used to specify the TCP metrics - cache size. See Documentation/networking/ip-sysctl.txt + cache size. See Documentation/networking/ip-sysctl.rst "tcp_no_metrics_save" section for more details.
tdfx= [HW,DRM] @@@ -5187,8 -5187,7 +5187,7 @@@
usbcore.old_scheme_first= [USB] Start with the old device initialization - scheme, applies only to low and full-speed devices - (default 0 = off). + scheme (default 0 = off).
usbcore.usbfs_memory_mb= [USB] Memory limit (in MB) for buffers allocated by diff --combined MAINTAINERS index db7a6d462dff,88bf36ab2b22..e581ae499057 --- a/MAINTAINERS +++ b/MAINTAINERS @@@ -147,7 -147,7 +147,7 @@@ Maintainers Lis M: Steffen Klassert klassert@kernel.org L: netdev@vger.kernel.org S: Odd Fixes -F: Documentation/networking/device_drivers/3com/vortex.txt +F: Documentation/networking/device_drivers/3com/vortex.rst F: drivers/net/ethernet/3com/3c59x.c
3CR990 NETWORK DRIVER @@@ -193,7 -193,7 +193,7 @@@ W: https://wireless.wiki.kernel.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211.git T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git F: Documentation/driver-api/80211/cfg80211.rst -F: Documentation/networking/regulatory.txt +F: Documentation/networking/regulatory.rst F: include/linux/ieee80211.h F: include/net/cfg80211.h F: include/net/ieee80211_radiotap.h @@@ -570,7 -570,7 +570,7 @@@ F: Documentation/devicetree/bindings/ii F: drivers/input/misc/adxl34x.c
ADXL372 THREE-AXIS DIGITAL ACCELEROMETER DRIVER - M: Stefan Popa stefan.popa@analog.com + M: Michael Hennerich michael.hennerich@analog.com S: Supported W: http://ez.analog.com/community/linux-device-drivers F: Documentation/devicetree/bindings/iio/accel/adi,adxl372.yaml @@@ -815,7 -815,7 +815,7 @@@ R: Saeed Bishara <saeedb@amazon.com R: Zorik Machulsky zorik@amazon.com L: netdev@vger.kernel.org S: Supported -F: Documentation/networking/device_drivers/amazon/ena.txt +F: Documentation/networking/device_drivers/amazon/ena.rst F: drivers/net/ethernet/amazon/
AMAZON RDMA EFA DRIVER @@@ -922,7 -922,7 +922,7 @@@ F: arch/arm64/boot/dts/amd/amd-seattle- F: drivers/net/ethernet/amd/xgbe/
ANALOG DEVICES INC AD5686 DRIVER - M: Stefan Popa stefan.popa@analog.com + M: Michael Hennerich Michael.Hennerich@analog.com L: linux-pm@vger.kernel.org S: Supported W: http://ez.analog.com/community/linux-device-drivers @@@ -930,7 -930,7 +930,7 @@@ F: drivers/iio/dac/ad5686 F: drivers/iio/dac/ad5696*
ANALOG DEVICES INC AD5758 DRIVER - M: Stefan Popa stefan.popa@analog.com + M: Michael Hennerich Michael.Hennerich@analog.com L: linux-iio@vger.kernel.org S: Supported W: http://ez.analog.com/community/linux-device-drivers @@@ -946,7 -946,7 +946,7 @@@ F: Documentation/devicetree/bindings/ii F: drivers/iio/adc/ad7091r5.c
ANALOG DEVICES INC AD7124 DRIVER - M: Stefan Popa stefan.popa@analog.com + M: Michael Hennerich Michael.Hennerich@analog.com L: linux-iio@vger.kernel.org S: Supported W: http://ez.analog.com/community/linux-device-drivers @@@ -970,7 -970,7 +970,7 @@@ F: Documentation/devicetree/bindings/ii F: drivers/iio/adc/ad7292.c
ANALOG DEVICES INC AD7606 DRIVER - M: Stefan Popa stefan.popa@analog.com + M: Michael Hennerich Michael.Hennerich@analog.com M: Beniamin Bia beniamin.bia@analog.com L: linux-iio@vger.kernel.org S: Supported @@@ -979,7 -979,7 +979,7 @@@ F: Documentation/devicetree/bindings/ii F: drivers/iio/adc/ad7606.c
ANALOG DEVICES INC AD7768-1 DRIVER - M: Stefan Popa stefan.popa@analog.com + M: Michael Hennerich Michael.Hennerich@analog.com L: linux-iio@vger.kernel.org S: Supported W: http://ez.analog.com/community/linux-device-drivers @@@ -1040,7 -1040,7 +1040,7 @@@ F: Documentation/devicetree/bindings/hw F: drivers/hwmon/adm1177.c
ANALOG DEVICES INC ADP5061 DRIVER - M: Stefan Popa stefan.popa@analog.com + M: Michael Hennerich Michael.Hennerich@analog.com L: linux-pm@vger.kernel.org S: Supported W: http://ez.analog.com/community/linux-device-drivers @@@ -1109,7 -1109,6 +1109,6 @@@ F: drivers/iio/amplifiers/hmc425a. ANALOG DEVICES INC IIO DRIVERS M: Lars-Peter Clausen lars@metafoo.de M: Michael Hennerich Michael.Hennerich@analog.com - M: Stefan Popa stefan.popa@analog.com S: Supported W: http://wiki.analog.com/ W: http://ez.analog.com/community/linux-device-drivers @@@ -1275,7 -1274,7 +1274,7 @@@ L: netdev@vger.kernel.or S: Supported W: https://www.marvell.com/ Q: http://patchwork.ozlabs.org/project/netdev/list/ -F: Documentation/networking/device_drivers/aquantia/atlantic.txt +F: Documentation/networking/device_drivers/aquantia/atlantic.rst F: drivers/net/ethernet/aquantia/atlantic/
AQUANTIA ETHERNET DRIVER PTP SUBSYSTEM @@@ -3192,7 -3191,7 +3191,7 @@@ Q: https://patchwork.ozlabs.org/project T: git git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf.git T: git git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git F: Documentation/bpf/ -F: Documentation/networking/filter.txt +F: Documentation/networking/filter.rst F: arch/*/net/* F: include/linux/bpf* F: include/linux/filter.h @@@ -3658,7 -3657,7 +3657,7 @@@ L: linux-btrfs@vger.kernel.or S: Maintained W: http://btrfs.wiki.kernel.org/ Q: http://patchwork.kernel.org/project/linux-btrfs/list/ - T: git git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs.git + T: git git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux.git F: Documentation/filesystems/btrfs.rst F: fs/btrfs/ F: include/linux/btrfs* @@@ -4694,7 -4693,7 +4693,7 @@@ F: net/ax25/sysctl_net_ax25. DAVICOM FAST ETHERNET (DMFE) NETWORK DRIVER L: netdev@vger.kernel.org S: Orphan -F: Documentation/networking/device_drivers/dec/dmfe.txt +F: Documentation/networking/device_drivers/dec/dmfe.rst F: drivers/net/ethernet/dec/tulip/dmfe.c
DC390/AM53C974 SCSI driver @@@ -4728,7 -4727,7 +4727,7 @@@ DECnet NETWORK LAYE L: linux-decnet-user@lists.sourceforge.net S: Orphan W: http://linux-decnet.sourceforge.net -F: Documentation/networking/decnet.txt +F: Documentation/networking/decnet.rst F: net/decnet/
DECSTATION PLATFORM SUPPORT @@@ -5936,9 -5935,9 +5935,9 @@@ F: lib/dynamic_debug. DYNAMIC INTERRUPT MODERATION M: Tal Gilboa talgi@mellanox.com S: Maintained + F: Documentation/networking/net_dim.rst F: include/linux/dim.h F: lib/dim/ - F: Documentation/networking/net_dim.rst
DZ DECSTATION DZ11 SERIAL DRIVER M: "Maciej W. Rozycki" macro@linux-mips.org @@@ -7815,7 -7814,7 +7814,7 @@@ HUAWEI ETHERNET DRIVE M: Aviad Krawczyk aviad.krawczyk@huawei.com L: netdev@vger.kernel.org S: Supported -F: Documentation/networking/hinic.txt +F: Documentation/networking/hinic.rst F: drivers/net/ethernet/huawei/hinic/
HUGETLB FILESYSTEM @@@ -7867,7 -7866,7 +7866,7 @@@ S: Supporte T: git git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux.git F: Documentation/ABI/stable/sysfs-bus-vmbus F: Documentation/ABI/testing/debugfs-hyperv -F: Documentation/networking/device_drivers/microsoft/netvsc.txt +F: Documentation/networking/device_drivers/microsoft/netvsc.rst F: arch/x86/hyperv F: arch/x86/include/asm/hyperv-tlfs.h F: arch/x86/include/asm/mshyperv.h @@@ -8742,8 -8741,8 +8741,8 @@@ INTEL PRO/WIRELESS 2100, 2200BG, 2915AB M: Stanislav Yakovlev stas.yakovlev@gmail.com L: linux-wireless@vger.kernel.org S: Maintained -F: Documentation/networking/device_drivers/intel/ipw2100.txt -F: Documentation/networking/device_drivers/intel/ipw2200.txt +F: Documentation/networking/device_drivers/intel/ipw2100.rst +F: Documentation/networking/device_drivers/intel/ipw2200.rst F: drivers/net/wireless/intel/ipw2x00/
INTEL PSTATE DRIVER @@@ -8934,7 -8933,7 +8933,7 @@@ L: lvs-devel@vger.kernel.or S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/horms/ipvs-next.git T: git git://git.kernel.org/pub/scm/linux/kernel/git/horms/ipvs.git -F: Documentation/networking/ipvs-sysctl.txt +F: Documentation/networking/ipvs-sysctl.rst F: include/net/ip_vs.h F: include/uapi/linux/ip_vs.h F: net/netfilter/ipvs/ @@@ -9515,7 -9514,7 +9514,7 @@@ F: drivers/soc/lanti LAPB module L: linux-x25@vger.kernel.org S: Orphan -F: Documentation/networking/lapb-module.txt +F: Documentation/networking/lapb-module.rst F: include/*/lapb.h F: net/lapb/
@@@ -10079,7 -10078,7 +10078,7 @@@ S: Maintaine W: https://wireless.wiki.kernel.org/ T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211.git T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git -F: Documentation/networking/mac80211-injection.txt +F: Documentation/networking/mac80211-injection.rst F: Documentation/networking/mac80211_hwsim/mac80211_hwsim.rst F: drivers/net/wireless/mac80211_hwsim.[ch] F: include/net/mac80211.h @@@ -11656,8 -11655,8 +11655,8 @@@ NETERION 10GbE DRIVERS (s2io/vxge M: Jon Mason jdmason@kudzu.us L: netdev@vger.kernel.org S: Supported -F: Documentation/networking/device_drivers/neterion/s2io.txt -F: Documentation/networking/device_drivers/neterion/vxge.txt +F: Documentation/networking/device_drivers/neterion/s2io.rst +F: Documentation/networking/device_drivers/neterion/vxge.rst F: drivers/net/ethernet/neterion/
NETFILTER @@@ -13262,7 -13261,7 +13261,7 @@@ F: drivers/input/joystick/pxrc. PHONET PROTOCOL M: Remi Denis-Courmont courmisch@gmail.com S: Supported -F: Documentation/networking/phonet.txt +F: Documentation/networking/phonet.rst F: include/linux/phonet.h F: include/net/phonet/ F: include/uapi/linux/phonet.h @@@ -14031,7 -14030,7 +14030,7 @@@ M: Subash Abhinov Kasiviswanathan <suba M: Sean Tranchetti stranche@codeaurora.org L: netdev@vger.kernel.org S: Maintained -F: Documentation/networking/device_drivers/qualcomm/rmnet.txt +F: Documentation/networking/device_drivers/qualcomm/rmnet.rst F: drivers/net/ethernet/qualcomm/rmnet/ F: include/linux/if_rmnet.h
@@@ -14219,7 -14218,7 +14218,7 @@@ L: linux-rdma@vger.kernel.or L: rds-devel@oss.oracle.com (moderated for non-subscribers) S: Supported W: https://oss.oracle.com/projects/rds/ -F: Documentation/networking/rds.txt +F: Documentation/networking/rds.rst F: net/rds/
RDT - RESOURCE ALLOCATION @@@ -14593,7 -14592,7 +14592,7 @@@ M: David Howells <dhowells@redhat.com L: linux-afs@lists.infradead.org S: Supported W: https://www.infradead.org/~dhowells/kafs/ -F: Documentation/networking/rxrpc.txt +F: Documentation/networking/rxrpc.rst F: include/keys/rxrpc-type.h F: include/net/af_rxrpc.h F: include/trace/events/rxrpc.h @@@ -14999,7 -14998,7 +14998,7 @@@ M: Marcelo Ricardo Leitner <marcelo.lei L: linux-sctp@vger.kernel.org S: Maintained W: http://lksctp.sourceforge.net -F: Documentation/networking/sctp.txt +F: Documentation/networking/sctp.rst F: include/linux/sctp.h F: include/net/sctp/ F: include/uapi/linux/sctp.h @@@ -15874,7 -15873,7 +15873,7 @@@ SPIDERNET NETWORK DRIVER for CEL M: Ishizaki Kou kou.ishizaki@toshiba.co.jp L: netdev@vger.kernel.org S: Supported -F: Documentation/networking/device_drivers/toshiba/spider_net.txt +F: Documentation/networking/device_drivers/toshiba/spider_net.rst F: drivers/net/ethernet/toshiba/spider_net*
SPMI SUBSYSTEM @@@ -16971,7 -16970,7 +16970,7 @@@ M: Samuel Chessman <chessman@tux.org L: tlan-devel@lists.sourceforge.net (subscribers-only) S: Maintained W: http://sourceforge.net/projects/tlan/ -F: Documentation/networking/device_drivers/ti/tlan.txt +F: Documentation/networking/device_drivers/ti/tlan.rst F: drivers/net/ethernet/ti/tlan.*
TM6000 VIDEO4LINUX DRIVER @@@ -17161,7 -17160,7 +17160,7 @@@ TUN/TAP drive M: Maxim Krasnyansky maxk@qti.qualcomm.com S: Maintained W: http://vtun.sourceforge.net/tun -F: Documentation/networking/tuntap.txt +F: Documentation/networking/tuntap.rst F: arch/um/os-Linux/drivers/
TURBOCHANNEL SUBSYSTEM @@@ -18106,7 -18105,7 +18105,7 @@@ M: David Ahern <dsahern@kernel.org M: Shrijeet Mukherjee shrijeet@gmail.com L: netdev@vger.kernel.org S: Maintained -F: Documentation/networking/vrf.txt +F: Documentation/networking/vrf.rst F: drivers/net/vrf.c
VSPRINTF @@@ -18644,7 -18643,7 +18643,7 @@@ L: linux-hams@vger.kernel.or S: Maintained W: http://yaina.de/jreuter/ W: http://www.qsl.net/dl1bke/ -F: Documentation/networking/z8530drv.txt +F: Documentation/networking/z8530drv.rst F: drivers/net/hamradio/*scc.c F: drivers/net/hamradio/z8530.h
diff --combined drivers/infiniband/hw/mlx5/qp.c index af599c8b88aa,2210759843ba..d93eec5d3277 --- a/drivers/infiniband/hw/mlx5/qp.c +++ b/drivers/infiniband/hw/mlx5/qp.c @@@ -39,7 -39,6 +39,7 @@@ #include "mlx5_ib.h" #include "ib_rep.h" #include "cmd.h" +#include "qp.h"
/* not supported currently */ static int wq_signature; @@@ -1255,7 -1254,7 +1255,7 @@@ static int create_raw_packet_qp_tis(str struct mlx5_ib_sq *sq, u32 tdn, struct ib_pd *pd) { - u32 in[MLX5_ST_SZ_DW(create_tis_in)] = {0}; + u32 in[MLX5_ST_SZ_DW(create_tis_in)] = {}; void *tisc = MLX5_ADDR_OF(create_tis_in, in, ctx);
MLX5_SET(create_tis_in, in, uid, to_mpd(pd)->uid); @@@ -1263,7 -1262,7 +1263,7 @@@ if (qp->flags & MLX5_IB_QP_UNDERLAY) MLX5_SET(tisc, tisc, underlay_qpn, qp->underlay_qpn);
- return mlx5_core_create_tis(dev->mdev, in, sizeof(in), &sq->tisn); + return mlx5_core_create_tis(dev->mdev, in, &sq->tisn); }
static void destroy_raw_packet_qp_tis(struct mlx5_ib_dev *dev, @@@ -1337,7 -1336,7 +1337,7 @@@ static int create_raw_packet_qp_sq(stru pas = (__be64 *)MLX5_ADDR_OF(wq, wq, pas); mlx5_ib_populate_pas(dev, sq->ubuffer.umem, page_shift, pas, 0);
- err = mlx5_core_create_sq_tracked(dev->mdev, in, inlen, &sq->base.mqp); + err = mlx5_core_create_sq_tracked(dev, in, inlen, &sq->base.mqp);
kvfree(in);
@@@ -1357,7 -1356,7 +1357,7 @@@ static void destroy_raw_packet_qp_sq(st struct mlx5_ib_sq *sq) { destroy_flow_rule_vport_sq(sq); - mlx5_core_destroy_sq_tracked(dev->mdev, &sq->base.mqp); + mlx5_core_destroy_sq_tracked(dev, &sq->base.mqp); ib_umem_release(sq->ubuffer.umem); }
@@@ -1427,7 -1426,7 +1427,7 @@@ static int create_raw_packet_qp_rq(stru qp_pas = (__be64 *)MLX5_ADDR_OF(create_qp_in, qpin, pas); memcpy(pas, qp_pas, rq_pas_size);
- err = mlx5_core_create_rq_tracked(dev->mdev, in, inlen, &rq->base.mqp); + err = mlx5_core_create_rq_tracked(dev, in, inlen, &rq->base.mqp);
kvfree(in);
@@@ -1437,7 -1436,7 +1437,7 @@@ static void destroy_raw_packet_qp_rq(struct mlx5_ib_dev *dev, struct mlx5_ib_rq *rq) { - mlx5_core_destroy_rq_tracked(dev->mdev, &rq->base.mqp); + mlx5_core_destroy_rq_tracked(dev, &rq->base.mqp); }
static bool tunnel_offload_supported(struct mlx5_core_dev *dev) @@@ -1460,8 -1459,9 +1460,8 @@@ static void destroy_raw_packet_qp_tir(s
static int create_raw_packet_qp_tir(struct mlx5_ib_dev *dev, struct mlx5_ib_rq *rq, u32 tdn, - u32 *qp_flags_en, - struct ib_pd *pd, - u32 *out, int outlen) + u32 *qp_flags_en, struct ib_pd *pd, + u32 *out) { u8 lb_flag = 0; u32 *in; @@@ -1494,8 -1494,9 +1494,8 @@@ }
MLX5_SET(tirc, tirc, self_lb_block, lb_flag); - - err = mlx5_core_create_tir_out(dev->mdev, in, inlen, out, outlen); - + MLX5_SET(create_tir_in, in, opcode, MLX5_CMD_OP_CREATE_TIR); + err = mlx5_cmd_exec_inout(dev->mdev, create_tir, in, out); rq->tirn = MLX5_GET(create_tir_out, out, tirn); if (!err && MLX5_GET(tirc, tirc, self_lb_block)) { err = mlx5_ib_enable_lb(dev, false, true); @@@ -1555,8 -1556,9 +1555,8 @@@ static int create_raw_packet_qp(struct if (err) goto err_destroy_sq;
- err = create_raw_packet_qp_tir( - dev, rq, tdn, &qp->flags_en, pd, out, - MLX5_ST_SZ_BYTES(create_tir_out)); + err = create_raw_packet_qp_tir(dev, rq, tdn, &qp->flags_en, pd, + out); if (err) goto err_destroy_rq;
@@@ -1851,8 -1853,7 +1851,8 @@@ static int create_rss_raw_qp_tir(struc MLX5_SET(rx_hash_field_select, hfso, selected_fields, selected_fields);
create_tir: - err = mlx5_core_create_tir_out(dev->mdev, in, inlen, out, outlen); + MLX5_SET(create_tir_in, in, opcode, MLX5_CMD_OP_CREATE_TIR); + err = mlx5_cmd_exec_inout(dev->mdev, create_tir, in, out);
qp->rss_qp.tirn = MLX5_GET(create_tir_out, out, tirn); if (!err && MLX5_GET(tirc, tirc, self_lb_block)) { @@@ -2346,7 -2347,7 +2346,7 @@@ static int create_qp_common(struct mlx5 err = create_raw_packet_qp(dev, qp, in, inlen, pd, udata, &resp); } else { - err = mlx5_core_create_qp(dev->mdev, &base->mqp, in, inlen); + err = mlx5_core_create_qp(dev, &base->mqp, in, inlen); }
if (err) { @@@ -2512,7 -2513,8 +2512,7 @@@ static void destroy_qp_common(struct ml if (qp->state != IB_QPS_RESET) { if (qp->ibqp.qp_type != IB_QPT_RAW_PACKET && !(qp->flags & MLX5_IB_QP_UNDERLAY)) { - err = mlx5_core_qp_modify(dev->mdev, - MLX5_CMD_OP_2RST_QP, 0, + err = mlx5_core_qp_modify(dev, MLX5_CMD_OP_2RST_QP, 0, NULL, &base->mqp); } else { struct mlx5_modify_raw_qp_param raw_qp_param = { @@@ -2553,7 -2555,7 +2553,7 @@@ qp->flags & MLX5_IB_QP_UNDERLAY) { destroy_raw_packet_qp(dev, qp); } else { - err = mlx5_core_destroy_qp(dev->mdev, &base->mqp); + err = mlx5_core_destroy_qp(dev, &base->mqp); if (err) mlx5_ib_warn(dev, "failed to destroy QP 0x%x\n", base->mqp.qpn); @@@ -2816,7 -2818,7 +2816,7 @@@ static int mlx5_ib_destroy_dct(struct m if (mqp->state == IB_QPS_RTR) { int err;
- err = mlx5_core_destroy_dct(dev->mdev, &mqp->dct.mdct); + err = mlx5_core_destroy_dct(dev, &mqp->dct.mdct); if (err) { mlx5_ib_warn(dev, "failed to destroy DCT %d\n", err); return err; @@@ -2931,7 -2933,7 +2931,7 @@@ static int modify_raw_packet_eth_prio(s tisc = MLX5_ADDR_OF(modify_tis_in, in, ctx); MLX5_SET(tisc, tisc, prio, ((sl & 0x7) << 1));
- err = mlx5_core_modify_tis(dev, sq->tisn, in, inlen); + err = mlx5_core_modify_tis(dev, sq->tisn, in);
kvfree(in);
@@@ -2958,7 -2960,7 +2958,7 @@@ static int modify_raw_packet_tx_affinit tisc = MLX5_ADDR_OF(modify_tis_in, in, ctx); MLX5_SET(tisc, tisc, lag_tx_port_affinity, tx_affinity);
- err = mlx5_core_modify_tis(dev, sq->tisn, in, inlen); + err = mlx5_core_modify_tis(dev, sq->tisn, in);
kvfree(in);
@@@ -3238,7 -3240,7 +3238,7 @@@ static int modify_raw_packet_qp_rq "RAW PACKET QP counters are not supported on current FW\n"); }
- err = mlx5_core_modify_rq(dev->mdev, rq->base.mqp.qpn, in, inlen); + err = mlx5_core_modify_rq(dev->mdev, rq->base.mqp.qpn, in); if (err) goto out;
@@@ -3301,7 -3303,7 +3301,7 @@@ static int modify_raw_packet_qp_sq MLX5_SET(sqc, sqc, packet_pacing_rate_limit_index, rl_index); }
- err = mlx5_core_modify_sq(dev, sq->base.mqp.qpn, in, inlen); + err = mlx5_core_modify_sq(dev, sq->base.mqp.qpn, in); if (err) { /* Remove new rate from table if failed */ if (new_rate_added) @@@ -3460,9 -3462,10 +3460,9 @@@ static int __mlx5_ib_qp_set_counter(str base = &mqp->trans_qp.base; context.qp_counter_set_usr_page &= cpu_to_be32(0xffffff); context.qp_counter_set_usr_page |= cpu_to_be32(set_id << 24); - return mlx5_core_qp_modify(dev->mdev, - MLX5_CMD_OP_RTS2RTS_QP, - MLX5_QP_OPTPAR_COUNTER_SET_ID, - &context, &base->mqp); + return mlx5_core_qp_modify(dev, MLX5_CMD_OP_RTS2RTS_QP, + MLX5_QP_OPTPAR_COUNTER_SET_ID, &context, + &base->mqp); }
static int __mlx5_ib_modify_qp(struct ib_qp *ibqp, @@@ -3749,7 -3752,8 +3749,7 @@@
err = modify_raw_packet_qp(dev, qp, &raw_qp_param, tx_affinity); } else { - err = mlx5_core_qp_modify(dev->mdev, op, optpar, context, - &base->mqp); + err = mlx5_core_qp_modify(dev, op, optpar, context, &base->mqp); }
if (err) @@@ -3923,7 -3927,7 +3923,7 @@@ static int mlx5_ib_modify_dct(struct ib MLX5_SET(dctc, dctc, my_addr_index, attr->ah_attr.grh.sgid_index); MLX5_SET(dctc, dctc, hop_limit, attr->ah_attr.grh.hop_limit);
- err = mlx5_core_create_dct(dev->mdev, &qp->dct.mdct, qp->dct.in, + err = mlx5_core_create_dct(dev, &qp->dct.mdct, qp->dct.in, MLX5_ST_SZ_BYTES(create_dct_in), out, sizeof(out)); if (err) @@@ -3931,7 -3935,7 +3931,7 @@@ resp.dctn = qp->dct.mdct.mqp.qpn; err = ib_copy_to_udata(udata, &resp, resp.response_length); if (err) { - mlx5_core_destroy_dct(dev->mdev, &qp->dct.mdct); + mlx5_core_destroy_dct(dev, &qp->dct.mdct); return err; } } else { @@@ -5554,7 -5558,9 +5554,9 @@@ static void to_rdma_ah_attr(struct mlx5 rdma_ah_set_path_bits(ah_attr, path->grh_mlid & 0x7f); rdma_ah_set_static_rate(ah_attr, path->static_rate ? path->static_rate - 5 : 0); - if (path->grh_mlid & (1 << 7)) { + + if (path->grh_mlid & (1 << 7) || + ah_attr->type == RDMA_AH_ATTR_TYPE_ROCE) { u32 tc_fl = be32_to_cpu(path->tclass_flowlabel);
rdma_ah_set_grh(ah_attr, NULL, @@@ -5693,7 -5699,8 +5695,7 @@@ static int query_qp_attr(struct mlx5_ib if (!outb) return -ENOMEM;
- err = mlx5_core_qp_query(dev->mdev, &qp->trans_qp.base.mqp, outb, - outlen); + err = mlx5_core_qp_query(dev, &qp->trans_qp.base.mqp, outb, outlen); if (err) goto out;
@@@ -5771,7 -5778,7 +5773,7 @@@ static int mlx5_ib_dct_query_qp(struct if (!out) return -ENOMEM;
- err = mlx5_core_dct_query(dev->mdev, dct, out, outlen); + err = mlx5_core_dct_query(dev, dct, out, outlen); if (err) goto out;
@@@ -5957,7 -5964,7 +5959,7 @@@ static int set_delay_drop(struct mlx5_i if (dev->delay_drop.activate) goto out;
- err = mlx5_core_set_delay_drop(dev->mdev, dev->delay_drop.timeout); + err = mlx5_core_set_delay_drop(dev, dev->delay_drop.timeout); if (err) goto out;
@@@ -6063,13 -6070,13 +6065,13 @@@ static int create_rq(struct mlx5_ib_rw } rq_pas0 = (__be64 *)MLX5_ADDR_OF(wq, wq, pas); mlx5_ib_populate_pas(dev, rwq->umem, rwq->page_shift, rq_pas0, 0); - err = mlx5_core_create_rq_tracked(dev->mdev, in, inlen, &rwq->core_qp); + err = mlx5_core_create_rq_tracked(dev, in, inlen, &rwq->core_qp); if (!err && init_attr->create_flags & IB_WQ_FLAGS_DELAY_DROP) { err = set_delay_drop(dev); if (err) { mlx5_ib_warn(dev, "Failed to enable delay drop err=%d\n", err); - mlx5_core_destroy_rq_tracked(dev->mdev, &rwq->core_qp); + mlx5_core_destroy_rq_tracked(dev, &rwq->core_qp); } else { rwq->create_flags |= MLX5_IB_WQ_FLAGS_DELAY_DROP; } @@@ -6251,7 -6258,7 +6253,7 @@@ struct ib_wq *mlx5_ib_create_wq(struct return &rwq->ibwq;
err_copy: - mlx5_core_destroy_rq_tracked(dev->mdev, &rwq->core_qp); + mlx5_core_destroy_rq_tracked(dev, &rwq->core_qp); err_user_rq: destroy_user_rq(dev, pd, rwq, udata); err: @@@ -6264,7 -6271,7 +6266,7 @@@ void mlx5_ib_destroy_wq(struct ib_wq *w struct mlx5_ib_dev *dev = to_mdev(wq->device); struct mlx5_ib_rwq *rwq = to_mrwq(wq);
- mlx5_core_destroy_rq_tracked(dev->mdev, &rwq->core_qp); + mlx5_core_destroy_rq_tracked(dev, &rwq->core_qp); destroy_user_rq(dev, wq->pd, rwq, udata); kfree(rwq); } @@@ -6442,7 -6449,7 +6444,7 @@@ int mlx5_ib_modify_wq(struct ib_wq *wq "Receive WQ counters are not supported on current FW\n"); }
- err = mlx5_core_modify_rq(dev->mdev, rwq->core_qp.qpn, in, inlen); + err = mlx5_core_modify_rq(dev->mdev, rwq->core_qp.qpn, in); if (!err) rwq->ibwq.state = (wq_state == MLX5_RQC_STATE_ERR) ? IB_WQS_ERR : wq_state;
diff --combined drivers/net/dsa/ocelot/felix.c index e5b6748f6654,e2c6bf0e430e..a2dfd73f8a1a --- a/drivers/net/dsa/ocelot/felix.c +++ b/drivers/net/dsa/ocelot/felix.c @@@ -7,7 -7,6 +7,7 @@@ #include <soc/mscc/ocelot_sys.h> #include <soc/mscc/ocelot_dev.h> #include <soc/mscc/ocelot_ana.h> +#include <soc/mscc/ocelot_ptp.h> #include <soc/mscc/ocelot.h> #include <linux/packing.h> #include <linux/module.h> @@@ -401,6 -400,7 +401,7 @@@ static int felix_init_structs(struct fe ocelot->stats_layout = felix->info->stats_layout; ocelot->num_stats = felix->info->num_stats; ocelot->shared_queue_sz = felix->info->shared_queue_sz; + ocelot->num_mact_rows = felix->info->num_mact_rows; ocelot->vcap_is2_keys = felix->info->vcap_is2_keys; ocelot->vcap_is2_actions= felix->info->vcap_is2_actions; ocelot->vcap = felix->info->vcap; @@@ -495,23 -495,6 +496,23 @@@ return 0; }
+static struct ptp_clock_info ocelot_ptp_clock_info = { + .owner = THIS_MODULE, + .name = "felix ptp", + .max_adj = 0x7fffffff, + .n_alarm = 0, + .n_ext_ts = 0, + .n_per_out = OCELOT_PTP_PINS_NUM, + .n_pins = OCELOT_PTP_PINS_NUM, + .pps = 0, + .gettime64 = ocelot_ptp_gettime64, + .settime64 = ocelot_ptp_settime64, + .adjtime = ocelot_ptp_adjtime, + .adjfine = ocelot_ptp_adjfine, + .verify = ocelot_ptp_verify, + .enable = ocelot_ptp_enable, +}; + /* Hardware initialization done here so that we can allocate structures with * devm without fear of dsa_register_switch returning -EPROBE_DEFER and causing * us to allocate structures twice (leak memory) and map PCI memory twice @@@ -522,21 -505,12 +523,21 @@@ static int felix_setup(struct dsa_switc struct ocelot *ocelot = ds->priv; struct felix *felix = ocelot_to_felix(ocelot); int port, err; + int tc;
err = felix_init_structs(felix, ds->num_ports); if (err) return err;
ocelot_init(ocelot); + if (ocelot->ptp) { + err = ocelot_init_timestamp(ocelot, &ocelot_ptp_clock_info); + if (err) { + dev_err(ocelot->dev, + "Timestamp initialization failed\n"); + ocelot->ptp = 0; + } + }
for (port = 0; port < ds->num_ports; port++) { ocelot_init_port(ocelot, port); @@@ -556,12 -530,6 +557,12 @@@ ocelot_write_rix(ocelot, ANA_PGID_PGID_PGID(GENMASK(ocelot->num_phys_ports, 0)), ANA_PGID_PGID, PGID_UC); + /* Setup the per-traffic class flooding PGIDs */ + for (tc = 0; tc < FELIX_NUM_TC; tc++) + ocelot_write_rix(ocelot, ANA_FLOODING_FLD_MULTICAST(PGID_MC) | + ANA_FLOODING_FLD_BROADCAST(PGID_MC) | + ANA_FLOODING_FLD_UNICAST(PGID_UC), + ANA_FLOODING, tc);
ds->mtu_enforcement_ingress = true; /* It looks like the MAC/PCS interrupt register - PM0_IEVENT (0x8040) @@@ -581,7 -549,6 +582,7 @@@ static void felix_teardown(struct dsa_s if (felix->info->mdio_bus_free) felix->info->mdio_bus_free(ocelot);
+ ocelot_deinit_timestamp(ocelot); /* stop workqueue thread */ ocelot_deinit(ocelot); } @@@ -773,11 -740,6 +774,11 @@@ static int felix_pci_probe(struct pci_d struct felix *felix; int err;
+ if (pdev->dev.of_node && !of_device_is_available(pdev->dev.of_node)) { + dev_info(&pdev->dev, "device is disabled, skipping\n"); + return -ENODEV; + } + err = pci_enable_device(pdev); if (err) { dev_err(&pdev->dev, "device enable failed\n"); diff --combined drivers/net/dsa/ocelot/felix.h index 2ad793c0e1df,9af106513e53..b94386fa8d63 --- a/drivers/net/dsa/ocelot/felix.h +++ b/drivers/net/dsa/ocelot/felix.h @@@ -5,7 -5,6 +5,7 @@@ #define _MSCC_FELIX_H
#define ocelot_to_felix(o) container_of((o), struct felix, ocelot) +#define FELIX_NUM_TC 8
/* Platform-specific information */ struct felix_info { @@@ -16,6 -15,7 +16,7 @@@ const u32 *const *map; const struct ocelot_ops *ops; int shared_queue_sz; + int num_mact_rows; const struct ocelot_stat_layout *stats_layout; unsigned int num_stats; int num_ports; diff --combined drivers/net/dsa/ocelot/felix_vsc9959.c index 4fe707ef54b8,8bf395f12b47..1c56568d5aca --- a/drivers/net/dsa/ocelot/felix_vsc9959.c +++ b/drivers/net/dsa/ocelot/felix_vsc9959.c @@@ -313,8 -313,6 +313,8 @@@ static const u32 vsc9959_ptp_regmap[] REG(PTP_PIN_TOD_SEC_MSB, 0x000004), REG(PTP_PIN_TOD_SEC_LSB, 0x000008), REG(PTP_PIN_TOD_NSEC, 0x00000c), + REG(PTP_PIN_WF_HIGH_PERIOD, 0x000014), + REG(PTP_PIN_WF_LOW_PERIOD, 0x000018), REG(PTP_CFG_MISC, 0x0000a0), REG(PTP_CLK_CFG_ADJ_CFG, 0x0000a4), REG(PTP_CLK_CFG_ADJ_FREQ, 0x0000a8), @@@ -1222,6 -1220,7 +1222,7 @@@ struct felix_info felix_info_vsc9959 = .vcap_is2_actions = vsc9959_vcap_is2_actions, .vcap = vsc9959_vcap_props, .shared_queue_sz = 128 * 1024, + .num_mact_rows = 2048, .num_ports = 6, .switch_pci_bar = 4, .imdio_pci_bar = 0, diff --combined drivers/net/ethernet/amazon/ena/ena_netdev.h index bd278c4721c6,9e1860d81908..7df67bf09b93 --- a/drivers/net/ethernet/amazon/ena/ena_netdev.h +++ b/drivers/net/ethernet/amazon/ena/ena_netdev.h @@@ -69,7 -69,7 +69,7 @@@ * 16kB. */ #if PAGE_SIZE > SZ_16K - #define ENA_PAGE_SIZE SZ_16K + #define ENA_PAGE_SIZE (_AC(SZ_16K, UL)) #else #define ENA_PAGE_SIZE PAGE_SIZE #endif @@@ -248,7 -248,6 +248,7 @@@ struct ena_stats_tx u64 bad_req_id; u64 llq_buffer_copy; u64 missed_tx; + u64 unmask_interrupt; };
struct ena_stats_rx { @@@ -334,7 -333,6 +334,7 @@@ struct ena_stats_dev u64 interface_down; u64 admin_q_pause; u64 rx_drops; + u64 tx_drops; };
enum ena_flags_t { diff --combined drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c index ce46cdbc69e6,8a70ffe1d326..d10fff8a8c71 --- a/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c @@@ -16,7 -16,6 +16,7 @@@ #include "aq_pci_func.h" #include "hw_atl/hw_atl_a0.h" #include "hw_atl/hw_atl_b0.h" +#include "hw_atl2/hw_atl2.h" #include "aq_filters.h" #include "aq_drvinfo.h" #include "aq_macsec.h" @@@ -42,13 -41,6 +42,13 @@@ static const struct pci_device_id aq_pc { PCI_VDEVICE(AQUANTIA, AQ_DEVICE_ID_AQC111S), }, { PCI_VDEVICE(AQUANTIA, AQ_DEVICE_ID_AQC112S), },
+ { PCI_VDEVICE(AQUANTIA, AQ_DEVICE_ID_AQC113DEV), }, + { PCI_VDEVICE(AQUANTIA, AQ_DEVICE_ID_AQC113CS), }, + { PCI_VDEVICE(AQUANTIA, AQ_DEVICE_ID_AQC114CS), }, + { PCI_VDEVICE(AQUANTIA, AQ_DEVICE_ID_AQC113), }, + { PCI_VDEVICE(AQUANTIA, AQ_DEVICE_ID_AQC113C), }, + { PCI_VDEVICE(AQUANTIA, AQ_DEVICE_ID_AQC115C), }, + {} };
@@@ -65,7 -57,7 +65,7 @@@ static const struct aq_board_revision_ { AQ_DEVICE_ID_D108, AQ_HWREV_2, &hw_atl_ops_b0, &hw_atl_b0_caps_aqc108, }, { AQ_DEVICE_ID_D109, AQ_HWREV_2, &hw_atl_ops_b0, &hw_atl_b0_caps_aqc109, },
- { AQ_DEVICE_ID_AQC100, AQ_HWREV_ANY, &hw_atl_ops_b1, &hw_atl_b0_caps_aqc107, }, + { AQ_DEVICE_ID_AQC100, AQ_HWREV_ANY, &hw_atl_ops_b1, &hw_atl_b0_caps_aqc100, }, { AQ_DEVICE_ID_AQC107, AQ_HWREV_ANY, &hw_atl_ops_b1, &hw_atl_b0_caps_aqc107, }, { AQ_DEVICE_ID_AQC108, AQ_HWREV_ANY, &hw_atl_ops_b1, &hw_atl_b0_caps_aqc108, }, { AQ_DEVICE_ID_AQC109, AQ_HWREV_ANY, &hw_atl_ops_b1, &hw_atl_b0_caps_aqc109, }, @@@ -78,13 -70,6 +78,13 @@@ { AQ_DEVICE_ID_AQC109S, AQ_HWREV_ANY, &hw_atl_ops_b1, &hw_atl_b0_caps_aqc109s, }, { AQ_DEVICE_ID_AQC111S, AQ_HWREV_ANY, &hw_atl_ops_b1, &hw_atl_b0_caps_aqc111s, }, { AQ_DEVICE_ID_AQC112S, AQ_HWREV_ANY, &hw_atl_ops_b1, &hw_atl_b0_caps_aqc112s, }, + + { AQ_DEVICE_ID_AQC113DEV, AQ_HWREV_ANY, &hw_atl2_ops, &hw_atl2_caps_aqc113, }, + { AQ_DEVICE_ID_AQC113, AQ_HWREV_ANY, &hw_atl2_ops, &hw_atl2_caps_aqc113, }, + { AQ_DEVICE_ID_AQC113CS, AQ_HWREV_ANY, &hw_atl2_ops, &hw_atl2_caps_aqc113, }, + { AQ_DEVICE_ID_AQC114CS, AQ_HWREV_ANY, &hw_atl2_ops, &hw_atl2_caps_aqc113, }, + { AQ_DEVICE_ID_AQC113C, AQ_HWREV_ANY, &hw_atl2_ops, &hw_atl2_caps_aqc113, }, + { AQ_DEVICE_ID_AQC115C, AQ_HWREV_ANY, &hw_atl2_ops, &hw_atl2_caps_aqc113, }, };
MODULE_DEVICE_TABLE(pci, aq_pci_tbl); @@@ -119,8 -104,10 +119,8 @@@ int aq_pci_func_init(struct pci_dev *pd int err;
err = pci_set_dma_mask(pdev, DMA_BIT_MASK(64)); - if (!err) { + if (!err) err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)); - - } if (err) { err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); if (!err) @@@ -250,15 -237,6 +250,15 @@@ static int aq_pci_probe(struct pci_dev goto err_ioremap; } self->aq_hw->aq_nic_cfg = aq_nic_get_cfg(self); + if (self->aq_hw->aq_nic_cfg->aq_hw_caps->priv_data_len) { + int len = self->aq_hw->aq_nic_cfg->aq_hw_caps->priv_data_len; + + self->aq_hw->priv = kzalloc(len, GFP_KERNEL); + if (!self->aq_hw->priv) { + err = -ENOMEM; + goto err_free_aq_hw; + } + }
for (bar = 0; bar < 4; ++bar) { if (IORESOURCE_MEM & pci_resource_flags(pdev, bar)) { @@@ -267,19 -245,19 +267,19 @@@ mmio_pa = pci_resource_start(pdev, bar); if (mmio_pa == 0U) { err = -EIO; - goto err_free_aq_hw; + goto err_free_aq_hw_priv; }
reg_sz = pci_resource_len(pdev, bar); if ((reg_sz <= 24 /*ATL_REGS_SIZE*/)) { err = -EIO; - goto err_free_aq_hw; + goto err_free_aq_hw_priv; }
self->aq_hw->mmio = ioremap(mmio_pa, reg_sz); if (!self->aq_hw->mmio) { err = -EIO; - goto err_free_aq_hw; + goto err_free_aq_hw_priv; } break; } @@@ -287,7 -265,7 +287,7 @@@
if (bar == 4) { err = -EIO; - goto err_free_aq_hw; + goto err_free_aq_hw_priv; }
numvecs = min((u8)AQ_CFG_VECS_DEF, @@@ -327,8 -305,6 +327,8 @@@ err_register aq_pci_free_irq_vectors(self); err_hwinit: iounmap(self->aq_hw->mmio); +err_free_aq_hw_priv: + kfree(self->aq_hw->priv); err_free_aq_hw: kfree(self->aq_hw); err_ioremap: @@@ -356,7 -332,6 +356,7 @@@ static void aq_pci_remove(struct pci_de aq_nic_free_vectors(self); aq_pci_free_irq_vectors(self); iounmap(self->aq_hw->mmio); + kfree(self->aq_hw->priv); kfree(self->aq_hw); pci_release_regions(pdev); free_netdev(self->ndev); diff --combined drivers/net/ethernet/broadcom/bnxt/bnxt.c index 4bbfea147d98,d1a83716d934..f86b6217f829 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@@ -1766,7 -1766,7 +1766,7 @@@ static int bnxt_rx_pkt(struct bnxt *bp
rc = -EIO; if (rx_err & RX_CMPL_ERRORS_BUFFER_ERROR_MASK) { - bnapi->cp_ring.rx_buf_errors++; + bnapi->cp_ring.sw_stats.rx.rx_buf_errors++; if (!(bp->flags & BNXT_FLAG_CHIP_P5)) { netdev_warn(bp->dev, "RX buffer error %x\n", rx_err); @@@ -1849,7 -1849,7 +1849,7 @@@ } else { if (rxcmp1->rx_cmp_cfa_code_errors_v2 & RX_CMP_L4_CS_ERR_BITS) { if (dev->features & NETIF_F_RXCSUM) - bnapi->cp_ring.rx_l4_csum_errors++; + bnapi->cp_ring.sw_stats.rx.rx_l4_csum_errors++; } }
@@@ -5045,7 -5045,8 +5045,7 @@@ int bnxt_hwrm_vnic_cfg(struct bnxt *bp req.dflt_ring_grp = cpu_to_le16(bp->grp_info[grp_idx].fw_grp_id); req.lb_rule = cpu_to_le16(0xffff); vnic_mru: - req.mru = cpu_to_le16(bp->dev->mtu + ETH_HLEN + ETH_FCS_LEN + - VLAN_HLEN); + req.mru = cpu_to_le16(bp->dev->mtu + ETH_HLEN + VLAN_HLEN);
req.vnic_id = cpu_to_le16(vnic->fw_vnic_id); #ifdef CONFIG_BNXT_SRIOV @@@ -5355,9 -5356,9 +5355,9 @@@ static void bnxt_set_db(struct bnxt *bp { if (bp->flags & BNXT_FLAG_CHIP_P5) { if (BNXT_PF(bp)) - db->doorbell = bp->bar1 + 0x10000; + db->doorbell = bp->bar1 + DB_PF_OFFSET_P5; else - db->doorbell = bp->bar1 + 0x4000; + db->doorbell = bp->bar1 + DB_VF_OFFSET_P5; switch (ring_type) { case HWRM_RING_ALLOC_TX: db->db_key64 = DBR_PATH_L2 | DBR_TYPE_SQ; @@@ -6364,7 -6365,6 +6364,7 @@@ static int bnxt_hwrm_func_qcfg(struct b { struct hwrm_func_qcfg_input req = {0}; struct hwrm_func_qcfg_output *resp = bp->hwrm_cmd_resp_addr; + u32 min_db_offset = 0; u16 flags; int rc;
@@@ -6413,21 -6413,6 +6413,21 @@@ if (!bp->max_mtu) bp->max_mtu = BNXT_MAX_MTU;
+ if (bp->db_size) + goto func_qcfg_exit; + + if (bp->flags & BNXT_FLAG_CHIP_P5) { + if (BNXT_PF(bp)) + min_db_offset = DB_PF_OFFSET_P5; + else + min_db_offset = DB_VF_OFFSET_P5; + } + bp->db_size = PAGE_ALIGN(le16_to_cpu(resp->l2_doorbell_bar_size_kb) * + 1024); + if (!bp->db_size || bp->db_size > pci_resource_len(bp->pdev, 2) || + bp->db_size <= min_db_offset) + bp->db_size = pci_resource_len(bp->pdev, 2); + func_qcfg_exit: mutex_unlock(&bp->hwrm_cmd_lock); return rc; @@@ -6449,13 -6434,23 +6449,13 @@@ static int bnxt_hwrm_func_backing_store if (!rc) { struct bnxt_ctx_pg_info *ctx_pg; struct bnxt_ctx_mem_info *ctx; - int i; + int i, tqm_rings;
ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); if (!ctx) { rc = -ENOMEM; goto ctx_err; } - ctx_pg = kzalloc(sizeof(*ctx_pg) * (bp->max_q + 1), GFP_KERNEL); - if (!ctx_pg) { - kfree(ctx); - rc = -ENOMEM; - goto ctx_err; - } - for (i = 0; i < bp->max_q + 1; i++, ctx_pg++) - ctx->tqm_mem[i] = ctx_pg; - - bp->ctx = ctx; ctx->qp_max_entries = le32_to_cpu(resp->qp_max_entries); ctx->qp_min_qp1_entries = le16_to_cpu(resp->qp_min_qp1_entries); ctx->qp_max_l2_entries = le16_to_cpu(resp->qp_max_l2_entries); @@@ -6488,20 -6483,6 +6488,20 @@@ ctx->tim_entry_size = le16_to_cpu(resp->tim_entry_size); ctx->tim_max_entries = le32_to_cpu(resp->tim_max_entries); ctx->ctx_kind_initializer = resp->ctx_kind_initializer; + ctx->tqm_fp_rings_count = resp->tqm_fp_rings_count; + if (!ctx->tqm_fp_rings_count) + ctx->tqm_fp_rings_count = bp->max_q; + + tqm_rings = ctx->tqm_fp_rings_count + 1; + ctx_pg = kcalloc(tqm_rings, sizeof(*ctx_pg), GFP_KERNEL); + if (!ctx_pg) { + kfree(ctx); + rc = -ENOMEM; + goto ctx_err; + } + for (i = 0; i < tqm_rings; i++, ctx_pg++) + ctx->tqm_mem[i] = ctx_pg; + bp->ctx = ctx; } else { rc = 0; } @@@ -6661,7 -6642,7 +6661,7 @@@ static int bnxt_alloc_ctx_pg_tbls(struc int rc;
if (!mem_size) - return 0; + return -EINVAL;
ctx_pg->nr_pages = DIV_ROUND_UP(mem_size, BNXT_PAGE_SIZE); if (ctx_pg->nr_pages > MAX_CTX_TOTAL_PAGES) { @@@ -6754,7 -6735,7 +6754,7 @@@ static void bnxt_free_ctx_mem(struct bn return;
if (ctx->tqm_mem[0]) { - for (i = 0; i < bp->max_q + 1; i++) + for (i = 0; i < ctx->tqm_fp_rings_count + 1; i++) bnxt_free_ctx_pg_tbls(bp, ctx->tqm_mem[i]); kfree(ctx->tqm_mem[0]); ctx->tqm_mem[0] = NULL; @@@ -6775,7 -6756,6 +6775,7 @@@ static int bnxt_alloc_ctx_mem(struct bn struct bnxt_ctx_pg_info *ctx_pg; struct bnxt_ctx_mem_info *ctx; u32 mem_size, ena, entries; + u32 entries_sp, min; u32 num_mr, num_ah; u32 extra_srqs = 0; u32 extra_qps = 0; @@@ -6865,17 -6845,14 +6865,17 @@@ ena |= FUNC_BACKING_STORE_CFG_REQ_ENABLES_TIM;
skip_rdma: - entries = ctx->qp_max_l2_entries + extra_qps; + min = ctx->tqm_min_entries_per_ring; + entries_sp = ctx->vnic_max_vnic_entries + ctx->qp_max_l2_entries + + 2 * (extra_qps + ctx->qp_min_qp1_entries) + min; + entries_sp = roundup(entries_sp, ctx->tqm_entries_multiple); + entries = ctx->qp_max_l2_entries + extra_qps + ctx->qp_min_qp1_entries; entries = roundup(entries, ctx->tqm_entries_multiple); - entries = clamp_t(u32, entries, ctx->tqm_min_entries_per_ring, - ctx->tqm_max_entries_per_ring); - for (i = 0; i < bp->max_q + 1; i++) { + entries = clamp_t(u32, entries, min, ctx->tqm_max_entries_per_ring); + for (i = 0; i < ctx->tqm_fp_rings_count + 1; i++) { ctx_pg = ctx->tqm_mem[i]; - ctx_pg->entries = entries; - mem_size = ctx->tqm_entry_size * entries; + ctx_pg->entries = i ? entries : entries_sp; + mem_size = ctx->tqm_entry_size * ctx_pg->entries; rc = bnxt_alloc_ctx_pg_tbls(bp, ctx_pg, mem_size, 1, false); if (rc) return rc; @@@ -9803,6 -9780,7 +9803,7 @@@ static netdev_features_t bnxt_fix_featu netdev_features_t features) { struct bnxt *bp = netdev_priv(dev); + netdev_features_t vlan_features;
if ((features & NETIF_F_NTUPLE) && !bnxt_rfs_capable(bp)) features &= ~NETIF_F_NTUPLE; @@@ -9819,12 -9797,14 +9820,14 @@@ /* Both CTAG and STAG VLAN accelaration on the RX side have to be * turned on or off together. */ - if ((features & (NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_STAG_RX)) != - (NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_STAG_RX)) { + vlan_features = features & (NETIF_F_HW_VLAN_CTAG_RX | + NETIF_F_HW_VLAN_STAG_RX); + if (vlan_features != (NETIF_F_HW_VLAN_CTAG_RX | + NETIF_F_HW_VLAN_STAG_RX)) { if (dev->features & NETIF_F_HW_VLAN_CTAG_RX) features &= ~(NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_STAG_RX); - else + else if (vlan_features) features |= NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_STAG_RX; } @@@ -10285,7 -10265,7 +10288,7 @@@ static void bnxt_chk_missed_irq(struct bnxt_dbg_hwrm_ring_info_get(bp, DBG_RING_INFO_GET_REQ_RING_TYPE_L2_CMPL, fw_ring_id, &val[0], &val[1]); - cpr->missed_irqs++; + cpr->sw_stats.cmn.missed_irqs++; } } } @@@ -10914,9 -10894,6 +10917,9 @@@ static int bnxt_init_board(struct pci_d bp->dev = dev; bp->pdev = pdev;
+ /* Doorbell BAR bp->bar1 is mapped after bnxt_fw_init_one_p2() + * determines the BAR size. + */ bp->bar0 = pci_ioremap_bar(pdev, 0); if (!bp->bar0) { dev_err(&pdev->dev, "Cannot map device registers, aborting\n"); @@@ -10924,6 -10901,13 +10927,6 @@@ goto init_err_release; }
- bp->bar1 = pci_ioremap_bar(pdev, 2); - if (!bp->bar1) { - dev_err(&pdev->dev, "Cannot map doorbell registers, aborting\n"); - rc = -ENOMEM; - goto init_err_release; - } - bp->bar2 = pci_ioremap_bar(pdev, 4); if (!bp->bar2) { dev_err(&pdev->dev, "Cannot map bar4 registers, aborting\n"); @@@ -11845,16 -11829,6 +11848,16 @@@ static int bnxt_pcie_dsn_get(struct bnx return 0; }
+static int bnxt_map_db_bar(struct bnxt *bp) +{ + if (!bp->db_size) + return -ENODEV; + bp->bar1 = pci_iomap(bp->pdev, 2, bp->db_size); + if (!bp->bar1) + return -ENOMEM; + return 0; +} + static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { struct net_device *dev; @@@ -11915,13 -11889,6 +11918,13 @@@ if (rc) goto init_err_pci_clean;
+ rc = bnxt_map_db_bar(bp); + if (rc) { + dev_err(&pdev->dev, "Cannot map doorbell BAR rc = %d, aborting\n", + rc); + goto init_err_pci_clean; + } + dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_GSO_UDP_TUNNEL | NETIF_F_GSO_GRE | @@@ -12248,12 -12215,15 +12251,15 @@@ static pci_ers_result_t bnxt_io_slot_re bnxt_ulp_start(bp, err); }
- if (result != PCI_ERS_RESULT_RECOVERED && netif_running(netdev)) - dev_close(netdev); + if (result != PCI_ERS_RESULT_RECOVERED) { + if (netif_running(netdev)) + dev_close(netdev); + pci_disable_device(pdev); + }
rtnl_unlock();
- return PCI_ERS_RESULT_RECOVERED; + return result; }
/** diff --combined drivers/net/ethernet/broadcom/bnxt/bnxt.h index c15517ff7ff6,f6a3250ef1c5..c04ac4a36005 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h @@@ -537,9 -537,6 +537,9 @@@ struct nqe_cn #define DBR_TYPE_NQ_ARM (0xbULL << 60) #define DBR_TYPE_NULL (0xfULL << 60)
+#define DB_PF_OFFSET_P5 0x10000 +#define DB_VF_OFFSET_P5 0x4000 + #define INVALID_HW_RING_ID ((u16)-1)
/* The hardware supports certain page sizes. Use the supported page sizes @@@ -910,20 -907,6 +910,20 @@@ struct bnxt_rx_ring_info struct page_pool *page_pool; };
+struct bnxt_rx_sw_stats { + u64 rx_l4_csum_errors; + u64 rx_buf_errors; +}; + +struct bnxt_cmn_sw_stats { + u64 missed_irqs; +}; + +struct bnxt_sw_stats { + struct bnxt_rx_sw_stats rx; + struct bnxt_cmn_sw_stats cmn; +}; + struct bnxt_cp_ring_info { struct bnxt_napi *bnapi; u32 cp_raw_cons; @@@ -951,8 -934,9 +951,8 @@@ struct ctx_hw_stats *hw_stats; dma_addr_t hw_stats_map; u32 hw_stats_ctx_id; - u64 rx_l4_csum_errors; - u64 rx_buf_errors; - u64 missed_irqs; + + struct bnxt_sw_stats sw_stats;
struct bnxt_ring_struct cp_ring_struct;
@@@ -1082,7 -1066,6 +1082,6 @@@ struct bnxt_vf_info #define BNXT_VF_LINK_FORCED 0x4 #define BNXT_VF_LINK_UP 0x8 #define BNXT_VF_TRUST 0x10 - u32 func_flags; /* func cfg flags */ u32 min_tx_rate; u32 max_tx_rate; void *hwrm_cmd_req_addr; @@@ -1373,7 -1356,6 +1372,7 @@@ struct bnxt_ctx_mem_info u16 mrav_num_entries_units; u8 tqm_entries_multiple; u8 ctx_kind_initializer; + u8 tqm_fp_rings_count;
u32 flags; #define BNXT_CTX_FLAG_INITED 0x01 @@@ -1833,7 -1815,6 +1832,7 @@@ struct bnxt /* ensure atomic 64-bit doorbell writes on 32-bit systems. */ spinlock_t db_lock; #endif + int db_size;
#define BNXT_NTP_FLTR_MAX_FLTR 4096 #define BNXT_NTP_FLTR_HASH_SIZE 512 diff --combined drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c index c883e8884faf,cea2f9958a1d..3a9a51f7063a --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c @@@ -85,11 -85,10 +85,10 @@@ int bnxt_set_vf_spoofchk(struct net_dev if (old_setting == setting) return 0;
- func_flags = vf->func_flags; if (setting) - func_flags |= FUNC_CFG_REQ_FLAGS_SRC_MAC_ADDR_CHECK_ENABLE; + func_flags = FUNC_CFG_REQ_FLAGS_SRC_MAC_ADDR_CHECK_ENABLE; else - func_flags |= FUNC_CFG_REQ_FLAGS_SRC_MAC_ADDR_CHECK_DISABLE; + func_flags = FUNC_CFG_REQ_FLAGS_SRC_MAC_ADDR_CHECK_DISABLE; /*TODO: if the driver supports VLAN filter on guest VLAN, * the spoof check should also include vlan anti-spoofing */ @@@ -98,7 -97,6 +97,6 @@@ req.flags = cpu_to_le32(func_flags); rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); if (!rc) { - vf->func_flags = func_flags; if (setting) vf->flags |= BNXT_VF_SPOOFCHK; else @@@ -228,7 -226,6 +226,6 @@@ int bnxt_set_vf_mac(struct net_device * memcpy(vf->mac_addr, mac, ETH_ALEN); bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_CFG, -1, -1); req.fid = cpu_to_le16(vf->fw_fid); - req.flags = cpu_to_le32(vf->func_flags); req.enables = cpu_to_le32(FUNC_CFG_REQ_ENABLES_DFLT_MAC_ADDR); memcpy(req.dflt_mac_addr, mac, ETH_ALEN); return hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); @@@ -266,7 -263,6 +263,6 @@@ int bnxt_set_vf_vlan(struct net_device
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_CFG, -1, -1); req.fid = cpu_to_le16(vf->fw_fid); - req.flags = cpu_to_le32(vf->func_flags); req.dflt_vlan = cpu_to_le16(vlan_tag); req.enables = cpu_to_le32(FUNC_CFG_REQ_ENABLES_DFLT_VLAN); rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); @@@ -305,7 -301,6 +301,6 @@@ int bnxt_set_vf_bw(struct net_device *d return 0; bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_CFG, -1, -1); req.fid = cpu_to_le16(vf->fw_fid); - req.flags = cpu_to_le32(vf->func_flags); req.enables = cpu_to_le32(FUNC_CFG_REQ_ENABLES_MAX_BW); req.max_bw = cpu_to_le32(max_tx_rate); req.enables |= cpu_to_le32(FUNC_CFG_REQ_ENABLES_MIN_BW); @@@ -477,7 -472,6 +472,6 @@@ static void __bnxt_set_vf_params(struc vf = &bp->pf.vf[vf_id]; bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_CFG, -1, -1); req.fid = cpu_to_le16(vf->fw_fid); - req.flags = cpu_to_le32(vf->func_flags);
if (is_valid_ether_addr(vf->mac_addr)) { req.enables |= cpu_to_le32(FUNC_CFG_REQ_ENABLES_DFLT_MAC_ADDR); @@@ -651,7 -645,7 +645,7 @@@ static int bnxt_hwrm_func_cfg(struct bn FUNC_CFG_REQ_ENABLES_NUM_VNICS | FUNC_CFG_REQ_ENABLES_NUM_HW_RING_GRPS);
- mtu = bp->dev->mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN; + mtu = bp->dev->mtu + ETH_HLEN + VLAN_HLEN; req.mru = cpu_to_le16(mtu); req.mtu = cpu_to_le16(mtu);
diff --combined drivers/net/ethernet/mellanox/mlx5/core/en_rep.c index 2de54d865dc8,f372e94948fd..1eac7a53d56f --- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c @@@ -1773,19 -1773,14 +1773,14 @@@ static void mlx5e_cleanup_rep_rx(struc
static int mlx5e_init_ul_rep_rx(struct mlx5e_priv *priv) { - int err = mlx5e_init_rep_rx(priv); - - if (err) - return err; - mlx5e_create_q_counters(priv); - return 0; + return mlx5e_init_rep_rx(priv); }
static void mlx5e_cleanup_ul_rep_rx(struct mlx5e_priv *priv) { - mlx5e_destroy_q_counters(priv); mlx5e_cleanup_rep_rx(priv); + mlx5e_destroy_q_counters(priv); }
static int mlx5e_init_uplink_rep_tx(struct mlx5e_rep_priv *rpriv) @@@ -2056,22 -2051,26 +2051,22 @@@ static int register_devlink_port(struc return 0;
mlx5e_rep_get_port_parent_id(rpriv->netdev, &ppid); + dl_port_index = vport_to_devlink_port_index(dev, rep->vport); pfnum = PCI_FUNC(dev->pdev->devfn);
- if (rep->vport == MLX5_VPORT_UPLINK) { + if (rep->vport == MLX5_VPORT_UPLINK) devlink_port_attrs_set(&rpriv->dl_port, DEVLINK_PORT_FLAVOUR_PHYSICAL, pfnum, false, 0, &ppid.id[0], ppid.id_len); - dl_port_index = vport_to_devlink_port_index(dev, rep->vport); - } else if (rep->vport == MLX5_VPORT_PF) { + else if (rep->vport == MLX5_VPORT_PF) devlink_port_attrs_pci_pf_set(&rpriv->dl_port, &ppid.id[0], ppid.id_len, pfnum); - dl_port_index = rep->vport; - } else if (mlx5_eswitch_is_vf_vport(dev->priv.eswitch, - rpriv->rep->vport)) { + else if (mlx5_eswitch_is_vf_vport(dev->priv.eswitch, rpriv->rep->vport)) devlink_port_attrs_pci_vf_set(&rpriv->dl_port, &ppid.id[0], ppid.id_len, pfnum, rep->vport - 1); - dl_port_index = vport_to_devlink_port_index(dev, rep->vport); - }
return devlink_port_register(devlink, &rpriv->dl_port, dl_port_index); } diff --combined drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c index 781c1d184b60,5d9def18ae3a..57ac2ef52e80 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c @@@ -784,8 -784,7 +784,8 @@@ static bool mlx5_eswitch_reg_c1_loopbac static int esw_set_passing_vport_metadata(struct mlx5_eswitch *esw, bool enable) { u32 out[MLX5_ST_SZ_DW(query_esw_vport_context_out)] = {}; - u32 in[MLX5_ST_SZ_DW(modify_esw_vport_context_in)] = {}; + u32 min[MLX5_ST_SZ_DW(modify_esw_vport_context_in)] = {}; + u32 in[MLX5_ST_SZ_DW(query_esw_vport_context_in)] = {}; u8 curr, wanted; int err;
@@@ -793,9 -792,8 +793,9 @@@ !mlx5_eswitch_vport_match_metadata_enabled(esw)) return 0;
- err = mlx5_eswitch_query_esw_vport_context(esw->dev, 0, false, - out, sizeof(out)); + MLX5_SET(query_esw_vport_context_in, in, opcode, + MLX5_CMD_OP_QUERY_ESW_VPORT_CONTEXT); + err = mlx5_cmd_exec_inout(esw->dev, query_esw_vport_context, in, out); if (err) return err;
@@@ -810,12 -808,14 +810,12 @@@ else curr &= ~wanted;
- MLX5_SET(modify_esw_vport_context_in, in, + MLX5_SET(modify_esw_vport_context_in, min, esw_vport_context.fdb_to_vport_reg_c_id, curr); - - MLX5_SET(modify_esw_vport_context_in, in, + MLX5_SET(modify_esw_vport_context_in, min, field_select.fdb_to_vport_reg_c_id, 1);
- err = mlx5_eswitch_modify_esw_vport_context(esw->dev, 0, false, in, - sizeof(in)); + err = mlx5_eswitch_modify_esw_vport_context(esw->dev, 0, false, min); if (!err) { if (enable && (curr & MLX5_FDB_TO_VPORT_REG_C_1)) esw->flags |= MLX5_ESWITCH_REG_C1_LOOPBACK_ENABLED; @@@ -1468,7 -1468,7 +1468,7 @@@ query_vports out: *mode = mlx5_mode; return 0; -} +}
static void esw_destroy_restore_table(struct mlx5_eswitch *esw) { @@@ -1484,7 -1484,7 +1484,7 @@@
static int esw_create_restore_table(struct mlx5_eswitch *esw) { - u8 modact[MLX5_UN_SZ_BYTES(set_action_in_add_action_in_auto)] = {}; + u8 modact[MLX5_UN_SZ_BYTES(set_add_copy_action_in_auto)] = {}; int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in); struct mlx5_flow_table_attr ft_attr = {}; struct mlx5_core_dev *dev = esw->dev; @@@ -1550,9 -1550,9 +1550,9 @@@ MLX5_FLOW_NAMESPACE_KERNEL, 1, modact); if (IS_ERR(mod_hdr)) { + err = PTR_ERR(mod_hdr); esw_warn(dev, "Failed to create restore mod header, err: %d\n", err); - err = PTR_ERR(mod_hdr); goto err_mod_hdr; }
@@@ -1894,7 -1894,7 +1894,7 @@@ static int esw_vport_ingress_prio_tag_c static int esw_vport_add_ingress_acl_modify_metadata(struct mlx5_eswitch *esw, struct mlx5_vport *vport) { - u8 action[MLX5_UN_SZ_BYTES(set_action_in_add_action_in_auto)] = {}; + u8 action[MLX5_UN_SZ_BYTES(set_add_copy_action_in_auto)] = {}; struct mlx5_flow_act flow_act = {}; int err = 0; u32 key; @@@ -2219,10 -2219,12 +2219,12 @@@ static int esw_offloads_steering_init(s total_vports = num_vfs + MLX5_SPECIAL_VPORTS(esw->dev);
memset(&esw->fdb_table.offloads, 0, sizeof(struct offloads_fdb)); + mutex_init(&esw->fdb_table.offloads.vports.lock); + hash_init(esw->fdb_table.offloads.vports.table);
err = esw_create_uplink_offloads_acl_tables(esw); if (err) - return err; + goto create_acl_err;
err = esw_create_offloads_table(esw, total_vports); if (err) @@@ -2240,9 -2242,6 +2242,6 @@@ if (err) goto create_fg_err;
- mutex_init(&esw->fdb_table.offloads.vports.lock); - hash_init(esw->fdb_table.offloads.vports.table); - return 0;
create_fg_err: @@@ -2253,18 -2252,19 +2252,19 @@@ create_restore_err esw_destroy_offloads_table(esw); create_offloads_err: esw_destroy_uplink_offloads_acl_tables(esw); - + create_acl_err: + mutex_destroy(&esw->fdb_table.offloads.vports.lock); return err; }
static void esw_offloads_steering_cleanup(struct mlx5_eswitch *esw) { - mutex_destroy(&esw->fdb_table.offloads.vports.lock); esw_destroy_vport_rx_group(esw); esw_destroy_offloads_fdb_tables(esw); esw_destroy_restore_table(esw); esw_destroy_offloads_table(esw); esw_destroy_uplink_offloads_acl_tables(esw); + mutex_destroy(&esw->fdb_table.offloads.vports.lock); }
static void @@@ -2377,9 -2377,9 +2377,9 @@@ int esw_offloads_enable(struct mlx5_esw err_vports: esw_offloads_unload_rep(esw, MLX5_VPORT_UPLINK); err_uplink: - esw_set_passing_vport_metadata(esw, false); - err_steering_init: esw_offloads_steering_cleanup(esw); + err_steering_init: + esw_set_passing_vport_metadata(esw, false); err_vport_metadata: mlx5_rdma_disable_roce(esw->dev); mutex_destroy(&esw->offloads.termtbl_mutex); diff --combined drivers/net/ethernet/mellanox/mlx5/core/steering/dr_send.c index c4ed25bb9ac8,18719acb7e54..b8d97d44be7b --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_send.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_send.c @@@ -100,10 -100,14 +100,10 @@@ static int dr_poll_cq(struct mlx5dr_cq return err == CQ_POLL_ERR ? err : npolled; }
-static void dr_qp_event(struct mlx5_core_qp *mqp, int event) -{ - pr_info("DR QP event %u on QP #%u\n", event, mqp->qpn); -} - static struct mlx5dr_qp *dr_create_rc_qp(struct mlx5_core_dev *mdev, struct dr_qp_init_attr *attr) { + u32 out[MLX5_ST_SZ_DW(create_qp_out)] = {}; u32 temp_qpc[MLX5_ST_SZ_DW(qpc)] = {}; struct mlx5_wq_param wqp; struct mlx5dr_qp *dr_qp; @@@ -176,12 -180,14 +176,12 @@@ (__be64 *)MLX5_ADDR_OF(create_qp_in, in, pas));
- err = mlx5_core_create_qp(mdev, &dr_qp->mqp, in, inlen); + MLX5_SET(create_qp_in, in, opcode, MLX5_CMD_OP_CREATE_QP); + err = mlx5_cmd_exec(mdev, in, inlen, out, sizeof(out)); + dr_qp->qpn = MLX5_GET(create_qp_out, out, qpn); kfree(in); - - if (err) { - mlx5_core_warn(mdev, " Can't create QP\n"); + if (err) goto err_in; - } - dr_qp->mqp.event = dr_qp_event; dr_qp->uar = attr->uar;
return dr_qp; @@@ -198,12 -204,7 +198,12 @@@ err_wq static void dr_destroy_qp(struct mlx5_core_dev *mdev, struct mlx5dr_qp *dr_qp) { - mlx5_core_destroy_qp(mdev, &dr_qp->mqp); + u32 in[MLX5_ST_SZ_DW(destroy_qp_in)] = {}; + + MLX5_SET(destroy_qp_in, in, opcode, MLX5_CMD_OP_DESTROY_QP); + MLX5_SET(destroy_qp_in, in, qpn, dr_qp->qpn); + mlx5_cmd_exec_in(mdev, destroy_qp, in); + kfree(dr_qp->sq.wqe_head); mlx5_wq_destroy(&dr_qp->wq_ctrl); kfree(dr_qp); @@@ -241,7 -242,7 +241,7 @@@ static void dr_rdma_segments(struct mlx MLX5_WQE_CTRL_CQ_UPDATE : 0; wq_ctrl->opmod_idx_opcode = cpu_to_be32(((dr_qp->sq.pc & 0xffff) << 8) | opcode); - wq_ctrl->qpn_ds = cpu_to_be32(size | dr_qp->mqp.qpn << 8); + wq_ctrl->qpn_ds = cpu_to_be32(size | dr_qp->qpn << 8); wq_raddr = (void *)(wq_ctrl + 1); wq_raddr->raddr = cpu_to_be64(remote_addr); wq_raddr->rkey = cpu_to_be32(rkey); @@@ -584,10 -585,8 +584,10 @@@ static int dr_modify_qp_rst2init(struc MLX5_SET(qpc, qpc, rre, 1); MLX5_SET(qpc, qpc, rwe, 1);
- return mlx5_core_qp_modify(mdev, MLX5_CMD_OP_RST2INIT_QP, 0, qpc, - &dr_qp->mqp); + MLX5_SET(rst2init_qp_in, in, opcode, MLX5_CMD_OP_RST2INIT_QP); + MLX5_SET(rst2init_qp_in, in, qpn, dr_qp->qpn); + + return mlx5_cmd_exec_in(mdev, rst2init_qp, in); }
static int dr_cmd_modify_qp_rtr2rts(struct mlx5_core_dev *mdev, @@@ -599,15 -598,14 +599,15 @@@
qpc = MLX5_ADDR_OF(rtr2rts_qp_in, in, qpc);
- MLX5_SET(rtr2rts_qp_in, in, qpn, dr_qp->mqp.qpn); + MLX5_SET(rtr2rts_qp_in, in, qpn, dr_qp->qpn);
- MLX5_SET(qpc, qpc, log_ack_req_freq, 0); MLX5_SET(qpc, qpc, retry_count, attr->retry_cnt); MLX5_SET(qpc, qpc, rnr_retry, attr->rnr_retry);
- return mlx5_core_qp_modify(mdev, MLX5_CMD_OP_RTR2RTS_QP, 0, qpc, - &dr_qp->mqp); + MLX5_SET(rtr2rts_qp_in, in, opcode, MLX5_CMD_OP_RTR2RTS_QP); + MLX5_SET(rtr2rts_qp_in, in, qpn, dr_qp->qpn); + + return mlx5_cmd_exec_in(mdev, rtr2rts_qp, in); }
static int dr_cmd_modify_qp_init2rtr(struct mlx5_core_dev *mdev, @@@ -619,7 -617,7 +619,7 @@@
qpc = MLX5_ADDR_OF(init2rtr_qp_in, in, qpc);
- MLX5_SET(init2rtr_qp_in, in, qpn, dr_qp->mqp.qpn); + MLX5_SET(init2rtr_qp_in, in, qpn, dr_qp->qpn);
MLX5_SET(qpc, qpc, mtu, attr->mtu); MLX5_SET(qpc, qpc, log_msg_max, DR_CHUNK_SIZE_MAX - 1); @@@ -638,10 -636,8 +638,10 @@@ MLX5_SET(qpc, qpc, primary_address_path.vhca_port_num, attr->port_num); MLX5_SET(qpc, qpc, min_rnr_nak, 1);
- return mlx5_core_qp_modify(mdev, MLX5_CMD_OP_INIT2RTR_QP, 0, qpc, - &dr_qp->mqp); + MLX5_SET(init2rtr_qp_in, in, opcode, MLX5_CMD_OP_INIT2RTR_QP); + MLX5_SET(init2rtr_qp_in, in, qpn, dr_qp->qpn); + + return mlx5_cmd_exec_in(mdev, init2rtr_qp, in); }
static int dr_prepare_qp_to_rts(struct mlx5dr_domain *dmn) @@@ -667,7 -663,7 +667,7 @@@ return ret;
rtr_attr.mtu = mtu; - rtr_attr.qp_num = dr_qp->mqp.qpn; + rtr_attr.qp_num = dr_qp->qpn; rtr_attr.min_rnr_timer = 12; rtr_attr.port_num = port; rtr_attr.sgid_index = gid_index; @@@ -693,6 -689,18 +693,12 @@@ return 0; }
-static void dr_cq_event(struct mlx5_core_cq *mcq, - enum mlx5_event event) -{ - pr_info("CQ event %u on CQ #%u\n", event, mcq->cqn); -} - + static void dr_cq_complete(struct mlx5_core_cq *mcq, + struct mlx5_eqe *eqe) + { + pr_err("CQ completion CQ: #%u\n", mcq->cqn); + } + static struct mlx5dr_cq *dr_create_cq(struct mlx5_core_dev *mdev, struct mlx5_uars_page *uar, size_t ncqe) @@@ -753,6 -761,9 +759,8 @@@ pas = (__be64 *)MLX5_ADDR_OF(create_cq_in, in, pas); mlx5_fill_page_frag_array(&cq->wq_ctrl.buf, pas);
- cq->mcq.event = dr_cq_event; + cq->mcq.comp = dr_cq_complete; + err = mlx5_core_create_cq(mdev, &cq->mcq, in, inlen, out, sizeof(out)); kvfree(in);
@@@ -763,7 -774,12 +771,12 @@@ cq->mcq.set_ci_db = cq->wq_ctrl.db.db; cq->mcq.arm_db = cq->wq_ctrl.db.db + 1; *cq->mcq.set_ci_db = 0; - *cq->mcq.arm_db = 0; + + /* set no-zero value, in order to avoid the HW to run db-recovery on + * CQ that used in polling mode. + */ + *cq->mcq.arm_db = cpu_to_be32(2 << 28); + cq->mcq.vector = 0; cq->mcq.irqn = irqn; cq->mcq.uar = uar; diff --combined drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c index 89c2e9820e95,890b078851c9..0897ca1967ab --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c @@@ -15,7 -15,7 +15,7 @@@ #include "core_acl_flex_keys.h"
static int mlxsw_sp_flower_parse_actions(struct mlxsw_sp *mlxsw_sp, - struct mlxsw_sp_acl_block *block, + struct mlxsw_sp_flow_block *block, struct mlxsw_sp_acl_rule_info *rulei, struct flow_action *flow_action, struct netlink_ext_ack *extack) @@@ -36,7 -36,8 +36,8 @@@ err = mlxsw_sp_acl_rulei_act_count(mlxsw_sp, rulei, extack); if (err) return err; - } else if (act->hw_stats != FLOW_ACTION_HW_STATS_DISABLED) { + } else if (act->hw_stats != FLOW_ACTION_HW_STATS_DISABLED && + act->hw_stats != FLOW_ACTION_HW_STATS_DONT_CARE) { NL_SET_ERR_MSG_MOD(extack, "Unsupported action HW stats type"); return -EOPNOTSUPP; } @@@ -53,11 -54,11 +54,11 @@@ case FLOW_ACTION_DROP: { bool ingress;
- if (mlxsw_sp_acl_block_is_mixed_bound(block)) { + if (mlxsw_sp_flow_block_is_mixed_bound(block)) { NL_SET_ERR_MSG_MOD(extack, "Drop action is not supported when block is bound to ingress and egress"); return -EOPNOTSUPP; } - ingress = mlxsw_sp_acl_block_is_ingress_bound(block); + ingress = mlxsw_sp_flow_block_is_ingress_bound(block); err = mlxsw_sp_acl_rulei_act_drop(rulei, ingress, act->cookie, extack); if (err) { @@@ -106,7 -107,7 +107,7 @@@ struct mlxsw_sp_fid *fid; u16 fid_index;
- if (mlxsw_sp_acl_block_is_egress_bound(block)) { + if (mlxsw_sp_flow_block_is_egress_bound(block)) { NL_SET_ERR_MSG_MOD(extack, "Redirect action is not supported on egress"); return -EOPNOTSUPP; } @@@ -190,7 -191,7 +191,7 @@@
static int mlxsw_sp_flower_parse_meta(struct mlxsw_sp_acl_rule_info *rulei, struct flow_cls_offload *f, - struct mlxsw_sp_acl_block *block) + struct mlxsw_sp_flow_block *block) { struct flow_rule *rule = flow_cls_offload_flow_rule(f); struct mlxsw_sp_port *mlxsw_sp_port; @@@ -371,7 -372,7 +372,7 @@@ static int mlxsw_sp_flower_parse_ip(str }
static int mlxsw_sp_flower_parse(struct mlxsw_sp *mlxsw_sp, - struct mlxsw_sp_acl_block *block, + struct mlxsw_sp_flow_block *block, struct mlxsw_sp_acl_rule_info *rulei, struct flow_cls_offload *f) { @@@ -460,7 -461,7 +461,7 @@@ struct flow_match_vlan match;
flow_rule_match_vlan(rule, &match); - if (mlxsw_sp_acl_block_is_egress_bound(block)) { + if (mlxsw_sp_flow_block_is_egress_bound(block)) { NL_SET_ERR_MSG_MOD(f->common.extack, "vlan_id key is not supported on egress"); return -EOPNOTSUPP; } @@@ -505,7 -506,7 +506,7 @@@ }
int mlxsw_sp_flower_replace(struct mlxsw_sp *mlxsw_sp, - struct mlxsw_sp_acl_block *block, + struct mlxsw_sp_flow_block *block, struct flow_cls_offload *f) { struct mlxsw_sp_acl_rule_info *rulei; @@@ -552,7 -553,7 +553,7 @@@ err_rule_create }
void mlxsw_sp_flower_destroy(struct mlxsw_sp *mlxsw_sp, - struct mlxsw_sp_acl_block *block, + struct mlxsw_sp_flow_block *block, struct flow_cls_offload *f) { struct mlxsw_sp_acl_ruleset *ruleset; @@@ -574,7 -575,7 +575,7 @@@ }
int mlxsw_sp_flower_stats(struct mlxsw_sp *mlxsw_sp, - struct mlxsw_sp_acl_block *block, + struct mlxsw_sp_flow_block *block, struct flow_cls_offload *f) { enum flow_action_hw_stats used_hw_stats = FLOW_ACTION_HW_STATS_DISABLED; @@@ -611,7 -612,7 +612,7 @@@ err_rule_get_stats }
int mlxsw_sp_flower_tmplt_create(struct mlxsw_sp *mlxsw_sp, - struct mlxsw_sp_acl_block *block, + struct mlxsw_sp_flow_block *block, struct flow_cls_offload *f) { struct mlxsw_sp_acl_ruleset *ruleset; @@@ -632,7 -633,7 +633,7 @@@ }
void mlxsw_sp_flower_tmplt_destroy(struct mlxsw_sp *mlxsw_sp, - struct mlxsw_sp_acl_block *block, + struct mlxsw_sp_flow_block *block, struct flow_cls_offload *f) { struct mlxsw_sp_acl_ruleset *ruleset; diff --combined drivers/net/ethernet/moxa/moxart_ether.c index 1b25cc42f442,f70bb81e1ed6..49fd843c4c8a --- a/drivers/net/ethernet/moxa/moxart_ether.c +++ b/drivers/net/ethernet/moxa/moxart_ether.c @@@ -331,15 -331,14 +331,15 @@@ static irqreturn_t moxart_mac_interrupt return IRQ_HANDLED; }
-static int moxart_mac_start_xmit(struct sk_buff *skb, struct net_device *ndev) +static netdev_tx_t moxart_mac_start_xmit(struct sk_buff *skb, + struct net_device *ndev) { struct moxart_mac_priv_t *priv = netdev_priv(ndev); void *desc; unsigned int len; unsigned int tx_head; u32 txdes1; - int ret = NETDEV_TX_BUSY; + netdev_tx_t ret = NETDEV_TX_BUSY;
spin_lock_irq(&priv->txlock);
@@@ -565,7 -564,7 +565,7 @@@ static int moxart_remove(struct platfor struct net_device *ndev = platform_get_drvdata(pdev);
unregister_netdev(ndev); - free_irq(ndev->irq, ndev); + devm_free_irq(&pdev->dev, ndev->irq, ndev); moxart_mac_free_memory(ndev); free_netdev(ndev);
diff --combined drivers/net/ethernet/mscc/ocelot.c index a2b9b85612a4,02350c3d9d01..c798431ce2a1 --- a/drivers/net/ethernet/mscc/ocelot.c +++ b/drivers/net/ethernet/mscc/ocelot.c @@@ -14,6 -14,7 +14,6 @@@ #include <linux/module.h> #include <linux/netdevice.h> #include <linux/phy.h> -#include <linux/ptp_clock_kernel.h> #include <linux/skbuff.h> #include <linux/iopoll.h> #include <net/arp.h> @@@ -1030,10 -1031,8 +1030,8 @@@ int ocelot_fdb_dump(struct ocelot *ocel { int i, j;
- /* Loop through all the mac tables entries. There are 1024 rows of 4 - * entries. - */ - for (i = 0; i < 1024; i++) { + /* Loop through all the mac tables entries. */ + for (i = 0; i < ocelot->num_mact_rows; i++) { for (j = 0; j < 4; j++) { struct ocelot_mact_entry entry; bool is_static; @@@ -1349,12 -1348,6 +1347,12 @@@ int ocelot_get_ts_info(struct ocelot *o { info->phc_index = ocelot->ptp_clock ? ptp_clock_index(ocelot->ptp_clock) : -1; + if (info->phc_index == -1) { + info->so_timestamping |= SOF_TIMESTAMPING_TX_SOFTWARE | + SOF_TIMESTAMPING_RX_SOFTWARE | + SOF_TIMESTAMPING_SOFTWARE; + return 0; + } info->so_timestamping |= SOF_TIMESTAMPING_TX_SOFTWARE | SOF_TIMESTAMPING_RX_SOFTWARE | SOF_TIMESTAMPING_SOFTWARE | @@@ -1458,8 -1451,15 +1456,15 @@@ static void ocelot_port_attr_stp_state_
void ocelot_set_ageing_time(struct ocelot *ocelot, unsigned int msecs) { - ocelot_write(ocelot, ANA_AUTOAGE_AGE_PERIOD(msecs / 2), - ANA_AUTOAGE); + unsigned int age_period = ANA_AUTOAGE_AGE_PERIOD(msecs / 2000); + + /* Setting AGE_PERIOD to zero effectively disables automatic aging, + * which is clearly not what our intention is. So avoid that. + */ + if (!age_period) + age_period = 1; + + ocelot_rmw(ocelot, age_period, ANA_AUTOAGE_AGE_PERIOD_M, ANA_AUTOAGE); } EXPORT_SYMBOL(ocelot_set_ageing_time);
@@@ -1996,6 -1996,200 +2001,6 @@@ struct notifier_block ocelot_switchdev_ }; EXPORT_SYMBOL(ocelot_switchdev_blocking_nb);
-int ocelot_ptp_gettime64(struct ptp_clock_info *ptp, struct timespec64 *ts) -{ - struct ocelot *ocelot = container_of(ptp, struct ocelot, ptp_info); - unsigned long flags; - time64_t s; - u32 val; - s64 ns; - - spin_lock_irqsave(&ocelot->ptp_clock_lock, flags); - - val = ocelot_read_rix(ocelot, PTP_PIN_CFG, TOD_ACC_PIN); - val &= ~(PTP_PIN_CFG_SYNC | PTP_PIN_CFG_ACTION_MASK | PTP_PIN_CFG_DOM); - val |= PTP_PIN_CFG_ACTION(PTP_PIN_ACTION_SAVE); - ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN); - - s = ocelot_read_rix(ocelot, PTP_PIN_TOD_SEC_MSB, TOD_ACC_PIN) & 0xffff; - s <<= 32; - s += ocelot_read_rix(ocelot, PTP_PIN_TOD_SEC_LSB, TOD_ACC_PIN); - ns = ocelot_read_rix(ocelot, PTP_PIN_TOD_NSEC, TOD_ACC_PIN); - - spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags); - - /* Deal with negative values */ - if (ns >= 0x3ffffff0 && ns <= 0x3fffffff) { - s--; - ns &= 0xf; - ns += 999999984; - } - - set_normalized_timespec64(ts, s, ns); - return 0; -} -EXPORT_SYMBOL(ocelot_ptp_gettime64); - -static int ocelot_ptp_settime64(struct ptp_clock_info *ptp, - const struct timespec64 *ts) -{ - struct ocelot *ocelot = container_of(ptp, struct ocelot, ptp_info); - unsigned long flags; - u32 val; - - spin_lock_irqsave(&ocelot->ptp_clock_lock, flags); - - val = ocelot_read_rix(ocelot, PTP_PIN_CFG, TOD_ACC_PIN); - val &= ~(PTP_PIN_CFG_SYNC | PTP_PIN_CFG_ACTION_MASK | PTP_PIN_CFG_DOM); - val |= PTP_PIN_CFG_ACTION(PTP_PIN_ACTION_IDLE); - - ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN); - - ocelot_write_rix(ocelot, lower_32_bits(ts->tv_sec), PTP_PIN_TOD_SEC_LSB, - TOD_ACC_PIN); - ocelot_write_rix(ocelot, upper_32_bits(ts->tv_sec), PTP_PIN_TOD_SEC_MSB, - TOD_ACC_PIN); - ocelot_write_rix(ocelot, ts->tv_nsec, PTP_PIN_TOD_NSEC, TOD_ACC_PIN); - - val = ocelot_read_rix(ocelot, PTP_PIN_CFG, TOD_ACC_PIN); - val &= ~(PTP_PIN_CFG_SYNC | PTP_PIN_CFG_ACTION_MASK | PTP_PIN_CFG_DOM); - val |= PTP_PIN_CFG_ACTION(PTP_PIN_ACTION_LOAD); - - ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN); - - spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags); - return 0; -} - -static int ocelot_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta) -{ - if (delta > -(NSEC_PER_SEC / 2) && delta < (NSEC_PER_SEC / 2)) { - struct ocelot *ocelot = container_of(ptp, struct ocelot, ptp_info); - unsigned long flags; - u32 val; - - spin_lock_irqsave(&ocelot->ptp_clock_lock, flags); - - val = ocelot_read_rix(ocelot, PTP_PIN_CFG, TOD_ACC_PIN); - val &= ~(PTP_PIN_CFG_SYNC | PTP_PIN_CFG_ACTION_MASK | PTP_PIN_CFG_DOM); - val |= PTP_PIN_CFG_ACTION(PTP_PIN_ACTION_IDLE); - - ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN); - - ocelot_write_rix(ocelot, 0, PTP_PIN_TOD_SEC_LSB, TOD_ACC_PIN); - ocelot_write_rix(ocelot, 0, PTP_PIN_TOD_SEC_MSB, TOD_ACC_PIN); - ocelot_write_rix(ocelot, delta, PTP_PIN_TOD_NSEC, TOD_ACC_PIN); - - val = ocelot_read_rix(ocelot, PTP_PIN_CFG, TOD_ACC_PIN); - val &= ~(PTP_PIN_CFG_SYNC | PTP_PIN_CFG_ACTION_MASK | PTP_PIN_CFG_DOM); - val |= PTP_PIN_CFG_ACTION(PTP_PIN_ACTION_DELTA); - - ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN); - - spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags); - } else { - /* Fall back using ocelot_ptp_settime64 which is not exact. */ - struct timespec64 ts; - u64 now; - - ocelot_ptp_gettime64(ptp, &ts); - - now = ktime_to_ns(timespec64_to_ktime(ts)); - ts = ns_to_timespec64(now + delta); - - ocelot_ptp_settime64(ptp, &ts); - } - return 0; -} - -static int ocelot_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm) -{ - struct ocelot *ocelot = container_of(ptp, struct ocelot, ptp_info); - u32 unit = 0, direction = 0; - unsigned long flags; - u64 adj = 0; - - spin_lock_irqsave(&ocelot->ptp_clock_lock, flags); - - if (!scaled_ppm) - goto disable_adj; - - if (scaled_ppm < 0) { - direction = PTP_CFG_CLK_ADJ_CFG_DIR; - scaled_ppm = -scaled_ppm; - } - - adj = PSEC_PER_SEC << 16; - do_div(adj, scaled_ppm); - do_div(adj, 1000); - - /* If the adjustment value is too large, use ns instead */ - if (adj >= (1L << 30)) { - unit = PTP_CFG_CLK_ADJ_FREQ_NS; - do_div(adj, 1000); - } - - /* Still too big */ - if (adj >= (1L << 30)) - goto disable_adj; - - ocelot_write(ocelot, unit | adj, PTP_CLK_CFG_ADJ_FREQ); - ocelot_write(ocelot, PTP_CFG_CLK_ADJ_CFG_ENA | direction, - PTP_CLK_CFG_ADJ_CFG); - - spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags); - return 0; - -disable_adj: - ocelot_write(ocelot, 0, PTP_CLK_CFG_ADJ_CFG); - - spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags); - return 0; -} - -static struct ptp_clock_info ocelot_ptp_clock_info = { - .owner = THIS_MODULE, - .name = "ocelot ptp", - .max_adj = 0x7fffffff, - .n_alarm = 0, - .n_ext_ts = 0, - .n_per_out = 0, - .n_pins = 0, - .pps = 0, - .gettime64 = ocelot_ptp_gettime64, - .settime64 = ocelot_ptp_settime64, - .adjtime = ocelot_ptp_adjtime, - .adjfine = ocelot_ptp_adjfine, -}; - -static int ocelot_init_timestamp(struct ocelot *ocelot) -{ - struct ptp_clock *ptp_clock; - - ocelot->ptp_info = ocelot_ptp_clock_info; - ptp_clock = ptp_clock_register(&ocelot->ptp_info, ocelot->dev); - if (IS_ERR(ptp_clock)) - return PTR_ERR(ptp_clock); - /* Check if PHC support is missing at the configuration level */ - if (!ptp_clock) - return 0; - - ocelot->ptp_clock = ptp_clock; - - ocelot_write(ocelot, SYS_PTP_CFG_PTP_STAMP_WID(30), SYS_PTP_CFG); - ocelot_write(ocelot, 0xffffffff, ANA_TABLES_PTP_ID_LOW); - ocelot_write(ocelot, 0xffffffff, ANA_TABLES_PTP_ID_HIGH); - - ocelot_write(ocelot, PTP_CFG_MISC_PTP_EN, PTP_CFG_MISC); - - /* There is no device reconfiguration, PTP Rx stamping is always - * enabled. - */ - ocelot->hwtstamp_config.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; - - return 0; -} - /* Configure the maximum SDU (L2 payload) on RX to the value specified in @sdu. * The length of VLAN tags is accounted for automatically via DEV_MAC_TAGS_CFG. * In the special case that it's the NPI port that we're configuring, the @@@ -2341,6 -2535,15 +2346,6 @@@ int ocelot_init(struct ocelot *ocelot queue_delayed_work(ocelot->stats_queue, &ocelot->stats_work, OCELOT_STATS_CHECK_DELAY);
- if (ocelot->ptp) { - ret = ocelot_init_timestamp(ocelot); - if (ret) { - dev_err(ocelot->dev, - "Timestamp initialization failed\n"); - return ret; - } - } - return 0; } EXPORT_SYMBOL(ocelot_init); @@@ -2353,6 -2556,8 +2358,6 @@@ void ocelot_deinit(struct ocelot *ocelo cancel_delayed_work(&ocelot->stats_work); destroy_workqueue(ocelot->stats_queue); mutex_destroy(&ocelot->stats_lock); - if (ocelot->ptp_clock) - ptp_clock_unregister(ocelot->ptp_clock);
for (i = 0; i < ocelot->num_phys_ports; i++) { port = ocelot->ports[i]; diff --combined drivers/net/ethernet/mscc/ocelot_regs.c index ed4dd01a41ad,7d4fd1b6adda..81d81ff75646 --- a/drivers/net/ethernet/mscc/ocelot_regs.c +++ b/drivers/net/ethernet/mscc/ocelot_regs.c @@@ -239,8 -239,6 +239,8 @@@ static const u32 ocelot_ptp_regmap[] = REG(PTP_PIN_TOD_SEC_MSB, 0x000004), REG(PTP_PIN_TOD_SEC_LSB, 0x000008), REG(PTP_PIN_TOD_NSEC, 0x00000c), + REG(PTP_PIN_WF_HIGH_PERIOD, 0x000014), + REG(PTP_PIN_WF_LOW_PERIOD, 0x000018), REG(PTP_CFG_MISC, 0x0000a0), REG(PTP_CLK_CFG_ADJ_CFG, 0x0000a4), REG(PTP_CLK_CFG_ADJ_FREQ, 0x0000a8), @@@ -433,6 -431,7 +433,7 @@@ int ocelot_chip_init(struct ocelot *oce ocelot->stats_layout = ocelot_stats_layout; ocelot->num_stats = ARRAY_SIZE(ocelot_stats_layout); ocelot->shared_queue_sz = 224 * 1024; + ocelot->num_mact_rows = 1024; ocelot->ops = ops;
ret = ocelot_regfields_init(ocelot, ocelot_regfields); diff --combined drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 90bddca1ddd8,a999d6b33a64..8f08393f25dd --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@@ -3543,6 -3543,15 +3543,6 @@@ static void stmmac_rx_vlan(struct net_d } }
- -static inline int stmmac_rx_threshold_count(struct stmmac_rx_queue *rx_q) -{ - if (rx_q->rx_zeroc_thresh < STMMAC_RX_THRESH) - return 0; - - return 1; -} - /** * stmmac_rx_refill - refill used skb preallocated buffers * @priv: driver private structure @@@ -4051,7 -4060,7 +4051,7 @@@ static int stmmac_set_features(struct n /** * stmmac_interrupt - main ISR * @irq: interrupt number. - * @dev_id: to pass the net device pointer. + * @dev_id: to pass the net device pointer (must be valid). * Description: this is the main driver interrupt service routine. * It can call: * o DMA service routine (to manage incoming frame reception and transmission @@@ -4075,11 -4084,6 +4075,6 @@@ static irqreturn_t stmmac_interrupt(in if (priv->irq_wake) pm_wakeup_event(priv->device, 0);
- if (unlikely(!dev)) { - netdev_err(priv->dev, "%s: invalid dev pointer\n", __func__); - return IRQ_NONE; - } - /* Check if adapter is up */ if (test_bit(STMMAC_DOWN, &priv->state)) return IRQ_HANDLED; diff --combined drivers/net/ethernet/ti/Kconfig index 519f5a8c5810,8e348780efb6..988e907e3322 --- a/drivers/net/ethernet/ti/Kconfig +++ b/drivers/net/ethernet/ti/Kconfig @@@ -90,9 -90,8 +90,8 @@@ config TI_CPT config TI_CPTS_MOD tristate depends on TI_CPTS + depends on PTP_1588_CLOCK default y if TI_CPSW=y || TI_KEYSTONE_NETCP=y || TI_CPSW_SWITCHDEV=y - select NET_PTP_CLASSIFY - imply PTP_1588_CLOCK default m
config TI_K3_AM65_CPSW_NUSS @@@ -100,7 -99,6 +99,7 @@@ depends on ARCH_K3 && OF && TI_K3_UDMA_GLUE_LAYER select TI_DAVINCI_MDIO imply PHY_TI_GMII_SEL + depends on TI_K3_AM65_CPTS || !TI_K3_AM65_CPTS help This driver supports TI K3 AM654/J721E CPSW2G Ethernet SubSystem. The two-port Gigabit Ethernet MAC (MCU_CPSW0) subsystem provides @@@ -111,19 -109,6 +110,19 @@@ To compile this driver as a module, choose M here: the module will be called ti-am65-cpsw-nuss.
+config TI_K3_AM65_CPTS + tristate "TI K3 AM65x CPTS" + depends on ARCH_K3 && OF + depends on PTP_1588_CLOCK + help + Say y here to support the TI K3 AM65x CPTS with 1588 features such as + PTP hardware clock for each CPTS device and network packets + timestamping where applicable. + Depending on integration CPTS blocks enable compliance with + the IEEE 1588-2008 standard for a precision clock synchronization + protocol, Ethernet Enhanced Scheduled Traffic Operations (CPTS_ESTFn) + and PCIe Subsystem Precision Time Measurement (PTM). + config TI_KEYSTONE_NETCP tristate "TI Keystone NETCP Core Support" select TI_DAVINCI_MDIO @@@ -152,7 -137,7 +151,7 @@@ config TLA
Devices currently supported by this driver are Compaq Netelligent, Compaq NetFlex and Olicom cards. Please read the file - file:Documentation/networking/device_drivers/ti/tlan.txt + file:Documentation/networking/device_drivers/ti/tlan.rst for more details.
To compile this driver as a module, choose M here. The module diff --combined drivers/net/ethernet/ti/am65-cpsw-nuss.c index bb391286d89e,2517ffba8178..f8c589929308 --- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c +++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c @@@ -30,7 -30,6 +30,7 @@@ #include "cpsw_sl.h" #include "am65-cpsw-nuss.h" #include "k3-cppi-desc-pool.h" +#include "am65-cpts.h"
#define AM65_CPSW_SS_BASE 0x0 #define AM65_CPSW_SGMII_BASE 0x100 @@@ -669,18 -668,6 +669,18 @@@ static void am65_cpsw_nuss_rx_cleanup(v dev_kfree_skb_any(skb); }
+static void am65_cpsw_nuss_rx_ts(struct sk_buff *skb, u32 *psdata) +{ + struct skb_shared_hwtstamps *ssh; + u64 ns; + + ns = ((u64)psdata[1] << 32) | psdata[0]; + + ssh = skb_hwtstamps(skb); + memset(ssh, 0, sizeof(*ssh)); + ssh->hwtstamp = ns_to_ktime(ns); +} + /* RX psdata[2] word format - checksum information */ #define AM65_CPSW_RX_PSD_CSUM_ADD GENMASK(15, 0) #define AM65_CPSW_RX_PSD_CSUM_ERR BIT(16) @@@ -758,9 -745,6 +758,9 @@@ static int am65_cpsw_nuss_rx_packets(st skb->dev = ndev;
psdata = cppi5_hdesc_get_psdata(desc_rx); + /* add RX timestamp */ + if (port->rx_ts_enabled) + am65_cpsw_nuss_rx_ts(skb, psdata); csum_info = psdata[2]; dev_dbg(dev, "%s rx csum_info:%#x\n", __func__, csum_info);
@@@ -920,8 -904,6 +920,8 @@@ static int am65_cpsw_nuss_tx_compl_pack
ndev = skb->dev;
+ am65_cpts_tx_timestamp(common->cpts, skb); + ndev_priv = netdev_priv(ndev); stats = this_cpu_ptr(ndev_priv->stats); u64_stats_update_begin(&stats->syncp); @@@ -1013,10 -995,6 +1013,10 @@@ static netdev_tx_t am65_cpsw_nuss_ndo_s /* padding enabled in hw */ pkt_len = skb_headlen(skb);
+ /* SKB TX timestamp */ + if (port->tx_ts_enabled) + am65_cpts_prep_tx_timestamp(common->cpts, skb); + q_idx = skb_get_queue_mapping(skb); dev_dbg(dev, "%s skb_queue:%d\n", __func__, q_idx);
@@@ -1180,111 -1158,6 +1180,111 @@@ static int am65_cpsw_nuss_ndo_slave_set return 0; }
+static int am65_cpsw_nuss_hwtstamp_set(struct net_device *ndev, + struct ifreq *ifr) +{ + struct am65_cpsw_common *common = am65_ndev_to_common(ndev); + struct am65_cpsw_port *port = am65_ndev_to_port(ndev); + u32 ts_ctrl, seq_id, ts_ctrl_ltype2, ts_vlan_ltype; + struct hwtstamp_config cfg; + + if (!IS_ENABLED(CONFIG_TI_K3_AM65_CPTS)) + return -EOPNOTSUPP; + + if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg))) + return -EFAULT; + + /* TX HW timestamp */ + switch (cfg.tx_type) { + case HWTSTAMP_TX_OFF: + case HWTSTAMP_TX_ON: + break; + default: + return -ERANGE; + } + + switch (cfg.rx_filter) { + case HWTSTAMP_FILTER_NONE: + port->rx_ts_enabled = false; + break; + case HWTSTAMP_FILTER_ALL: + case HWTSTAMP_FILTER_SOME: + case HWTSTAMP_FILTER_PTP_V1_L4_EVENT: + case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: + case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: + case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: + case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: + case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ: + case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: + case HWTSTAMP_FILTER_PTP_V2_L2_SYNC: + case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ: + case HWTSTAMP_FILTER_PTP_V2_EVENT: + case HWTSTAMP_FILTER_PTP_V2_SYNC: + case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: + case HWTSTAMP_FILTER_NTP_ALL: + port->rx_ts_enabled = true; + cfg.rx_filter = HWTSTAMP_FILTER_ALL; + break; + default: + return -ERANGE; + } + + port->tx_ts_enabled = (cfg.tx_type == HWTSTAMP_TX_ON); + + /* cfg TX timestamp */ + seq_id = (AM65_CPSW_TS_SEQ_ID_OFFSET << + AM65_CPSW_PN_TS_SEQ_ID_OFFSET_SHIFT) | ETH_P_1588; + + ts_vlan_ltype = ETH_P_8021Q; + + ts_ctrl_ltype2 = ETH_P_1588 | + AM65_CPSW_PN_TS_CTL_LTYPE2_TS_107 | + AM65_CPSW_PN_TS_CTL_LTYPE2_TS_129 | + AM65_CPSW_PN_TS_CTL_LTYPE2_TS_130 | + AM65_CPSW_PN_TS_CTL_LTYPE2_TS_131 | + AM65_CPSW_PN_TS_CTL_LTYPE2_TS_132 | + AM65_CPSW_PN_TS_CTL_LTYPE2_TS_319 | + AM65_CPSW_PN_TS_CTL_LTYPE2_TS_320 | + AM65_CPSW_PN_TS_CTL_LTYPE2_TS_TTL_NONZERO; + + ts_ctrl = AM65_CPSW_TS_EVENT_MSG_TYPE_BITS << + AM65_CPSW_PN_TS_CTL_MSG_TYPE_EN_SHIFT; + + if (port->tx_ts_enabled) + ts_ctrl |= AM65_CPSW_TS_TX_ANX_ALL_EN | + AM65_CPSW_PN_TS_CTL_TX_VLAN_LT1_EN; + + writel(seq_id, port->port_base + AM65_CPSW_PORTN_REG_TS_SEQ_LTYPE_REG); + writel(ts_vlan_ltype, port->port_base + + AM65_CPSW_PORTN_REG_TS_VLAN_LTYPE_REG); + writel(ts_ctrl_ltype2, port->port_base + + AM65_CPSW_PORTN_REG_TS_CTL_LTYPE2); + writel(ts_ctrl, port->port_base + AM65_CPSW_PORTN_REG_TS_CTL); + + /* en/dis RX timestamp */ + am65_cpts_rx_enable(common->cpts, port->rx_ts_enabled); + + return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0; +} + +static int am65_cpsw_nuss_hwtstamp_get(struct net_device *ndev, + struct ifreq *ifr) +{ + struct am65_cpsw_port *port = am65_ndev_to_port(ndev); + struct hwtstamp_config cfg; + + if (!IS_ENABLED(CONFIG_TI_K3_AM65_CPTS)) + return -EOPNOTSUPP; + + cfg.flags = 0; + cfg.tx_type = port->tx_ts_enabled ? + HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF; + cfg.rx_filter = port->rx_ts_enabled ? + HWTSTAMP_FILTER_ALL : HWTSTAMP_FILTER_NONE; + + return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0; +} + static int am65_cpsw_nuss_ndo_slave_ioctl(struct net_device *ndev, struct ifreq *req, int cmd) { @@@ -1293,13 -1166,6 +1293,13 @@@ if (!netif_running(ndev)) return -EINVAL;
+ switch (cmd) { + case SIOCSHWTSTAMP: + return am65_cpsw_nuss_hwtstamp_set(ndev, req); + case SIOCGHWTSTAMP: + return am65_cpsw_nuss_hwtstamp_get(ndev, req); + } + if (!port->slave.phy) return -EOPNOTSUPP;
@@@ -1665,40 -1531,6 +1665,40 @@@ static int am65_cpsw_am654_get_efuse_ma return 0; }
+static int am65_cpsw_init_cpts(struct am65_cpsw_common *common) +{ + struct device *dev = common->dev; + struct device_node *node; + struct am65_cpts *cpts; + void __iomem *reg_base; + + if (!IS_ENABLED(CONFIG_TI_K3_AM65_CPTS)) + return 0; + + node = of_get_child_by_name(dev->of_node, "cpts"); + if (!node) { + dev_err(dev, "%s cpts not found\n", __func__); + return -ENOENT; + } + + reg_base = common->cpsw_base + AM65_CPSW_NU_CPTS_BASE; + cpts = am65_cpts_create(dev, reg_base, node); + if (IS_ERR(cpts)) { + int ret = PTR_ERR(cpts); + + if (ret == -EOPNOTSUPP) { + dev_info(dev, "cpts disabled\n"); + return 0; + } + + dev_err(dev, "cpts create err %d\n", ret); + return ret; + } + common->cpts = cpts; + + return 0; +} + static int am65_cpsw_nuss_init_slave_ports(struct am65_cpsw_common *common) { struct device_node *node, *port_np; @@@ -1887,7 -1719,8 +1887,8 @@@ static int am65_cpsw_nuss_ndev_add_napi
ret = devm_request_irq(dev, tx_chn->irq, am65_cpsw_nuss_tx_irq, - 0, tx_chn->tx_chn_name, tx_chn); + IRQF_TRIGGER_HIGH, + tx_chn->tx_chn_name, tx_chn); if (ret) { dev_err(dev, "failure requesting tx%u irq %u, %d\n", tx_chn->id, tx_chn->irq, ret); @@@ -1912,7 -1745,7 +1913,7 @@@ static int am65_cpsw_nuss_ndev_reg_2g(s
ret = devm_request_irq(dev, common->rx_chns.irq, am65_cpsw_nuss_rx_irq, - 0, dev_name(dev), common); + IRQF_TRIGGER_HIGH, dev_name(dev), common); if (ret) { dev_err(dev, "failure requesting rx irq %u, %d\n", common->rx_chns.irq, ret); @@@ -2067,10 -1900,6 +2068,10 @@@ static int am65_cpsw_nuss_probe(struct goto err_of_clear; }
+ ret = am65_cpsw_init_cpts(common); + if (ret) + goto err_of_clear; + /* init ports */ for (i = 0; i < common->port_num; i++) am65_cpsw_nuss_slave_disable_unused(&common->ports[i]); diff --combined drivers/net/hyperv/netvsc_drv.c index c0b647a4c893,ebcfbae05690..5de57fc3ec60 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c @@@ -707,7 -707,8 +707,8 @@@ no_memory goto drop; }
- static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *ndev) + static netdev_tx_t netvsc_start_xmit(struct sk_buff *skb, + struct net_device *ndev) { return netvsc_xmit(skb, ndev, false); } @@@ -2456,8 -2457,6 +2457,8 @@@ static int netvsc_probe(struct hv_devic NETIF_F_HW_VLAN_CTAG_RX; net->vlan_features = net->features;
+ netdev_lockdep_set_classes(net); + /* MTU range: 68 - 1500 or 65521 */ net->min_mtu = NETVSC_MTU_MIN; if (nvdev->nvsp_version >= NVSP_PROTOCOL_VERSION_2) diff --combined drivers/net/ipa/gsi.c index 8ccbbb920c11,b671bea0aa7c..66570609c845 --- a/drivers/net/ipa/gsi.c +++ b/drivers/net/ipa/gsi.c @@@ -415,14 -415,13 +415,14 @@@ static void gsi_evt_ring_de_alloc_comma evt_ring->state); }
-/* Return the hardware's notion of the current state of a channel */ -static enum gsi_channel_state -gsi_channel_state(struct gsi *gsi, u32 channel_id) +/* Fetch the current state of a channel from hardware */ +static enum gsi_channel_state gsi_channel_state(struct gsi_channel *channel) { + u32 channel_id = gsi_channel_id(channel); + void *virt = channel->gsi->virt; u32 val;
- val = ioread32(gsi->virt + GSI_CH_C_CNTXT_0_OFFSET(channel_id)); + val = ioread32(virt + GSI_CH_C_CNTXT_0_OFFSET(channel_id));
return u32_get_bits(val, CHSTATE_FMASK); } @@@ -433,18 -432,16 +433,18 @@@ gsi_channel_command(struct gsi_channel { struct completion *completion = &channel->completion; u32 channel_id = gsi_channel_id(channel); + struct gsi *gsi = channel->gsi; u32 val;
val = u32_encode_bits(channel_id, CH_CHID_FMASK); val |= u32_encode_bits(opcode, CH_OPCODE_FMASK);
- if (gsi_command(channel->gsi, GSI_CH_CMD_OFFSET, val, completion)) + if (gsi_command(gsi, GSI_CH_CMD_OFFSET, val, completion)) return 0; /* Success! */
- dev_err(channel->gsi->dev, "GSI command %u to channel %u timed out " - "(state is %u)\n", opcode, channel_id, channel->state); + dev_err(gsi->dev, + "GSI command %u to channel %u timed out (state is %u)\n", + opcode, channel_id, gsi_channel_state(channel));
return -ETIMEDOUT; } @@@ -453,21 -450,18 +453,21 @@@ static int gsi_channel_alloc_command(struct gsi *gsi, u32 channel_id) { struct gsi_channel *channel = &gsi->channel[channel_id]; + enum gsi_channel_state state; int ret;
/* Get initial channel state */ - channel->state = gsi_channel_state(gsi, channel_id); - - if (channel->state != GSI_CHANNEL_STATE_NOT_ALLOCATED) + state = gsi_channel_state(channel); + if (state != GSI_CHANNEL_STATE_NOT_ALLOCATED) return -EINVAL;
ret = gsi_channel_command(channel, GSI_CH_ALLOCATE); - if (!ret && channel->state != GSI_CHANNEL_STATE_ALLOCATED) { + + /* Channel state will normally have been updated */ + state = gsi_channel_state(channel); + if (!ret && state != GSI_CHANNEL_STATE_ALLOCATED) { dev_err(gsi->dev, "bad channel state (%u) after alloc\n", - channel->state); + state); ret = -EIO; }
@@@ -477,21 -471,18 +477,21 @@@ /* Start an ALLOCATED channel */ static int gsi_channel_start_command(struct gsi_channel *channel) { - enum gsi_channel_state state = channel->state; + enum gsi_channel_state state; int ret;
+ state = gsi_channel_state(channel); if (state != GSI_CHANNEL_STATE_ALLOCATED && state != GSI_CHANNEL_STATE_STOPPED) return -EINVAL;
ret = gsi_channel_command(channel, GSI_CH_START); - if (!ret && channel->state != GSI_CHANNEL_STATE_STARTED) { + + /* Channel state will normally have been updated */ + state = gsi_channel_state(channel); + if (!ret && state != GSI_CHANNEL_STATE_STARTED) { dev_err(channel->gsi->dev, - "bad channel state (%u) after start\n", - channel->state); + "bad channel state (%u) after start\n", state); ret = -EIO; }
@@@ -501,27 -492,23 +501,27 @@@ /* Stop a GSI channel in STARTED state */ static int gsi_channel_stop_command(struct gsi_channel *channel) { - enum gsi_channel_state state = channel->state; + enum gsi_channel_state state; int ret;
+ state = gsi_channel_state(channel); if (state != GSI_CHANNEL_STATE_STARTED && state != GSI_CHANNEL_STATE_STOP_IN_PROC) return -EINVAL;
ret = gsi_channel_command(channel, GSI_CH_STOP); - if (ret || channel->state == GSI_CHANNEL_STATE_STOPPED) + + /* Channel state will normally have been updated */ + state = gsi_channel_state(channel); + if (ret || state == GSI_CHANNEL_STATE_STOPPED) return ret;
/* We may have to try again if stop is in progress */ - if (channel->state == GSI_CHANNEL_STATE_STOP_IN_PROC) + if (state == GSI_CHANNEL_STATE_STOP_IN_PROC) return -EAGAIN;
- dev_err(channel->gsi->dev, "bad channel state (%u) after stop\n", - channel->state); + dev_err(channel->gsi->dev, + "bad channel state (%u) after stop\n", state);
return -EIO; } @@@ -529,49 -516,41 +529,49 @@@ /* Reset a GSI channel in ALLOCATED or ERROR state. */ static void gsi_channel_reset_command(struct gsi_channel *channel) { + enum gsi_channel_state state; int ret;
msleep(1); /* A short delay is required before a RESET command */
- if (channel->state != GSI_CHANNEL_STATE_STOPPED && - channel->state != GSI_CHANNEL_STATE_ERROR) { + state = gsi_channel_state(channel); + if (state != GSI_CHANNEL_STATE_STOPPED && + state != GSI_CHANNEL_STATE_ERROR) { dev_err(channel->gsi->dev, - "bad channel state (%u) before reset\n", - channel->state); + "bad channel state (%u) before reset\n", state); return; }
ret = gsi_channel_command(channel, GSI_CH_RESET); - if (!ret && channel->state != GSI_CHANNEL_STATE_ALLOCATED) + + /* Channel state will normally have been updated */ + state = gsi_channel_state(channel); + if (!ret && state != GSI_CHANNEL_STATE_ALLOCATED) dev_err(channel->gsi->dev, - "bad channel state (%u) after reset\n", - channel->state); + "bad channel state (%u) after reset\n", state); }
/* Deallocate an ALLOCATED GSI channel */ static void gsi_channel_de_alloc_command(struct gsi *gsi, u32 channel_id) { struct gsi_channel *channel = &gsi->channel[channel_id]; + enum gsi_channel_state state; int ret;
- if (channel->state != GSI_CHANNEL_STATE_ALLOCATED) { - dev_err(gsi->dev, "bad channel state (%u) before dealloc\n", - channel->state); + state = gsi_channel_state(channel); + if (state != GSI_CHANNEL_STATE_ALLOCATED) { + dev_err(gsi->dev, + "bad channel state (%u) before dealloc\n", state); return; }
ret = gsi_channel_command(channel, GSI_CH_DE_ALLOC); - if (!ret && channel->state != GSI_CHANNEL_STATE_NOT_ALLOCATED) - dev_err(gsi->dev, "bad channel state (%u) after dealloc\n", - channel->state); + + /* Channel state will normally have been updated */ + state = gsi_channel_state(channel); + if (!ret && state != GSI_CHANNEL_STATE_NOT_ALLOCATED) + dev_err(gsi->dev, + "bad channel state (%u) after dealloc\n", state); }
/* Ring an event ring doorbell, reporting the last entry processed by the AP. @@@ -798,7 -777,6 +798,7 @@@ int gsi_channel_start(struct gsi *gsi, int gsi_channel_stop(struct gsi *gsi, u32 channel_id) { struct gsi_channel *channel = &gsi->channel[channel_id]; + enum gsi_channel_state state; u32 retries; int ret;
@@@ -808,8 -786,7 +808,8 @@@ * STOP command timed out. We won't stop a channel if stopping it * was successful previously (so we still want the freeze above). */ - if (channel->state == GSI_CHANNEL_STATE_STOPPED) + state = gsi_channel_state(channel); + if (state == GSI_CHANNEL_STATE_STOPPED) return 0;
/* RX channels might require a little time to enter STOPPED state */ @@@ -834,18 -811,18 +834,18 @@@ }
/* Reset and reconfigure a channel (possibly leaving doorbell disabled) */ -void gsi_channel_reset(struct gsi *gsi, u32 channel_id, bool db_enable) +void gsi_channel_reset(struct gsi *gsi, u32 channel_id, bool legacy) { struct gsi_channel *channel = &gsi->channel[channel_id];
mutex_lock(&gsi->mutex);
- /* Due to a hardware quirk we need to reset RX channels twice. */ gsi_channel_reset_command(channel); - if (!channel->toward_ipa) + /* Due to a hardware quirk we may need to reset RX channels twice. */ + if (legacy && !channel->toward_ipa) gsi_channel_reset_command(channel);
- gsi_channel_program(channel, db_enable); + gsi_channel_program(channel, legacy); gsi_channel_trans_cancel_pending(channel);
mutex_unlock(&gsi->mutex); @@@ -963,6 -940,7 +963,6 @@@ static void gsi_isr_chan_ctrl(struct gs channel_mask ^= BIT(channel_id);
channel = &gsi->channel[channel_id]; - channel->state = gsi_channel_state(gsi, channel_id);
complete(&channel->completion); } @@@ -1063,6 -1041,7 +1063,7 @@@ static void gsi_isr_gp_int1(struct gsi
complete(&gsi->completion); } + /* Inter-EE interrupt handler */ static void gsi_isr_glob_ee(struct gsi *gsi) { @@@ -1455,7 -1434,7 +1456,7 @@@ static void gsi_evt_ring_teardown(struc
/* Setup function for a single channel */ static int gsi_channel_setup_one(struct gsi *gsi, u32 channel_id, - bool db_enable) + bool legacy) { struct gsi_channel *channel = &gsi->channel[channel_id]; u32 evt_ring_id = channel->evt_ring_id; @@@ -1474,7 -1453,7 +1475,7 @@@ if (ret) goto err_evt_ring_de_alloc;
- gsi_channel_program(channel, db_enable); + gsi_channel_program(channel, legacy);
if (channel->toward_ipa) netif_tx_napi_add(&gsi->dummy_dev, &channel->napi, @@@ -1515,6 -1494,12 +1516,12 @@@ static int gsi_generic_command(struct g struct completion *completion = &gsi->completion; u32 val;
+ /* First zero the result code field */ + val = ioread32(gsi->virt + GSI_CNTXT_SCRATCH_0_OFFSET); + val &= ~GENERIC_EE_RESULT_FMASK; + iowrite32(val, gsi->virt + GSI_CNTXT_SCRATCH_0_OFFSET); + + /* Now issue the command */ val = u32_encode_bits(opcode, GENERIC_OPCODE_FMASK); val |= u32_encode_bits(channel_id, GENERIC_CHID_FMASK); val |= u32_encode_bits(GSI_EE_MODEM, GENERIC_EE_FMASK); @@@ -1545,7 -1530,7 +1552,7 @@@ static void gsi_modem_channel_halt(stru }
/* Setup function for channels */ -static int gsi_channel_setup(struct gsi *gsi, bool db_enable) +static int gsi_channel_setup(struct gsi *gsi, bool legacy) { u32 channel_id = 0; u32 mask; @@@ -1557,7 -1542,7 +1564,7 @@@ mutex_lock(&gsi->mutex);
do { - ret = gsi_channel_setup_one(gsi, channel_id, db_enable); + ret = gsi_channel_setup_one(gsi, channel_id, legacy); if (ret) goto err_unwind; } while (++channel_id < gsi->channel_count); @@@ -1643,7 -1628,7 +1650,7 @@@ static void gsi_channel_teardown(struc }
/* Setup function for GSI. GSI firmware must be loaded and initialized */ -int gsi_setup(struct gsi *gsi, bool db_enable) +int gsi_setup(struct gsi *gsi, bool legacy) { u32 val;
@@@ -1686,7 -1671,7 +1693,7 @@@ /* Writing 1 indicates IRQ interrupts; 0 would be MSI */ iowrite32(1, gsi->virt + GSI_CNTXT_INTSET_OFFSET);
- return gsi_channel_setup(gsi, db_enable); + return gsi_channel_setup(gsi, legacy); }
/* Inverse of gsi_setup() */ @@@ -1820,9 -1805,9 +1827,9 @@@ static int gsi_channel_init_one(struct
/* Worst case we need an event for every outstanding TRE */ if (data->channel.tre_count > data->channel.event_count) { - dev_warn(gsi->dev, "channel %u limited to %u TREs\n", - data->channel_id, data->channel.tre_count); tre_count = data->channel.event_count; + dev_warn(gsi->dev, "channel %u limited to %u TREs\n", + data->channel_id, tre_count); } else { tre_count = data->channel.tre_count; } diff --combined drivers/net/ipa/ipa_endpoint.c index 82066a223a67,a21534f1462f..5fec30e542cb --- a/drivers/net/ipa/ipa_endpoint.c +++ b/drivers/net/ipa/ipa_endpoint.c @@@ -32,9 -32,14 +32,9 @@@ /* The amount of RX buffer space consumed by standard skb overhead */ #define IPA_RX_BUFFER_OVERHEAD (PAGE_SIZE - SKB_MAX_ORDER(NET_SKB_PAD, 0))
-#define IPA_ENDPOINT_STOP_RX_RETRIES 10 -#define IPA_ENDPOINT_STOP_RX_SIZE 1 /* bytes */ - #define IPA_ENDPOINT_RESET_AGGR_RETRY_MAX 3 #define IPA_AGGR_TIME_LIMIT_DEFAULT 1000 /* microseconds */
-#define ENDPOINT_STOP_DMA_TIMEOUT 15 /* milliseconds */ - /** enum ipa_status_opcode - status element opcode hardware values */ enum ipa_status_opcode { IPA_STATUS_OPCODE_PACKET = 0x01, @@@ -279,52 -284,25 +279,52 @@@ static struct gsi_trans *ipa_endpoint_t /* suspend_delay represents suspend for RX, delay for TX endpoints. * Note that suspend is not supported starting with IPA v4.0. */ -static int +static bool ipa_endpoint_init_ctrl(struct ipa_endpoint *endpoint, bool suspend_delay) { u32 offset = IPA_REG_ENDP_INIT_CTRL_N_OFFSET(endpoint->endpoint_id); struct ipa *ipa = endpoint->ipa; + bool state; u32 mask; u32 val;
- /* assert(ipa->version == IPA_VERSION_3_5_1 */ + /* Suspend is not supported for IPA v4.0+. Delay doesn't work + * correctly on IPA v4.2. + * + * if (endpoint->toward_ipa) + * assert(ipa->version != IPA_VERSION_4.2); + * else + * assert(ipa->version == IPA_VERSION_3_5_1); + */ mask = endpoint->toward_ipa ? ENDP_DELAY_FMASK : ENDP_SUSPEND_FMASK;
val = ioread32(ipa->reg_virt + offset); - if (suspend_delay == !!(val & mask)) - return -EALREADY; /* Already set to desired state */ + /* Don't bother if it's already in the requested state */ + state = !!(val & mask); + if (suspend_delay != state) { + val ^= mask; + iowrite32(val, ipa->reg_virt + offset); + }
- val ^= mask; - iowrite32(val, ipa->reg_virt + offset); + return state; +}
- return 0; +/* We currently don't care what the previous state was for delay mode */ +static void +ipa_endpoint_program_delay(struct ipa_endpoint *endpoint, bool enable) +{ + /* assert(endpoint->toward_ipa); */ + + (void)ipa_endpoint_init_ctrl(endpoint, enable); +} + +/* Returns previous suspend state (true means it was enabled) */ +static bool +ipa_endpoint_program_suspend(struct ipa_endpoint *endpoint, bool enable) +{ + /* assert(!endpoint->toward_ipa); */ + + return ipa_endpoint_init_ctrl(endpoint, enable); }
/* Enable or disable delay or suspend mode on all modem endpoints */ @@@ -333,7 -311,7 +333,7 @@@ void ipa_endpoint_modem_pause_all(struc bool support_suspend; u32 endpoint_id;
- /* DELAY mode doesn't work right on IPA v4.2 */ + /* DELAY mode doesn't work correctly on IPA v4.2 */ if (ipa->version == IPA_VERSION_4_2) return;
@@@ -347,10 -325,8 +347,10 @@@ continue;
/* Set TX delay mode, or for IPA v3.5.1 RX suspend mode */ - if (endpoint->toward_ipa || support_suspend) - (void)ipa_endpoint_init_ctrl(endpoint, enable); + if (endpoint->toward_ipa) + ipa_endpoint_program_delay(endpoint, enable); + else if (support_suspend) + (void)ipa_endpoint_program_suspend(endpoint, enable); } }
@@@ -1157,10 -1133,10 +1157,10 @@@ static int ipa_endpoint_reset_rx_aggr(s { struct device *dev = &endpoint->ipa->pdev->dev; struct ipa *ipa = endpoint->ipa; - bool endpoint_suspended = false; struct gsi *gsi = &ipa->gsi; + bool suspended = false; dma_addr_t addr; - bool db_enable; + bool legacy; u32 retries; u32 len = 1; void *virt; @@@ -1188,7 -1164,8 +1188,7 @@@
/* Make sure the channel isn't suspended */ if (endpoint->ipa->version == IPA_VERSION_3_5_1) - if (!ipa_endpoint_init_ctrl(endpoint, false)) - endpoint_suspended = true; + suspended = ipa_endpoint_program_suspend(endpoint, false);
/* Start channel and do a 1 byte read */ ret = gsi_channel_start(gsi, endpoint->channel_id); @@@ -1214,7 -1191,7 +1214,7 @@@
gsi_trans_read_byte_done(gsi, endpoint->channel_id);
- ret = ipa_endpoint_stop(endpoint); + ret = gsi_channel_stop(gsi, endpoint->channel_id); if (ret) goto out_suspend_again;
@@@ -1223,18 -1200,18 +1223,18 @@@ * complete the channel reset sequence. Finish by suspending the * channel again (if necessary). */ - db_enable = ipa->version == IPA_VERSION_3_5_1; - gsi_channel_reset(gsi, endpoint->channel_id, db_enable); + legacy = ipa->version == IPA_VERSION_3_5_1; + gsi_channel_reset(gsi, endpoint->channel_id, legacy);
msleep(1);
goto out_suspend_again;
err_endpoint_stop: - ipa_endpoint_stop(endpoint); + (void)gsi_channel_stop(gsi, endpoint->channel_id); out_suspend_again: - if (endpoint_suspended) - (void)ipa_endpoint_init_ctrl(endpoint, true); + if (suspended) + (void)ipa_endpoint_program_suspend(endpoint, true); dma_unmap_single(dev, addr, len, DMA_FROM_DEVICE); out_kfree: kfree(virt); @@@ -1246,8 -1223,8 +1246,8 @@@ static void ipa_endpoint_reset(struct i { u32 channel_id = endpoint->channel_id; struct ipa *ipa = endpoint->ipa; - bool db_enable; bool special; + bool legacy; int ret = 0;
/* On IPA v3.5.1, if an RX endpoint is reset while aggregation @@@ -1256,12 -1233,12 +1256,12 @@@ * * IPA v3.5.1 enables the doorbell engine. Newer versions do not. */ - db_enable = ipa->version == IPA_VERSION_3_5_1; + legacy = ipa->version == IPA_VERSION_3_5_1; special = !endpoint->toward_ipa && endpoint->data->aggregation; if (special && ipa_endpoint_aggr_active(endpoint)) ret = ipa_endpoint_reset_rx_aggr(endpoint); else - gsi_channel_reset(&ipa->gsi, channel_id, db_enable); + gsi_channel_reset(&ipa->gsi, channel_id, legacy);
if (ret) dev_err(&ipa->pdev->dev, @@@ -1269,18 -1246,94 +1269,79 @@@ ret, endpoint->channel_id, endpoint->endpoint_id); }
+ static int ipa_endpoint_stop_rx_dma(struct ipa *ipa) + { + u16 size = IPA_ENDPOINT_STOP_RX_SIZE; + struct gsi_trans *trans; + dma_addr_t addr; + int ret; + + trans = ipa_cmd_trans_alloc(ipa, 1); + if (!trans) { + dev_err(&ipa->pdev->dev, + "no transaction for RX endpoint STOP workaround\n"); + return -EBUSY; + } + + /* Read into the highest part of the zero memory area */ + addr = ipa->zero_addr + ipa->zero_size - size; + + ipa_cmd_dma_task_32b_addr_add(trans, size, addr, false); + + ret = gsi_trans_commit_wait_timeout(trans, ENDPOINT_STOP_DMA_TIMEOUT); + if (ret) + gsi_trans_free(trans); + + return ret; + } + + /** + * ipa_endpoint_stop() - Stops a GSI channel in IPA + * @client: Client whose endpoint should be stopped + * + * This function implements the sequence to stop a GSI channel + * in IPA. This function returns when the channel is is STOP state. + * + * Return value: 0 on success, negative otherwise + */ + int ipa_endpoint_stop(struct ipa_endpoint *endpoint) + { + u32 retries = IPA_ENDPOINT_STOP_RX_RETRIES; + int ret; + + do { + struct ipa *ipa = endpoint->ipa; + struct gsi *gsi = &ipa->gsi; + + ret = gsi_channel_stop(gsi, endpoint->channel_id); + if (ret != -EAGAIN || endpoint->toward_ipa) + break; + + /* For IPA v3.5.1, send a DMA read task and check again */ + if (ipa->version == IPA_VERSION_3_5_1) { + ret = ipa_endpoint_stop_rx_dma(ipa); + if (ret) + break; + } + + msleep(1); + } while (retries--); + + return retries ? ret : -EIO; + } + static void ipa_endpoint_program(struct ipa_endpoint *endpoint) { - struct device *dev = &endpoint->ipa->pdev->dev; - int ret; - if (endpoint->toward_ipa) { - bool delay_mode = endpoint->data->tx.delay; - - ret = ipa_endpoint_init_ctrl(endpoint, delay_mode); - /* Endpoint is expected to not be in delay mode */ - if (!ret != delay_mode) { - dev_warn(dev, - "TX endpoint %u was %sin delay mode\n", - endpoint->endpoint_id, - delay_mode ? "already " : ""); - } + if (endpoint->ipa->version != IPA_VERSION_4_2) + ipa_endpoint_program_delay(endpoint, false); ipa_endpoint_init_hdr_ext(endpoint); ipa_endpoint_init_aggr(endpoint); ipa_endpoint_init_deaggr(endpoint); ipa_endpoint_init_seq(endpoint); } else { - if (endpoint->ipa->version == IPA_VERSION_3_5_1) { - if (!ipa_endpoint_init_ctrl(endpoint, false)) - dev_warn(dev, - "RX endpoint %u was suspended\n", - endpoint->endpoint_id); - } + if (endpoint->ipa->version == IPA_VERSION_3_5_1) + (void)ipa_endpoint_program_suspend(endpoint, false); ipa_endpoint_init_hdr_ext(endpoint); ipa_endpoint_init_aggr(endpoint); } @@@ -1321,13 -1374,12 +1382,13 @@@ void ipa_endpoint_disable_one(struct ip { u32 mask = BIT(endpoint->endpoint_id); struct ipa *ipa = endpoint->ipa; + struct gsi *gsi = &ipa->gsi; int ret;
- if (!(endpoint->ipa->enabled & mask)) + if (!(ipa->enabled & mask)) return;
- endpoint->ipa->enabled ^= mask; + ipa->enabled ^= mask;
if (!endpoint->toward_ipa) { ipa_endpoint_replenish_disable(endpoint); @@@ -1336,7 -1388,7 +1397,7 @@@ }
/* Note that if stop fails, the channel's state is not well-defined */ - ret = ipa_endpoint_stop(endpoint); + ret = gsi_channel_stop(gsi, endpoint->channel_id); if (ret) dev_err(&ipa->pdev->dev, "error %d attempting to stop endpoint %u\n", ret, @@@ -1393,7 -1445,7 +1454,7 @@@ void ipa_endpoint_suspend_one(struct ip * aggregation frame, then simulating the arrival of such * an interrupt. */ - WARN_ON(ipa_endpoint_init_ctrl(endpoint, true)); + (void)ipa_endpoint_program_suspend(endpoint, true); ipa_endpoint_suspend_aggr(endpoint); }
@@@ -1416,7 -1468,7 +1477,7 @@@ void ipa_endpoint_resume_one(struct ipa /* IPA v3.5.1 doesn't use channel start for resume */ start_channel = endpoint->ipa->version != IPA_VERSION_3_5_1; if (!endpoint->toward_ipa && !start_channel) - WARN_ON(ipa_endpoint_init_ctrl(endpoint, false)); + (void)ipa_endpoint_program_suspend(endpoint, false);
ret = gsi_channel_resume(gsi, endpoint->channel_id, start_channel); if (ret) diff --combined drivers/net/macsec.c index ea3f25cc79ef,d0d31cb99180..20b53e255f68 --- a/drivers/net/macsec.c +++ b/drivers/net/macsec.c @@@ -1305,7 -1305,8 +1305,8 @@@ static struct crypto_aead *macsec_alloc struct crypto_aead *tfm; int ret;
- tfm = crypto_alloc_aead("gcm(aes)", 0, 0); + /* Pick a sync gcm(aes) cipher to ensure order is preserved. */ + tfm = crypto_alloc_aead("gcm(aes)", 0, CRYPTO_ALG_ASYNC);
if (IS_ERR(tfm)) return tfm; @@@ -2640,11 -2641,12 +2641,12 @@@ static int macsec_upd_offload(struct sk if (ret) goto rollback;
- rtnl_unlock(); /* Force features update, since they are different for SW MACSec and * HW offloading cases. */ netdev_update_features(dev); + + rtnl_unlock(); return 0;
rollback: @@@ -4047,8 -4049,6 +4049,8 @@@ static int macsec_newlink(struct net *n if (err < 0) return err;
+ netdev_lockdep_set_classes(dev); + err = netdev_upper_dev_link(real_dev, dev, extack); if (err < 0) goto unregister; diff --combined drivers/net/phy/marvell10g.c index 8352c09004c7,1f1a01c98e44..d4c2e62b2439 --- a/drivers/net/phy/marvell10g.c +++ b/drivers/net/phy/marvell10g.c @@@ -66,6 -66,9 +66,9 @@@ enum MV_PCS_CSSR1_SPD2_2500 = 0x0004, MV_PCS_CSSR1_SPD2_10000 = 0x0000,
+ /* Temperature read register (88E2110 only) */ + MV_PCS_TEMP = 0x8042, + /* These registers appear at 0x800X and 0xa00X - the 0xa00X control * registers appear to set themselves to the 0x800X when AN is * restarted, but status registers appear readable from either. @@@ -77,6 -80,7 +80,7 @@@ MV_V2_PORT_CTRL = 0xf001, MV_V2_PORT_CTRL_SWRST = BIT(15), MV_V2_PORT_CTRL_PWRDOWN = BIT(11), + /* Temperature control/read registers (88X3310 only) */ MV_V2_TEMP_CTRL = 0xf08a, MV_V2_TEMP_CTRL_MASK = 0xc000, MV_V2_TEMP_CTRL_SAMPLE = 0x0000, @@@ -104,6 -108,24 +108,24 @@@ static umode_t mv3310_hwmon_is_visible( return 0; }
+ static int mv3310_hwmon_read_temp_reg(struct phy_device *phydev) + { + return phy_read_mmd(phydev, MDIO_MMD_VEND2, MV_V2_TEMP); + } + + static int mv2110_hwmon_read_temp_reg(struct phy_device *phydev) + { + return phy_read_mmd(phydev, MDIO_MMD_PCS, MV_PCS_TEMP); + } + + static int mv10g_hwmon_read_temp_reg(struct phy_device *phydev) + { + if (phydev->drv->phy_id == MARVELL_PHY_ID_88X3310) + return mv3310_hwmon_read_temp_reg(phydev); + else /* MARVELL_PHY_ID_88E2110 */ + return mv2110_hwmon_read_temp_reg(phydev); + } + static int mv3310_hwmon_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel, long *value) { @@@ -116,7 -138,7 +138,7 @@@ }
if (type == hwmon_temp && attr == hwmon_temp_input) { - temp = phy_read_mmd(phydev, MDIO_MMD_VEND2, MV_V2_TEMP); + temp = mv10g_hwmon_read_temp_reg(phydev); if (temp < 0) return temp;
@@@ -169,6 -191,9 +191,9 @@@ static int mv3310_hwmon_config(struct p u16 val; int ret;
+ if (phydev->drv->phy_id != MARVELL_PHY_ID_88X3310) + return 0; + ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, MV_V2_TEMP, MV_V2_TEMP_UNKNOWN); if (ret < 0) @@@ -728,6 -753,7 +753,6 @@@ static struct phy_driver mv3310_drivers .phy_id_mask = MARVELL_PHY_ID_MASK, .name = "mv88x3310", .get_features = mv3310_get_features, - .soft_reset = genphy_no_soft_reset, .config_init = mv3310_config_init, .probe = mv3310_probe, .suspend = mv3310_suspend, @@@ -745,6 -771,7 +770,6 @@@ .probe = mv3310_probe, .suspend = mv3310_suspend, .resume = mv3310_resume, - .soft_reset = genphy_no_soft_reset, .config_init = mv3310_config_init, .config_aneg = mv3310_config_aneg, .aneg_done = mv3310_aneg_done, diff --combined drivers/s390/net/qeth_core_main.c index c0ab6e7bc129,569966bdc513..db8e069be3a0 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@@ -26,7 -26,6 +26,7 @@@ #include <linux/if_vlan.h> #include <linux/netdevice.h> #include <linux/netdev_features.h> +#include <linux/rcutree.h> #include <linux/skbuff.h> #include <linux/vmalloc.h>
@@@ -61,7 -60,6 +61,7 @@@ EXPORT_SYMBOL_GPL(qeth_core_header_cach static struct kmem_cache *qeth_qdio_outbuf_cache;
static struct device *qeth_core_root_dev; +static struct dentry *qeth_debugfs_root; static struct lock_class_key qdio_out_skb_queue_key;
static void qeth_issue_next_read_cb(struct qeth_card *card, @@@ -625,257 -623,6 +625,257 @@@ void qeth_notify_cmd(struct qeth_cmd_bu } EXPORT_SYMBOL_GPL(qeth_notify_cmd);
+static void qeth_flush_local_addrs4(struct qeth_card *card) +{ + struct qeth_local_addr *addr; + struct hlist_node *tmp; + unsigned int i; + + spin_lock_irq(&card->local_addrs4_lock); + hash_for_each_safe(card->local_addrs4, i, tmp, addr, hnode) { + hash_del_rcu(&addr->hnode); + kfree_rcu(addr, rcu); + } + spin_unlock_irq(&card->local_addrs4_lock); +} + +static void qeth_flush_local_addrs6(struct qeth_card *card) +{ + struct qeth_local_addr *addr; + struct hlist_node *tmp; + unsigned int i; + + spin_lock_irq(&card->local_addrs6_lock); + hash_for_each_safe(card->local_addrs6, i, tmp, addr, hnode) { + hash_del_rcu(&addr->hnode); + kfree_rcu(addr, rcu); + } + spin_unlock_irq(&card->local_addrs6_lock); +} + +void qeth_flush_local_addrs(struct qeth_card *card) +{ + qeth_flush_local_addrs4(card); + qeth_flush_local_addrs6(card); +} +EXPORT_SYMBOL_GPL(qeth_flush_local_addrs); + +static void qeth_add_local_addrs4(struct qeth_card *card, + struct qeth_ipacmd_local_addrs4 *cmd) +{ + unsigned int i; + + if (cmd->addr_length != + sizeof_field(struct qeth_ipacmd_local_addr4, addr)) { + dev_err_ratelimited(&card->gdev->dev, + "Dropped IPv4 ADD LOCAL ADDR event with bad length %u\n", + cmd->addr_length); + return; + } + + spin_lock(&card->local_addrs4_lock); + for (i = 0; i < cmd->count; i++) { + unsigned int key = ipv4_addr_hash(cmd->addrs[i].addr); + struct qeth_local_addr *addr; + bool duplicate = false; + + hash_for_each_possible(card->local_addrs4, addr, hnode, key) { + if (addr->addr.s6_addr32[3] == cmd->addrs[i].addr) { + duplicate = true; + break; + } + } + + if (duplicate) + continue; + + addr = kmalloc(sizeof(*addr), GFP_ATOMIC); + if (!addr) { + dev_err(&card->gdev->dev, + "Failed to allocate local addr object. Traffic to %pI4 might suffer.\n", + &cmd->addrs[i].addr); + continue; + } + + ipv6_addr_set(&addr->addr, 0, 0, 0, cmd->addrs[i].addr); + hash_add_rcu(card->local_addrs4, &addr->hnode, key); + } + spin_unlock(&card->local_addrs4_lock); +} + +static void qeth_add_local_addrs6(struct qeth_card *card, + struct qeth_ipacmd_local_addrs6 *cmd) +{ + unsigned int i; + + if (cmd->addr_length != + sizeof_field(struct qeth_ipacmd_local_addr6, addr)) { + dev_err_ratelimited(&card->gdev->dev, + "Dropped IPv6 ADD LOCAL ADDR event with bad length %u\n", + cmd->addr_length); + return; + } + + spin_lock(&card->local_addrs6_lock); + for (i = 0; i < cmd->count; i++) { + u32 key = ipv6_addr_hash(&cmd->addrs[i].addr); + struct qeth_local_addr *addr; + bool duplicate = false; + + hash_for_each_possible(card->local_addrs6, addr, hnode, key) { + if (ipv6_addr_equal(&addr->addr, &cmd->addrs[i].addr)) { + duplicate = true; + break; + } + } + + if (duplicate) + continue; + + addr = kmalloc(sizeof(*addr), GFP_ATOMIC); + if (!addr) { + dev_err(&card->gdev->dev, + "Failed to allocate local addr object. Traffic to %pI6c might suffer.\n", + &cmd->addrs[i].addr); + continue; + } + + addr->addr = cmd->addrs[i].addr; + hash_add_rcu(card->local_addrs6, &addr->hnode, key); + } + spin_unlock(&card->local_addrs6_lock); +} + +static void qeth_del_local_addrs4(struct qeth_card *card, + struct qeth_ipacmd_local_addrs4 *cmd) +{ + unsigned int i; + + if (cmd->addr_length != + sizeof_field(struct qeth_ipacmd_local_addr4, addr)) { + dev_err_ratelimited(&card->gdev->dev, + "Dropped IPv4 DEL LOCAL ADDR event with bad length %u\n", + cmd->addr_length); + return; + } + + spin_lock(&card->local_addrs4_lock); + for (i = 0; i < cmd->count; i++) { + struct qeth_ipacmd_local_addr4 *addr = &cmd->addrs[i]; + unsigned int key = ipv4_addr_hash(addr->addr); + struct qeth_local_addr *tmp; + + hash_for_each_possible(card->local_addrs4, tmp, hnode, key) { + if (tmp->addr.s6_addr32[3] == addr->addr) { + hash_del_rcu(&tmp->hnode); + kfree_rcu(tmp, rcu); + break; + } + } + } + spin_unlock(&card->local_addrs4_lock); +} + +static void qeth_del_local_addrs6(struct qeth_card *card, + struct qeth_ipacmd_local_addrs6 *cmd) +{ + unsigned int i; + + if (cmd->addr_length != + sizeof_field(struct qeth_ipacmd_local_addr6, addr)) { + dev_err_ratelimited(&card->gdev->dev, + "Dropped IPv6 DEL LOCAL ADDR event with bad length %u\n", + cmd->addr_length); + return; + } + + spin_lock(&card->local_addrs6_lock); + for (i = 0; i < cmd->count; i++) { + struct qeth_ipacmd_local_addr6 *addr = &cmd->addrs[i]; + u32 key = ipv6_addr_hash(&addr->addr); + struct qeth_local_addr *tmp; + + hash_for_each_possible(card->local_addrs6, tmp, hnode, key) { + if (ipv6_addr_equal(&tmp->addr, &addr->addr)) { + hash_del_rcu(&tmp->hnode); + kfree_rcu(tmp, rcu); + break; + } + } + } + spin_unlock(&card->local_addrs6_lock); +} + +static bool qeth_next_hop_is_local_v4(struct qeth_card *card, + struct sk_buff *skb) +{ + struct qeth_local_addr *tmp; + bool is_local = false; + unsigned int key; + __be32 next_hop; + + if (hash_empty(card->local_addrs4)) + return false; + + rcu_read_lock(); + next_hop = qeth_next_hop_v4_rcu(skb, qeth_dst_check_rcu(skb, 4)); + key = ipv4_addr_hash(next_hop); + + hash_for_each_possible_rcu(card->local_addrs4, tmp, hnode, key) { + if (tmp->addr.s6_addr32[3] == next_hop) { + is_local = true; + break; + } + } + rcu_read_unlock(); + + return is_local; +} + +static bool qeth_next_hop_is_local_v6(struct qeth_card *card, + struct sk_buff *skb) +{ + struct qeth_local_addr *tmp; + struct in6_addr *next_hop; + bool is_local = false; + u32 key; + + if (hash_empty(card->local_addrs6)) + return false; + + rcu_read_lock(); + next_hop = qeth_next_hop_v6_rcu(skb, qeth_dst_check_rcu(skb, 6)); + key = ipv6_addr_hash(next_hop); + + hash_for_each_possible_rcu(card->local_addrs6, tmp, hnode, key) { + if (ipv6_addr_equal(&tmp->addr, next_hop)) { + is_local = true; + break; + } + } + rcu_read_unlock(); + + return is_local; +} + +static int qeth_debugfs_local_addr_show(struct seq_file *m, void *v) +{ + struct qeth_card *card = m->private; + struct qeth_local_addr *tmp; + unsigned int i; + + rcu_read_lock(); + hash_for_each_rcu(card->local_addrs4, i, tmp, hnode) + seq_printf(m, "%pI4\n", &tmp->addr.s6_addr32[3]); + hash_for_each_rcu(card->local_addrs6, i, tmp, hnode) + seq_printf(m, "%pI6c\n", &tmp->addr); + rcu_read_unlock(); + + return 0; +} + +DEFINE_SHOW_ATTRIBUTE(qeth_debugfs_local_addr); + static void qeth_issue_ipa_msg(struct qeth_ipa_cmd *cmd, int rc, struct qeth_card *card) { @@@ -939,19 -686,9 +939,19 @@@ static struct qeth_ipa_cmd *qeth_check_ case IPA_CMD_MODCCID: return cmd; case IPA_CMD_REGISTER_LOCAL_ADDR: + if (cmd->hdr.prot_version == QETH_PROT_IPV4) + qeth_add_local_addrs4(card, &cmd->data.local_addrs4); + else if (cmd->hdr.prot_version == QETH_PROT_IPV6) + qeth_add_local_addrs6(card, &cmd->data.local_addrs6); + QETH_CARD_TEXT(card, 3, "irla"); return NULL; case IPA_CMD_UNREGISTER_LOCAL_ADDR: + if (cmd->hdr.prot_version == QETH_PROT_IPV4) + qeth_del_local_addrs4(card, &cmd->data.local_addrs4); + else if (cmd->hdr.prot_version == QETH_PROT_IPV6) + qeth_del_local_addrs6(card, &cmd->data.local_addrs6); + QETH_CARD_TEXT(card, 3, "urla"); return NULL; default: @@@ -1131,18 -868,16 +1131,18 @@@ static int qeth_set_thread_start_bit(st unsigned long thread) { unsigned long flags; + int rc = 0;
spin_lock_irqsave(&card->thread_mask_lock, flags); - if (!(card->thread_allowed_mask & thread) || - (card->thread_start_mask & thread)) { - spin_unlock_irqrestore(&card->thread_mask_lock, flags); - return -EPERM; - } - card->thread_start_mask |= thread; + if (!(card->thread_allowed_mask & thread)) + rc = -EPERM; + else if (card->thread_start_mask & thread) + rc = -EBUSY; + else + card->thread_start_mask |= thread; spin_unlock_irqrestore(&card->thread_mask_lock, flags); - return 0; + + return rc; }
static void qeth_clear_thread_start_bit(struct qeth_card *card, @@@ -1195,17 -930,11 +1195,17 @@@ static int qeth_do_run_thread(struct qe return rc; }
-void qeth_schedule_recovery(struct qeth_card *card) +int qeth_schedule_recovery(struct qeth_card *card) { + int rc; + QETH_CARD_TEXT(card, 2, "startrec"); - if (qeth_set_thread_start_bit(card, QETH_RECOVER_THREAD) == 0) + + rc = qeth_set_thread_start_bit(card, QETH_RECOVER_THREAD); + if (!rc) schedule_work(&card->kernel_thread_starter); + + return rc; }
static int qeth_get_problem(struct qeth_card *card, struct ccw_device *cdev, @@@ -1647,10 -1376,6 +1647,10 @@@ static void qeth_setup_card(struct qeth qeth_init_qdio_info(card); INIT_DELAYED_WORK(&card->buffer_reclaim_work, qeth_buffer_reclaim_work); INIT_WORK(&card->close_dev_work, qeth_close_dev_handler); + hash_init(card->local_addrs4); + hash_init(card->local_addrs6); + spin_lock_init(&card->local_addrs4_lock); + spin_lock_init(&card->local_addrs6_lock); }
static void qeth_core_sl_print(struct seq_file *m, struct service_level *slr) @@@ -1687,11 -1412,6 +1687,11 @@@ static struct qeth_card *qeth_alloc_car if (!card->read_cmd) goto out_read_cmd;
+ card->debugfs = debugfs_create_dir(dev_name(&gdev->dev), + qeth_debugfs_root); + debugfs_create_file("local_addrs", 0400, card->debugfs, card, + &qeth_debugfs_local_addr_fops); + card->qeth_service_level.seq_print = qeth_core_sl_print; register_service_level(&card->qeth_service_level); return card; @@@ -3625,11 -3345,11 +3625,11 @@@ static int qeth_switch_to_nonpacking_if static void qeth_flush_buffers(struct qeth_qdio_out_q *queue, int index, int count) { + struct qeth_qdio_out_buffer *buf = queue->bufs[index]; + unsigned int qdio_flags = QDIO_FLAG_SYNC_OUTPUT; struct qeth_card *card = queue->card; - struct qeth_qdio_out_buffer *buf; int rc; int i; - unsigned int qdio_flags;
for (i = index; i < index + count; ++i) { unsigned int bidx = QDIO_BUFNR(i); @@@ -3646,10 -3366,9 +3646,10 @@@ if (IS_IQD(card)) { skb_queue_walk(&buf->skb_list, skb) skb_tx_timestamp(skb); - continue; } + }
+ if (!IS_IQD(card)) { if (!queue->do_pack) { if ((atomic_read(&queue->used_buffers) >= (QETH_HIGH_WATERMARK_PACK - @@@ -3674,12 -3393,12 +3674,12 @@@ buf->buffer->element[0].sflags |= SBAL_SFLAGS0_PCI_REQ; } } + + if (atomic_read(&queue->set_pci_flags_count)) + qdio_flags |= QDIO_FLAG_PCI_OUT; }
QETH_TXQ_STAT_INC(queue, doorbell); - qdio_flags = QDIO_FLAG_SYNC_OUTPUT; - if (atomic_read(&queue->set_pci_flags_count)) - qdio_flags |= QDIO_FLAG_PCI_OUT; rc = do_QDIO(CARD_DDEV(queue->card), qdio_flags, queue->queue_no, index, count);
@@@ -4090,47 -3809,15 +4090,47 @@@ static bool qeth_iqd_may_bulk(struct qe qeth_l3_iqd_same_vlan(&prev_hdr->hdr.l3, &curr_hdr->hdr.l3); }
-static unsigned int __qeth_fill_buffer(struct sk_buff *skb, - struct qeth_qdio_out_buffer *buf, - bool is_first_elem, unsigned int offset) +/** + * qeth_fill_buffer() - map skb into an output buffer + * @buf: buffer to transport the skb + * @skb: skb to map into the buffer + * @hdr: qeth_hdr for this skb. Either at skb->data, or allocated + * from qeth_core_header_cache. + * @offset: when mapping the skb, start at skb->data + offset + * @hd_len: if > 0, build a dedicated header element of this size + */ +static unsigned int qeth_fill_buffer(struct qeth_qdio_out_buffer *buf, + struct sk_buff *skb, struct qeth_hdr *hdr, + unsigned int offset, unsigned int hd_len) { struct qdio_buffer *buffer = buf->buffer; int element = buf->next_element_to_fill; int length = skb_headlen(skb) - offset; char *data = skb->data + offset; unsigned int elem_length, cnt; + bool is_first_elem = true; + + __skb_queue_tail(&buf->skb_list, skb); + + /* build dedicated element for HW Header */ + if (hd_len) { + is_first_elem = false; + + buffer->element[element].addr = virt_to_phys(hdr); + buffer->element[element].length = hd_len; + buffer->element[element].eflags = SBAL_EFLAGS_FIRST_FRAG; + + /* HW header is allocated from cache: */ + if ((void *)hdr != skb->data) + buf->is_header[element] = 1; + /* HW header was pushed and is contiguous with linear part: */ + else if (length > 0 && !PAGE_ALIGNED(data) && + (data == (char *)hdr + hd_len)) + buffer->element[element].eflags |= + SBAL_EFLAGS_CONTIGUOUS; + + element++; + }
/* map linear part into buffer element(s) */ while (length > 0) { @@@ -4184,6 -3871,40 +4184,6 @@@ return element; }
-/** - * qeth_fill_buffer() - map skb into an output buffer - * @buf: buffer to transport the skb - * @skb: skb to map into the buffer - * @hdr: qeth_hdr for this skb. Either at skb->data, or allocated - * from qeth_core_header_cache. - * @offset: when mapping the skb, start at skb->data + offset - * @hd_len: if > 0, build a dedicated header element of this size - */ -static unsigned int qeth_fill_buffer(struct qeth_qdio_out_buffer *buf, - struct sk_buff *skb, struct qeth_hdr *hdr, - unsigned int offset, unsigned int hd_len) -{ - struct qdio_buffer *buffer = buf->buffer; - bool is_first_elem = true; - - __skb_queue_tail(&buf->skb_list, skb); - - /* build dedicated header element */ - if (hd_len) { - int element = buf->next_element_to_fill; - is_first_elem = false; - - buffer->element[element].addr = virt_to_phys(hdr); - buffer->element[element].length = hd_len; - buffer->element[element].eflags = SBAL_EFLAGS_FIRST_FRAG; - /* remember to free cache-allocated qeth_hdr: */ - buf->is_header[element] = ((void *)hdr != skb->data); - buf->next_element_to_fill++; - } - - return __qeth_fill_buffer(skb, buf, is_first_elem, offset); -} - static int __qeth_xmit(struct qeth_card *card, struct qeth_qdio_out_q *queue, struct sk_buff *skb, unsigned int elements, struct qeth_hdr *hdr, unsigned int offset, @@@ -5168,11 -4889,9 +5168,11 @@@ out_free_nothing static void qeth_core_free_card(struct qeth_card *card) { QETH_CARD_TEXT(card, 2, "freecrd"); + + unregister_service_level(&card->qeth_service_level); + debugfs_remove_recursive(card->debugfs); qeth_put_cmd(card->read_cmd); destroy_workqueue(card->event_wq); - unregister_service_level(&card->qeth_service_level); dev_set_drvdata(&card->gdev->dev, NULL); kfree(card); } @@@ -6581,7 -6300,7 +6581,7 @@@ static int qeth_set_csum_off(struct qet }
static int qeth_set_csum_on(struct qeth_card *card, enum qeth_ipa_funcs cstype, - enum qeth_prot_versions prot) + enum qeth_prot_versions prot, u8 *lp2lp) { u32 required_features = QETH_IPA_CHECKSUM_UDP | QETH_IPA_CHECKSUM_TCP; struct qeth_cmd_buffer *iob; @@@ -6633,17 -6352,18 +6633,17 @@@
dev_info(&card->gdev->dev, "HW Checksumming (%sbound IPv%d) enabled\n", cstype == IPA_INBOUND_CHECKSUM ? "in" : "out", prot); - if (!qeth_ipa_caps_enabled(&caps, QETH_IPA_CHECKSUM_LP2LP) && - cstype == IPA_OUTBOUND_CHECKSUM) - dev_warn(&card->gdev->dev, - "Hardware checksumming is performed only if %s and its peer use different OSA Express 3 ports\n", - QETH_CARD_IFNAME(card)); + + if (lp2lp) + *lp2lp = qeth_ipa_caps_enabled(&caps, QETH_IPA_CHECKSUM_LP2LP); + return 0; }
static int qeth_set_ipa_csum(struct qeth_card *card, bool on, int cstype, - enum qeth_prot_versions prot) + enum qeth_prot_versions prot, u8 *lp2lp) { - return on ? qeth_set_csum_on(card, cstype, prot) : + return on ? qeth_set_csum_on(card, cstype, prot, lp2lp) : qeth_set_csum_off(card, cstype, prot); }
@@@ -6731,13 -6451,13 +6731,13 @@@ static int qeth_set_ipa_rx_csum(struct
if (qeth_is_supported(card, IPA_INBOUND_CHECKSUM)) rc_ipv4 = qeth_set_ipa_csum(card, on, IPA_INBOUND_CHECKSUM, - QETH_PROT_IPV4); + QETH_PROT_IPV4, NULL); if (!qeth_is_supported6(card, IPA_INBOUND_CHECKSUM_V6)) /* no/one Offload Assist available, so the rc is trivial */ return rc_ipv4;
rc_ipv6 = qeth_set_ipa_csum(card, on, IPA_INBOUND_CHECKSUM, - QETH_PROT_IPV6); + QETH_PROT_IPV6, NULL);
if (on) /* enable: success if any Assist is active */ @@@ -6773,24 -6493,6 +6773,24 @@@ void qeth_enable_hw_features(struct net } EXPORT_SYMBOL_GPL(qeth_enable_hw_features);
+static void qeth_check_restricted_features(struct qeth_card *card, + netdev_features_t changed, + netdev_features_t actual) +{ + netdev_features_t ipv6_features = NETIF_F_TSO6; + netdev_features_t ipv4_features = NETIF_F_TSO; + + if (!card->info.has_lp2lp_cso_v6) + ipv6_features |= NETIF_F_IPV6_CSUM; + if (!card->info.has_lp2lp_cso_v4) + ipv4_features |= NETIF_F_IP_CSUM; + + if ((changed & ipv6_features) && !(actual & ipv6_features)) + qeth_flush_local_addrs6(card); + if ((changed & ipv4_features) && !(actual & ipv4_features)) + qeth_flush_local_addrs4(card); +} + int qeth_set_features(struct net_device *dev, netdev_features_t features) { struct qeth_card *card = dev->ml_priv; @@@ -6802,15 -6504,13 +6802,15 @@@
if ((changed & NETIF_F_IP_CSUM)) { rc = qeth_set_ipa_csum(card, features & NETIF_F_IP_CSUM, - IPA_OUTBOUND_CHECKSUM, QETH_PROT_IPV4); + IPA_OUTBOUND_CHECKSUM, QETH_PROT_IPV4, + &card->info.has_lp2lp_cso_v4); if (rc) changed ^= NETIF_F_IP_CSUM; } if (changed & NETIF_F_IPV6_CSUM) { rc = qeth_set_ipa_csum(card, features & NETIF_F_IPV6_CSUM, - IPA_OUTBOUND_CHECKSUM, QETH_PROT_IPV6); + IPA_OUTBOUND_CHECKSUM, QETH_PROT_IPV6, + &card->info.has_lp2lp_cso_v6); if (rc) changed ^= NETIF_F_IPV6_CSUM; } @@@ -6832,9 -6532,6 +6832,9 @@@ changed ^= NETIF_F_TSO6; }
+ qeth_check_restricted_features(card, dev->features ^ features, + dev->features ^ changed); + /* everything changed successfully? */ if ((dev->features ^ features) == changed) return 0; @@@ -6871,34 -6568,6 +6871,34 @@@ netdev_features_t qeth_features_check(s struct net_device *dev, netdev_features_t features) { + /* Traffic with local next-hop is not eligible for some offloads: */ + if (skb->ip_summed == CHECKSUM_PARTIAL) { + struct qeth_card *card = dev->ml_priv; + netdev_features_t restricted = 0; + + if (skb_is_gso(skb) && !netif_needs_gso(skb, features)) + restricted |= NETIF_F_ALL_TSO; + + switch (vlan_get_protocol(skb)) { + case htons(ETH_P_IP): + if (!card->info.has_lp2lp_cso_v4) + restricted |= NETIF_F_IP_CSUM; + + if (restricted && qeth_next_hop_is_local_v4(card, skb)) + features &= ~restricted; + break; + case htons(ETH_P_IPV6): + if (!card->info.has_lp2lp_cso_v6) + restricted |= NETIF_F_IPV6_CSUM; + + if (restricted && qeth_next_hop_is_local_v6(card, skb)) + features &= ~restricted; + break; + default: + break; + } + } + /* GSO segmentation builds skbs with * a (small) linear part for the headers, and * page frags for the data. @@@ -7048,17 -6717,17 +7048,17 @@@ int qeth_stop(struct net_device *dev unsigned int i;
/* Quiesce the NAPI instances: */ - qeth_for_each_output_queue(card, queue, i) { + qeth_for_each_output_queue(card, queue, i) napi_disable(&queue->napi); - del_timer_sync(&queue->timer); - }
/* Stop .ndo_start_xmit, might still access queue->napi. */ netif_tx_disable(dev);
- /* Queues may get re-allocated, so remove the NAPIs here. */ - qeth_for_each_output_queue(card, queue, i) + qeth_for_each_output_queue(card, queue, i) { + del_timer_sync(&queue->timer); + /* Queues may get re-allocated, so remove the NAPIs. */ netif_napi_del(&queue->napi); + } } else { netif_tx_disable(dev); } @@@ -7076,8 -6745,6 +7076,8 @@@ static int __init qeth_core_init(void
pr_info("loading core functions\n");
+ qeth_debugfs_root = debugfs_create_dir("qeth", NULL); + rc = qeth_register_dbf_views(); if (rc) goto dbf_err; @@@ -7119,7 -6786,6 +7119,7 @@@ slab_err register_err: qeth_unregister_dbf_views(); dbf_err: + debugfs_remove_recursive(qeth_debugfs_root); pr_err("Initializing the qeth device driver failed\n"); return rc; } @@@ -7133,7 -6799,6 +7133,7 @@@ static void __exit qeth_core_exit(void kmem_cache_destroy(qeth_core_header_cache); root_device_unregister(qeth_core_root_dev); qeth_unregister_dbf_views(); + debugfs_remove_recursive(qeth_debugfs_root); pr_info("core functions removed\n"); }
diff --combined include/linux/fs.h index 9b028d260649,45cc10cdf6dd..5ee9e583bde2 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@@ -983,7 -983,7 +983,7 @@@ struct file_handle __u32 handle_bytes; int handle_type; /* file identifier */ - unsigned char f_handle[0]; + unsigned char f_handle[]; };
static inline struct file *get_file(struct file *f) @@@ -3536,11 -3536,11 +3536,11 @@@ ssize_t simple_attr_write(struct file *
struct ctl_table; int proc_nr_files(struct ctl_table *table, int write, - void __user *buffer, size_t *lenp, loff_t *ppos); + void *buffer, size_t *lenp, loff_t *ppos); int proc_nr_dentry(struct ctl_table *table, int write, - void __user *buffer, size_t *lenp, loff_t *ppos); + void *buffer, size_t *lenp, loff_t *ppos); int proc_nr_inodes(struct ctl_table *table, int write, - void __user *buffer, size_t *lenp, loff_t *ppos); + void *buffer, size_t *lenp, loff_t *ppos); int __init get_filesystem_list(char *buf);
#define __FMODE_EXEC ((__force int) FMODE_EXEC) diff --combined include/linux/tcp.h index 2c6f87e9f0cf,4f8159e90ce1..e60db06ec28d --- a/include/linux/tcp.h +++ b/include/linux/tcp.h @@@ -78,47 -78,6 +78,6 @@@ struct tcp_sack_block #define TCP_SACK_SEEN (1 << 0) /*1 = peer is SACK capable, */ #define TCP_DSACK_SEEN (1 << 2) /*1 = DSACK was received from peer*/
- #if IS_ENABLED(CONFIG_MPTCP) - struct mptcp_options_received { - u64 sndr_key; - u64 rcvr_key; - u64 data_ack; - u64 data_seq; - u32 subflow_seq; - u16 data_len; - u16 mp_capable : 1, - mp_join : 1, - dss : 1, - add_addr : 1, - rm_addr : 1, - family : 4, - echo : 1, - backup : 1; - u32 token; - u32 nonce; - u64 thmac; - u8 hmac[20]; - u8 join_id; - u8 use_map:1, - dsn64:1, - data_fin:1, - use_ack:1, - ack64:1, - mpc_map:1, - __unused:2; - u8 addr_id; - u8 rm_id; - union { - struct in_addr addr; - #if IS_ENABLED(CONFIG_MPTCP_IPV6) - struct in6_addr addr6; - #endif - }; - u64 ahmac; - u16 port; - }; - #endif - struct tcp_options_received { /* PAWS/RTTM data */ int ts_recent_stamp;/* Time we stored ts_recent (for aging) */ @@@ -136,9 -95,6 +95,6 @@@ u8 num_sacks; /* Number of SACK blocks */ u16 user_mss; /* mss requested by user in ioctl */ u16 mss_clamp; /* Maximal mss, negotiated at connection setup */ - #if IS_ENABLED(CONFIG_MPTCP) - struct mptcp_options_received mptcp; - #endif };
static inline void tcp_clear_options(struct tcp_options_received *rx_opt) @@@ -148,13 -104,6 +104,6 @@@ #if IS_ENABLED(CONFIG_SMC) rx_opt->smc_ok = 0; #endif - #if IS_ENABLED(CONFIG_MPTCP) - rx_opt->mptcp.mp_capable = 0; - rx_opt->mptcp.mp_join = 0; - rx_opt->mptcp.add_addr = 0; - rx_opt->mptcp.rm_addr = 0; - rx_opt->mptcp.dss = 0; - #endif }
/* This is the max number of SACKS that we'll generate and process. It's safe @@@ -268,7 -217,6 +217,7 @@@ struct tcp_sock } rack; u16 advmss; /* Advertised MSS */ u8 compressed_ack; + u8 dup_ack_counter; u32 chrono_start; /* Start time in jiffies of a TCP chrono */ u32 chrono_stat[3]; /* Time in jiffies for chrono_stat stats */ u8 chrono_type:2, /* current chronograph type */ diff --combined include/net/flow_offload.h index 94a30fe02e6d,efc8350b42fb..4001ffb04f0d --- a/include/net/flow_offload.h +++ b/include/net/flow_offload.h @@@ -147,7 -147,6 +147,7 @@@ enum flow_action_id FLOW_ACTION_MPLS_PUSH, FLOW_ACTION_MPLS_POP, FLOW_ACTION_MPLS_MANGLE, + FLOW_ACTION_GATE, NUM_FLOW_ACTIONS, };
@@@ -167,15 -166,18 +167,18 @@@ enum flow_action_mangle_base enum flow_action_hw_stats_bit { FLOW_ACTION_HW_STATS_IMMEDIATE_BIT, FLOW_ACTION_HW_STATS_DELAYED_BIT, + FLOW_ACTION_HW_STATS_DISABLED_BIT, };
enum flow_action_hw_stats { - FLOW_ACTION_HW_STATS_DISABLED = 0, + FLOW_ACTION_HW_STATS_DONT_CARE = 0, FLOW_ACTION_HW_STATS_IMMEDIATE = BIT(FLOW_ACTION_HW_STATS_IMMEDIATE_BIT), FLOW_ACTION_HW_STATS_DELAYED = BIT(FLOW_ACTION_HW_STATS_DELAYED_BIT), FLOW_ACTION_HW_STATS_ANY = FLOW_ACTION_HW_STATS_IMMEDIATE | FLOW_ACTION_HW_STATS_DELAYED, + FLOW_ACTION_HW_STATS_DISABLED = + BIT(FLOW_ACTION_HW_STATS_DISABLED_BIT), };
typedef void (*action_destr)(void *priv); @@@ -256,15 -258,6 +259,15 @@@ struct flow_action_entry u8 bos; u8 ttl; } mpls_mangle; + struct { + u32 index; + s32 prio; + u64 basetime; + u64 cycletime; + u64 cycletimeext; + u32 num_entries; + struct action_gate_entry *entries; + } gate; }; struct flow_action_cookie *cookie; /* user defined action cookie */ }; @@@ -335,7 -328,11 +338,11 @@@ __flow_action_hw_stats_check(const stru return true; if (!flow_action_mixed_hw_stats_check(action, extack)) return false; + action_entry = flow_action_first_entry_get(action); + if (action_entry->hw_stats == FLOW_ACTION_HW_STATS_DONT_CARE) + return true; + if (!check_allow_bit && action_entry->hw_stats != FLOW_ACTION_HW_STATS_ANY) { NL_SET_ERR_MSG_MOD(extack, "Driver supports only default HW stats type "any""); diff --combined include/net/mptcp.h index 5288fba56e55,3bce2019e4da..e60275659de6 --- a/include/net/mptcp.h +++ b/include/net/mptcp.h @@@ -68,13 -68,8 +68,9 @@@ static inline bool rsk_is_mptcp(const s return tcp_rsk(req)->is_mptcp; }
+void mptcp_space(const struct sock *ssk, int *space, int *full_space); - - void mptcp_parse_option(const struct sk_buff *skb, const unsigned char *ptr, - int opsize, struct tcp_options_received *opt_rx); bool mptcp_syn_options(struct sock *sk, const struct sk_buff *skb, unsigned int *size, struct mptcp_out_options *opts); - void mptcp_rcv_synsent(struct sock *sk); bool mptcp_synack_options(const struct request_sock *req, unsigned int *size, struct mptcp_out_options *opts); bool mptcp_established_options(struct sock *sk, struct sk_buff *skb, @@@ -199,7 -194,6 +195,7 @@@ static inline bool mptcp_sk_is_subflow( return false; }
+static inline void mptcp_space(const struct sock *ssk, int *s, int *fs) { } static inline void mptcp_seq_show(struct seq_file *seq) { } #endif /* CONFIG_MPTCP */
diff --combined include/net/sch_generic.h index 1862bf5a105b,8428aa614265..ab87a8b86a32 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@@ -407,6 -407,7 +407,7 @@@ struct tcf_block struct mutex lock; struct list_head chain_list; u32 index; /* block index for shared blocks */ + u32 classid; /* which class this block belongs to */ refcount_t refcnt; struct net *net; struct Qdisc *q; @@@ -710,6 -711,11 +711,6 @@@ static inline void qdisc_reset_all_tx_g } }
-static inline void qdisc_reset_all_tx(struct net_device *dev) -{ - qdisc_reset_all_tx_gt(dev, 0); -} - /* Are all TX queues of the device empty? */ static inline bool qdisc_all_tx_empty(const struct net_device *dev) { diff --combined include/soc/mscc/ocelot.h index a025fb798164,efc8b613d486..4953e9994df3 --- a/include/soc/mscc/ocelot.h +++ b/include/soc/mscc/ocelot.h @@@ -92,8 -92,6 +92,8 @@@ #define OCELOT_SPEED_100 2 #define OCELOT_SPEED_10 3
+#define OCELOT_PTP_PINS_NUM 4 + #define TARGET_OFFSET 24 #define REG_MASK GENMASK(TARGET_OFFSET - 1, 0) #define REG(reg, offset) [reg & REG_MASK] = offset @@@ -387,8 -385,6 +387,8 @@@ enum ocelot_reg PTP_PIN_TOD_SEC_MSB, PTP_PIN_TOD_SEC_LSB, PTP_PIN_TOD_NSEC, + PTP_PIN_WF_HIGH_PERIOD, + PTP_PIN_WF_LOW_PERIOD, PTP_CFG_MISC, PTP_CLK_CFG_ADJ_CFG, PTP_CLK_CFG_ADJ_FREQ, @@@ -444,11 -440,10 +444,11 @@@ enum ocelot_regfield REGFIELD_MAX };
-enum ocelot_clk_pins { - ALT_PPS_PIN = 1, - EXT_CLK_PIN, - ALT_LDST_PIN, +enum ocelot_ptp_pins { + PTP_PIN_0, + PTP_PIN_1, + PTP_PIN_2, + PTP_PIN_3, TOD_ACC_PIN };
@@@ -507,6 -502,7 +507,7 @@@ struct ocelot unsigned int num_stats;
int shared_queue_sz; + int num_mact_rows;
struct net_device *hw_bridge_dev; u16 bridge_mask; @@@ -554,7 -550,6 +555,7 @@@ struct mutex ptp_lock; /* Protects the PTP clock */ spinlock_t ptp_clock_lock; + struct ptp_pin_desc ptp_pins[OCELOT_PTP_PINS_NUM]; };
struct ocelot_policer { @@@ -626,6 -621,7 +627,6 @@@ int ocelot_vlan_add(struct ocelot *ocel int ocelot_vlan_del(struct ocelot *ocelot, int port, u16 vid); int ocelot_hwstamp_get(struct ocelot *ocelot, int port, struct ifreq *ifr); int ocelot_hwstamp_set(struct ocelot *ocelot, int port, struct ifreq *ifr); -int ocelot_ptp_gettime64(struct ptp_clock_info *ptp, struct timespec64 *ts); int ocelot_port_add_txtstamp_skb(struct ocelot_port *ocelot_port, struct sk_buff *skb); void ocelot_get_txtstamp(struct ocelot *ocelot); diff --combined include/uapi/linux/bpf.h index b3643e27e264,f9b7fdd951e4..101b0c8a3784 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@@ -73,7 -73,7 +73,7 @@@ struct bpf_insn /* Key of an a BPF_MAP_TYPE_LPM_TRIE entry */ struct bpf_lpm_trie_key { __u32 prefixlen; /* up to 32 for AF_INET, 128 for AF_INET6 */ - __u8 data[]; /* Arbitrary size */ + __u8 data[0]; /* Arbitrary size */ };
struct bpf_cgroup_storage_key { @@@ -113,9 -113,6 +113,9 @@@ enum bpf_cmd BPF_MAP_DELETE_BATCH, BPF_LINK_CREATE, BPF_LINK_UPDATE, + BPF_LINK_GET_FD_BY_ID, + BPF_LINK_GET_NEXT_ID, + BPF_ENABLE_STATS, };
enum bpf_map_type { @@@ -223,15 -220,6 +223,15 @@@ enum bpf_attach_type
#define MAX_BPF_ATTACH_TYPE __MAX_BPF_ATTACH_TYPE
+enum bpf_link_type { + BPF_LINK_TYPE_UNSPEC = 0, + BPF_LINK_TYPE_RAW_TRACEPOINT = 1, + BPF_LINK_TYPE_TRACING = 2, + BPF_LINK_TYPE_CGROUP = 3, + + MAX_BPF_LINK_TYPE, +}; + /* cgroup-bpf attach flags used in BPF_PROG_ATTACH command * * NONE(default): No further bpf programs allowed in the subtree. @@@ -391,12 -379,6 +391,12 @@@ enum */ #define BPF_F_QUERY_EFFECTIVE (1U << 0)
+/* type for BPF_ENABLE_STATS */ +enum bpf_stats_type { + /* enabled run_time_ns and run_cnt */ + BPF_STATS_RUN_TIME = 0, +}; + enum bpf_stack_build_id_status { /* user space need an empty entry to identify end of a trace */ BPF_STACK_BUILD_ID_EMPTY = 0, @@@ -541,7 -523,6 +541,7 @@@ union bpf_attr __u32 prog_id; __u32 map_id; __u32 btf_id; + __u32 link_id; }; __u32 next_id; __u32 open_flags; @@@ -608,10 -589,6 +608,10 @@@ __u32 old_prog_fd; } link_update;
+ struct { /* struct used by BPF_ENABLE_STATS command */ + __u32 type; + } enable_stats; + } __attribute__((aligned(8)));
/* The description below is an attempt at providing documentation to eBPF @@@ -675,8 -652,6 +675,8 @@@ * u64 bpf_ktime_get_ns(void) * Description * Return the time elapsed since system boot, in nanoseconds. + * Does not include time the system was suspended. + * See: clock_gettime(CLOCK_MONOTONIC) * Return * Current *ktime*. * @@@ -1587,7 -1562,7 +1587,7 @@@ * Return * 0 * - * int bpf_setsockopt(struct bpf_sock_ops *bpf_socket, int level, int optname, void *optval, int optlen) + * int bpf_setsockopt(void *bpf_socket, int level, int optname, void *optval, int optlen) * Description * Emulate a call to **setsockopt()** on the socket associated to * *bpf_socket*, which must be a full socket. The *level* at @@@ -1595,11 -1570,6 +1595,11 @@@ * must be specified, see **setsockopt(2)** for more information. * The option value of length *optlen* is pointed by *optval*. * + * *bpf_socket* should be one of the following: + * * **struct bpf_sock_ops** for **BPF_PROG_TYPE_SOCK_OPS**. + * * **struct bpf_sock_addr** for **BPF_CGROUP_INET4_CONNECT** + * and **BPF_CGROUP_INET6_CONNECT**. + * * This helper actually implements a subset of **setsockopt()**. * It supports the following *level*\ s: * @@@ -1794,7 -1764,7 +1794,7 @@@ * Return * 0 on success, or a negative error in case of failure. * - * int bpf_getsockopt(struct bpf_sock_ops *bpf_socket, int level, int optname, void *optval, int optlen) + * int bpf_getsockopt(void *bpf_socket, int level, int optname, void *optval, int optlen) * Description * Emulate a call to **getsockopt()** on the socket associated to * *bpf_socket*, which must be a full socket. The *level* at @@@ -1803,11 -1773,6 +1803,11 @@@ * The retrieved value is stored in the structure pointed by * *opval* and of length *optlen*. * + * *bpf_socket* should be one of the following: + * * **struct bpf_sock_ops** for **BPF_PROG_TYPE_SOCK_OPS**. + * * **struct bpf_sock_addr** for **BPF_CGROUP_INET4_CONNECT** + * and **BPF_CGROUP_INET6_CONNECT**. + * * This helper actually implements a subset of **getsockopt()**. * It supports the following *level*\ s: * @@@ -3060,14 -3025,6 +3060,14 @@@ * * **-EOPNOTSUPP** Unsupported operation, for example a * call from outside of TC ingress. * * **-ESOCKTNOSUPPORT** Socket type not supported (reuseport). + * + * u64 bpf_ktime_get_boot_ns(void) + * Description + * Return the time elapsed since system boot, in nanoseconds. + * Does include the time the system was suspended. + * See: clock_gettime(CLOCK_BOOTTIME) + * Return + * Current *ktime*. */ #define __BPF_FUNC_MAPPER(FN) \ FN(unspec), \ @@@ -3194,8 -3151,7 +3194,8 @@@ FN(xdp_output), \ FN(get_netns_cookie), \ FN(get_current_ancestor_cgroup_id), \ - FN(sk_assign), + FN(sk_assign), \ + FN(ktime_get_boot_ns),
/* integer value in 'imm' field of BPF_CALL instruction selects which helper * function eBPF program intends to call @@@ -3642,25 -3598,6 +3642,25 @@@ struct bpf_btf_info __u32 id; } __attribute__((aligned(8)));
+struct bpf_link_info { + __u32 type; + __u32 id; + __u32 prog_id; + union { + struct { + __aligned_u64 tp_name; /* in/out: tp_name buffer ptr */ + __u32 tp_name_len; /* in/out: tp_name buffer len */ + } raw_tracepoint; + struct { + __u32 attach_type; + } tracing; + struct { + __u64 cgroup_id; + __u32 attach_type; + } cgroup; + }; +} __attribute__((aligned(8))); + /* User bpf_sock_addr struct to access socket fields and sockaddr struct passed * by user and intended to be used by socket (e.g. to bind to, depends on * attach attach type). diff --combined net/batman-adv/bat_v_ogm.c index 0959d32be65c,80b87b1f4e3a..18028b9f95f0 --- a/net/batman-adv/bat_v_ogm.c +++ b/net/batman-adv/bat_v_ogm.c @@@ -88,7 -88,7 +88,7 @@@ static void batadv_v_ogm_start_queue_ti unsigned int msecs = BATADV_MAX_AGGREGATION_MS * 1000;
/* msecs * [0.9, 1.1] */ - msecs += prandom_u32() % (msecs / 5) - (msecs / 10); + msecs += prandom_u32_max(msecs / 5) - (msecs / 10); queue_delayed_work(batadv_event_workqueue, &hard_iface->bat_v.aggr_wq, msecs_to_jiffies(msecs / 1000)); } @@@ -107,7 -107,7 +107,7 @@@ static void batadv_v_ogm_start_timer(st return;
msecs = atomic_read(&bat_priv->orig_interval) - BATADV_JITTER; - msecs += prandom_u32() % (2 * BATADV_JITTER); + msecs += prandom_u32_max(2 * BATADV_JITTER); queue_delayed_work(batadv_event_workqueue, &bat_priv->bat_v.ogm_wq, msecs_to_jiffies(msecs)); } @@@ -893,7 -893,7 +893,7 @@@ static void batadv_v_ogm_process(const
orig_node = batadv_v_ogm_orig_get(bat_priv, ogm_packet->orig); if (!orig_node) - return; + goto out;
neigh_node = batadv_neigh_node_get_or_create(orig_node, if_incoming, ethhdr->h_source); diff --combined net/bridge/br_netlink.c index a774e19c41bb,a0f5dbee8f9c..240e260e3461 --- a/net/bridge/br_netlink.c +++ b/net/bridge/br_netlink.c @@@ -151,7 -151,6 +151,7 @@@ static inline size_t br_port_info_size( + nla_total_size(sizeof(u8)) /* IFLA_BRPORT_MULTICAST_ROUTER */ #endif + nla_total_size(sizeof(u16)) /* IFLA_BRPORT_GROUP_FWD_MASK */ + + nla_total_size(sizeof(u8)) /* IFLA_BRPORT_MRP_RING_OPEN */ + 0; }
@@@ -214,8 -213,6 +214,8 @@@ static int br_port_fill_attrs(struct sk nla_put_u16(skb, IFLA_BRPORT_GROUP_FWD_MASK, p->group_fwd_mask) || nla_put_u8(skb, IFLA_BRPORT_NEIGH_SUPPRESS, !!(p->flags & BR_NEIGH_SUPPRESS)) || + nla_put_u8(skb, IFLA_BRPORT_MRP_RING_OPEN, !!(p->flags & + BR_MRP_LOST_CONT)) || nla_put_u8(skb, IFLA_BRPORT_ISOLATED, !!(p->flags & BR_ISOLATED))) return -EMSGSIZE;
@@@ -615,6 -612,7 +615,7 @@@ int br_process_vlan_info(struct net_bri v - 1, rtm_cmd); v_change_start = 0; } + cond_resched(); } /* v_change_start is set only if the last/whole range changed */ if (v_change_start) @@@ -672,11 -670,6 +673,11 @@@ static int br_afspec(struct net_bridge if (err) return err; break; + case IFLA_BRIDGE_MRP: + err = br_mrp_parse(br, p, attr, cmd, extack); + if (err) + return err; + break; } }
@@@ -1109,9 -1102,7 +1110,9 @@@ static int br_changelink(struct net_dev if (data[IFLA_BR_STP_STATE]) { u32 stp_enabled = nla_get_u32(data[IFLA_BR_STP_STATE]);
- br_stp_set_enabled(br, stp_enabled); + err = br_stp_set_enabled(br, stp_enabled, extack); + if (err) + return err; }
if (data[IFLA_BR_PRIORITY]) { diff --combined net/core/devlink.c index 43a9d5be73ca,899edcee7dab..20f935fa29f5 --- a/net/core/devlink.c +++ b/net/core/devlink.c @@@ -3716,26 -3716,24 +3716,26 @@@ nla_put_failure return err; }
-static void devlink_nl_region_notify(struct devlink_region *region, - struct devlink_snapshot *snapshot, - enum devlink_command cmd) +static struct sk_buff * +devlink_nl_region_notify_build(struct devlink_region *region, + struct devlink_snapshot *snapshot, + enum devlink_command cmd, u32 portid, u32 seq) { struct devlink *devlink = region->devlink; struct sk_buff *msg; void *hdr; int err;
- WARN_ON(cmd != DEVLINK_CMD_REGION_NEW && cmd != DEVLINK_CMD_REGION_DEL);
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); if (!msg) - return; + return ERR_PTR(-ENOMEM);
- hdr = genlmsg_put(msg, 0, 0, &devlink_nl_family, 0, cmd); - if (!hdr) + hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, 0, cmd); + if (!hdr) { + err = -EMSGSIZE; goto out_free_msg; + }
err = devlink_nl_put_handle(msg, devlink); if (err) @@@ -3759,30 -3757,15 +3759,30 @@@ } genlmsg_end(msg, hdr);
- genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), - msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); - - return; + return msg;
out_cancel_msg: genlmsg_cancel(msg, hdr); out_free_msg: nlmsg_free(msg); + return ERR_PTR(err); +} + +static void devlink_nl_region_notify(struct devlink_region *region, + struct devlink_snapshot *snapshot, + enum devlink_command cmd) +{ + struct devlink *devlink = region->devlink; + struct sk_buff *msg; + + WARN_ON(cmd != DEVLINK_CMD_REGION_NEW && cmd != DEVLINK_CMD_REGION_DEL); + + msg = devlink_nl_region_notify_build(region, snapshot, cmd, 0, 0); + if (IS_ERR(msg)) + return; + + genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), + msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); }
/** @@@ -4086,8 -4069,6 +4086,8 @@@ static in devlink_nl_cmd_region_new(struct sk_buff *skb, struct genl_info *info) { struct devlink *devlink = info->user_ptr[0]; + struct devlink_snapshot *snapshot; + struct nlattr *snapshot_id_attr; struct devlink_region *region; const char *region_name; u32 snapshot_id; @@@ -4099,6 -4080,11 +4099,6 @@@ return -EINVAL; }
- if (!info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]) { - NL_SET_ERR_MSG_MOD(info->extack, "No snapshot id provided"); - return -EINVAL; - } - region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]); region = devlink_region_get_by_name(devlink, region_name); if (!region) { @@@ -4116,25 -4102,16 +4116,25 @@@ return -ENOSPC; }
- snapshot_id = nla_get_u32(info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]); + snapshot_id_attr = info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]; + if (snapshot_id_attr) { + snapshot_id = nla_get_u32(snapshot_id_attr);
- if (devlink_region_snapshot_get_by_id(region, snapshot_id)) { - NL_SET_ERR_MSG_MOD(info->extack, "The requested snapshot id is already in use"); - return -EEXIST; - } + if (devlink_region_snapshot_get_by_id(region, snapshot_id)) { + NL_SET_ERR_MSG_MOD(info->extack, "The requested snapshot id is already in use"); + return -EEXIST; + }
- err = __devlink_snapshot_id_insert(devlink, snapshot_id); - if (err) - return err; + err = __devlink_snapshot_id_insert(devlink, snapshot_id); + if (err) + return err; + } else { + err = __devlink_region_snapshot_id_get(devlink, &snapshot_id); + if (err) { + NL_SET_ERR_MSG_MOD(info->extack, "Failed to allocate a new snapshot id"); + return err; + } + }
err = region->ops->snapshot(devlink, info->extack, &data); if (err) @@@ -4144,27 -4121,6 +4144,27 @@@ if (err) goto err_snapshot_create;
+ if (!snapshot_id_attr) { + struct sk_buff *msg; + + snapshot = devlink_region_snapshot_get_by_id(region, + snapshot_id); + if (WARN_ON(!snapshot)) + return -EINVAL; + + msg = devlink_nl_region_notify_build(region, snapshot, + DEVLINK_CMD_REGION_NEW, + info->snd_portid, + info->snd_seq); + err = PTR_ERR_OR_ZERO(msg); + if (err) + goto err_notify; + + err = genlmsg_reply(msg, info); + if (err) + goto err_notify; + } + return 0;
err_snapshot_create: @@@ -4172,10 -4128,6 +4172,10 @@@ err_snapshot_capture: __devlink_snapshot_id_decrement(devlink, snapshot_id); return err; + +err_notify: + devlink_region_snapshot_del(region, snapshot); + return err; }
static int devlink_nl_cmd_region_read_chunk_fill(struct sk_buff *msg, @@@ -4331,6 -4283,11 +4331,11 @@@ static int devlink_nl_cmd_region_read_d end_offset = nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]); end_offset += nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]); dump = false; + + if (start_offset == end_offset) { + err = 0; + goto nla_put_failure; + } }
err = devlink_nl_region_read_snapshot_fill(skb, devlink, @@@ -5411,6 -5368,7 +5416,7 @@@ int devlink_health_report(struct devlin { enum devlink_health_reporter_state prev_health_state; struct devlink *devlink = reporter->devlink; + unsigned long recover_ts_threshold;
/* write a log message of the current error */ WARN_ON(!msg); @@@ -5421,10 -5379,12 +5427,12 @@@ devlink_recover_notify(reporter, DEVLINK_CMD_HEALTH_REPORTER_RECOVER);
/* abort if the previous error wasn't recovered */ + recover_ts_threshold = reporter->last_recovery_ts + + msecs_to_jiffies(reporter->graceful_period); if (reporter->auto_recover && (prev_health_state != DEVLINK_HEALTH_REPORTER_STATE_HEALTHY || - jiffies - reporter->last_recovery_ts < - msecs_to_jiffies(reporter->graceful_period))) { + (reporter->last_recovery_ts && reporter->recovery_count && + time_is_after_jiffies(recover_ts_threshold)))) { trace_devlink_health_recover_aborted(devlink, reporter->ops->name, reporter->health_state, diff --combined net/core/neighbour.c index 3f2263e79e4b,116139233d57..b607ea602774 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@@ -1956,6 -1956,9 +1956,9 @@@ static int neigh_add(struct sk_buff *sk NEIGH_UPDATE_F_OVERRIDE_ISROUTER); }
+ if (protocol) + neigh->protocol = protocol; + if (ndm->ndm_flags & NTF_EXT_LEARNED) flags |= NEIGH_UPDATE_F_EXT_LEARNED;
@@@ -1969,9 -1972,6 +1972,6 @@@ err = __neigh_update(neigh, lladdr, ndm->ndm_state, flags, NETLINK_CB(skb).portid, extack);
- if (protocol) - neigh->protocol = protocol; - neigh_release(neigh);
out: @@@ -3379,7 -3379,7 +3379,7 @@@ EXPORT_SYMBOL(neigh_app_ns) static int unres_qlen_max = INT_MAX / SKB_TRUESIZE(ETH_FRAME_LEN);
static int proc_unres_qlen(struct ctl_table *ctl, int write, - void __user *buffer, size_t *lenp, loff_t *ppos) + void *buffer, size_t *lenp, loff_t *ppos) { int size, ret; struct ctl_table tmp = *ctl; @@@ -3443,8 -3443,8 +3443,8 @@@ static void neigh_proc_update(struct ct }
static int neigh_proc_dointvec_zero_intmax(struct ctl_table *ctl, int write, - void __user *buffer, - size_t *lenp, loff_t *ppos) + void *buffer, size_t *lenp, + loff_t *ppos) { struct ctl_table tmp = *ctl; int ret; @@@ -3457,8 -3457,8 +3457,8 @@@ return ret; }
-int neigh_proc_dointvec(struct ctl_table *ctl, int write, - void __user *buffer, size_t *lenp, loff_t *ppos) +int neigh_proc_dointvec(struct ctl_table *ctl, int write, void *buffer, + size_t *lenp, loff_t *ppos) { int ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
@@@ -3467,7 -3467,8 +3467,7 @@@ } EXPORT_SYMBOL(neigh_proc_dointvec);
-int neigh_proc_dointvec_jiffies(struct ctl_table *ctl, int write, - void __user *buffer, +int neigh_proc_dointvec_jiffies(struct ctl_table *ctl, int write, void *buffer, size_t *lenp, loff_t *ppos) { int ret = proc_dointvec_jiffies(ctl, write, buffer, lenp, ppos); @@@ -3478,8 -3479,8 +3478,8 @@@ EXPORT_SYMBOL(neigh_proc_dointvec_jiffies);
static int neigh_proc_dointvec_userhz_jiffies(struct ctl_table *ctl, int write, - void __user *buffer, - size_t *lenp, loff_t *ppos) + void *buffer, size_t *lenp, + loff_t *ppos) { int ret = proc_dointvec_userhz_jiffies(ctl, write, buffer, lenp, ppos);
@@@ -3488,7 -3489,8 +3488,7 @@@ }
int neigh_proc_dointvec_ms_jiffies(struct ctl_table *ctl, int write, - void __user *buffer, - size_t *lenp, loff_t *ppos) + void *buffer, size_t *lenp, loff_t *ppos) { int ret = proc_dointvec_ms_jiffies(ctl, write, buffer, lenp, ppos);
@@@ -3498,8 -3500,8 +3498,8 @@@ EXPORT_SYMBOL(neigh_proc_dointvec_ms_jiffies);
static int neigh_proc_dointvec_unres_qlen(struct ctl_table *ctl, int write, - void __user *buffer, - size_t *lenp, loff_t *ppos) + void *buffer, size_t *lenp, + loff_t *ppos) { int ret = proc_unres_qlen(ctl, write, buffer, lenp, ppos);
@@@ -3508,8 -3510,8 +3508,8 @@@ }
static int neigh_proc_base_reachable_time(struct ctl_table *ctl, int write, - void __user *buffer, - size_t *lenp, loff_t *ppos) + void *buffer, size_t *lenp, + loff_t *ppos) { struct neigh_parms *p = ctl->extra2; int ret; diff --combined net/dsa/slave.c index fa2634043751,62f4ee3da172..ea0fcf7bf786 --- a/net/dsa/slave.c +++ b/net/dsa/slave.c @@@ -856,20 -856,18 +856,18 @@@ dsa_slave_add_cls_matchall_mirred(struc struct dsa_port *to_dp; int err;
- act = &cls->rule->action.entries[0]; - if (!ds->ops->port_mirror_add) return -EOPNOTSUPP;
- if (!act->dev) - return -EINVAL; - if (!flow_action_basic_hw_stats_check(&cls->rule->action, cls->common.extack)) return -EOPNOTSUPP;
act = &cls->rule->action.entries[0];
+ if (!act->dev) + return -EINVAL; + if (!dsa_slave_dev_check(act->dev)) return -EOPNOTSUPP;
@@@ -1590,10 -1588,10 +1588,10 @@@ void dsa_port_phylink_mac_change(struc } EXPORT_SYMBOL_GPL(dsa_port_phylink_mac_change);
-static void dsa_slave_phylink_fixed_state(struct net_device *dev, +static void dsa_slave_phylink_fixed_state(struct phylink_config *config, struct phylink_link_state *state) { - struct dsa_port *dp = dsa_slave_to_port(dev); + struct dsa_port *dp = container_of(config, struct dsa_port, pl_config); struct dsa_switch *ds = dp->ds;
/* No need to check that this operation is valid, the callback would @@@ -1633,15 -1631,6 +1631,15 @@@ static int dsa_slave_phy_setup(struct n dp->pl_config.dev = &slave_dev->dev; dp->pl_config.type = PHYLINK_NETDEV;
+ /* The get_fixed_state callback takes precedence over polling the + * link GPIO in PHYLINK (see phylink_get_fixed_state). Only set + * this if the switch provides such a callback. + */ + if (ds->ops->phylink_fixed_state) { + dp->pl_config.get_fixed_state = dsa_slave_phylink_fixed_state; + dp->pl_config.poll_fixed_state = true; + } + dp->pl = phylink_create(&dp->pl_config, of_fwnode_handle(port_dn), mode, &dsa_port_phylink_mac_ops); if (IS_ERR(dp->pl)) { @@@ -1650,6 -1639,13 +1648,6 @@@ return PTR_ERR(dp->pl); }
- /* Register only if the switch provides such a callback, since this - * callback takes precedence over polling the link GPIO in PHYLINK - * (see phylink_get_fixed_state). - */ - if (ds->ops->phylink_fixed_state) - phylink_fixed_state_cb(dp->pl, dsa_slave_phylink_fixed_state); - if (ds->ops->get_phy_flags) phy_flags = ds->ops->get_phy_flags(ds, dp->index);
@@@ -1671,15 -1667,6 +1669,15 @@@ return ret; }
+static struct lock_class_key dsa_slave_netdev_xmit_lock_key; +static void dsa_slave_set_lockdep_class_one(struct net_device *dev, + struct netdev_queue *txq, + void *_unused) +{ + lockdep_set_class(&txq->_xmit_lock, + &dsa_slave_netdev_xmit_lock_key); +} + int dsa_slave_suspend(struct net_device *slave_dev) { struct dsa_port *dp = dsa_slave_to_port(slave_dev); @@@ -1763,9 -1750,6 +1761,9 @@@ int dsa_slave_create(struct dsa_port *p slave_dev->max_mtu = ETH_MAX_MTU; SET_NETDEV_DEVTYPE(slave_dev, &dsa_type);
+ netdev_for_each_tx_queue(slave_dev, dsa_slave_set_lockdep_class_one, + NULL); + SET_NETDEV_DEV(slave_dev, port->ds->dev); slave_dev->dev.of_node = port->dn; slave_dev->vlan_features = master->vlan_features; @@@ -1776,11 -1760,6 +1774,11 @@@ free_netdev(slave_dev); return -ENOMEM; } + + ret = gro_cells_init(&p->gcells, slave_dev); + if (ret) + goto out_free; + p->dp = port; INIT_LIST_HEAD(&p->mall_tc_list); p->xmit = cpu_dp->tag_ops->xmit; @@@ -1798,7 -1777,7 +1796,7 @@@ ret = dsa_slave_phy_setup(slave_dev); if (ret) { netdev_err(master, "error %d setting up slave phy\n", ret); - goto out_free; + goto out_gcells; }
dsa_slave_notify(slave_dev, DSA_PORT_REGISTER); @@@ -1817,8 -1796,6 +1815,8 @@@ out_phy phylink_disconnect_phy(p->dp->pl); rtnl_unlock(); phylink_destroy(p->dp->pl); +out_gcells: + gro_cells_destroy(&p->gcells); out_free: free_percpu(p->stats64); free_netdev(slave_dev); @@@ -1839,7 -1816,6 +1837,7 @@@ void dsa_slave_destroy(struct net_devic dsa_slave_notify(slave_dev, DSA_PORT_UNREGISTER); unregister_netdev(slave_dev); phylink_destroy(dp->pl); + gro_cells_destroy(&p->gcells); free_percpu(p->stats64); free_netdev(slave_dev); } diff --combined net/ipv4/tcp_input.c index 7d205b2a733c,b996dc1069c5..66e55e51c550 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@@ -3014,7 -3014,7 +3014,7 @@@ void tcp_rearm_rto(struct sock *sk rto = usecs_to_jiffies(max_t(int, delta_us, 1)); } tcp_reset_xmit_timer(sk, ICSK_TIME_RETRANS, rto, - TCP_RTO_MAX, tcp_rtx_queue_head(sk)); + TCP_RTO_MAX); } }
@@@ -3291,7 -3291,7 +3291,7 @@@ static void tcp_ack_probe(struct sock * unsigned long when = tcp_probe0_when(sk, TCP_RTO_MAX);
tcp_reset_xmit_timer(sk, ICSK_TIME_PROBE0, - when, TCP_RTO_MAX, NULL); + when, TCP_RTO_MAX); } }
@@@ -3926,10 -3926,6 +3926,6 @@@ void tcp_parse_options(const struct ne */ break; #endif - case TCPOPT_MPTCP: - mptcp_parse_option(skb, ptr, opsize, opt_rx); - break; - case TCPOPT_FASTOPEN: tcp_parse_fastopen_option( opsize - TCPOLEN_FASTOPEN_BASE, @@@ -4327,33 -4323,6 +4323,33 @@@ static void tcp_sack_maybe_coalesce(str } }
+static void tcp_sack_compress_send_ack(struct sock *sk) +{ + struct tcp_sock *tp = tcp_sk(sk); + + if (!tp->compressed_ack) + return; + + if (hrtimer_try_to_cancel(&tp->compressed_ack_timer) == 1) + __sock_put(sk); + + /* Since we have to send one ack finally, + * substract one from tp->compressed_ack to keep + * LINUX_MIB_TCPACKCOMPRESSED accurate. + */ + NET_ADD_STATS(sock_net(sk), LINUX_MIB_TCPACKCOMPRESSED, + tp->compressed_ack - 1); + + tp->compressed_ack = 0; + tcp_send_ack(sk); +} + +/* Reasonable amount of sack blocks included in TCP SACK option + * The max is 4, but this becomes 3 if TCP timestamps are there. + * Given that SACK packets might be lost, be conservative and use 2. + */ +#define TCP_SACK_BLOCKS_EXPECTED 2 + static void tcp_sack_new_ofo_skb(struct sock *sk, u32 seq, u32 end_seq) { struct tcp_sock *tp = tcp_sk(sk); @@@ -4366,8 -4335,6 +4362,8 @@@
for (this_sack = 0; this_sack < cur_sacks; this_sack++, sp++) { if (tcp_sack_extend(sp, seq, end_seq)) { + if (this_sack >= TCP_SACK_BLOCKS_EXPECTED) + tcp_sack_compress_send_ack(sk); /* Rotate this_sack to the first one. */ for (; this_sack > 0; this_sack--, sp--) swap(*sp, *(sp - 1)); @@@ -4377,9 -4344,6 +4373,9 @@@ } }
+ if (this_sack >= TCP_SACK_BLOCKS_EXPECTED) + tcp_sack_compress_send_ack(sk); + /* Could not find an adjacent existing SACK, build a new one, * put it at the front, and shift everyone else down. We * always know there is at least one SACK present already here. @@@ -4387,6 -4351,8 +4383,6 @@@ * If the sack array is full, forget about the last one. */ if (this_sack >= TCP_NUM_SACKS) { - if (tp->compressed_ack > TCP_FASTRETRANS_THRESH) - tcp_send_ack(sk); this_sack--; tp->rx_opt.num_sacks--; sp--; @@@ -5305,13 -5271,15 +5301,13 @@@ send_now
if (tp->compressed_ack_rcv_nxt != tp->rcv_nxt) { tp->compressed_ack_rcv_nxt = tp->rcv_nxt; - if (tp->compressed_ack > TCP_FASTRETRANS_THRESH) - NET_ADD_STATS(sock_net(sk), LINUX_MIB_TCPACKCOMPRESSED, - tp->compressed_ack - TCP_FASTRETRANS_THRESH); - tp->compressed_ack = 0; + tp->dup_ack_counter = 0; } - - if (++tp->compressed_ack <= TCP_FASTRETRANS_THRESH) + if (tp->dup_ack_counter < TCP_FASTRETRANS_THRESH) { + tp->dup_ack_counter++; goto send_now; - + } + tp->compressed_ack++; if (hrtimer_is_queued(&tp->compressed_ack_timer)) return;
@@@ -5324,9 -5292,8 +5320,9 @@@ delay = min_t(unsigned long, sock_net(sk)->ipv4.sysctl_tcp_comp_sack_delay_ns, rtt * (NSEC_PER_USEC >> 3)/20); sock_hold(sk); - hrtimer_start(&tp->compressed_ack_timer, ns_to_ktime(delay), - HRTIMER_MODE_REL_PINNED_SOFT); + hrtimer_start_range_ns(&tp->compressed_ack_timer, ns_to_ktime(delay), + sock_net(sk)->ipv4.sysctl_tcp_comp_sack_slack_ns, + HRTIMER_MODE_REL_PINNED_SOFT); }
static inline void tcp_ack_snd_check(struct sock *sk) @@@ -6019,9 -5986,6 +6015,6 @@@ static int tcp_rcv_synsent_state_proces tcp_sync_mss(sk, icsk->icsk_pmtu_cookie); tcp_initialize_rcv_mss(sk);
- if (sk_is_mptcp(sk)) - mptcp_rcv_synsent(sk); - /* Remember, tcp_poll() does not lock socket! * Change state from SYN-SENT only after copied_seq * is initialized. */ diff --combined net/ipv6/route.c index 3912aac7854d,8d418038fe32..1ff142393c76 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@@ -984,7 -984,7 +984,7 @@@ int rt6_route_rcv(struct net_device *de gwaddr, dev);
if (rt && !lifetime) { - ip6_del_rt(net, rt); + ip6_del_rt(net, rt, false); rt = NULL; }
@@@ -1385,9 -1385,18 +1385,18 @@@ static struct rt6_info *ip6_rt_pcpu_all } ip6_rt_copy_init(pcpu_rt, res); pcpu_rt->rt6i_flags |= RTF_PCPU; + + if (f6i->nh) + pcpu_rt->sernum = rt_genid_ipv6(dev_net(dev)); + return pcpu_rt; }
+ static bool rt6_is_valid(const struct rt6_info *rt6) + { + return rt6->sernum == rt_genid_ipv6(dev_net(rt6->dst.dev)); + } + /* It should be called with rcu_read_lock() acquired */ static struct rt6_info *rt6_get_pcpu_route(const struct fib6_result *res) { @@@ -1395,6 -1404,19 +1404,19 @@@
pcpu_rt = this_cpu_read(*res->nh->rt6i_pcpu);
+ if (pcpu_rt && pcpu_rt->sernum && !rt6_is_valid(pcpu_rt)) { + struct rt6_info *prev, **p; + + p = this_cpu_ptr(res->nh->rt6i_pcpu); + prev = xchg(p, NULL); + if (prev) { + dst_dev_put(&prev->dst); + dst_release(&prev->dst); + } + + pcpu_rt = NULL; + } + return pcpu_rt; }
@@@ -2593,6 -2615,9 +2615,9 @@@ static struct dst_entry *ip6_dst_check(
rt = container_of(dst, struct rt6_info, dst);
+ if (rt->sernum) + return rt6_is_valid(rt) ? dst : NULL; + rcu_read_lock();
/* All IPV6 dsts are created with ->obsolete set to the value @@@ -3729,12 -3754,9 +3754,12 @@@ out return err; }
-int ip6_del_rt(struct net *net, struct fib6_info *rt) +int ip6_del_rt(struct net *net, struct fib6_info *rt, bool skip_notify) { - struct nl_info info = { .nl_net = net }; + struct nl_info info = { + .nl_net = net, + .skip_notify = skip_notify + };
return __ip6_del_rt(rt, &info); } @@@ -4255,7 -4277,7 +4280,7 @@@ restart (!idev || idev->cnf.accept_ra != 2) && fib6_info_hold_safe(rt)) { rcu_read_unlock(); - ip6_del_rt(net, rt); + ip6_del_rt(net, rt, false); goto restart; } } @@@ -5557,8 -5579,7 +5582,8 @@@ static int rt6_fill_node(struct net *ne if (nexthop_is_blackhole(rt->nh)) rtm->rtm_type = RTN_BLACKHOLE;
- if (rt6_fill_node_nexthop(skb, rt->nh, &nh_flags) < 0) + if (net->ipv4.sysctl_nexthop_compat_mode && + rt6_fill_node_nexthop(skb, rt->nh, &nh_flags) < 0) goto nla_put_failure;
rtm->rtm_flags |= nh_flags; @@@ -6092,8 -6113,9 +6117,8 @@@ static int rt6_stats_seq_show(struct se
#ifdef CONFIG_SYSCTL
-static -int ipv6_sysctl_rtcache_flush(struct ctl_table *ctl, int write, - void __user *buffer, size_t *lenp, loff_t *ppos) +static int ipv6_sysctl_rtcache_flush(struct ctl_table *ctl, int write, + void *buffer, size_t *lenp, loff_t *ppos) { struct net *net; int delay; diff --combined net/mptcp/subflow.c index 87c094702d63,67a4e35d4838..009d5c478062 --- a/net/mptcp/subflow.c +++ b/net/mptcp/subflow.c @@@ -124,12 -124,11 +124,11 @@@ static void subflow_init_req(struct req { struct mptcp_subflow_context *listener = mptcp_subflow_ctx(sk_listener); struct mptcp_subflow_request_sock *subflow_req = mptcp_subflow_rsk(req); - struct tcp_options_received rx_opt; + struct mptcp_options_received mp_opt;
pr_debug("subflow_req=%p, listener=%p", subflow_req, listener);
- memset(&rx_opt.mptcp, 0, sizeof(rx_opt.mptcp)); - mptcp_get_options(skb, &rx_opt); + mptcp_get_options(skb, &mp_opt);
subflow_req->mp_capable = 0; subflow_req->mp_join = 0; @@@ -142,16 -141,16 +141,16 @@@ return; #endif
- if (rx_opt.mptcp.mp_capable) { + if (mp_opt.mp_capable) { SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_MPCAPABLEPASSIVE);
- if (rx_opt.mptcp.mp_join) + if (mp_opt.mp_join) return; - } else if (rx_opt.mptcp.mp_join) { + } else if (mp_opt.mp_join) { SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_JOINSYNRX); }
- if (rx_opt.mptcp.mp_capable && listener->request_mptcp) { + if (mp_opt.mp_capable && listener->request_mptcp) { int err;
err = mptcp_token_new_request(req); @@@ -159,13 -158,13 +158,13 @@@ subflow_req->mp_capable = 1;
subflow_req->ssn_offset = TCP_SKB_CB(skb)->seq; - } else if (rx_opt.mptcp.mp_join && listener->request_mptcp) { + } else if (mp_opt.mp_join && listener->request_mptcp) { subflow_req->ssn_offset = TCP_SKB_CB(skb)->seq; subflow_req->mp_join = 1; - subflow_req->backup = rx_opt.mptcp.backup; - subflow_req->remote_id = rx_opt.mptcp.join_id; - subflow_req->token = rx_opt.mptcp.token; - subflow_req->remote_nonce = rx_opt.mptcp.nonce; + subflow_req->backup = mp_opt.backup; + subflow_req->remote_id = mp_opt.join_id; + subflow_req->token = mp_opt.token; + subflow_req->remote_nonce = mp_opt.nonce; pr_debug("token=%u, remote_nonce=%u", subflow_req->token, subflow_req->remote_nonce); if (!subflow_token_join_request(req, skb)) { @@@ -221,23 -220,47 +220,47 @@@ static bool subflow_thmac_valid(struct static void subflow_finish_connect(struct sock *sk, const struct sk_buff *skb) { struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk); + struct mptcp_options_received mp_opt; struct sock *parent = subflow->conn; + struct tcp_sock *tp = tcp_sk(sk);
subflow->icsk_af_ops->sk_rx_dst_set(sk, skb);
- if (inet_sk_state_load(parent) != TCP_ESTABLISHED) { + if (inet_sk_state_load(parent) == TCP_SYN_SENT) { inet_sk_state_store(parent, TCP_ESTABLISHED); parent->sk_state_change(parent); }
- if (subflow->conn_finished || !tcp_sk(sk)->is_mptcp) + /* be sure no special action on any packet other than syn-ack */ + if (subflow->conn_finished) + return; + + subflow->conn_finished = 1; + + mptcp_get_options(skb, &mp_opt); + if (subflow->request_mptcp && mp_opt.mp_capable) { + subflow->mp_capable = 1; + subflow->can_ack = 1; + subflow->remote_key = mp_opt.sndr_key; + pr_debug("subflow=%p, remote_key=%llu", subflow, + subflow->remote_key); + } else if (subflow->request_join && mp_opt.mp_join) { + subflow->mp_join = 1; + subflow->thmac = mp_opt.thmac; + subflow->remote_nonce = mp_opt.nonce; + pr_debug("subflow=%p, thmac=%llu, remote_nonce=%u", subflow, + subflow->thmac, subflow->remote_nonce); + } else if (subflow->request_mptcp) { + tp->is_mptcp = 0; + } + + if (!tp->is_mptcp) return;
if (subflow->mp_capable) { pr_debug("subflow=%p, remote_key=%llu", mptcp_subflow_ctx(sk), subflow->remote_key); mptcp_finish_connect(sk); - subflow->conn_finished = 1;
if (skb) { pr_debug("synack seq=%u", TCP_SKB_CB(skb)->seq); @@@ -264,7 -287,6 +287,6 @@@ if (!mptcp_finish_join(sk)) goto do_reset;
- subflow->conn_finished = 1; MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_JOINSYNACKRX); } else { do_reset: @@@ -322,7 -344,7 +344,7 @@@ drop
/* validate hmac received in third ACK */ static bool subflow_hmac_valid(const struct request_sock *req, - const struct tcp_options_received *rx_opt) + const struct mptcp_options_received *mp_opt) { const struct mptcp_subflow_request_sock *subflow_req; u8 hmac[MPTCPOPT_HMAC_LEN]; @@@ -339,7 -361,7 +361,7 @@@ subflow_req->local_nonce, hmac);
ret = true; - if (crypto_memneq(hmac, rx_opt->mptcp.hmac, sizeof(hmac))) + if (crypto_memneq(hmac, mp_opt->hmac, sizeof(hmac))) ret = false;
sock_put((struct sock *)msk); @@@ -395,7 -417,7 +417,7 @@@ static struct sock *subflow_syn_recv_so { struct mptcp_subflow_context *listener = mptcp_subflow_ctx(sk); struct mptcp_subflow_request_sock *subflow_req; - struct tcp_options_received opt_rx; + struct mptcp_options_received mp_opt; bool fallback_is_fatal = false; struct sock *new_msk = NULL; bool fallback = false; @@@ -403,7 -425,10 +425,10 @@@
pr_debug("listener=%p, req=%p, conn=%p", listener, req, listener->conn);
- opt_rx.mptcp.mp_capable = 0; + /* we need later a valid 'mp_capable' value even when options are not + * parsed + */ + mp_opt.mp_capable = 0; if (tcp_rsk(req)->is_mptcp == 0) goto create_child;
@@@ -418,22 -443,21 +443,21 @@@ goto create_msk; }
- mptcp_get_options(skb, &opt_rx); - if (!opt_rx.mptcp.mp_capable) { + mptcp_get_options(skb, &mp_opt); + if (!mp_opt.mp_capable) { fallback = true; goto create_child; }
create_msk: - new_msk = mptcp_sk_clone(listener->conn, &opt_rx, req); + new_msk = mptcp_sk_clone(listener->conn, &mp_opt, req); if (!new_msk) fallback = true; } else if (subflow_req->mp_join) { fallback_is_fatal = true; - opt_rx.mptcp.mp_join = 0; - mptcp_get_options(skb, &opt_rx); - if (!opt_rx.mptcp.mp_join || - !subflow_hmac_valid(req, &opt_rx)) { + mptcp_get_options(skb, &mp_opt); + if (!mp_opt.mp_join || + !subflow_hmac_valid(req, &mp_opt)) { SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_JOINACKMAC); return NULL; } @@@ -473,9 -497,9 +497,9 @@@ create_child /* with OoO packets we can reach here without ingress * mpc option */ - ctx->remote_key = opt_rx.mptcp.sndr_key; - ctx->fully_established = opt_rx.mptcp.mp_capable; - ctx->can_ack = opt_rx.mptcp.mp_capable; + ctx->remote_key = mp_opt.sndr_key; + ctx->fully_established = mp_opt.mp_capable; + ctx->can_ack = mp_opt.mp_capable; } else if (ctx->mp_join) { struct mptcp_sock *owner;
@@@ -499,7 -523,7 +523,7 @@@ out /* check for expected invariant - should never trigger, just help * catching eariler subtle bugs */ - WARN_ON_ONCE(*own_req && child && tcp_sk(child)->is_mptcp && + WARN_ON_ONCE(child && *own_req && tcp_sk(child)->is_mptcp && (!mptcp_subflow_ctx(child) || !mptcp_subflow_ctx(child)->conn)); return child; @@@ -821,24 -845,6 +845,24 @@@ bool mptcp_subflow_data_available(struc return subflow->data_avail; }
+/* If ssk has an mptcp parent socket, use the mptcp rcvbuf occupancy, + * not the ssk one. + * + * In mptcp, rwin is about the mptcp-level connection data. + * + * Data that is still on the ssk rx queue can thus be ignored, + * as far as mptcp peer is concerened that data is still inflight. + * DSS ACK is updated when skb is moved to the mptcp rx queue. + */ +void mptcp_space(const struct sock *ssk, int *space, int *full_space) +{ + const struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk); + const struct sock *sk = subflow->conn; + + *space = tcp_space(sk); + *full_space = tcp_full_space(sk); +} + static void subflow_data_ready(struct sock *sk) { struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk); diff --combined net/sched/cls_api.c index 7e85c91d0752,0a7ecc292bd3..299b963c796e --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c @@@ -39,7 -39,6 +39,7 @@@ #include <net/tc_act/tc_skbedit.h> #include <net/tc_act/tc_ct.h> #include <net/tc_act/tc_mpls.h> +#include <net/tc_act/tc_gate.h> #include <net/flow_offload.h>
extern const struct nla_policy rtm_tca_policy[TCA_MAX + 1]; @@@ -736,11 -735,8 +736,11 @@@ static int tcf_block_offload_cmd(struc INIT_LIST_HEAD(&bo.cb_list);
err = dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_BLOCK, &bo); - if (err < 0) + if (err < 0) { + if (err != -EOPNOTSUPP) + NL_SET_ERR_MSG(extack, "Driver ndo_setup_tc failed"); return err; + }
return tcf_block_setup(block, &bo); } @@@ -2074,6 -2070,7 +2074,7 @@@ replay err = PTR_ERR(block); goto errout; } + block->classid = parent;
chain_index = tca[TCA_CHAIN] ? nla_get_u32(tca[TCA_CHAIN]) : 0; if (chain_index > TC_ACT_EXT_VAL_MASK) { @@@ -2616,12 -2613,10 +2617,10 @@@ static int tc_dump_tfilter(struct sk_bu return skb->len;
parent = tcm->tcm_parent; - if (!parent) { + if (!parent) q = dev->qdisc; - parent = q->handle; - } else { + else q = qdisc_lookup(dev, TC_H_MAJ(tcm->tcm_parent)); - } if (!q) goto out; cops = q->ops->cl_ops; @@@ -2637,6 -2632,7 +2636,7 @@@ block = cops->tcf_block(q, cl, NULL); if (!block) goto out; + parent = block->classid; if (tcf_block_shared(block)) q = NULL; } @@@ -3527,27 -3523,16 +3527,37 @@@ static void tcf_sample_get_group(struc #endif }
+static void tcf_gate_entry_destructor(void *priv) +{ + struct action_gate_entry *oe = priv; + + kfree(oe); +} + +static int tcf_gate_get_entries(struct flow_action_entry *entry, + const struct tc_action *act) +{ + entry->gate.entries = tcf_gate_get_list(act); + + if (!entry->gate.entries) + return -EINVAL; + + entry->destructor = tcf_gate_entry_destructor; + entry->destructor_priv = entry->gate.entries; + + return 0; +} + + static enum flow_action_hw_stats tc_act_hw_stats(u8 hw_stats) + { + if (WARN_ON_ONCE(hw_stats > TCA_ACT_HW_STATS_ANY)) + return FLOW_ACTION_HW_STATS_DONT_CARE; + else if (!hw_stats) + return FLOW_ACTION_HW_STATS_DISABLED; + + return hw_stats; + } + int tc_setup_flow_action(struct flow_action *flow_action, const struct tcf_exts *exts) { @@@ -3571,7 -3556,7 +3581,7 @@@ if (err) goto err_out_locked;
- entry->hw_stats = act->hw_stats; + entry->hw_stats = tc_act_hw_stats(act->hw_stats);
if (is_tcf_gact_ok(act)) { entry->id = FLOW_ACTION_ACCEPT; @@@ -3639,7 -3624,7 +3649,7 @@@ entry->mangle.mask = tcf_pedit_mask(act, k); entry->mangle.val = tcf_pedit_val(act, k); entry->mangle.offset = tcf_pedit_offset(act, k); - entry->hw_stats = act->hw_stats; + entry->hw_stats = tc_act_hw_stats(act->hw_stats); entry = &flow_action->entries[++j]; } } else if (is_tcf_csum(act)) { @@@ -3694,17 -3679,6 +3704,17 @@@ } else if (is_tcf_skbedit_priority(act)) { entry->id = FLOW_ACTION_PRIORITY; entry->priority = tcf_skbedit_priority(act); + } else if (is_tcf_gate(act)) { + entry->id = FLOW_ACTION_GATE; + entry->gate.index = tcf_gate_index(act); + entry->gate.prio = tcf_gate_prio(act); + entry->gate.basetime = tcf_gate_basetime(act); + entry->gate.cycletime = tcf_gate_cycletime(act); + entry->gate.cycletimeext = tcf_gate_cycletimeext(act); + entry->gate.num_entries = tcf_gate_num_entries(act); + err = tcf_gate_get_entries(entry, act); + if (err) + goto err_out; } else { err = -EOPNOTSUPP; goto err_out_locked; diff --combined net/sched/sch_choke.c index 59ff466ec7cb,1bcf8fbfd40e..bd618b00d319 --- a/net/sched/sch_choke.c +++ b/net/sched/sch_choke.c @@@ -131,6 -131,7 +131,6 @@@ static void choke_drop_by_idx(struct Qd }
struct choke_skb_cb { - u16 classid; u8 keys_valid; struct flow_keys_digest keys; }; @@@ -141,6 -142,11 +141,6 @@@ static inline struct choke_skb_cb *chok return (struct choke_skb_cb *)qdisc_skb_cb(skb)->data; }
-static inline void choke_set_classid(struct sk_buff *skb, u16 classid) -{ - choke_skb_cb(skb)->classid = classid; -} - /* * Compare flow of two packets * Returns true only if source and destination address and port match. @@@ -317,7 -323,8 +317,8 @@@ static void choke_reset(struct Qdisc *s
sch->q.qlen = 0; sch->qstats.backlog = 0; - memset(q->tab, 0, (q->tab_mask + 1) * sizeof(struct sk_buff *)); + if (q->tab) + memset(q->tab, 0, (q->tab_mask + 1) * sizeof(struct sk_buff *)); q->head = q->tail = 0; red_restart(&q->vars); }