The following commit has been merged in the master branch: commit b19580323685a80be54f2d0bacbb4c19e993e6b8 Merge: 773538e428c5ac1cbbdffdb31b0b097557b44db1 b217566a525ff24334d17635a865f44b68c2c583 Author: Stephen Rothwell sfr@canb.auug.org.au Date: Wed Jun 14 10:24:21 2017 +1000
Merge remote-tracking branch 'net-next/master'
diff --combined MAINTAINERS index 6e35d4308837,f4e682c67475..dce53cfb0717 --- a/MAINTAINERS +++ b/MAINTAINERS @@@ -155,7 -155,7 +155,7 @@@ S: Maintaine F: drivers/scsi/53c700*
6LOWPAN GENERIC (BTLE/IEEE 802.15.4) - M: Alexander Aring aar@pengutronix.de + M: Alexander Aring alex.aring@gmail.com M: Jukka Rissanen jukka.rissanen@linux.intel.com L: linux-bluetooth@vger.kernel.org L: linux-wpan@vger.kernel.org @@@ -478,7 -478,7 +478,7 @@@ L: linux-hwmon@vger.kernel.or S: Maintained F: Documentation/hwmon/ads1015 F: drivers/hwmon/ads1015.c -F: include/linux/i2c/ads1015.h +F: include/linux/platform_data/ads1015.h
ADT746X FAN DRIVER M: Colin Leroy colin@colino.net @@@ -1172,7 -1172,7 +1172,7 @@@ N: clps711
ARM/CIRRUS LOGIC EP93XX ARM ARCHITECTURE M: Hartley Sweeten hsweeten@visionengravers.com -M: Ryan Mallon rmallon@gmail.com +M: Alexander Sverdlin alexander.sverdlin@gmail.com L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained F: arch/arm/mach-ep93xx/ @@@ -1489,15 -1489,13 +1489,15 @@@ M: Gregory Clement <gregory.clement@fre M: Sebastian Hesselbarth sebastian.hesselbarth@gmail.com L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained -F: arch/arm/mach-mvebu/ -F: drivers/rtc/rtc-armada38x.c F: arch/arm/boot/dts/armada* F: arch/arm/boot/dts/kirkwood* +F: arch/arm/configs/mvebu_*_defconfig +F: arch/arm/mach-mvebu/ F: arch/arm64/boot/dts/marvell/armada* F: drivers/cpufreq/mvebu-cpufreq.c -F: arch/arm/configs/mvebu_*_defconfig +F: drivers/irqchip/irq-armada-370-xp.c +F: drivers/irqchip/irq-mvebu-* +F: drivers/rtc/rtc-armada38x.c
ARM/Marvell Berlin SoC support M: Jisheng Zhang jszhang@marvell.com @@@ -1679,13 -1677,6 +1679,13 @@@ M: Lennert Buytenhek <kernel@wantstofly L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained
+ARM/REALTEK ARCHITECTURE +M: Andreas Färber afaerber@suse.de +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +S: Maintained +F: arch/arm64/boot/dts/realtek/ +F: Documentation/devicetree/bindings/arm/realtek.txt + ARM/RENESAS ARM64 ARCHITECTURE M: Simon Horman horms@verge.net.au M: Magnus Damm magnus.damm@gmail.com @@@ -1730,6 -1721,7 +1730,6 @@@ N: rockchi ARM/SAMSUNG EXYNOS ARM ARCHITECTURES M: Kukjin Kim kgene@kernel.org M: Krzysztof Kozlowski krzk@kernel.org -R: Javier Martinez Canillas javier@osg.samsung.com L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers) Q: https://patchwork.kernel.org/project/linux-samsung-soc/list/ @@@ -1837,6 -1829,7 +1837,6 @@@ F: drivers/edac/altera_edac ARM/STI ARCHITECTURE M: Patrice Chotard patrice.chotard@st.com L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) -L: kernel@stlinux.com W: http://www.stlinux.com S: Maintained F: arch/arm/mach-sti/ @@@ -2692,6 -2685,7 +2692,6 @@@ N: kon F: arch/arm/mach-bcm/
BROADCOM BCM2835 ARM ARCHITECTURE -M: Lee Jones lee@kernel.org M: Eric Anholt eric@anholt.net M: Stefan Wahren stefan.wahren@i2se.com L: linux-rpi-kernel@lists.infradead.org (moderated for non-subscribers) @@@ -3592,6 -3586,7 +3592,6 @@@ T: git git://git.kernel.org/pub/scm/lin S: Maintained F: Documentation/crypto/ F: Documentation/devicetree/bindings/crypto/ -F: Documentation/DocBook/crypto-API.tmpl F: arch/*/crypto/ F: crypto/ F: drivers/crypto/ @@@ -5287,7 -5282,7 +5287,7 @@@ S: Maintaine F: drivers/video/fbdev/fsl-diu-fb.*
FREESCALE DMA DRIVER -M: Li Yang leoli@freescale.com +M: Li Yang leoyang.li@nxp.com M: Zhang Wei zw@zh-kernel.org L: linuxppc-dev@lists.ozlabs.org S: Maintained @@@ -5352,11 -5347,11 +5352,11 @@@ S: Maintaine F: drivers/net/ethernet/freescale/dpaa
FREESCALE SOC DRIVERS -M: Scott Wood oss@buserror.net +M: Li Yang leoyang.li@nxp.com L: linuxppc-dev@lists.ozlabs.org L: linux-arm-kernel@lists.infradead.org S: Maintained -F: Documentation/devicetree/bindings/powerpc/fsl/ +F: Documentation/devicetree/bindings/soc/fsl/ F: drivers/soc/fsl/ F: include/linux/fsl/
@@@ -5369,14 -5364,14 +5369,14 @@@ F: include/soc/fsl/*qe*. F: include/soc/fsl/*ucc*.h
FREESCALE USB PERIPHERAL DRIVERS -M: Li Yang leoli@freescale.com +M: Li Yang leoyang.li@nxp.com L: linux-usb@vger.kernel.org L: linuxppc-dev@lists.ozlabs.org S: Maintained F: drivers/usb/gadget/udc/fsl*
FREESCALE QUICC ENGINE UCC ETHERNET DRIVER -M: Li Yang leoli@freescale.com +M: Li Yang leoyang.li@nxp.com L: netdev@vger.kernel.org L: linuxppc-dev@lists.ozlabs.org S: Maintained @@@ -5627,7 -5622,7 +5627,7 @@@ F: scripts/get_maintainer.p
GENWQE (IBM Generic Workqueue Card) M: Frank Haverkamp haver@linux.vnet.ibm.com -M: Gabriel Krisman Bertazi krisman@linux.vnet.ibm.com +M: Guilherme G. Piccoli gpiccoli@linux.vnet.ibm.com S: Supported F: drivers/misc/genwqe/
@@@ -5672,6 -5667,7 +5672,6 @@@ F: tools/testing/selftests/gpio
GPIO SUBSYSTEM M: Linus Walleij linus.walleij@linaro.org -M: Alexandre Courbot gnurou@gmail.com L: linux-gpio@vger.kernel.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio.git S: Maintained @@@ -6277,7 -6273,6 +6277,7 @@@ M: Mika Westerberg <mika.westerberg@lin L: linux-i2c@vger.kernel.org L: linux-acpi@vger.kernel.org S: Maintained +F: drivers/i2c/i2c-core-acpi.c
I2C-TAOS-EVM DRIVER M: Jean Delvare jdelvare@suse.com @@@ -6432,7 -6427,7 +6432,7 @@@ F: Documentation/cdrom/ide-c F: drivers/ide/ide-cd*
IEEE 802.15.4 SUBSYSTEM - M: Alexander Aring aar@pengutronix.de + M: Alexander Aring alex.aring@gmail.com M: Stefan Schmidt stefan@osg.samsung.com L: linux-wpan@vger.kernel.org W: http://wpan.cakelab.org/ @@@ -6743,6 -6738,7 +6743,7 @@@ F: Documentation/networking/i40e.tx F: Documentation/networking/i40evf.txt F: drivers/net/ethernet/intel/ F: drivers/net/ethernet/intel/*/ + F: include/linux/avf/virtchnl.h
INTEL RDMA RNIC DRIVER M: Faisal Latif faisal.latif@intel.com @@@ -7354,7 -7350,7 +7355,7 @@@ KEYS/KEYRINGS M: David Howells dhowells@redhat.com L: keyrings@vger.kernel.org S: Maintained -F: Documentation/security/keys.txt +F: Documentation/security/keys/core.rst F: include/linux/key.h F: include/linux/key-type.h F: include/linux/keyctl.h @@@ -7368,7 -7364,7 +7369,7 @@@ M: Mimi Zohar <zohar@linux.vnet.ibm.com L: linux-security-module@vger.kernel.org L: keyrings@vger.kernel.org S: Supported -F: Documentation/security/keys-trusted-encrypted.txt +F: Documentation/security/keys/trusted-encrypted.rst F: include/keys/trusted-type.h F: security/keys/trusted.c F: security/keys/trusted.h @@@ -7379,7 -7375,7 +7380,7 @@@ M: David Safford <safford@us.ibm.com L: linux-security-module@vger.kernel.org L: keyrings@vger.kernel.org S: Supported -F: Documentation/security/keys-trusted-encrypted.txt +F: Documentation/security/keys/trusted-encrypted.rst F: include/keys/encrypted-type.h F: security/keys/encrypted-keys/
@@@ -7389,7 -7385,7 +7390,7 @@@ W: http://kgdb.wiki.kernel.org L: kgdb-bugreport@lists.sourceforge.net T: git git://git.kernel.org/pub/scm/linux/kernel/git/jwessel/kgdb.git S: Maintained -F: Documentation/DocBook/kgdb.tmpl +F: Documentation/dev-tools/kgdb.rst F: drivers/misc/kgdbts.c F: drivers/tty/serial/kgdboc.c F: include/linux/kdb.h @@@ -7690,7 -7686,6 +7691,7 @@@ T: git git://git.kernel.org/pub/scm/lin S: Maintained F: arch/powerpc/platforms/83xx/ F: arch/powerpc/platforms/85xx/ +F: Documentation/devicetree/bindings/powerpc/fsl/
LINUX FOR POWERPC PA SEMI PWRFICIENT L: linuxppc-dev@lists.ozlabs.org @@@ -7713,7 -7708,7 +7714,7 @@@ F: drivers/platform/x86/hp_accel.
LIVE PATCHING M: Josh Poimboeuf jpoimboe@redhat.com -M: Jessica Yu jeyu@redhat.com +M: Jessica Yu jeyu@kernel.org M: Jiri Kosina jikos@kernel.org M: Miroslav Benes mbenes@suse.cz R: Petr Mladek pmladek@suse.com @@@ -7984,6 -7979,12 +7985,12 @@@ S: Maintaine F: drivers/net/ethernet/marvell/mv643xx_eth.* F: include/linux/mv643xx.h
+ MARVELL MV88X3310 PHY DRIVER + M: Russell King rmk@armlinux.org.uk + L: netdev@vger.kernel.org + S: Maintained + F: drivers/net/phy/marvell10g.c + MARVELL MVNETA ETHERNET DRIVER M: Thomas Petazzoni thomas.petazzoni@free-electrons.com L: netdev@vger.kernel.org @@@ -8317,6 -8318,16 +8324,16 @@@ W: http://www.mellanox.co Q: http://patchwork.ozlabs.org/project/netdev/list/ F: drivers/net/ethernet/mellanox/mlx5/core/en_*
+ MELLANOX ETHERNET INNOVA DRIVER + M: Ilan Tayari ilant@mellanox.com + R: Boris Pismenny borisp@mellanox.com + L: netdev@vger.kernel.org + S: Supported + W: http://www.mellanox.com + Q: http://patchwork.ozlabs.org/project/netdev/list/ + F: drivers/net/ethernet/mellanox/mlx5/core/fpga/* + F: include/linux/mlx5/mlx5_ifc_fpga.h + MELLANOX ETHERNET SWITCH DRIVERS M: Jiri Pirko jiri@mellanox.com M: Ido Schimmel idosch@mellanox.com @@@ -8326,6 -8337,14 +8343,14 @@@ W: http://www.mellanox.co Q: http://patchwork.ozlabs.org/project/netdev/list/ F: drivers/net/ethernet/mellanox/mlxsw/
+ MELLANOX FIRMWARE FLASH LIBRARY (mlxfw) + M: Yotam Gigi yotamg@mellanox.com + L: netdev@vger.kernel.org + S: Supported + W: http://www.mellanox.com + Q: http://patchwork.ozlabs.org/project/netdev/list/ + F: drivers/net/ethernet/mellanox/mlxfw/ + MELLANOX MLXCPLD I2C AND MUX DRIVER M: Vadim Pasternak vadimp@mellanox.com M: Michael Shych michaelsh@mellanox.com @@@ -8467,6 -8486,16 +8492,16 @@@ F: drivers/media/platform/atmel/atmel-i F: drivers/media/platform/atmel/atmel-isc-regs.h F: devicetree/bindings/media/atmel-isc.txt
+ MICROCHIP KSZ SERIES ETHERNET SWITCH DRIVER + M: Woojung Huh Woojung.Huh@microchip.com + M: Microchip Linux Driver Support UNGLinuxDriver@microchip.com + L: netdev@vger.kernel.org + S: Maintained + F: net/dsa/tag_ksz.c + F: drivers/net/dsa/microchip/* + F: include/linux/platform_data/microchip-ksz.h + F: Documentation/devicetree/bindings/net/dsa/ksz.txt + MICROCHIP USB251XB DRIVER M: Richard Leitner richard.leitner@skidata.com L: linux-usb@vger.kernel.org @@@ -8594,7 -8623,7 +8629,7 @@@ S: Maintaine F: drivers/media/dvb-frontends/mn88473*
MODULE SUPPORT -M: Jessica Yu jeyu@redhat.com +M: Jessica Yu jeyu@kernel.org M: Rusty Russell rusty@rustcorp.com.au T: git git://git.kernel.org/pub/scm/linux/kernel/git/jeyu/linux.git modules-next S: Maintained @@@ -10161,7 -10190,7 +10196,7 @@@ T: git git://git.kernel.org/pub/scm/lin S: Maintained F: Documentation/hwmon/pmbus F: drivers/hwmon/pmbus/ -F: include/linux/i2c/pmbus.h +F: include/linux/pmbus.h
PMC SIERRA MaxRAID DRIVER L: linux-scsi@vger.kernel.org @@@ -10605,6 -10634,14 +10640,14 @@@ L: qemu-devel@nongnu.or S: Maintained F: drivers/firmware/qemu_fw_cfg.c
+ QUANTENNA QTNFMAC WIRELESS DRIVER + M: Igor Mitsyanko imitsyanko@quantenna.com + M: Avinash Patil avinashp@quantenna.com + M: Sergey Matyukevich smatyukevich@quantenna.com + L: linux-wireless@vger.kernel.org + S: Maintained + F: drivers/net/wireless/quantenna + RADOS BLOCK DEVICE (RBD) M: Ilya Dryomov idryomov@gmail.com M: Sage Weil sage@redhat.com @@@ -10999,7 -11036,7 +11042,7 @@@ S: Supporte F: arch/s390/ F: drivers/s390/ F: Documentation/s390/ -F: Documentation/DocBook/s390* +F: Documentation/driver-api/s390-drivers.rst
S390 COMMON I/O LAYER M: Sebastian Ott sebott@linux.vnet.ibm.com @@@ -11274,6 -11311,7 +11317,6 @@@ F: drivers/media/rc/serial_ir.
STI CEC DRIVER M: Benjamin Gaignard benjamin.gaignard@linaro.org -L: kernel@stlinux.com S: Maintained F: drivers/staging/media/st-cec/ F: Documentation/devicetree/bindings/media/stih-cec.txt @@@ -11500,7 -11538,6 +11543,7 @@@ F: kernel/seccomp. F: include/uapi/linux/seccomp.h F: include/linux/seccomp.h F: tools/testing/selftests/seccomp/* +F: Documentation/userspace-api/seccomp_filter.rst K: \bsecure_computing K: \bTIF_SECCOMP\b
@@@ -11559,7 -11596,6 +11602,7 @@@ S: Supporte F: include/linux/selinux* F: security/selinux/ F: scripts/selinux/ +F: Documentation/admin-guide/LSM/SELinux.rst
APPARMOR SECURITY MODULE M: John Johansen john.johansen@canonical.com @@@ -11568,21 -11604,18 +11611,21 @@@ W: apparmor.wiki.kernel.or T: git git://git.kernel.org/pub/scm/linux/kernel/git/jj/apparmor-dev.git S: Supported F: security/apparmor/ +F: Documentation/admin-guide/LSM/apparmor.rst
LOADPIN SECURITY MODULE M: Kees Cook keescook@chromium.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git lsm/loadpin S: Supported F: security/loadpin/ +F: Documentation/admin-guide/LSM/LoadPin.rst
YAMA SECURITY MODULE M: Kees Cook keescook@chromium.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git yama/tip S: Supported F: security/yama/ +F: Documentation/admin-guide/LSM/Yama.rst
SENSABLE PHANTOM M: Jiri Slaby jirislaby@gmail.com @@@ -11788,7 -11821,6 +11831,7 @@@ T: git git://git.kernel.org/pub/scm/lin S: Supported F: arch/arm/mach-davinci/ F: drivers/i2c/busses/i2c-davinci.c +F: arch/arm/boot/dts/da850*
TI DAVINCI SERIES MEDIA DRIVER M: "Lad, Prabhakar" prabhakar.csengg@gmail.com @@@ -11885,7 -11917,7 +11928,7 @@@ L: linux-security-module@vger.kernel.or W: http://schaufler-ca.com T: git git://github.com/cschaufler/smack-next S: Maintained -F: Documentation/security/Smack.txt +F: Documentation/admin-guide/LSM/Smack.rst F: security/smack/
DRIVERS FOR ADAPTIVE VOLTAGE SCALING (AVS) @@@ -12644,8 -12676,6 +12687,8 @@@ F: include/linux/soc/ti/ti_sci_protocol F: Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt F: include/dt-bindings/genpd/k2g.h F: drivers/soc/ti/ti_sci_pm_domains.c +F: Documentation/devicetree/bindings/reset/ti,sci-reset.txt +F: drivers/reset/reset-ti-sci.c
THANKO'S RAREMONO AM/FM/SW RADIO RECEIVER USB DRIVER M: Hans Verkuil hverkuil@xs4all.nl @@@ -13874,7 -13904,7 +13917,7 @@@ S: Odd fixe F: drivers/net/wireless/wl3501*
WOLFSON MICROELECTRONICS DRIVERS -L: patches@opensource.wolfsonmicro.com +L: patches@opensource.cirrus.com T: git https://github.com/CirrusLogic/linux-drivers.git W: https://github.com/CirrusLogic/linux-drivers/wiki S: Supported diff --combined arch/arm/configs/multi_v7_defconfig index 705d908e004a,6da6af8881f7..60c0c01002c2 --- a/arch/arm/configs/multi_v7_defconfig +++ b/arch/arm/configs/multi_v7_defconfig @@@ -257,6 -257,7 +257,7 @@@ CONFIG_SMSC911X= CONFIG_STMMAC_ETH=y CONFIG_STMMAC_PLATFORM=y CONFIG_DWMAC_DWC_QOS_ETH=y + CONFIG_DWMAC_SUN8I=y CONFIG_TI_CPSW=y CONFIG_XILINX_EMACLITE=y CONFIG_AT803X_PHY=y @@@ -935,13 -936,7 +936,13 @@@ CONFIG_CPUFREQ_DT= CONFIG_KEYSTONE_IRQ=y CONFIG_HW_RANDOM=y CONFIG_HW_RANDOM_ST=y +CONFIG_CRYPTO_USER=m +CONFIG_CRYPTO_USER_API_HASH=m +CONFIG_CRYPTO_USER_API_SKCIPHER=m +CONFIG_CRYPTO_USER_API_RNG=m +CONFIG_CRYPTO_USER_API_AEAD=m CONFIG_CRYPTO_DEV_MARVELL_CESA=m +CONFIG_CRYPTO_DEV_EXYNOS_RNG=m CONFIG_CRYPTO_DEV_S5P=m CONFIG_CRYPTO_DEV_SUN4I_SS=m CONFIG_CRYPTO_DEV_ROCKCHIP=m diff --combined arch/arm/configs/sunxi_defconfig index 0ec1d1ec130f,504e02238031..44198e79642e --- a/arch/arm/configs/sunxi_defconfig +++ b/arch/arm/configs/sunxi_defconfig @@@ -27,6 -27,7 +27,6 @@@ CONFIG_IP_PNP_BOOTP= # CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set # CONFIG_INET_DIAG is not set # CONFIG_IPV6 is not set CONFIG_CAN=y @@@ -39,6 -40,7 +39,7 @@@ CONFIG_ATA= CONFIG_AHCI_SUNXI=y CONFIG_NETDEVICES=y CONFIG_SUN4I_EMAC=y + CONFIG_DWMAC_SUN8I=y # CONFIG_NET_VENDOR_ARC is not set # CONFIG_NET_CADENCE is not set # CONFIG_NET_VENDOR_BROADCOM is not set diff --combined arch/arm64/configs/defconfig index 2f46ba8f7129,d673c7096b90..5808bba9bae3 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@@ -56,6 -56,7 +56,6 @@@ CONFIG_ARCH_THUNDER= CONFIG_ARCH_THUNDER2=y CONFIG_ARCH_UNIPHIER=y CONFIG_ARCH_VEXPRESS=y -CONFIG_ARCH_VULCAN=y CONFIG_ARCH_XGENE=y CONFIG_ARCH_ZX=y CONFIG_ARCH_ZYNQMP=y @@@ -67,7 -68,6 +67,7 @@@ CONFIG_PCIE_QCOM= CONFIG_PCIE_ARMADA_8K=y CONFIG_PCI_AARDVARK=y CONFIG_PCIE_RCAR=y +CONFIG_PCIE_ROCKCHIP=m CONFIG_PCI_HOST_GENERIC=y CONFIG_PCI_XGENE=y CONFIG_ARM64_VA_BITS_48=y @@@ -190,6 -190,7 +190,7 @@@ CONFIG_RAVB= CONFIG_SMC91X=y CONFIG_SMSC911X=y CONFIG_STMMAC_ETH=m + CONFIG_DWMAC_SUN8I=m CONFIG_MDIO_BUS_MUX_MMIOREG=y CONFIG_MESON_GXL_PHY=m CONFIG_MICREL_PHY=y @@@ -208,8 -209,6 +209,8 @@@ CONFIG_BRCMFMAC= CONFIG_WL18XX=m CONFIG_WLCORE_SDIO=m CONFIG_INPUT_EVDEV=y +CONFIG_KEYBOARD_ADC=m +CONFIG_KEYBOARD_CROS_EC=y CONFIG_KEYBOARD_GPIO=y CONFIG_INPUT_MISC=y CONFIG_INPUT_PM8941_PWRKEY=y @@@ -265,7 -264,6 +266,7 @@@ CONFIG_SPI_MESON_SPIFC= CONFIG_SPI_ORION=y CONFIG_SPI_PL022=y CONFIG_SPI_QUP=y +CONFIG_SPI_ROCKCHIP=y CONFIG_SPI_S3C64XX=y CONFIG_SPI_SPIDEV=m CONFIG_SPMI=y @@@ -295,7 -293,6 +296,7 @@@ CONFIG_THERMAL_GOV_POWER_ALLOCATOR= CONFIG_CPU_THERMAL=y CONFIG_THERMAL_EMULATION=y CONFIG_EXYNOS_THERMAL=y +CONFIG_ROCKCHIP_THERMAL=m CONFIG_WATCHDOG=y CONFIG_S3C2410_WATCHDOG=y CONFIG_MESON_GXBB_WATCHDOG=m @@@ -304,14 -301,12 +305,14 @@@ CONFIG_RENESAS_WDT= CONFIG_BCM2835_WDT=y CONFIG_MFD_CROS_EC=y CONFIG_MFD_CROS_EC_I2C=y +CONFIG_MFD_CROS_EC_SPI=y CONFIG_MFD_EXYNOS_LPASS=m CONFIG_MFD_HI655X_PMIC=y CONFIG_MFD_MAX77620=y CONFIG_MFD_SPMI_PMIC=y CONFIG_MFD_RK808=y CONFIG_MFD_SEC_CORE=y +CONFIG_REGULATOR_FAN53555=y CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_REGULATOR_GPIO=y CONFIG_REGULATOR_HI655X=y @@@ -326,11 -321,6 +327,11 @@@ CONFIG_MEDIA_CAMERA_SUPPORT= CONFIG_MEDIA_ANALOG_TV_SUPPORT=y CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y CONFIG_MEDIA_CONTROLLER=y +CONFIG_MEDIA_RC_SUPPORT=y +CONFIG_RC_CORE=m +CONFIG_RC_DEVICES=y +CONFIG_RC_DECODERS=y +CONFIG_IR_MESON=m CONFIG_VIDEO_V4L2_SUBDEV_API=y # CONFIG_DVB_NET is not set CONFIG_V4L_MEM2MEM_DRIVERS=y @@@ -372,7 -362,6 +373,7 @@@ CONFIG_SND_BCM2835_SOC_I2S= CONFIG_SND_SOC_SAMSUNG=y CONFIG_SND_SOC_RCAR=y CONFIG_SND_SOC_AK4613=y +CONFIG_SND_SIMPLE_CARD=y CONFIG_USB=y CONFIG_USB_OTG=y CONFIG_USB_XHCI_HCD=y @@@ -485,10 -474,8 +486,10 @@@ CONFIG_ARCH_TEGRA_186_SOC= CONFIG_EXTCON_USB_GPIO=y CONFIG_IIO=y CONFIG_EXYNOS_ADC=y +CONFIG_ROCKCHIP_SARADC=m CONFIG_PWM=y CONFIG_PWM_BCM2835=m +CONFIG_PWM_CROS_EC=m CONFIG_PWM_MESON=m CONFIG_PWM_ROCKCHIP=y CONFIG_PWM_SAMSUNG=y @@@ -498,7 -485,6 +499,7 @@@ CONFIG_PHY_HI6220_USB= CONFIG_PHY_SUN4I_USB=y CONFIG_PHY_ROCKCHIP_INNO_USB2=y CONFIG_PHY_ROCKCHIP_EMMC=y +CONFIG_PHY_ROCKCHIP_PCIE=m CONFIG_PHY_XGENE=y CONFIG_PHY_TEGRA_XUSB=y CONFIG_ARM_SCPI_PROTOCOL=y diff --combined arch/arm64/net/bpf_jit_comp.c index c870d6f01ac2,73de2c71cfb0..2f0505b5c240 --- a/arch/arm64/net/bpf_jit_comp.c +++ b/arch/arm64/net/bpf_jit_comp.c @@@ -36,7 -36,6 +36,7 @@@ int bpf_jit_enable __read_mostly #define TMP_REG_1 (MAX_BPF_JIT_REG + 0) #define TMP_REG_2 (MAX_BPF_JIT_REG + 1) #define TCALL_CNT (MAX_BPF_JIT_REG + 2) +#define TMP_REG_3 (MAX_BPF_JIT_REG + 3)
/* Map BPF registers to A64 registers */ static const int bpf2a64[] = { @@@ -58,7 -57,6 +58,7 @@@ /* temporary registers for internal BPF JIT */ [TMP_REG_1] = A64_R(10), [TMP_REG_2] = A64_R(11), + [TMP_REG_3] = A64_R(12), /* tail_call_cnt */ [TCALL_CNT] = A64_R(26), /* temporary register for blinding constants */ @@@ -71,6 -69,7 +71,7 @@@ struct jit_ctx int epilogue_offset; int *offset; u32 *image; + u32 stack_size; };
static inline void emit(const u32 insn, struct jit_ctx *ctx) @@@ -147,16 -146,11 +148,11 @@@ static inline int epilogue_offset(cons /* Stack must be multiples of 16B */ #define STACK_ALIGN(sz) (((sz) + 15) & ~15)
- #define _STACK_SIZE \ - (MAX_BPF_STACK \ - + 4 /* extra for skb_copy_bits buffer */) - - #define STACK_SIZE STACK_ALIGN(_STACK_SIZE) - #define PROLOGUE_OFFSET 8
static int build_prologue(struct jit_ctx *ctx) { + const struct bpf_prog *prog = ctx->prog; const u8 r6 = bpf2a64[BPF_REG_6]; const u8 r7 = bpf2a64[BPF_REG_7]; const u8 r8 = bpf2a64[BPF_REG_8]; @@@ -178,9 -172,9 +174,9 @@@ * | | * | ... | BPF prog stack * | | - * +-----+ <= (BPF_FP - MAX_BPF_STACK) + * +-----+ <= (BPF_FP - prog->aux->stack_depth) * |RSVD | JIT scratchpad - * current A64_SP => +-----+ <= (BPF_FP - STACK_SIZE) + * current A64_SP => +-----+ <= (BPF_FP - ctx->stack_size) * | | * | ... | Function call stack * | | @@@ -204,8 -198,12 +200,12 @@@ /* Initialize tail_call_cnt */ emit(A64_MOVZ(1, tcc, 0, 0), ctx);
+ /* 4 byte extra for skb_copy_bits buffer */ + ctx->stack_size = prog->aux->stack_depth + 4; + ctx->stack_size = STACK_ALIGN(ctx->stack_size); + /* Set up function call stack */ - emit(A64_SUB_I(1, A64_SP, A64_SP, STACK_SIZE), ctx); + emit(A64_SUB_I(1, A64_SP, A64_SP, ctx->stack_size), ctx);
cur_offset = ctx->idx - idx0; if (cur_offset != PROLOGUE_OFFSET) { @@@ -290,7 -288,7 +290,7 @@@ static void build_epilogue(struct jit_c const u8 fp = bpf2a64[BPF_REG_FP];
/* We're done with BPF stack */ - emit(A64_ADD_I(1, A64_SP, A64_SP, STACK_SIZE), ctx); + emit(A64_ADD_I(1, A64_SP, A64_SP, ctx->stack_size), ctx);
/* Restore fs (x25) and x26 */ emit(A64_POP(fp, A64_R(26), A64_SP), ctx); @@@ -321,7 -319,6 +321,7 @@@ static int build_insn(const struct bpf_ const u8 src = bpf2a64[insn->src_reg]; const u8 tmp = bpf2a64[TMP_REG_1]; const u8 tmp2 = bpf2a64[TMP_REG_2]; + const u8 tmp3 = bpf2a64[TMP_REG_3]; const s16 off = insn->off; const s32 imm = insn->imm; const int i = insn - ctx->prog->insnsi; @@@ -589,7 -586,7 +589,7 @@@ emit_cond_jmp break; } /* tail call */ - case BPF_JMP | BPF_CALL | BPF_X: + case BPF_JMP | BPF_TAIL_CALL: if (emit_bpf_tail_call(ctx)) return -EFAULT; break; @@@ -692,10 -689,10 +692,10 @@@ emit(A64_PRFM(tmp, PST, L1, STRM), ctx); emit(A64_LDXR(isdw, tmp2, tmp), ctx); emit(A64_ADD(isdw, tmp2, tmp2, src), ctx); - emit(A64_STXR(isdw, tmp2, tmp, tmp2), ctx); + emit(A64_STXR(isdw, tmp2, tmp, tmp3), ctx); jmp_offset = -3; check_imm19(jmp_offset); - emit(A64_CBNZ(0, tmp2, jmp_offset), ctx); + emit(A64_CBNZ(0, tmp3, jmp_offset), ctx); break;
/* R0 = ntohx(*(size *)(((struct sk_buff *)R6)->data + imm)) */ @@@ -735,7 -732,7 +735,7 @@@ return -EINVAL; } emit_a64_mov_i64(r3, size, ctx); - emit(A64_SUB_I(1, r4, fp, STACK_SIZE), ctx); + emit(A64_SUB_I(1, r4, fp, ctx->stack_size), ctx); emit_a64_mov_i64(r5, (unsigned long)bpf_load_pointer, ctx); emit(A64_BLR(r5), ctx); emit(A64_MOV(1, r0, A64_R(0)), ctx); @@@ -903,6 -900,7 +903,7 @@@ struct bpf_prog *bpf_int_jit_compile(st bpf_jit_binary_lock_ro(header); prog->bpf_func = (void *)ctx.image; prog->jited = 1; + prog->jited_len = image_size;
out_off: kfree(ctx.offset); diff --combined drivers/net/bonding/bond_3ad.c index e5386ab706ec,165a8009c640..5427032aa05e --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c @@@ -90,13 -90,10 +90,13 @@@ enum ad_link_speed_type AD_LINK_SPEED_100MBPS, AD_LINK_SPEED_1000MBPS, AD_LINK_SPEED_2500MBPS, + AD_LINK_SPEED_5000MBPS, AD_LINK_SPEED_10000MBPS, + AD_LINK_SPEED_14000MBPS, AD_LINK_SPEED_20000MBPS, AD_LINK_SPEED_25000MBPS, AD_LINK_SPEED_40000MBPS, + AD_LINK_SPEED_50000MBPS, AD_LINK_SPEED_56000MBPS, AD_LINK_SPEED_100000MBPS, }; @@@ -262,13 -259,10 +262,13 @@@ static inline int __check_agg_selection * %AD_LINK_SPEED_100MBPS, * %AD_LINK_SPEED_1000MBPS, * %AD_LINK_SPEED_2500MBPS, + * %AD_LINK_SPEED_5000MBPS, * %AD_LINK_SPEED_10000MBPS + * %AD_LINK_SPEED_14000MBPS, * %AD_LINK_SPEED_20000MBPS * %AD_LINK_SPEED_25000MBPS * %AD_LINK_SPEED_40000MBPS + * %AD_LINK_SPEED_50000MBPS * %AD_LINK_SPEED_56000MBPS * %AD_LINK_SPEED_100000MBPS */ @@@ -302,18 -296,10 +302,18 @@@ static u16 __get_link_speed(struct por speed = AD_LINK_SPEED_2500MBPS; break;
+ case SPEED_5000: + speed = AD_LINK_SPEED_5000MBPS; + break; + case SPEED_10000: speed = AD_LINK_SPEED_10000MBPS; break;
+ case SPEED_14000: + speed = AD_LINK_SPEED_14000MBPS; + break; + case SPEED_20000: speed = AD_LINK_SPEED_20000MBPS; break; @@@ -326,10 -312,6 +326,10 @@@ speed = AD_LINK_SPEED_40000MBPS; break;
+ case SPEED_50000: + speed = AD_LINK_SPEED_50000MBPS; + break; + case SPEED_56000: speed = AD_LINK_SPEED_56000MBPS; break; @@@ -340,6 -322,11 +340,11 @@@
default: /* unknown speed value from ethtool. shouldn't happen */ + if (slave->speed != SPEED_UNKNOWN) + pr_warn_once("%s: unknown ethtool speed (%d) for port %d (set it to 0)\n", + slave->bond->dev->name, + slave->speed, + port->actor_port_number); speed = 0; break; } @@@ -725,15 -712,9 +730,15 @@@ static u32 __get_agg_bandwidth(struct a case AD_LINK_SPEED_2500MBPS: bandwidth = nports * 2500; break; + case AD_LINK_SPEED_5000MBPS: + bandwidth = nports * 5000; + break; case AD_LINK_SPEED_10000MBPS: bandwidth = nports * 10000; break; + case AD_LINK_SPEED_14000MBPS: + bandwidth = nports * 14000; + break; case AD_LINK_SPEED_20000MBPS: bandwidth = nports * 20000; break; @@@ -743,9 -724,6 +748,9 @@@ case AD_LINK_SPEED_40000MBPS: bandwidth = nports * 40000; break; + case AD_LINK_SPEED_50000MBPS: + bandwidth = nports * 50000; + break; case AD_LINK_SPEED_56000MBPS: bandwidth = nports * 56000; break; diff --combined drivers/net/bonding/bond_main.c index 8ab6bdbe1682,7d9474352c36..2865f31c6076 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@@ -3488,7 -3488,8 +3488,8 @@@ static int bond_do_ioctl(struct net_dev case BOND_CHANGE_ACTIVE_OLD: case SIOCBONDCHANGEACTIVE: bond_opt_initstr(&newval, slave_dev->name); - res = __bond_opt_set(bond, BOND_OPT_ACTIVE_SLAVE, &newval); + res = __bond_opt_set_notify(bond, BOND_OPT_ACTIVE_SLAVE, + &newval); break; default: res = -EOPNOTSUPP; @@@ -4174,12 -4175,6 +4175,6 @@@ static const struct net_device_ops bond .ndo_add_slave = bond_enslave, .ndo_del_slave = bond_release, .ndo_fix_features = bond_fix_features, - .ndo_bridge_setlink = switchdev_port_bridge_setlink, - .ndo_bridge_getlink = switchdev_port_bridge_getlink, - .ndo_bridge_dellink = switchdev_port_bridge_dellink, - .ndo_fdb_add = switchdev_port_fdb_add, - .ndo_fdb_del = switchdev_port_fdb_del, - .ndo_fdb_dump = switchdev_port_fdb_dump, .ndo_features_check = passthru_features_check, };
@@@ -4192,6 -4187,7 +4187,6 @@@ static void bond_destructor(struct net_ struct bonding *bond = netdev_priv(bond_dev); if (bond->wq) destroy_workqueue(bond->wq); - free_netdev(bond_dev); }
void bond_setup(struct net_device *bond_dev) @@@ -4211,8 -4207,7 +4206,8 @@@ bond_dev->netdev_ops = &bond_netdev_ops; bond_dev->ethtool_ops = &bond_ethtool_ops;
- bond_dev->destructor = bond_destructor; + bond_dev->needs_free_netdev = true; + bond_dev->priv_destructor = bond_destructor;
SET_NETDEV_DEVTYPE(bond_dev, &bond_type);
@@@ -4736,7 -4731,7 +4731,7 @@@ int bond_create(struct net *net, const
rtnl_unlock(); if (res < 0) - bond_destructor(bond_dev); + free_netdev(bond_dev); return res; }
diff --combined drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index f619c4cac51f,ef734675885e..67fe3d826566 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@@ -3883,26 -3883,15 +3883,26 @@@ netdev_tx_t bnx2x_start_xmit(struct sk_ /* when transmitting in a vf, start bd must hold the ethertype * for fw to enforce it */ + u16 vlan_tci = 0; #ifndef BNX2X_STOP_ON_ERROR - if (IS_VF(bp)) + if (IS_VF(bp)) { #endif - tx_start_bd->vlan_or_ethertype = - cpu_to_le16(ntohs(eth->h_proto)); + /* Still need to consider inband vlan for enforced */ + if (__vlan_get_tag(skb, &vlan_tci)) { + tx_start_bd->vlan_or_ethertype = + cpu_to_le16(ntohs(eth->h_proto)); + } else { + tx_start_bd->bd_flags.as_bitfield |= + (X_ETH_INBAND_VLAN << + ETH_TX_BD_FLAGS_VLAN_MODE_SHIFT); + tx_start_bd->vlan_or_ethertype = + cpu_to_le16(vlan_tci); + } #ifndef BNX2X_STOP_ON_ERROR - else + } else { /* used by FW for packet accounting */ tx_start_bd->vlan_or_ethertype = cpu_to_le16(pkt_prod); + } #endif }
@@@ -4284,8 -4273,8 +4284,8 @@@ int bnx2x_setup_tc(struct net_device *d return 0; }
- int __bnx2x_setup_tc(struct net_device *dev, u32 handle, __be16 proto, - struct tc_to_netdev *tc) + int __bnx2x_setup_tc(struct net_device *dev, u32 handle, u32 chain_index, + __be16 proto, struct tc_to_netdev *tc) { if (tc->type != TC_SETUP_MQPRIO) return -EINVAL; diff --combined drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index ea1bfcf1870a,01c9710fc62e..2c6de769f4e6 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@@ -891,7 -891,7 +891,7 @@@ static u16 cxgb_select_queue(struct net * The skb's priority is determined via the VLAN Tag Priority Code * Point field. */ - if (cxgb4_dcb_enabled(dev)) { + if (cxgb4_dcb_enabled(dev) && !is_kdump_kernel()) { u16 vlan_tci; int err;
@@@ -1093,10 -1093,12 +1093,12 @@@ int cxgb4_alloc_stid(struct tid_info *t * This is equivalent to 4 TIDs. With CLIP enabled it * needs 2 TIDs. */ - if (family == PF_INET) - t->stids_in_use++; - else + if (family == PF_INET6) { t->stids_in_use += 2; + t->v6_stids_in_use += 2; + } else { + t->stids_in_use++; + } } spin_unlock_bh(&t->stid_lock); return stid; @@@ -1150,13 -1152,16 +1152,16 @@@ void cxgb4_free_stid(struct tid_info *t bitmap_release_region(t->stid_bmap, stid, 1); t->stid_tab[stid].data = NULL; if (stid < t->nstids) { - if (family == PF_INET) - t->stids_in_use--; - else + if (family == PF_INET6) { t->stids_in_use -= 2; + t->v6_stids_in_use -= 2; + } else { + t->stids_in_use--; + } } else { t->sftids_in_use--; } + spin_unlock_bh(&t->stid_lock); } EXPORT_SYMBOL(cxgb4_free_stid); @@@ -1232,7 -1237,8 +1237,8 @@@ static void process_tid_release_list(st * Release a TID and inform HW. If we are unable to allocate the release * message we defer to a work queue. */ - void cxgb4_remove_tid(struct tid_info *t, unsigned int chan, unsigned int tid) + void cxgb4_remove_tid(struct tid_info *t, unsigned int chan, unsigned int tid, + unsigned short family) { struct sk_buff *skb; struct adapter *adap = container_of(t, struct adapter, tids); @@@ -1241,10 -1247,18 +1247,18 @@@
if (t->tid_tab[tid]) { t->tid_tab[tid] = NULL; - if (t->hash_base && (tid >= t->hash_base)) - atomic_dec(&t->hash_tids_in_use); - else - atomic_dec(&t->tids_in_use); + atomic_dec(&t->conns_in_use); + if (t->hash_base && (tid >= t->hash_base)) { + if (family == AF_INET6) + atomic_sub(2, &t->hash_tids_in_use); + else + atomic_dec(&t->hash_tids_in_use); + } else { + if (family == AF_INET6) + atomic_sub(2, &t->tids_in_use); + else + atomic_dec(&t->tids_in_use); + } }
skb = alloc_skb(sizeof(struct cpl_tid_release), GFP_ATOMIC); @@@ -1292,10 -1306,12 +1306,12 @@@ static int tid_init(struct tid_info *t spin_lock_init(&t->ftid_lock);
t->stids_in_use = 0; + t->v6_stids_in_use = 0; t->sftids_in_use = 0; t->afree = NULL; t->atids_in_use = 0; atomic_set(&t->tids_in_use, 0); + atomic_set(&t->conns_in_use, 0); atomic_set(&t->hash_tids_in_use, 0);
/* Setup the free list for atid_tab and clear the stid bitmap. */ @@@ -2249,6 -2265,13 +2265,13 @@@ static int cxgb_open(struct net_device return err; }
+ /* It's possible that the basic port information could have + * changed since we first read it. + */ + err = t4_update_port_info(pi); + if (err < 0) + return err; + err = link_start(dev); if (!err) netif_tx_start_all_queues(dev); @@@ -2560,6 -2583,8 +2583,8 @@@ static int cxgb_get_vf_config(struct ne if (vf >= adap->num_vfs) return -EINVAL; ivi->vf = vf; + ivi->max_tx_rate = adap->vfinfo[vf].tx_rate; + ivi->min_tx_rate = 0; ether_addr_copy(ivi->mac, adap->vfinfo[vf].vf_mac_addr); return 0; } @@@ -2576,6 -2601,109 +2601,109 @@@ static int cxgb_get_phys_port_id(struc return 0; }
+ static int cxgb_set_vf_rate(struct net_device *dev, int vf, int min_tx_rate, + int max_tx_rate) + { + struct port_info *pi = netdev_priv(dev); + struct adapter *adap = pi->adapter; + struct fw_port_cmd port_cmd, port_rpl; + u32 link_status, speed = 0; + u32 fw_pfvf, fw_class; + int class_id = vf; + int link_ok, ret; + u16 pktsize; + + if (vf >= adap->num_vfs) + return -EINVAL; + + if (min_tx_rate) { + dev_err(adap->pdev_dev, + "Min tx rate (%d) (> 0) for VF %d is Invalid.\n", + min_tx_rate, vf); + return -EINVAL; + } + /* Retrieve link details for VF port */ + memset(&port_cmd, 0, sizeof(port_cmd)); + port_cmd.op_to_portid = cpu_to_be32(FW_CMD_OP_V(FW_PORT_CMD) | + FW_CMD_REQUEST_F | + FW_CMD_READ_F | + FW_PORT_CMD_PORTID_V(pi->port_id)); + port_cmd.action_to_len16 = + cpu_to_be32(FW_PORT_CMD_ACTION_V(FW_PORT_ACTION_GET_PORT_INFO) | + FW_LEN16(port_cmd)); + ret = t4_wr_mbox(adap, adap->mbox, &port_cmd, sizeof(port_cmd), + &port_rpl); + if (ret != FW_SUCCESS) { + dev_err(adap->pdev_dev, + "Failed to get link status for VF %d\n", vf); + return -EINVAL; + } + link_status = be32_to_cpu(port_rpl.u.info.lstatus_to_modtype); + link_ok = (link_status & FW_PORT_CMD_LSTATUS_F) != 0; + if (!link_ok) { + dev_err(adap->pdev_dev, "Link down for VF %d\n", vf); + return -EINVAL; + } + /* Determine link speed */ + if (link_status & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_100M)) + speed = 100; + else if (link_status & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_1G)) + speed = 1000; + else if (link_status & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_10G)) + speed = 10000; + else if (link_status & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_25G)) + speed = 25000; + else if (link_status & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_40G)) + speed = 40000; + else if (link_status & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_100G)) + speed = 100000; + + if (max_tx_rate > speed) { + dev_err(adap->pdev_dev, + "Max tx rate %d for VF %d can't be > link-speed %u", + max_tx_rate, vf, speed); + return -EINVAL; + } + pktsize = be16_to_cpu(port_rpl.u.info.mtu); + /* subtract ethhdr size and 4 bytes crc since, f/w appends it */ + pktsize = pktsize - sizeof(struct ethhdr) - 4; + /* subtract ipv4 hdr size, tcp hdr size to get typical IPv4 MSS size */ + pktsize = pktsize - sizeof(struct iphdr) - sizeof(struct tcphdr); + /* configure Traffic Class for rate-limiting */ + ret = t4_sched_params(adap, SCHED_CLASS_TYPE_PACKET, + SCHED_CLASS_LEVEL_CL_RL, + SCHED_CLASS_MODE_CLASS, + SCHED_CLASS_RATEUNIT_BITS, + SCHED_CLASS_RATEMODE_ABS, + pi->port_id, class_id, 0, + max_tx_rate * 1000, 0, pktsize); + if (ret) { + dev_err(adap->pdev_dev, "Err %d for Traffic Class config\n", + ret); + return -EINVAL; + } + dev_info(adap->pdev_dev, + "Class %d with MSS %u configured with rate %u\n", + class_id, pktsize, max_tx_rate); + + /* bind VF to configured Traffic Class */ + fw_pfvf = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_PFVF) | + FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_PFVF_SCHEDCLASS_ETH)); + fw_class = class_id; + ret = t4_set_params(adap, adap->mbox, adap->pf, vf + 1, 1, &fw_pfvf, + &fw_class); + if (ret) { + dev_err(adap->pdev_dev, + "Err %d in binding VF %d to Traffic Class %d\n", + ret, vf, class_id); + return -EINVAL; + } + dev_info(adap->pdev_dev, "PF %d VF %d is bound to Class %d\n", + adap->pf, vf, class_id); + adap->vfinfo[vf].tx_rate = max_tx_rate; + return 0; + } + #endif
static int cxgb_set_mac_addr(struct net_device *dev, void *p) @@@ -2695,12 -2823,15 +2823,15 @@@ static int cxgb_set_tx_maxrate(struct n return err; }
- static int cxgb_setup_tc(struct net_device *dev, u32 handle, __be16 proto, - struct tc_to_netdev *tc) + static int cxgb_setup_tc(struct net_device *dev, u32 handle, u32 chain_index, + __be16 proto, struct tc_to_netdev *tc) { struct port_info *pi = netdev2pinfo(dev); struct adapter *adap = netdev2adap(dev);
+ if (chain_index) + return -EOPNOTSUPP; + if (!(adap->flags & FULL_INIT_DONE)) { dev_err(adap->pdev_dev, "Failed to setup tc on port %d. Link Down?\n", @@@ -2724,6 -2855,16 +2855,16 @@@ return -EOPNOTSUPP; }
+ static netdev_features_t cxgb_fix_features(struct net_device *dev, + netdev_features_t features) + { + /* Disable GRO, if RX_CSUM is disabled */ + if (!(features & NETIF_F_RXCSUM)) + features &= ~NETIF_F_GRO; + + return features; + } + static const struct net_device_ops cxgb4_netdev_ops = { .ndo_open = cxgb_open, .ndo_stop = cxgb_close, @@@ -2745,6 -2886,7 +2886,7 @@@ #endif /* CONFIG_CHELSIO_T4_FCOE */ .ndo_set_tx_maxrate = cxgb_set_tx_maxrate, .ndo_setup_tc = cxgb_setup_tc, + .ndo_fix_features = cxgb_fix_features, };
#ifdef CONFIG_PCI_IOV @@@ -2752,6 -2894,7 +2894,7 @@@ static const struct net_device_ops cxgb .ndo_open = dummy_open, .ndo_set_vf_mac = cxgb_set_vf_mac, .ndo_get_vf_config = cxgb_get_vf_config, + .ndo_set_vf_rate = cxgb_set_vf_rate, .ndo_get_phys_port_id = cxgb_get_phys_port_id, }; #endif @@@ -4016,10 -4159,7 +4159,7 @@@ static void cfg_queues(struct adapter *
/* Reduce memory usage in kdump environment, disable all offload. */ - if (is_kdump_kernel()) { - adap->params.offload = 0; - adap->params.crypto = 0; - } else if (is_uld(adap) && t4_uld_mem_alloc(adap)) { + if (is_kdump_kernel() || (is_uld(adap) && t4_uld_mem_alloc(adap))) { adap->params.offload = 0; adap->params.crypto = 0; } @@@ -4040,7 -4180,7 +4180,7 @@@ struct port_info *pi = adap2pinfo(adap, i);
pi->first_qset = qidx; - pi->nqsets = 8; + pi->nqsets = is_kdump_kernel() ? 1 : 8; qidx += pi->nqsets; } #else /* !CONFIG_CHELSIO_T4_DCB */ @@@ -4053,6 -4193,9 +4193,9 @@@ if (q10g > netif_get_num_default_rss_queues()) q10g = netif_get_num_default_rss_queues();
+ if (is_kdump_kernel()) + q10g = 1; + for_each_port(adap, i) { struct port_info *pi = adap2pinfo(adap, i);
@@@ -4525,7 -4668,7 +4668,7 @@@ static void dummy_setup(struct net_devi /* Initialize the device structure. */ dev->netdev_ops = &cxgb4_mgmt_netdev_ops; dev->ethtool_ops = &cxgb4_mgmt_ethtool_ops; - dev->destructor = free_netdev; + dev->needs_free_netdev = true; }
static int config_mgmt_dev(struct pci_dev *pdev) @@@ -4958,6 -5101,8 +5101,8 @@@ static int init_one(struct pci_dev *pde netif_set_real_num_tx_queues(adapter->port[i], pi->nqsets); netif_set_real_num_rx_queues(adapter->port[i], pi->nqsets);
+ netif_carrier_off(adapter->port[i]); + err = register_netdev(adapter->port[i]); if (err) break; @@@ -5024,13 -5169,15 +5169,15 @@@ sriov &v, &port_vec); if (err < 0) { dev_err(adapter->pdev_dev, "Could not fetch port params\n"); - goto free_adapter; + goto free_mbox_log; }
adapter->params.nports = hweight32(port_vec); pci_set_drvdata(pdev, adapter); return 0;
+ free_mbox_log: + kfree(adapter->mbox_log); free_adapter: kfree(adapter); free_pci_region: @@@ -5130,6 -5277,7 +5277,7 @@@ static void remove_one(struct pci_dev * unregister_netdev(adapter->port[0]); iounmap(adapter->regs); kfree(adapter->vfinfo); + kfree(adapter->mbox_log); kfree(adapter); pci_disable_sriov(pdev); pci_release_regions(pdev); @@@ -5176,6 -5324,7 +5324,7 @@@ static void shutdown_one(struct pci_de unregister_netdev(adapter->port[0]); iounmap(adapter->regs); kfree(adapter->vfinfo); + kfree(adapter->mbox_log); kfree(adapter); pci_disable_sriov(pdev); pci_release_regions(pdev); diff --combined drivers/net/ethernet/ibm/ibmvnic.c index c0fbeb387db4,59ea7a5ae776..78fdd4f0e341 --- a/drivers/net/ethernet/ibm/ibmvnic.c +++ b/drivers/net/ethernet/ibm/ibmvnic.c @@@ -163,6 -163,16 +163,16 @@@ static long h_reg_sub_crq(unsigned lon return rc; }
+ static void reset_long_term_buff(struct ibmvnic_adapter *adapter, + struct ibmvnic_long_term_buff *ltb) + { + memset(ltb->buff, 0, ltb->size); + + init_completion(&adapter->fw_done); + send_request_map(adapter, ltb->addr, ltb->size, ltb->map_id); + wait_for_completion(&adapter->fw_done); + } + static int alloc_long_term_buff(struct ibmvnic_adapter *adapter, struct ibmvnic_long_term_buff *ltb, int size) { @@@ -200,6 -210,15 +210,15 @@@ static void free_long_term_buff(struct dma_free_coherent(dev, ltb->size, ltb->buff, ltb->addr); }
+ static void deactivate_rx_pools(struct ibmvnic_adapter *adapter) + { + int i; + + for (i = 0; i < be32_to_cpu(adapter->login_rsp_buf->num_rxadd_subcrqs); + i++) + adapter->rx_pool[i].active = 0; + } + static void replenish_rx_pool(struct ibmvnic_adapter *adapter, struct ibmvnic_rx_pool *pool) { @@@ -217,6 -236,9 +236,9 @@@ int index; int i;
+ if (!pool->active) + return; + handle_array = (u64 *)((u8 *)(adapter->login_rsp_buf) + be32_to_cpu(adapter->login_rsp_buf-> off_rxadd_subcrqs)); @@@ -287,6 -309,15 +309,15 @@@ failure dev_kfree_skb_any(skb); adapter->replenish_add_buff_failure++; atomic_add(buffers_added, &pool->available); + + if (lpar_rc == H_CLOSED) { + /* Disable buffer pool replenishment and report carrier off if + * queue is closed. Firmware guarantees that a signal will + * be sent to the driver, triggering a reset. + */ + deactivate_rx_pools(adapter); + netif_carrier_off(adapter->netdev); + } }
static void replenish_pools(struct ibmvnic_adapter *adapter) @@@ -331,6 -362,32 +362,32 @@@ static int init_stats_token(struct ibmv return 0; }
+ static int reset_rx_pools(struct ibmvnic_adapter *adapter) + { + struct ibmvnic_rx_pool *rx_pool; + int rx_scrqs; + int i, j; + + rx_scrqs = be32_to_cpu(adapter->login_rsp_buf->num_rxadd_subcrqs); + for (i = 0; i < rx_scrqs; i++) { + rx_pool = &adapter->rx_pool[i]; + + reset_long_term_buff(adapter, &rx_pool->long_term_buff); + + for (j = 0; j < rx_pool->size; j++) + rx_pool->free_map[j] = j; + + memset(rx_pool->rx_buff, 0, + rx_pool->size * sizeof(struct ibmvnic_rx_buff)); + + atomic_set(&rx_pool->available, 0); + rx_pool->next_alloc = 0; + rx_pool->next_free = 0; + } + + return 0; + } + static void release_rx_pools(struct ibmvnic_adapter *adapter) { struct ibmvnic_rx_pool *rx_pool; @@@ -432,6 -489,32 +489,32 @@@ static int init_rx_pools(struct net_dev return 0; }
+ static int reset_tx_pools(struct ibmvnic_adapter *adapter) + { + struct ibmvnic_tx_pool *tx_pool; + int tx_scrqs; + int i, j; + + tx_scrqs = be32_to_cpu(adapter->login_rsp_buf->num_txsubm_subcrqs); + for (i = 0; i < tx_scrqs; i++) { + tx_pool = &adapter->tx_pool[i]; + + reset_long_term_buff(adapter, &tx_pool->long_term_buff); + + memset(tx_pool->tx_buff, 0, + adapter->req_tx_entries_per_subcrq * + sizeof(struct ibmvnic_tx_buff)); + + for (j = 0; j < adapter->req_tx_entries_per_subcrq; j++) + tx_pool->free_map[j] = j; + + tx_pool->consumer_index = 0; + tx_pool->producer_index = 0; + } + + return 0; + } + static void release_tx_pools(struct ibmvnic_adapter *adapter) { struct ibmvnic_tx_pool *tx_pool; @@@ -518,6 -601,32 +601,32 @@@ static void release_error_buffers(struc spin_unlock_irqrestore(&adapter->error_list_lock, flags); }
+ static void ibmvnic_napi_enable(struct ibmvnic_adapter *adapter) + { + int i; + + if (adapter->napi_enabled) + return; + + for (i = 0; i < adapter->req_rx_queues; i++) + napi_enable(&adapter->napi[i]); + + adapter->napi_enabled = true; + } + + static void ibmvnic_napi_disable(struct ibmvnic_adapter *adapter) + { + int i; + + if (!adapter->napi_enabled) + return; + + for (i = 0; i < adapter->req_rx_queues; i++) + napi_disable(&adapter->napi[i]); + + adapter->napi_enabled = false; + } + static int ibmvnic_login(struct net_device *netdev) { struct ibmvnic_adapter *adapter = netdev_priv(netdev); @@@ -674,9 -783,7 +783,7 @@@ static int __ibmvnic_open(struct net_de
adapter->state = VNIC_OPENING; replenish_pools(adapter); - - for (i = 0; i < adapter->req_rx_queues; i++) - napi_enable(&adapter->napi[i]); + ibmvnic_napi_enable(adapter);
/* We're ready to receive frames, enable the sub-crq interrupts and * set the logical link state to up @@@ -779,13 -886,7 +886,7 @@@ static int __ibmvnic_close(struct net_d
adapter->state = VNIC_CLOSING; netif_tx_stop_all_queues(netdev); - - if (adapter->napi) { - for (i = 0; i < adapter->req_rx_queues; i++) - napi_disable(&adapter->napi[i]); - } - - clean_tx_pools(adapter); + ibmvnic_napi_disable(adapter);
if (adapter->tx_scrq) { for (i = 0; i < adapter->req_tx_queues; i++) @@@ -814,6 -915,7 +915,7 @@@ } }
+ clean_tx_pools(adapter); adapter->state = VNIC_CLOSED; return rc; } @@@ -1092,8 -1194,14 +1194,14 @@@ static int ibmvnic_xmit(struct sk_buff dev_kfree_skb_any(skb); tx_buff->skb = NULL;
- if (lpar_rc == H_CLOSED) - netif_stop_subqueue(netdev, queue_num); + if (lpar_rc == H_CLOSED) { + /* Disable TX and report carrier off if queue is closed. + * Firmware guarantees that a signal will be sent to the + * driver, triggering a reset or some other action. + */ + netif_tx_stop_all_queues(netdev); + netif_carrier_off(netdev); + }
tx_send_failed++; tx_dropped++; @@@ -1206,37 -1314,39 +1314,39 @@@ static int do_reset(struct ibmvnic_adap if (rc) return rc;
- /* remove the closed state so when we call open it appears - * we are coming from the probed state. - */ - adapter->state = VNIC_PROBED; + if (adapter->reset_reason != VNIC_RESET_NON_FATAL) { + /* remove the closed state so when we call open it appears + * we are coming from the probed state. + */ + adapter->state = VNIC_PROBED;
- release_resources(adapter); - release_sub_crqs(adapter); - release_crq_queue(adapter); + rc = ibmvnic_init(adapter); + if (rc) + return 0;
- rc = ibmvnic_init(adapter); - if (rc) - return 0; + /* If the adapter was in PROBE state prior to the reset, + * exit here. + */ + if (reset_state == VNIC_PROBED) + return 0;
- /* If the adapter was in PROBE state prior to the reset, exit here. */ - if (reset_state == VNIC_PROBED) - return 0; + rc = ibmvnic_login(netdev); + if (rc) { + adapter->state = VNIC_PROBED; + return 0; + }
- rc = ibmvnic_login(netdev); - if (rc) { - adapter->state = VNIC_PROBED; - return 0; - } + rc = reset_tx_pools(adapter); + if (rc) + return rc;
- rtnl_lock(); - rc = init_resources(adapter); - rtnl_unlock(); - if (rc) - return rc; + rc = reset_rx_pools(adapter); + if (rc) + return rc;
- if (reset_state == VNIC_CLOSED) - return 0; + if (reset_state == VNIC_CLOSED) + return 0; + }
rc = __ibmvnic_open(netdev); if (rc) { @@@ -1254,6 -1364,9 +1364,9 @@@ for (i = 0; i < adapter->req_rx_queues; i++) napi_schedule(&adapter->napi[i]);
+ if (adapter->reset_reason != VNIC_RESET_FAILOVER) + netdev_notify_peers(netdev); + return 0; }
@@@ -1313,6 -1426,7 +1426,7 @@@ static void __ibmvnic_reset(struct work
if (rc) { free_all_rwi(adapter); + mutex_unlock(&adapter->reset_lock); return; }
@@@ -1383,6 -1497,10 +1497,10 @@@ static int ibmvnic_poll(struct napi_str struct ibmvnic_adapter *adapter = netdev_priv(netdev); int scrq_num = (int)(napi - adapter->napi); int frames_processed = 0; + + if (adapter->resetting) + return 0; + restart_poll: while (frames_processed < budget) { struct sk_buff *skb; @@@ -1441,7 -1559,9 +1559,9 @@@ netdev->stats.rx_bytes += length; frames_processed++; } - replenish_rx_pool(adapter, &adapter->rx_pool[scrq_num]); + + if (adapter->state != VNIC_CLOSING) + replenish_rx_pool(adapter, &adapter->rx_pool[scrq_num]);
if (frames_processed < budget) { enable_scrq_irq(adapter, adapter->rx_scrq[scrq_num]); @@@ -1468,11 -1588,6 +1588,11 @@@ static void ibmvnic_netpoll_controller( } #endif
+static int ibmvnic_change_mtu(struct net_device *netdev, int new_mtu) +{ + return -EOPNOTSUPP; +} + static const struct net_device_ops ibmvnic_netdev_ops = { .ndo_open = ibmvnic_open, .ndo_stop = ibmvnic_close, @@@ -1484,7 -1599,6 +1604,7 @@@ #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = ibmvnic_netpoll_controller, #endif + .ndo_change_mtu = ibmvnic_change_mtu, };
/* ethtool functions */ @@@ -1614,6 -1728,45 +1734,45 @@@ static const struct ethtool_ops ibmvnic
/* Routines for managing CRQs/sCRQs */
+ static int reset_one_sub_crq_queue(struct ibmvnic_adapter *adapter, + struct ibmvnic_sub_crq_queue *scrq) + { + int rc; + + if (scrq->irq) { + free_irq(scrq->irq, scrq); + irq_dispose_mapping(scrq->irq); + scrq->irq = 0; + } + + memset(scrq->msgs, 0, 2 * PAGE_SIZE); + scrq->cur = 0; + + rc = h_reg_sub_crq(adapter->vdev->unit_address, scrq->msg_token, + 4 * PAGE_SIZE, &scrq->crq_num, &scrq->hw_irq); + return rc; + } + + static int reset_sub_crq_queues(struct ibmvnic_adapter *adapter) + { + int i, rc; + + for (i = 0; i < adapter->req_tx_queues; i++) { + rc = reset_one_sub_crq_queue(adapter, adapter->tx_scrq[i]); + if (rc) + return rc; + } + + for (i = 0; i < adapter->req_rx_queues; i++) { + rc = reset_one_sub_crq_queue(adapter, adapter->rx_scrq[i]); + if (rc) + return rc; + } + + rc = init_sub_crq_irqs(adapter); + return rc; + } + static void release_sub_crq_queue(struct ibmvnic_adapter *adapter, struct ibmvnic_sub_crq_queue *scrq) { @@@ -2748,6 -2901,8 +2907,8 @@@ static void handle_error_indication(uni
if (crq->error_indication.flags & IBMVNIC_FATAL_ERROR) ibmvnic_reset(adapter, VNIC_RESET_FATAL); + else + ibmvnic_reset(adapter, VNIC_RESET_NON_FATAL); }
static void handle_change_mac_rsp(union ibmvnic_crq *crq, @@@ -3153,6 -3308,8 +3314,8 @@@ static void ibmvnic_handle_crq(union ib switch (gen_crq->cmd) { case IBMVNIC_CRQ_INIT: dev_info(dev, "Partner initialized\n"); + adapter->from_passive_init = true; + complete(&adapter->init_done); break; case IBMVNIC_CRQ_INIT_COMPLETE: dev_info(dev, "Partner initialization complete\n"); @@@ -3461,21 -3618,38 +3624,38 @@@ static int ibmvnic_init(struct ibmvnic_ unsigned long timeout = msecs_to_jiffies(30000); int rc;
- rc = init_crq_queue(adapter); + if (adapter->resetting) { + rc = ibmvnic_reset_crq(adapter); + if (!rc) + rc = vio_enable_interrupts(adapter->vdev); + } else { + rc = init_crq_queue(adapter); + } + if (rc) { dev_err(dev, "Couldn't initialize crq. rc=%d\n", rc); return rc; }
+ adapter->from_passive_init = false; + init_completion(&adapter->init_done); ibmvnic_send_crq_init(adapter); if (!wait_for_completion_timeout(&adapter->init_done, timeout)) { dev_err(dev, "Initialization sequence timed out\n"); - release_crq_queue(adapter); return -1; }
- rc = init_sub_crqs(adapter); + if (adapter->from_passive_init) { + adapter->state = VNIC_OPEN; + adapter->from_passive_init = false; + return -1; + } + + if (adapter->resetting) + rc = reset_sub_crq_queues(adapter); + else + rc = init_sub_crqs(adapter); if (rc) { dev_err(dev, "Initialization of sub crqs failed\n"); release_crq_queue(adapter); @@@ -3484,6 -3658,8 +3664,8 @@@ return rc; }
+ static struct device_attribute dev_attr_failover; + static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id) { struct ibmvnic_adapter *adapter; @@@ -3540,9 -3716,16 +3722,16 @@@
netdev->mtu = adapter->req_mtu - ETH_HLEN;
+ rc = device_create_file(&dev->dev, &dev_attr_failover); + if (rc) { + free_netdev(netdev); + return rc; + } + rc = register_netdev(netdev); if (rc) { dev_err(&dev->dev, "failed to register netdev rc=%d\n", rc); + device_remove_file(&dev->dev, &dev_attr_failover); free_netdev(netdev); return rc; } @@@ -3568,12 -3751,49 +3757,49 @@@ static int ibmvnic_remove(struct vio_de adapter->state = VNIC_REMOVED;
mutex_unlock(&adapter->reset_lock); + device_remove_file(&dev->dev, &dev_attr_failover); free_netdev(netdev); dev_set_drvdata(&dev->dev, NULL);
return 0; }
+ static ssize_t failover_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) + { + struct net_device *netdev = dev_get_drvdata(dev); + struct ibmvnic_adapter *adapter = netdev_priv(netdev); + unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; + __be64 session_token; + long rc; + + if (!sysfs_streq(buf, "1")) + return -EINVAL; + + rc = plpar_hcall(H_VIOCTL, retbuf, adapter->vdev->unit_address, + H_GET_SESSION_TOKEN, 0, 0, 0); + if (rc) { + netdev_err(netdev, "Couldn't retrieve session token, rc %ld\n", + rc); + return -EINVAL; + } + + session_token = (__be64)retbuf[0]; + netdev_dbg(netdev, "Initiating client failover, session id %llx\n", + be64_to_cpu(session_token)); + rc = plpar_hcall_norets(H_VIOCTL, adapter->vdev->unit_address, + H_SESSION_ERR_DETECTED, session_token, 0, 0); + if (rc) { + netdev_err(netdev, "Client initiated failover failed, rc %ld\n", + rc); + return -EINVAL; + } + + return count; + } + + static DEVICE_ATTR(failover, 0200, NULL, failover_store); + static unsigned long ibmvnic_get_desired_dma(struct vio_dev *vdev) { struct net_device *netdev = dev_get_drvdata(&vdev->dev); diff --combined drivers/net/ethernet/intel/i40e/i40e.h index 44d9610f7a15,60dc9b2c19ff..395ca94faf80 --- a/drivers/net/ethernet/intel/i40e/i40e.h +++ b/drivers/net/ethernet/intel/i40e/i40e.h @@@ -57,7 -57,7 +57,7 @@@ #include "i40e_type.h" #include "i40e_prototype.h" #include "i40e_client.h" - #include "i40e_virtchnl.h" + #include <linux/avf/virtchnl.h> #include "i40e_virtchnl_pf.h" #include "i40e_txrx.h" #include "i40e_dcb.h" @@@ -399,7 -399,6 +399,7 @@@ struct i40e_pf #define I40E_FLAG_RX_CSUM_ENABLED BIT_ULL(1) #define I40E_FLAG_MSI_ENABLED BIT_ULL(2) #define I40E_FLAG_MSIX_ENABLED BIT_ULL(3) +#define I40E_FLAG_HW_ATR_EVICT_ENABLED BIT_ULL(4) #define I40E_FLAG_RSS_ENABLED BIT_ULL(6) #define I40E_FLAG_VMDQ_ENABLED BIT_ULL(7) #define I40E_FLAG_IWARP_ENABLED BIT_ULL(10) @@@ -503,10 -502,12 +503,12 @@@ struct ptp_clock *ptp_clock; struct ptp_clock_info ptp_caps; struct sk_buff *ptp_tx_skb; + unsigned long ptp_tx_start; struct hwtstamp_config tstamp_config; struct mutex tmreg_lock; /* Used to protect the SYSTIME registers. */ u64 ptp_base_adj; u32 tx_hwtstamp_timeouts; + u32 tx_hwtstamp_skipped; u32 rx_hwtstamp_cleared; u32 latch_event_flags; spinlock_t ptp_rx_lock; /* Used to protect Rx timestamp registers. */ @@@ -956,7 -957,8 +958,8 @@@ bool i40e_dcb_need_reconfig(struct i40e struct i40e_dcbx_config *old_cfg, struct i40e_dcbx_config *new_cfg); #endif /* CONFIG_I40E_DCB */ - void i40e_ptp_rx_hang(struct i40e_vsi *vsi); + void i40e_ptp_rx_hang(struct i40e_pf *pf); + void i40e_ptp_tx_hang(struct i40e_pf *pf); void i40e_ptp_tx_hwtstamp(struct i40e_pf *pf); void i40e_ptp_rx_hwtstamp(struct i40e_pf *pf, struct sk_buff *skb, u8 index); void i40e_ptp_set_increment(struct i40e_pf *pf); diff --combined drivers/net/ethernet/intel/i40e/i40e_ethtool.c index 894c8e57ba00,35a246f05520..3d58762efbc0 --- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c +++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c @@@ -147,6 -147,7 +147,7 @@@ static const struct i40e_stats i40e_gst I40E_PF_STAT("VF_admin_queue_requests", vf_aq_requests), I40E_PF_STAT("arq_overflows", arq_overflows), I40E_PF_STAT("rx_hwtstamp_cleared", rx_hwtstamp_cleared), + I40E_PF_STAT("tx_hwtstamp_skipped", tx_hwtstamp_skipped), I40E_PF_STAT("fdir_flush_cnt", fd_flush_cnt), I40E_PF_STAT("fdir_atr_match", stats.fd_atr_match), I40E_PF_STAT("fdir_atr_tunnel_match", stats.fd_atr_tunnel_match), @@@ -224,7 -225,7 +225,7 @@@ static const struct i40e_priv_flags i40 I40E_PRIV_FLAG("LinkPolling", I40E_FLAG_LINK_POLLING_ENABLED, 0), I40E_PRIV_FLAG("flow-director-atr", I40E_FLAG_FD_ATR_ENABLED, 0), I40E_PRIV_FLAG("veb-stats", I40E_FLAG_VEB_STATS_ENABLED, 0), - I40E_PRIV_FLAG("hw-atr-eviction", I40E_FLAG_HW_ATR_EVICT_CAPABLE, 0), + I40E_PRIV_FLAG("hw-atr-eviction", I40E_FLAG_HW_ATR_EVICT_ENABLED, 0), I40E_PRIV_FLAG("legacy-rx", I40E_FLAG_LEGACY_RX, 0), };
@@@ -4092,7 -4093,7 +4093,7 @@@ flags_complete
/* Only allow ATR evict on hardware that is capable of handling it */ if (pf->flags & I40E_FLAG_HW_ATR_EVICT_CAPABLE) - pf->flags &= ~I40E_FLAG_HW_ATR_EVICT_CAPABLE; + pf->flags &= ~I40E_FLAG_HW_ATR_EVICT_ENABLED;
if (changed_flags & I40E_FLAG_TRUE_PROMISC_SUPPORT) { u16 sw_flags = 0, valid_flags = 0; diff --combined drivers/net/ethernet/intel/i40e/i40e_main.c index a7a4b28b4144,abab7fb7a3fc..98fb644a580e --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@@ -5509,7 -5509,8 +5509,8 @@@ exit return ret; }
- static int __i40e_setup_tc(struct net_device *netdev, u32 handle, __be16 proto, + static int __i40e_setup_tc(struct net_device *netdev, u32 handle, + u32 chain_index, __be16 proto, struct tc_to_netdev *tc) { if (tc->type != TC_SETUP_MQPRIO) @@@ -6372,7 -6373,8 +6373,8 @@@ static void i40e_watchdog_subtask(struc i40e_update_veb_stats(pf->veb[i]); }
- i40e_ptp_rx_hang(pf->vsi[pf->lan_vsi]); + i40e_ptp_rx_hang(pf); + i40e_ptp_tx_hang(pf); }
/** @@@ -8821,12 -8823,11 +8823,12 @@@ static int i40e_sw_init(struct i40e_pf (pf->hw.aq.api_min_ver > 4))) { /* Supported in FW API version higher than 1.4 */ pf->flags |= I40E_FLAG_GENEVE_OFFLOAD_CAPABLE; - pf->flags = I40E_FLAG_HW_ATR_EVICT_CAPABLE; - } else { - pf->flags = I40E_FLAG_HW_ATR_EVICT_CAPABLE; }
+ /* Enable HW ATR eviction if possible */ + if (pf->flags & I40E_FLAG_HW_ATR_EVICT_CAPABLE) + pf->flags |= I40E_FLAG_HW_ATR_EVICT_ENABLED; + pf->eeprom_version = 0xDEAD; pf->lan_veb = I40E_NO_VEB; pf->lan_vsi = I40E_NO_VSI; diff --combined drivers/net/ethernet/intel/i40e/i40e_txrx.c index 77115c25d96f,ddf885084c77..af554f3cda19 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c @@@ -2341,7 -2341,7 +2341,7 @@@ static void i40e_atr(struct i40e_ring * /* Due to lack of space, no more new filters can be programmed */ if (th->syn && (pf->flags & I40E_FLAG_FD_ATR_AUTO_DISABLED)) return; - if (pf->flags & I40E_FLAG_HW_ATR_EVICT_CAPABLE) { + if (pf->flags & I40E_FLAG_HW_ATR_EVICT_ENABLED) { /* HW ATR eviction will take care of removing filters on FIN * and RST packets. */ @@@ -2403,7 -2403,7 +2403,7 @@@ I40E_TXD_FLTR_QW1_CNTINDEX_SHIFT) & I40E_TXD_FLTR_QW1_CNTINDEX_MASK;
- if (pf->flags & I40E_FLAG_HW_ATR_EVICT_CAPABLE) + if (pf->flags & I40E_FLAG_HW_ATR_EVICT_ENABLED) dtype_cmd |= I40E_TXD_FLTR_QW1_ATR_MASK;
fdir_desc->qindex_flex_ptype_vsi = cpu_to_le32(flex_ptype); @@@ -2629,8 -2629,10 +2629,10 @@@ static int i40e_tsyn(struct i40e_ring * if (pf->ptp_tx && !test_and_set_bit_lock(__I40E_PTP_TX_IN_PROGRESS, pf->state)) { skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; + pf->ptp_tx_start = jiffies; pf->ptp_tx_skb = skb_get(skb); } else { + pf->tx_hwtstamp_skipped++; return 0; }
@@@ -2933,10 -2935,12 +2935,12 @@@ bool __i40e_chk_linearize(struct sk_buf * @hdr_len: size of the packet header * @td_cmd: the command field in the descriptor * @td_offset: offset for checksum or crc + * + * Returns 0 on success, -1 on failure to DMA **/ - static inline void i40e_tx_map(struct i40e_ring *tx_ring, struct sk_buff *skb, - struct i40e_tx_buffer *first, u32 tx_flags, - const u8 hdr_len, u32 td_cmd, u32 td_offset) + static inline int i40e_tx_map(struct i40e_ring *tx_ring, struct sk_buff *skb, + struct i40e_tx_buffer *first, u32 tx_flags, + const u8 hdr_len, u32 td_cmd, u32 td_offset) { unsigned int data_len = skb->data_len; unsigned int size = skb_headlen(skb); @@@ -3094,7 -3098,7 +3098,7 @@@ do_rs mmiowb(); }
- return; + return 0;
dma_error: dev_info(tx_ring->dev, "TX DMA map failed\n"); @@@ -3111,6 -3115,8 +3115,8 @@@ }
tx_ring->next_to_use = i; + + return -1; }
/** @@@ -3211,8 -3217,9 +3217,9 @@@ static netdev_tx_t i40e_xmit_frame_ring */ i40e_atr(tx_ring, skb, tx_flags);
- i40e_tx_map(tx_ring, skb, first, tx_flags, hdr_len, - td_cmd, td_offset); + if (i40e_tx_map(tx_ring, skb, first, tx_flags, hdr_len, + td_cmd, td_offset)) + goto cleanup_tx_tstamp;
return NETDEV_TX_OK;
@@@ -3220,6 -3227,15 +3227,15 @@@ out_drop i40e_trace(xmit_frame_ring_drop, first->skb, tx_ring); dev_kfree_skb_any(first->skb); first->skb = NULL; + cleanup_tx_tstamp: + if (unlikely(tx_flags & I40E_TX_FLAGS_TSYN)) { + struct i40e_pf *pf = i40e_netdev_to_pf(tx_ring->netdev); + + dev_kfree_skb_any(pf->ptp_tx_skb); + pf->ptp_tx_skb = NULL; + clear_bit_unlock(__I40E_PTP_TX_IN_PROGRESS, pf->state); + } + return NETDEV_TX_OK; }
diff --combined drivers/net/ethernet/marvell/mvpp2.c index 33c901622ed5,fe1458450e44..ca4b55c60682 --- a/drivers/net/ethernet/marvell/mvpp2.c +++ b/drivers/net/ethernet/marvell/mvpp2.c @@@ -345,9 -345,15 +345,15 @@@ /* Per-port XGMAC registers. PPv2.2 only, only for GOP port 0, * relative to port->base. */ + #define MVPP22_XLG_CTRL0_REG 0x100 + #define MVPP22_XLG_CTRL0_PORT_EN BIT(0) + #define MVPP22_XLG_CTRL0_MAC_RESET_DIS BIT(1) + #define MVPP22_XLG_CTRL0_MIB_CNT_DIS BIT(14) + #define MVPP22_XLG_CTRL3_REG 0x11c #define MVPP22_XLG_CTRL3_MACMODESELECT_MASK (7 << 13) #define MVPP22_XLG_CTRL3_MACMODESELECT_GMAC (0 << 13) + #define MVPP22_XLG_CTRL3_MACMODESELECT_10G (1 << 13)
/* SMI registers. PPv2.2 only, relative to priv->iface_base. */ #define MVPP22_SMI_MISC_CFG_REG 0x1204 @@@ -3719,7 -3725,7 +3725,7 @@@ static void mvpp2_bm_bufs_get_addrs(str dma_addr_t *dma_addr, phys_addr_t *phys_addr) { - int cpu = smp_processor_id(); + int cpu = get_cpu();
*dma_addr = mvpp2_percpu_read(priv, cpu, MVPP2_BM_PHY_ALLOC_REG(bm_pool->id)); @@@ -3740,8 -3746,6 +3746,8 @@@ if (sizeof(phys_addr_t) == 8) *phys_addr |= (u64)phys_addr_highbits << 32; } + + put_cpu(); }
/* Free all buffers from the pool */ @@@ -3922,12 -3926,18 +3928,12 @@@ static inline u32 mvpp2_bm_cookie_pool_ return bm; }
-/* Get pool number from a BM cookie */ -static inline int mvpp2_bm_cookie_pool_get(unsigned long cookie) -{ - return (cookie >> MVPP2_BM_COOKIE_POOL_OFFS) & 0xFF; -} - /* Release buffer to BM */ static inline void mvpp2_bm_pool_put(struct mvpp2_port *port, int pool, dma_addr_t buf_dma_addr, phys_addr_t buf_phys_addr) { - int cpu = smp_processor_id(); + int cpu = get_cpu();
if (port->priv->hw_version == MVPP22) { u32 val = 0; @@@ -3954,15 -3964,15 +3960,15 @@@ MVPP2_BM_VIRT_RLS_REG, buf_phys_addr); mvpp2_percpu_write(port->priv, cpu, MVPP2_BM_PHY_RLS_REG(pool), buf_dma_addr); + + put_cpu(); }
/* Refill BM pool */ -static void mvpp2_pool_refill(struct mvpp2_port *port, u32 bm, +static void mvpp2_pool_refill(struct mvpp2_port *port, int pool, dma_addr_t dma_addr, phys_addr_t phys_addr) { - int pool = mvpp2_bm_cookie_pool_get(bm); - mvpp2_bm_pool_put(port, pool, dma_addr, phys_addr); }
@@@ -4182,11 -4192,19 +4188,17 @@@ static void mvpp22_port_mii_set(struct { u32 val;
- return; - /* Only GOP port 0 has an XLG MAC */ if (port->gop_id == 0) { val = readl(port->base + MVPP22_XLG_CTRL3_REG); val &= ~MVPP22_XLG_CTRL3_MACMODESELECT_MASK; - val |= MVPP22_XLG_CTRL3_MACMODESELECT_GMAC; + + if (port->phy_interface == PHY_INTERFACE_MODE_XAUI || + port->phy_interface == PHY_INTERFACE_MODE_10GKR) + val |= MVPP22_XLG_CTRL3_MACMODESELECT_10G; + else + val |= MVPP22_XLG_CTRL3_MACMODESELECT_GMAC; + writel(val, port->base + MVPP22_XLG_CTRL3_REG); }
@@@ -4236,19 -4254,40 +4248,40 @@@ static void mvpp2_port_enable(struct mv { u32 val;
- val = readl(port->base + MVPP2_GMAC_CTRL_0_REG); - val |= MVPP2_GMAC_PORT_EN_MASK; - val |= MVPP2_GMAC_MIB_CNTR_EN_MASK; - writel(val, port->base + MVPP2_GMAC_CTRL_0_REG); + /* Only GOP port 0 has an XLG MAC */ + if (port->gop_id == 0 && + (port->phy_interface == PHY_INTERFACE_MODE_XAUI || + port->phy_interface == PHY_INTERFACE_MODE_10GKR)) { + val = readl(port->base + MVPP22_XLG_CTRL0_REG); + val |= MVPP22_XLG_CTRL0_PORT_EN | + MVPP22_XLG_CTRL0_MAC_RESET_DIS; + val &= ~MVPP22_XLG_CTRL0_MIB_CNT_DIS; + writel(val, port->base + MVPP22_XLG_CTRL0_REG); + } else { + val = readl(port->base + MVPP2_GMAC_CTRL_0_REG); + val |= MVPP2_GMAC_PORT_EN_MASK; + val |= MVPP2_GMAC_MIB_CNTR_EN_MASK; + writel(val, port->base + MVPP2_GMAC_CTRL_0_REG); + } }
static void mvpp2_port_disable(struct mvpp2_port *port) { u32 val;
- val = readl(port->base + MVPP2_GMAC_CTRL_0_REG); - val &= ~(MVPP2_GMAC_PORT_EN_MASK); - writel(val, port->base + MVPP2_GMAC_CTRL_0_REG); + /* Only GOP port 0 has an XLG MAC */ + if (port->gop_id == 0 && + (port->phy_interface == PHY_INTERFACE_MODE_XAUI || + port->phy_interface == PHY_INTERFACE_MODE_10GKR)) { + val = readl(port->base + MVPP22_XLG_CTRL0_REG); + val &= ~(MVPP22_XLG_CTRL0_PORT_EN | + MVPP22_XLG_CTRL0_MAC_RESET_DIS); + writel(val, port->base + MVPP22_XLG_CTRL0_REG); + } else { + val = readl(port->base + MVPP2_GMAC_CTRL_0_REG); + val &= ~(MVPP2_GMAC_PORT_EN_MASK); + writel(val, port->base + MVPP2_GMAC_CTRL_0_REG); + } }
/* Set IEEE 802.3x Flow Control Xon Packet Transmission Mode */ @@@ -4509,6 -4548,21 +4542,6 @@@ static void mvpp2_rxq_offset_set(struc mvpp2_write(port->priv, MVPP2_RXQ_CONFIG_REG(prxq), val); }
-/* Obtain BM cookie information from descriptor */ -static u32 mvpp2_bm_cookie_build(struct mvpp2_port *port, - struct mvpp2_rx_desc *rx_desc) -{ - int cpu = smp_processor_id(); - int pool; - - pool = (mvpp2_rxdesc_status_get(port, rx_desc) & - MVPP2_RXD_BM_POOL_ID_MASK) >> - MVPP2_RXD_BM_POOL_ID_OFFS; - - return ((pool & 0xFF) << MVPP2_BM_COOKIE_POOL_OFFS) | - ((cpu & 0xFF) << MVPP2_BM_COOKIE_CPU_OFFS); -} - /* Tx descriptors helper methods */
/* Get pointer to next Tx descriptor to be processed (send) by HW */ @@@ -4736,7 -4790,7 +4769,7 @@@ static void mvpp2_txp_max_tx_size_set(s static void mvpp2_rx_pkts_coal_set(struct mvpp2_port *port, struct mvpp2_rx_queue *rxq) { - int cpu = smp_processor_id(); + int cpu = get_cpu();
if (rxq->pkts_coal > MVPP2_OCCUPIED_THRESH_MASK) rxq->pkts_coal = MVPP2_OCCUPIED_THRESH_MASK; @@@ -4744,8 -4798,6 +4777,8 @@@ mvpp2_percpu_write(port->priv, cpu, MVPP2_RXQ_NUM_REG, rxq->id); mvpp2_percpu_write(port->priv, cpu, MVPP2_RXQ_THRESH_REG, rxq->pkts_coal); + + put_cpu(); }
static u32 mvpp2_usec_to_cycles(u32 usec, unsigned long clk_hz) @@@ -4926,7 -4978,7 +4959,7 @@@ static int mvpp2_rxq_init(struct mvpp2_ mvpp2_write(port->priv, MVPP2_RXQ_STATUS_REG(rxq->id), 0);
/* Set Rx descriptors queue starting address - indirect access */ - cpu = smp_processor_id(); + cpu = get_cpu(); mvpp2_percpu_write(port->priv, cpu, MVPP2_RXQ_NUM_REG, rxq->id); if (port->priv->hw_version == MVPP21) rxq_dma = rxq->descs_dma; @@@ -4935,7 -4987,6 +4968,7 @@@ mvpp2_percpu_write(port->priv, cpu, MVPP2_RXQ_DESC_ADDR_REG, rxq_dma); mvpp2_percpu_write(port->priv, cpu, MVPP2_RXQ_DESC_SIZE_REG, rxq->size); mvpp2_percpu_write(port->priv, cpu, MVPP2_RXQ_INDEX_REG, 0); + put_cpu();
/* Set Offset */ mvpp2_rxq_offset_set(port, rxq->id, NET_SKB_PAD); @@@ -4962,13 -5013,9 +4995,13 @@@ static void mvpp2_rxq_drop_pkts(struct
for (i = 0; i < rx_received; i++) { struct mvpp2_rx_desc *rx_desc = mvpp2_rxq_next_desc_get(rxq); - u32 bm = mvpp2_bm_cookie_build(port, rx_desc); + u32 status = mvpp2_rxdesc_status_get(port, rx_desc); + int pool; + + pool = (status & MVPP2_RXD_BM_POOL_ID_MASK) >> + MVPP2_RXD_BM_POOL_ID_OFFS;
- mvpp2_pool_refill(port, bm, + mvpp2_pool_refill(port, pool, mvpp2_rxdesc_dma_addr_get(port, rx_desc), mvpp2_rxdesc_cookie_get(port, rx_desc)); } @@@ -4998,11 -5045,10 +5031,11 @@@ static void mvpp2_rxq_deinit(struct mvp * free descriptor number */ mvpp2_write(port->priv, MVPP2_RXQ_STATUS_REG(rxq->id), 0); - cpu = smp_processor_id(); + cpu = get_cpu(); mvpp2_percpu_write(port->priv, cpu, MVPP2_RXQ_NUM_REG, rxq->id); mvpp2_percpu_write(port->priv, cpu, MVPP2_RXQ_DESC_ADDR_REG, 0); mvpp2_percpu_write(port->priv, cpu, MVPP2_RXQ_DESC_SIZE_REG, 0); + put_cpu(); }
/* Create and initialize a Tx queue */ @@@ -5025,7 -5071,7 +5058,7 @@@ static int mvpp2_txq_init(struct mvpp2_ txq->last_desc = txq->size - 1;
/* Set Tx descriptors queue starting address - indirect access */ - cpu = smp_processor_id(); + cpu = get_cpu(); mvpp2_percpu_write(port->priv, cpu, MVPP2_TXQ_NUM_REG, txq->id); mvpp2_percpu_write(port->priv, cpu, MVPP2_TXQ_DESC_ADDR_REG, txq->descs_dma); @@@ -5050,7 -5096,6 +5083,7 @@@ mvpp2_percpu_write(port->priv, cpu, MVPP2_TXQ_PREF_BUF_REG, MVPP2_PREF_BUF_PTR(desc) | MVPP2_PREF_BUF_SIZE_16 | MVPP2_PREF_BUF_THRESH(desc_per_txq / 2)); + put_cpu();
/* WRR / EJP configuration - indirect access */ tx_port_num = mvpp2_egress_port(port); @@@ -5121,11 -5166,10 +5154,11 @@@ static void mvpp2_txq_deinit(struct mvp mvpp2_write(port->priv, MVPP2_TXQ_SCHED_TOKEN_CNTR_REG(txq->id), 0);
/* Set Tx descriptors queue starting address and size */ - cpu = smp_processor_id(); + cpu = get_cpu(); mvpp2_percpu_write(port->priv, cpu, MVPP2_TXQ_NUM_REG, txq->id); mvpp2_percpu_write(port->priv, cpu, MVPP2_TXQ_DESC_ADDR_REG, 0); mvpp2_percpu_write(port->priv, cpu, MVPP2_TXQ_DESC_SIZE_REG, 0); + put_cpu(); }
/* Cleanup Tx ports */ @@@ -5135,7 -5179,7 +5168,7 @@@ static void mvpp2_txq_clean(struct mvpp int delay, pending, cpu; u32 val;
- cpu = smp_processor_id(); + cpu = get_cpu(); mvpp2_percpu_write(port->priv, cpu, MVPP2_TXQ_NUM_REG, txq->id); val = mvpp2_percpu_read(port->priv, cpu, MVPP2_TXQ_PREF_BUF_REG); val |= MVPP2_TXQ_DRAIN_EN_MASK; @@@ -5162,7 -5206,6 +5195,7 @@@
val &= ~MVPP2_TXQ_DRAIN_EN_MASK; mvpp2_percpu_write(port->priv, cpu, MVPP2_TXQ_PREF_BUF_REG, val); + put_cpu();
for_each_present_cpu(cpu) { txq_pcpu = per_cpu_ptr(txq->pcpu, cpu); @@@ -5410,7 -5453,7 +5443,7 @@@ static void mvpp2_rx_csum(struct mvpp2_
/* Reuse skb if possible, or allocate a new skb and add it to BM pool */ static int mvpp2_rx_refill(struct mvpp2_port *port, - struct mvpp2_bm_pool *bm_pool, u32 bm) + struct mvpp2_bm_pool *bm_pool, int pool) { dma_addr_t dma_addr; phys_addr_t phys_addr; @@@ -5422,7 -5465,7 +5455,7 @@@ if (!buf) return -ENOMEM;
- mvpp2_pool_refill(port, bm, dma_addr, phys_addr); + mvpp2_pool_refill(port, pool, dma_addr, phys_addr);
return 0; } @@@ -5480,7 -5523,7 +5513,7 @@@ static int mvpp2_rx(struct mvpp2_port * unsigned int frag_size; dma_addr_t dma_addr; phys_addr_t phys_addr; - u32 bm, rx_status; + u32 rx_status; int pool, rx_bytes, err; void *data;
@@@ -5492,8 -5535,8 +5525,8 @@@ phys_addr = mvpp2_rxdesc_cookie_get(port, rx_desc); data = (void *)phys_to_virt(phys_addr);
- bm = mvpp2_bm_cookie_build(port, rx_desc); - pool = mvpp2_bm_cookie_pool_get(bm); + pool = (rx_status & MVPP2_RXD_BM_POOL_ID_MASK) >> + MVPP2_RXD_BM_POOL_ID_OFFS; bm_pool = &port->priv->bm_pools[pool];
/* In case of an error, release the requested buffer pointer @@@ -5506,7 -5549,7 +5539,7 @@@ err_drop_frame dev->stats.rx_errors++; mvpp2_rx_error(port, rx_desc); /* Return the buffer to the pool */ - mvpp2_pool_refill(port, bm, dma_addr, phys_addr); + mvpp2_pool_refill(port, pool, dma_addr, phys_addr); continue; }
@@@ -5521,7 -5564,7 +5554,7 @@@ goto err_drop_frame; }
- err = mvpp2_rx_refill(port, bm_pool, bm); + err = mvpp2_rx_refill(port, bm_pool, pool); if (err) { netdev_err(port->dev, "failed to refill BM pools\n"); goto err_drop_frame; diff --combined drivers/net/ethernet/mellanox/mlx5/core/en.h index 944fc1742464,f4b95dbd1c7f..a0516b0a5273 --- a/drivers/net/ethernet/mellanox/mlx5/core/en.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h @@@ -458,15 -458,13 +458,15 @@@ struct mlx5e_mpw_info
struct mlx5e_rx_am_stats { int ppms; /* packets per msec */ + int bpms; /* bytes per msec */ int epms; /* events per msec */ };
struct mlx5e_rx_am_sample { - ktime_t time; - unsigned int pkt_ctr; - u16 event_ctr; + ktime_t time; + u32 pkt_ctr; + u32 byte_ctr; + u16 event_ctr; };
struct mlx5e_rx_am { /* Adaptive Moderation */ @@@ -625,6 -623,8 +625,8 @@@ struct mlx5e_tc_table
struct rhashtable_params ht_params; struct rhashtable ht; + + DECLARE_HASHTABLE(mod_hdr_tbl, 8); };
struct mlx5e_vlan_table { diff --combined drivers/net/ethernet/mellanox/mlx5/core/fs_core.c index 8f5125ccd8d4,6c636c21d24f..6380c2db355a --- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c @@@ -376,11 -376,9 +376,9 @@@ static void del_rule(struct fs_node *no int err; bool update_fte = false;
- match_value = mlx5_vzalloc(match_len); - if (!match_value) { - mlx5_core_warn(dev, "failed to allocate inbox\n"); + match_value = kvzalloc(match_len, GFP_KERNEL); + if (!match_value) return; - }
fs_get_obj(rule, node); fs_get_obj(fte, rule->node.parent); @@@ -862,7 -860,7 +860,7 @@@ struct mlx5_flow_table *mlx5_create_vpo ft_attr.level = level; ft_attr.prio = prio;
- return __mlx5_create_flow_table(ns, &ft_attr, FS_FT_OP_MOD_NORMAL, 0); + return __mlx5_create_flow_table(ns, &ft_attr, FS_FT_OP_MOD_NORMAL, vport); }
struct mlx5_flow_table* @@@ -1157,7 -1155,7 +1155,7 @@@ static struct mlx5_flow_group *create_a if (!ft->autogroup.active) return ERR_PTR(-ENOENT);
- in = mlx5_vzalloc(inlen); + in = kvzalloc(inlen, GFP_KERNEL); if (!in) return ERR_PTR(-ENOMEM);
@@@ -1777,7 -1775,7 +1775,7 @@@ static struct mlx5_flow_root_namespace struct mlx5_flow_namespace *ns;
/* Create the root namespace */ - root_ns = mlx5_vzalloc(sizeof(*root_ns)); + root_ns = kvzalloc(sizeof(*root_ns), GFP_KERNEL); if (!root_ns) return NULL;
diff --combined drivers/net/ethernet/mellanox/mlx5/core/health.c index f27f84ffbc85,80b23333de7a..c6679b21884e --- a/drivers/net/ethernet/mellanox/mlx5/core/health.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/health.c @@@ -185,6 -185,7 +185,7 @@@ static void health_care(struct work_str struct mlx5_core_health *health; struct mlx5_core_dev *dev; struct mlx5_priv *priv; + unsigned long flags;
health = container_of(work, struct mlx5_core_health, work); priv = container_of(health, struct mlx5_priv, health); @@@ -192,13 -193,13 +193,13 @@@ mlx5_core_warn(dev, "handling bad device here\n"); mlx5_handle_bad_state(dev);
- spin_lock(&health->wq_lock); + spin_lock_irqsave(&health->wq_lock, flags); if (!test_bit(MLX5_DROP_NEW_HEALTH_WORK, &health->flags)) schedule_delayed_work(&health->recover_work, recover_delay); else dev_err(&dev->pdev->dev, "new health works are not permitted at this stage\n"); - spin_unlock(&health->wq_lock); + spin_unlock_irqrestore(&health->wq_lock, flags); }
static const char *hsynd_str(u8 synd) @@@ -269,14 -270,30 +270,28 @@@ static unsigned long get_next_poll_jiff return next; }
+ void mlx5_trigger_health_work(struct mlx5_core_dev *dev) + { + struct mlx5_core_health *health = &dev->priv.health; + unsigned long flags; + + spin_lock_irqsave(&health->wq_lock, flags); + if (!test_bit(MLX5_DROP_NEW_HEALTH_WORK, &health->flags)) + queue_work(health->wq, &health->work); + else + dev_err(&dev->pdev->dev, + "new health works are not permitted at this stage\n"); + spin_unlock_irqrestore(&health->wq_lock, flags); + } + static void poll_health(unsigned long data) { struct mlx5_core_dev *dev = (struct mlx5_core_dev *)data; struct mlx5_core_health *health = &dev->priv.health; u32 count;
- if (dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR) { - mod_timer(&health->timer, get_next_poll_jiffies()); - return; - } + if (dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR) + goto out;
count = ioread32be(health->health_counter); if (count == health->prev) @@@ -288,22 -305,15 +303,16 @@@ if (health->miss_counter == MAX_MISSES) { dev_err(&dev->pdev->dev, "device's health compromised - reached miss count\n"); print_health_info(dev); - } else { - mod_timer(&health->timer, get_next_poll_jiffies()); }
if (in_fatal(dev) && !health->sick) { health->sick = true; print_health_info(dev); - spin_lock(&health->wq_lock); - if (!test_bit(MLX5_DROP_NEW_HEALTH_WORK, &health->flags)) - queue_work(health->wq, &health->work); - else - dev_err(&dev->pdev->dev, - "new health works are not permitted at this stage\n"); - spin_unlock(&health->wq_lock); + mlx5_trigger_health_work(dev); } + +out: + mod_timer(&health->timer, get_next_poll_jiffies()); }
void mlx5_start_health_poll(struct mlx5_core_dev *dev) @@@ -332,10 -342,11 +341,11 @@@ void mlx5_stop_health_poll(struct mlx5_ void mlx5_drain_health_wq(struct mlx5_core_dev *dev) { struct mlx5_core_health *health = &dev->priv.health; + unsigned long flags;
- spin_lock(&health->wq_lock); + spin_lock_irqsave(&health->wq_lock, flags); set_bit(MLX5_DROP_NEW_HEALTH_WORK, &health->flags); - spin_unlock(&health->wq_lock); + spin_unlock_irqrestore(&health->wq_lock, flags); cancel_delayed_work_sync(&health->recover_work); cancel_work_sync(&health->work); } diff --combined drivers/net/ethernet/mellanox/mlx5/core/main.c index 4f577a5abf88,9274d93d3183..dc890944c4ea --- a/drivers/net/ethernet/mellanox/mlx5/core/main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c @@@ -56,6 -56,7 +56,7 @@@ #ifdef CONFIG_MLX5_CORE_EN #include "eswitch.h" #endif + #include "fpga/core.h"
MODULE_AUTHOR("Eli Cohen eli@mellanox.com"); MODULE_DESCRIPTION("Mellanox Connect-IB, ConnectX-4 core driver"); @@@ -537,10 -538,8 +538,10 @@@ static int handle_hca_cap(struct mlx5_c /* disable cmdif checksum */ MLX5_SET(cmd_hca_cap, set_hca_cap, cmdif_checksum, 0);
- /* If the HCA supports 4K UARs use it */ - if (MLX5_CAP_GEN_MAX(dev, uar_4k)) + /* Enable 4K UAR only when HCA supports it and page size is bigger + * than 4K. + */ + if (MLX5_CAP_GEN_MAX(dev, uar_4k) && PAGE_SIZE > 4096) MLX5_SET(cmd_hca_cap, set_hca_cap, uar_4k, 1);
MLX5_SET(cmd_hca_cap, set_hca_cap, log_uar_page_sz, PAGE_SHIFT - 12); @@@ -1107,10 -1106,16 +1108,16 @@@ static int mlx5_load_one(struct mlx5_co goto err_disable_msix; }
+ err = mlx5_fpga_device_init(dev); + if (err) { + dev_err(&pdev->dev, "fpga device init failed %d\n", err); + goto err_put_uars; + } + err = mlx5_start_eqs(dev); if (err) { dev_err(&pdev->dev, "Failed to start pages and async EQs\n"); - goto err_put_uars; + goto err_fpga_init; }
err = alloc_comp_eqs(dev); @@@ -1141,6 -1146,12 +1148,12 @@@ goto err_sriov; }
+ err = mlx5_fpga_device_start(dev); + if (err) { + dev_err(&pdev->dev, "fpga device start failed %d\n", err); + goto err_reg_dev; + } + if (mlx5_device_registered(dev)) { mlx5_attach_device(dev); } else { @@@ -1176,6 -1187,9 +1189,9 @@@ err_affinity_hints err_stop_eqs: mlx5_stop_eqs(dev);
+ err_fpga_init: + mlx5_fpga_device_cleanup(dev); + err_put_uars: mlx5_put_uars_page(dev, priv->uar);
@@@ -1240,6 -1254,7 +1256,7 @@@ static int mlx5_unload_one(struct mlx5_ mlx5_irq_clear_affinity_hints(dev); free_comp_eqs(dev); mlx5_stop_eqs(dev); + mlx5_fpga_device_cleanup(dev); mlx5_put_uars_page(dev, priv->uar); mlx5_disable_msix(dev); if (cleanup) @@@ -1514,6 -1529,8 +1531,8 @@@ static const struct pci_device_id mlx5_ { PCI_VDEVICE(MELLANOX, 0x101a), MLX5_PCI_DEV_IS_VF}, /* ConnectX-5 Ex VF */ { PCI_VDEVICE(MELLANOX, 0x101b) }, /* ConnectX-6 */ { PCI_VDEVICE(MELLANOX, 0x101c), MLX5_PCI_DEV_IS_VF}, /* ConnectX-6 VF */ + { PCI_VDEVICE(MELLANOX, 0xa2d2) }, /* BlueField integrated ConnectX-5 network controller */ + { PCI_VDEVICE(MELLANOX, 0xa2d3), MLX5_PCI_DEV_IS_VF}, /* BlueField integrated ConnectX-5 network controller VF */ { 0, } };
diff --combined drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index d16d11bfc046,f446f368dd20..6a1cb59728fe --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@@ -235,6 -235,17 +235,17 @@@ static void stmmac_clk_csr_set(struct s else if ((clk_rate >= CSR_F_250M) && (clk_rate < CSR_F_300M)) priv->clk_csr = STMMAC_CSR_250_300M; } + + if (priv->plat->has_sun8i) { + if (clk_rate > 160000000) + priv->clk_csr = 0x03; + else if (clk_rate > 80000000) + priv->clk_csr = 0x02; + else if (clk_rate > 40000000) + priv->clk_csr = 0x01; + else + priv->clk_csr = 0; + } }
static void print_pkt(unsigned char *buf, int len) @@@ -434,14 -445,14 +445,14 @@@ static void stmmac_get_tx_hwtstamp(stru return;
/* check tx tstamp status */ - if (!priv->hw->desc->get_tx_timestamp_status(p)) { + if (priv->hw->desc->get_tx_timestamp_status(p)) { /* get the valid tstamp */ ns = priv->hw->desc->get_timestamp(p, priv->adv_ts);
memset(&shhwtstamp, 0, sizeof(struct skb_shared_hwtstamps)); shhwtstamp.hwtstamp = ns_to_ktime(ns);
- netdev_info(priv->dev, "get valid TX hw timestamp %llu\n", ns); + netdev_dbg(priv->dev, "get valid TX hw timestamp %llu\n", ns); /* pass tstamp to stack */ skb_tstamp_tx(skb, &shhwtstamp); } @@@ -468,19 -479,19 +479,19 @@@ static void stmmac_get_rx_hwtstamp(stru return;
/* Check if timestamp is available */ - if (!priv->hw->desc->get_rx_timestamp_status(p, priv->adv_ts)) { + if (priv->hw->desc->get_rx_timestamp_status(p, priv->adv_ts)) { /* For GMAC4, the valid timestamp is from CTX next desc. */ if (priv->plat->has_gmac4) ns = priv->hw->desc->get_timestamp(np, priv->adv_ts); else ns = priv->hw->desc->get_timestamp(p, priv->adv_ts);
- netdev_info(priv->dev, "get valid RX hw timestamp %llu\n", ns); + netdev_dbg(priv->dev, "get valid RX hw timestamp %llu\n", ns); shhwtstamp = skb_hwtstamps(skb); memset(shhwtstamp, 0, sizeof(struct skb_shared_hwtstamps)); shhwtstamp->hwtstamp = ns_to_ktime(ns); } else { - netdev_err(priv->dev, "cannot get RX hw timestamp\n"); + netdev_dbg(priv->dev, "cannot get RX hw timestamp\n"); } }
@@@ -546,10 -557,7 +557,10 @@@ static int stmmac_hwtstamp_ioctl(struc /* PTP v1, UDP, any kind of event packet */ config.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT; /* take time stamp for all event messages */ - snap_type_sel = PTP_TCR_SNAPTYPSEL_1; + if (priv->plat->has_gmac4) + snap_type_sel = PTP_GMAC4_TCR_SNAPTYPSEL_1; + else + snap_type_sel = PTP_TCR_SNAPTYPSEL_1;
ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA; ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA; @@@ -581,10 -589,7 +592,10 @@@ config.rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT; ptp_v2 = PTP_TCR_TSVER2ENA; /* take time stamp for all event messages */ - snap_type_sel = PTP_TCR_SNAPTYPSEL_1; + if (priv->plat->has_gmac4) + snap_type_sel = PTP_GMAC4_TCR_SNAPTYPSEL_1; + else + snap_type_sel = PTP_TCR_SNAPTYPSEL_1;
ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA; ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA; @@@ -618,10 -623,7 +629,10 @@@ config.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; ptp_v2 = PTP_TCR_TSVER2ENA; /* take time stamp for all event messages */ - snap_type_sel = PTP_TCR_SNAPTYPSEL_1; + if (priv->plat->has_gmac4) + snap_type_sel = PTP_GMAC4_TCR_SNAPTYPSEL_1; + else + snap_type_sel = PTP_TCR_SNAPTYPSEL_1;
ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA; ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA; @@@ -653,6 -655,7 +664,7 @@@ ptp_over_ethernet = PTP_TCR_TSIPENA; break;
+ case HWTSTAMP_FILTER_NTP_ALL: case HWTSTAMP_FILTER_ALL: /* time stamp any incoming packet */ config.rx_filter = HWTSTAMP_FILTER_ALL; @@@ -783,7 -786,7 +795,7 @@@ static void stmmac_adjust_link(struct n struct stmmac_priv *priv = netdev_priv(dev); struct phy_device *phydev = dev->phydev; unsigned long flags; - int new_state = 0; + bool new_state = false;
if (!phydev) return; @@@ -796,8 -799,8 +808,8 @@@ /* Now we make sure that we can be in full duplex mode. * If not, we operate in half-duplex mode. */ if (phydev->duplex != priv->oldduplex) { - new_state = 1; - if (!(phydev->duplex)) + new_state = true; + if (!phydev->duplex) ctrl &= ~priv->hw->link.duplex; else ctrl |= priv->hw->link.duplex; @@@ -808,30 -811,17 +820,17 @@@ stmmac_mac_flow_ctrl(priv, phydev->duplex);
if (phydev->speed != priv->speed) { - new_state = 1; + new_state = true; + ctrl &= ~priv->hw->link.speed_mask; switch (phydev->speed) { - case 1000: - if (priv->plat->has_gmac || - priv->plat->has_gmac4) - ctrl &= ~priv->hw->link.port; + case SPEED_1000: + ctrl |= priv->hw->link.speed1000; break; - case 100: - if (priv->plat->has_gmac || - priv->plat->has_gmac4) { - ctrl |= priv->hw->link.port; - ctrl |= priv->hw->link.speed; - } else { - ctrl &= ~priv->hw->link.port; - } + case SPEED_100: + ctrl |= priv->hw->link.speed100; break; - case 10: - if (priv->plat->has_gmac || - priv->plat->has_gmac4) { - ctrl |= priv->hw->link.port; - ctrl &= ~(priv->hw->link.speed); - } else { - ctrl &= ~priv->hw->link.port; - } + case SPEED_10: + ctrl |= priv->hw->link.speed10; break; default: netif_warn(priv, link, priv->dev, @@@ -847,12 -837,12 +846,12 @@@ writel(ctrl, priv->ioaddr + MAC_CTRL_REG);
if (!priv->oldlink) { - new_state = 1; - priv->oldlink = 1; + new_state = true; + priv->oldlink = true; } } else if (priv->oldlink) { - new_state = 1; - priv->oldlink = 0; + new_state = true; + priv->oldlink = false; priv->speed = SPEED_UNKNOWN; priv->oldduplex = DUPLEX_UNKNOWN; } @@@ -915,7 -905,7 +914,7 @@@ static int stmmac_init_phy(struct net_d char bus_id[MII_BUS_ID_SIZE]; int interface = priv->plat->interface; int max_speed = priv->plat->max_speed; - priv->oldlink = 0; + priv->oldlink = false; priv->speed = SPEED_UNKNOWN; priv->oldduplex = DUPLEX_UNKNOWN;
@@@ -2888,8 -2878,7 +2887,7 @@@ static netdev_tx_t stmmac_tso_xmit(stru priv->xstats.tx_set_ic_bit++; }
- if (!priv->hwts_tx_en) - skb_tx_timestamp(skb); + skb_tx_timestamp(skb);
if (unlikely((skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) && priv->hwts_tx_en)) { @@@ -3093,8 -3082,7 +3091,7 @@@ static netdev_tx_t stmmac_xmit(struct s priv->xstats.tx_set_ic_bit++; }
- if (!priv->hwts_tx_en) - skb_tx_timestamp(skb); + skb_tx_timestamp(skb);
/* Ready to fill the first descriptor and set the OWN bit w/o any * problems because all the descriptors are actually ready to be @@@ -3957,7 -3945,9 +3954,9 @@@ static int stmmac_hw_init(struct stmmac struct mac_device_info *mac;
/* Identify the MAC HW device */ - if (priv->plat->has_gmac) { + if (priv->plat->setup) { + mac = priv->plat->setup(priv); + } else if (priv->plat->has_gmac) { priv->dev->priv_flags |= IFF_UNICAST_FLT; mac = dwmac1000_setup(priv->ioaddr, priv->plat->multicast_filter_bins, @@@ -3977,6 -3967,10 +3976,10 @@@
priv->hw = mac;
+ /* dwmac-sun8i only work in chain mode */ + if (priv->plat->has_sun8i) + chain_mode = 1; + /* To use the chained or ring mode */ if (priv->synopsys_id >= DWMAC_CORE_4_00) { priv->hw->mode = &dwmac4_ring_mode_ops; @@@ -4302,7 -4296,7 +4305,7 @@@ int stmmac_suspend(struct device *dev } spin_unlock_irqrestore(&priv->lock, flags);
- priv->oldlink = 0; + priv->oldlink = false; priv->speed = SPEED_UNKNOWN; priv->oldduplex = DUPLEX_UNKNOWN; return 0; diff --combined drivers/net/geneve.c index 199459bd6961,ff626dbde23f..7bcf1b52020e --- a/drivers/net/geneve.c +++ b/drivers/net/geneve.c @@@ -212,6 -212,7 +212,7 @@@ static void geneve_rx(struct geneve_de struct genevehdr *gnvh = geneve_hdr(skb); struct metadata_dst *tun_dst = NULL; struct pcpu_sw_netstats *stats; + unsigned int len; int err = 0; void *oiph;
@@@ -225,8 -226,10 +226,10 @@@ tun_dst = udp_tun_rx_dst(skb, geneve_get_sk_family(gs), flags, vni_to_tunnel_id(gnvh->vni), gnvh->opt_len * 4); - if (!tun_dst) + if (!tun_dst) { + geneve->dev->stats.rx_dropped++; goto drop; + } /* Update tunnel dst according to Geneve options. */ ip_tunnel_info_opts_set(&tun_dst->u.tun_info, gnvh->options, gnvh->opt_len * 4); @@@ -234,8 -237,11 +237,11 @@@ /* Drop packets w/ critical options, * since we don't support any... */ - if (gnvh->critical) + if (gnvh->critical) { + geneve->dev->stats.rx_frame_errors++; + geneve->dev->stats.rx_errors++; goto drop; + } }
skb_reset_mac_header(skb); @@@ -246,8 -252,10 +252,10 @@@ skb_dst_set(skb, &tun_dst->dst);
/* Ignore packet loops (and multicast echo) */ - if (ether_addr_equal(eth_hdr(skb)->h_source, geneve->dev->dev_addr)) + if (ether_addr_equal(eth_hdr(skb)->h_source, geneve->dev->dev_addr)) { + geneve->dev->stats.rx_errors++; goto drop; + }
oiph = skb_network_header(skb); skb_reset_network_header(skb); @@@ -279,13 -287,15 +287,15 @@@ } }
- stats = this_cpu_ptr(geneve->dev->tstats); - u64_stats_update_begin(&stats->syncp); - stats->rx_packets++; - stats->rx_bytes += skb->len; - u64_stats_update_end(&stats->syncp); - - gro_cells_receive(&geneve->gro_cells, skb); + len = skb->len; + err = gro_cells_receive(&geneve->gro_cells, skb); + if (likely(err == NET_RX_SUCCESS)) { + stats = this_cpu_ptr(geneve->dev->tstats); + u64_stats_update_begin(&stats->syncp); + stats->rx_packets++; + stats->rx_bytes += len; + u64_stats_update_end(&stats->syncp); + } return; drop: /* Consume bad packet */ @@@ -334,7 -344,7 +344,7 @@@ static int geneve_udp_encap_recv(struc struct geneve_sock *gs; int opts_len;
- /* Need Geneve and inner Ethernet header to be present */ + /* Need UDP and Geneve header to be present */ if (unlikely(!pskb_may_pull(skb, GENEVE_BASE_HLEN))) goto drop;
@@@ -357,8 -367,10 +367,10 @@@ opts_len = geneveh->opt_len * 4; if (iptunnel_pull_header(skb, GENEVE_BASE_HLEN + opts_len, htons(ETH_P_TEB), - !net_eq(geneve->net, dev_net(geneve->dev)))) + !net_eq(geneve->net, dev_net(geneve->dev)))) { + geneve->dev->stats.rx_dropped++; goto drop; + }
geneve_rx(geneve, gs, skb); return 0; @@@ -1007,7 -1019,7 +1019,7 @@@ static void geneve_setup(struct net_dev
dev->netdev_ops = &geneve_netdev_ops; dev->ethtool_ops = &geneve_ethtool_ops; - dev->destructor = free_netdev; + dev->needs_free_netdev = true;
SET_NETDEV_DEVTYPE(dev, &geneve_type);
diff --combined drivers/net/hyperv/hyperv_net.h index 6066f1bcaf2d,f82d54e0208c..b30a3c2f772b --- a/drivers/net/hyperv/hyperv_net.h +++ b/drivers/net/hyperv/hyperv_net.h @@@ -171,8 -171,6 +171,8 @@@ struct rndis_device spinlock_t request_lock; struct list_head req_list;
+ struct work_struct mcast_work; + u8 hw_mac_adr[ETH_ALEN]; u8 rss_key[NETVSC_HASH_KEYLEN]; u16 ind_table[ITAB_NUM]; @@@ -203,7 -201,6 +203,7 @@@ int rndis_filter_open(struct netvsc_dev int rndis_filter_close(struct netvsc_device *nvdev); int rndis_filter_device_add(struct hv_device *dev, struct netvsc_device_info *info); +void rndis_filter_update(struct netvsc_device *nvdev); void rndis_filter_device_remove(struct hv_device *dev, struct netvsc_device *nvdev); int rndis_filter_set_rss_param(struct rndis_device *rdev, @@@ -214,6 -211,7 +214,6 @@@ int rndis_filter_receive(struct net_dev struct vmbus_channel *channel, void *data, u32 buflen);
-int rndis_filter_set_packet_filter(struct rndis_device *dev, u32 new_filter); int rndis_filter_set_device_mac(struct net_device *ndev, char *mac);
void netvsc_switch_datapath(struct net_device *nv_dev, bool vf); @@@ -698,6 -696,7 +698,6 @@@ struct net_device_context /* list protection */ spinlock_t lock;
- struct work_struct work; u32 msg_enable; /* debug level */
u32 tx_checksum_mask; @@@ -764,8 -763,7 +764,7 @@@ struct netvsc_device
refcount_t sc_offered;
- /* Holds rndis device info */ - void *extension; + struct rndis_device *extension;
int ring_size;
diff --combined drivers/net/hyperv/netvsc_drv.c index 82d6c022ca85,436a3ad55cfd..b65a97ecb78e --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c @@@ -37,6 -37,8 +37,8 @@@ #include <net/route.h> #include <net/sock.h> #include <net/pkt_sched.h> + #include <net/checksum.h> + #include <net/ip6_checksum.h>
#include "hyperv_net.h"
@@@ -56,12 -58,37 +58,12 @@@ static int debug = -1 module_param(debug, int, S_IRUGO); MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
-static void do_set_multicast(struct work_struct *w) -{ - struct net_device_context *ndevctx = - container_of(w, struct net_device_context, work); - struct hv_device *device_obj = ndevctx->device_ctx; - struct net_device *ndev = hv_get_drvdata(device_obj); - struct netvsc_device *nvdev = rcu_dereference(ndevctx->nvdev); - struct rndis_device *rdev; - - if (!nvdev) - return; - - rdev = nvdev->extension; - if (rdev == NULL) - return; - - if (ndev->flags & IFF_PROMISC) - rndis_filter_set_packet_filter(rdev, - NDIS_PACKET_TYPE_PROMISCUOUS); - else - rndis_filter_set_packet_filter(rdev, - NDIS_PACKET_TYPE_BROADCAST | - NDIS_PACKET_TYPE_ALL_MULTICAST | - NDIS_PACKET_TYPE_DIRECTED); -} - static void netvsc_set_multicast_list(struct net_device *net) { struct net_device_context *net_device_ctx = netdev_priv(net); + struct netvsc_device *nvdev = rtnl_dereference(net_device_ctx->nvdev);
- schedule_work(&net_device_ctx->work); + rndis_filter_update(nvdev); }
static int netvsc_open(struct net_device *net) @@@ -93,11 -120,13 +95,11 @@@ static int netvsc_close(struct net_devi struct net_device_context *net_device_ctx = netdev_priv(net); struct netvsc_device *nvdev = rtnl_dereference(net_device_ctx->nvdev); int ret; - u32 aread, awrite, i, msec = 10, retry = 0, retry_max = 20; + u32 aread, i, msec = 10, retry = 0, retry_max = 20; struct vmbus_channel *chn;
netif_tx_disable(net);
- /* Make sure netvsc_set_multicast_list doesn't re-enable filter! */ - cancel_work_sync(&net_device_ctx->work); ret = rndis_filter_close(nvdev); if (ret != 0) { netdev_err(net, "unable to close device (ret %d).\n", ret); @@@ -112,15 -141,11 +114,11 @@@ if (!chn) continue;
- hv_get_ringbuffer_availbytes(&chn->inbound, &aread, - &awrite); - + aread = hv_get_bytes_to_read(&chn->inbound); if (aread) break;
- hv_get_ringbuffer_availbytes(&chn->outbound, &aread, - &awrite); - + aread = hv_get_bytes_to_read(&chn->outbound); if (aread) break; } @@@ -316,34 -341,14 +314,14 @@@ static u32 init_page_array(void *hdr, u return slots_used; }
- static int count_skb_frag_slots(struct sk_buff *skb) - { - int i, frags = skb_shinfo(skb)->nr_frags; - int pages = 0; - - for (i = 0; i < frags; i++) { - skb_frag_t *frag = skb_shinfo(skb)->frags + i; - unsigned long size = skb_frag_size(frag); - unsigned long offset = frag->page_offset; - - /* Skip unused frames from start of page */ - offset &= ~PAGE_MASK; - pages += PFN_UP(offset + size); - } - return pages; - } - - static int netvsc_get_slots(struct sk_buff *skb) + /* Estimate number of page buffers neede to transmit + * Need at most 2 for RNDIS header plus skb body and fragments. + */ + static unsigned int netvsc_get_slots(const struct sk_buff *skb) { - char *data = skb->data; - unsigned int offset = offset_in_page(data); - unsigned int len = skb_headlen(skb); - int slots; - int frag_slots; - - slots = DIV_ROUND_UP(offset + len, PAGE_SIZE); - frag_slots = count_skb_frag_slots(skb); - return slots + frag_slots; + return PFN_UP(offset_in_page(skb->data) + skb_headlen(skb)) + + skb_shinfo(skb)->nr_frags + + 2; }
static u32 net_checksum_info(struct sk_buff *skb) @@@ -381,21 -386,18 +359,18 @@@ static int netvsc_start_xmit(struct sk_ struct hv_page_buffer page_buf[MAX_PAGE_BUFFER_COUNT]; struct hv_page_buffer *pb = page_buf;
- /* We will atmost need two pages to describe the rndis - * header. We can only transmit MAX_PAGE_BUFFER_COUNT number + /* We can only transmit MAX_PAGE_BUFFER_COUNT number * of pages in a single packet. If skb is scattered around * more pages we try linearizing it. */ - - num_data_pgs = netvsc_get_slots(skb) + 2; - + num_data_pgs = netvsc_get_slots(skb); if (unlikely(num_data_pgs > MAX_PAGE_BUFFER_COUNT)) { ++net_device_ctx->eth_stats.tx_scattered;
if (skb_linearize(skb)) goto no_memory;
- num_data_pgs = netvsc_get_slots(skb) + 2; + num_data_pgs = netvsc_get_slots(skb); if (num_data_pgs > MAX_PAGE_BUFFER_COUNT) { ++net_device_ctx->eth_stats.tx_too_big; goto drop; @@@ -1001,7 -1003,7 +976,7 @@@ static const struct static int netvsc_get_sset_count(struct net_device *dev, int string_set) { struct net_device_context *ndc = netdev_priv(dev); - struct netvsc_device *nvdev = rcu_dereference(ndc->nvdev); + struct netvsc_device *nvdev = rtnl_dereference(ndc->nvdev);
if (!nvdev) return -ENODEV; @@@ -1131,22 -1133,11 +1106,22 @@@ netvsc_get_rxnfc(struct net_device *dev }
#ifdef CONFIG_NET_POLL_CONTROLLER -static void netvsc_poll_controller(struct net_device *net) +static void netvsc_poll_controller(struct net_device *dev) { - /* As netvsc_start_xmit() works synchronous we don't have to - * trigger anything here. - */ + struct net_device_context *ndc = netdev_priv(dev); + struct netvsc_device *ndev; + int i; + + rcu_read_lock(); + ndev = rcu_dereference(ndc->nvdev); + if (ndev) { + for (i = 0; i < ndev->num_chn; i++) { + struct netvsc_channel *nvchan = &ndev->chan_table[i]; + + napi_schedule(&nvchan->napi); + } + } + rcu_read_unlock(); } #endif
@@@ -1536,6 -1527,7 +1511,6 @@@ static int netvsc_probe(struct hv_devic hv_set_drvdata(dev, net);
INIT_DELAYED_WORK(&net_device_ctx->dwork, netvsc_link_change); - INIT_WORK(&net_device_ctx->work, do_set_multicast);
spin_lock_init(&net_device_ctx->lock); INIT_LIST_HEAD(&net_device_ctx->reconfig_events); @@@ -1605,6 -1597,7 +1580,6 @@@ static int netvsc_remove(struct hv_devi netif_device_detach(net);
cancel_delayed_work_sync(&ndev_ctx->dwork); - cancel_work_sync(&ndev_ctx->work);
/* * Call to the vsc driver to let it know that the device is being diff --combined drivers/net/ipvlan/ipvlan_main.c index 7c7680c8f0e3,e4141d62b5c3..dc888dd344eb --- a/drivers/net/ipvlan/ipvlan_main.c +++ b/drivers/net/ipvlan/ipvlan_main.c @@@ -632,7 -632,7 +632,7 @@@ void ipvlan_link_setup(struct net_devic dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING); dev->priv_flags |= IFF_UNICAST_FLT | IFF_NO_QUEUE; dev->netdev_ops = &ipvlan_netdev_ops; - dev->destructor = free_netdev; + dev->needs_free_netdev = true; dev->header_ops = &ipvlan_header_ops; dev->ethtool_ops = &ipvlan_ethtool_ops; } @@@ -824,6 -824,33 +824,33 @@@ static int ipvlan_addr6_event(struct no return NOTIFY_OK; }
+ static int ipvlan_addr6_validator_event(struct notifier_block *unused, + unsigned long event, void *ptr) + { + struct in6_validator_info *i6vi = (struct in6_validator_info *)ptr; + struct net_device *dev = (struct net_device *)i6vi->i6vi_dev->dev; + struct ipvl_dev *ipvlan = netdev_priv(dev); + + /* FIXME IPv6 autoconf calls us from bh without RTNL */ + if (in_softirq()) + return NOTIFY_DONE; + + if (!netif_is_ipvlan(dev)) + return NOTIFY_DONE; + + if (!ipvlan || !ipvlan->port) + return NOTIFY_DONE; + + switch (event) { + case NETDEV_UP: + if (ipvlan_addr_busy(ipvlan->port, &i6vi->i6vi_addr, true)) + return notifier_from_errno(-EADDRINUSE); + break; + } + + return NOTIFY_OK; + } + static int ipvlan_add_addr4(struct ipvl_dev *ipvlan, struct in_addr *ip4_addr) { if (ipvlan_addr_busy(ipvlan->port, ip4_addr, false)) { @@@ -871,10 -898,37 +898,37 @@@ static int ipvlan_addr4_event(struct no return NOTIFY_OK; }
+ static int ipvlan_addr4_validator_event(struct notifier_block *unused, + unsigned long event, void *ptr) + { + struct in_validator_info *ivi = (struct in_validator_info *)ptr; + struct net_device *dev = (struct net_device *)ivi->ivi_dev->dev; + struct ipvl_dev *ipvlan = netdev_priv(dev); + + if (!netif_is_ipvlan(dev)) + return NOTIFY_DONE; + + if (!ipvlan || !ipvlan->port) + return NOTIFY_DONE; + + switch (event) { + case NETDEV_UP: + if (ipvlan_addr_busy(ipvlan->port, &ivi->ivi_addr, false)) + return notifier_from_errno(-EADDRINUSE); + break; + } + + return NOTIFY_OK; + } + static struct notifier_block ipvlan_addr4_notifier_block __read_mostly = { .notifier_call = ipvlan_addr4_event, };
+ static struct notifier_block ipvlan_addr4_vtor_notifier_block __read_mostly = { + .notifier_call = ipvlan_addr4_validator_event, + }; + static struct notifier_block ipvlan_notifier_block __read_mostly = { .notifier_call = ipvlan_device_event, }; @@@ -883,6 -937,10 +937,10 @@@ static struct notifier_block ipvlan_add .notifier_call = ipvlan_addr6_event, };
+ static struct notifier_block ipvlan_addr6_vtor_notifier_block __read_mostly = { + .notifier_call = ipvlan_addr6_validator_event, + }; + static void ipvlan_ns_exit(struct net *net) { struct ipvlan_netns *vnet = net_generic(net, ipvlan_netid); @@@ -907,7 -965,10 +965,10 @@@ static int __init ipvlan_init_module(vo ipvlan_init_secret(); register_netdevice_notifier(&ipvlan_notifier_block); register_inet6addr_notifier(&ipvlan_addr6_notifier_block); + register_inet6addr_validator_notifier( + &ipvlan_addr6_vtor_notifier_block); register_inetaddr_notifier(&ipvlan_addr4_notifier_block); + register_inetaddr_validator_notifier(&ipvlan_addr4_vtor_notifier_block);
err = register_pernet_subsys(&ipvlan_net_ops); if (err < 0) @@@ -922,7 -983,11 +983,11 @@@ return 0; error: unregister_inetaddr_notifier(&ipvlan_addr4_notifier_block); + unregister_inetaddr_validator_notifier( + &ipvlan_addr4_vtor_notifier_block); unregister_inet6addr_notifier(&ipvlan_addr6_notifier_block); + unregister_inet6addr_validator_notifier( + &ipvlan_addr6_vtor_notifier_block); unregister_netdevice_notifier(&ipvlan_notifier_block); return err; } @@@ -933,7 -998,11 +998,11 @@@ static void __exit ipvlan_cleanup_modul unregister_pernet_subsys(&ipvlan_net_ops); unregister_netdevice_notifier(&ipvlan_notifier_block); unregister_inetaddr_notifier(&ipvlan_addr4_notifier_block); + unregister_inetaddr_validator_notifier( + &ipvlan_addr4_vtor_notifier_block); unregister_inet6addr_notifier(&ipvlan_addr6_notifier_block); + unregister_inet6addr_validator_notifier( + &ipvlan_addr6_vtor_notifier_block); }
module_init(ipvlan_init_module); diff --combined drivers/net/macsec.c index 79411675f0e6,b79513b8322f..2067dcc71535 --- a/drivers/net/macsec.c +++ b/drivers/net/macsec.c @@@ -588,8 -588,6 +588,6 @@@ static void count_tx(struct net_device stats->tx_packets++; stats->tx_bytes += len; u64_stats_update_end(&stats->syncp); - } else { - dev->stats.tx_dropped++; } }
@@@ -742,7 -740,12 +740,12 @@@ static struct sk_buff *macsec_encrypt(s macsec_fill_iv(iv, secy->sci, pn);
sg_init_table(sg, ret); - skb_to_sgvec(skb, sg, 0, skb->len); + ret = skb_to_sgvec(skb, sg, 0, skb->len); + if (unlikely(ret < 0)) { + macsec_txsa_put(tx_sa); + kfree_skb(skb); + return ERR_PTR(ret); + }
if (tx_sc->encrypt) { int len = skb->len - macsec_hdr_len(sci_present) - @@@ -883,7 -886,7 +886,7 @@@ static void macsec_decrypt_done(struct struct macsec_dev *macsec = macsec_priv(dev); struct macsec_rx_sa *rx_sa = macsec_skb_cb(skb)->rx_sa; struct macsec_rx_sc *rx_sc = rx_sa->sc; - int len, ret; + int len; u32 pn;
aead_request_free(macsec_skb_cb(skb)->req); @@@ -904,11 -907,8 +907,8 @@@ macsec_reset_skb(skb, macsec->secy.netdev);
len = skb->len; - ret = gro_cells_receive(&macsec->gro_cells, skb); - if (ret == NET_RX_SUCCESS) + if (gro_cells_receive(&macsec->gro_cells, skb) == NET_RX_SUCCESS) count_rx(dev, len); - else - macsec->secy.netdev->stats.rx_dropped++;
rcu_read_unlock_bh();
@@@ -952,7 -952,11 +952,11 @@@ static struct sk_buff *macsec_decrypt(s macsec_fill_iv(iv, sci, ntohl(hdr->packet_number));
sg_init_table(sg, ret); - skb_to_sgvec(skb, sg, 0, skb->len); + ret = skb_to_sgvec(skb, sg, 0, skb->len); + if (unlikely(ret < 0)) { + kfree_skb(skb); + return ERR_PTR(ret); + }
if (hdr->tci_an & MACSEC_TCI_E) { /* confidentiality: ethernet + macsec header @@@ -1037,7 -1041,6 +1041,6 @@@ static void handle_not_macsec(struct sk */ list_for_each_entry_rcu(macsec, &rxd->secys, secys) { struct sk_buff *nskb; - int ret; struct pcpu_secy_stats *secy_stats = this_cpu_ptr(macsec->stats);
if (macsec->secy.validate_frames == MACSEC_VALIDATE_STRICT) { @@@ -1054,13 -1057,10 +1057,10 @@@
nskb->dev = macsec->secy.netdev;
- ret = netif_rx(nskb); - if (ret == NET_RX_SUCCESS) { + if (netif_rx(nskb) == NET_RX_SUCCESS) { u64_stats_update_begin(&secy_stats->syncp); secy_stats->stats.InPktsUntagged++; u64_stats_update_end(&secy_stats->syncp); - } else { - macsec->secy.netdev->stats.rx_dropped++; } }
@@@ -2996,6 -2996,7 +2996,6 @@@ static void macsec_free_netdev(struct n free_percpu(macsec->secy.tx_sc.stats);
dev_put(real_dev); - free_netdev(dev); }
static void macsec_setup(struct net_device *dev) @@@ -3005,8 -3006,7 +3005,8 @@@ dev->max_mtu = ETH_MAX_MTU; dev->priv_flags |= IFF_NO_QUEUE; dev->netdev_ops = &macsec_netdev_ops; - dev->destructor = macsec_free_netdev; + dev->needs_free_netdev = true; + dev->priv_destructor = macsec_free_netdev; SET_NETDEV_DEVTYPE(dev, &macsec_type);
eth_zero_addr(dev->broadcast); diff --combined drivers/net/phy/Kconfig index 3ab6c58d4be6,65af31f24f01..2dda72004a7d --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig @@@ -127,7 -127,6 +127,7 @@@ config MDIO_THUNDE tristate "ThunderX SOCs MDIO buses" depends on 64BIT depends on PCI + depends on !(MDIO_DEVICE=y && PHYLIB=m) select MDIO_CAVIUM help This driver supports the MDIO interfaces found on Cavium @@@ -235,6 -234,11 +235,11 @@@ config CICADA_PH ---help--- Currently supports the cis8204
+ config CORTINA_PHY + tristate "Cortina EDC CDR 10G Ethernet PHY" + ---help--- + Currently supports the CS4340 phy. + config DAVICOM_PHY tristate "Davicom PHYs" ---help--- @@@ -288,6 -292,11 +293,11 @@@ config MARVELL_PH ---help--- Currently has a driver for the 88E1011S
+ config MARVELL_10G_PHY + tristate "Marvell Alaska 10Gbit PHYs" + ---help--- + Support for the Marvell Alaska MV88X3310 and compatible PHYs. + config MESON_GXL_PHY tristate "Amlogic Meson GXL Internal PHY" depends on ARCH_MESON || COMPILE_TEST diff --combined drivers/net/phy/phy.c index 3e231a54476e,edcdf0d872ed..d0626bf5c540 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@@ -54,8 -54,6 +54,8 @@@ static const char *phy_speed_to_str(in return "5Gbps"; case SPEED_10000: return "10Gbps"; + case SPEED_14000: + return "14Gbps"; case SPEED_20000: return "20Gbps"; case SPEED_25000: @@@ -151,6 -149,25 +151,25 @@@ static int phy_config_interrupt(struct return 0; }
+ /** + * phy_restart_aneg - restart auto-negotiation + * @phydev: target phy_device struct + * + * Restart the autonegotiation on @phydev. Returns >= 0 on success or + * negative errno on error. + */ + int phy_restart_aneg(struct phy_device *phydev) + { + int ret; + + if (phydev->is_c45 && !(phydev->c45_ids.devices_in_package & BIT(0))) + ret = genphy_c45_restart_aneg(phydev); + else + ret = genphy_restart_aneg(phydev); + + return ret; + } + EXPORT_SYMBOL_GPL(phy_restart_aneg);
/** * phy_aneg_done - return auto-negotiation status @@@ -165,6 -182,12 +184,12 @@@ int phy_aneg_done(struct phy_device *ph if (phydev->drv && phydev->drv->aneg_done) return phydev->drv->aneg_done(phydev);
+ /* Avoid genphy_aneg_done() if the Clause 45 PHY does not + * implement Clause 22 registers + */ + if (phydev->is_c45 && !(phydev->c45_ids.devices_in_package & BIT(0))) + return -EINVAL; + return genphy_aneg_done(phydev); } EXPORT_SYMBOL(phy_aneg_done); @@@ -379,7 -402,6 +404,7 @@@ static void phy_sanitize_settings(struc * @cmd: ethtool_cmd * * A few notes about parameter checking: + * * - We don't set port or transceiver, so we don't care what they * were set to. * - phy_start_aneg() will make sure forced settings are sane, and @@@ -487,32 -509,8 +512,8 @@@ int phy_ethtool_ksettings_set(struct ph } EXPORT_SYMBOL(phy_ethtool_ksettings_set);
- int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd) - { - cmd->supported = phydev->supported; - - cmd->advertising = phydev->advertising; - cmd->lp_advertising = phydev->lp_advertising; - - ethtool_cmd_speed_set(cmd, phydev->speed); - cmd->duplex = phydev->duplex; - if (phydev->interface == PHY_INTERFACE_MODE_MOCA) - cmd->port = PORT_BNC; - else - cmd->port = PORT_MII; - cmd->phy_address = phydev->mdio.addr; - cmd->transceiver = phy_is_internal(phydev) ? - XCVR_INTERNAL : XCVR_EXTERNAL; - cmd->autoneg = phydev->autoneg; - cmd->eth_tp_mdix_ctrl = phydev->mdix_ctrl; - cmd->eth_tp_mdix = phydev->mdix; - - return 0; - } - EXPORT_SYMBOL(phy_ethtool_gset); - - int phy_ethtool_ksettings_get(struct phy_device *phydev, - struct ethtool_link_ksettings *cmd) + void phy_ethtool_ksettings_get(struct phy_device *phydev, + struct ethtool_link_ksettings *cmd) { ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.supported, phydev->supported); @@@ -534,8 -532,6 +535,6 @@@ cmd->base.autoneg = phydev->autoneg; cmd->base.eth_tp_mdix_ctrl = phydev->mdix_ctrl; cmd->base.eth_tp_mdix = phydev->mdix; - - return 0; } EXPORT_SYMBOL(phy_ethtool_ksettings_get);
@@@ -1418,7 -1414,7 +1417,7 @@@ int phy_ethtool_set_eee(struct phy_devi /* Restart autonegotiation so the new modes get sent to the * link partner. */ - ret = genphy_restart_aneg(phydev); + ret = phy_restart_aneg(phydev); if (ret < 0) return ret; } @@@ -1451,7 -1447,9 +1450,9 @@@ int phy_ethtool_get_link_ksettings(stru if (!phydev) return -ENODEV;
- return phy_ethtool_ksettings_get(phydev, cmd); + phy_ethtool_ksettings_get(phydev, cmd); + + return 0; } EXPORT_SYMBOL(phy_ethtool_get_link_ksettings);
@@@ -1477,6 -1475,6 +1478,6 @@@ int phy_ethtool_nway_reset(struct net_d if (!phydev->drv) return -EIO;
- return genphy_restart_aneg(phydev); + return phy_restart_aneg(phydev); } EXPORT_SYMBOL(phy_ethtool_nway_reset); diff --combined drivers/net/team/team.c index fba8c136aa7c,a3ec1892a286..629a412dc690 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c @@@ -1643,6 -1643,7 +1643,6 @@@ static void team_destructor(struct net_ struct team *team = netdev_priv(dev);
free_percpu(team->pcpu_stats); - free_netdev(dev); }
static int team_open(struct net_device *dev) @@@ -2004,12 -2005,6 +2004,6 @@@ static const struct net_device_ops team .ndo_del_slave = team_del_slave, .ndo_fix_features = team_fix_features, .ndo_change_carrier = team_change_carrier, - .ndo_bridge_setlink = switchdev_port_bridge_setlink, - .ndo_bridge_getlink = switchdev_port_bridge_getlink, - .ndo_bridge_dellink = switchdev_port_bridge_dellink, - .ndo_fdb_add = switchdev_port_fdb_add, - .ndo_fdb_del = switchdev_port_fdb_del, - .ndo_fdb_dump = switchdev_port_fdb_dump, .ndo_features_check = passthru_features_check, };
@@@ -2078,8 -2073,7 +2072,8 @@@ static void team_setup(struct net_devic
dev->netdev_ops = &team_netdev_ops; dev->ethtool_ops = &team_ethtool_ops; - dev->destructor = team_destructor; + dev->needs_free_netdev = true; + dev->priv_destructor = team_destructor; dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING); dev->priv_flags |= IFF_NO_QUEUE; dev->priv_flags |= IFF_TEAM; diff --combined drivers/net/tun.c index 9ee7d4275640,fe660e524af9..ae49f4b99b67 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@@ -465,7 -465,7 +465,7 @@@ static u16 tun_select_queue(struct net_ rcu_read_lock(); numqueues = ACCESS_ONCE(tun->numqueues);
- txq = skb_get_hash(skb); + txq = __skb_get_hash_symmetric(skb); if (txq) { e = tun_flow_find(&tun->flows[tun_hashfn(txq)], txq); if (e) { @@@ -867,7 -867,7 +867,7 @@@ static netdev_tx_t tun_net_xmit(struct */ __u32 rxhash;
- rxhash = skb_get_hash(skb); + rxhash = __skb_get_hash_symmetric(skb); if (rxhash) { struct tun_flow_entry *e; e = tun_flow_find(&tun->flows[tun_hashfn(rxhash)], @@@ -1334,7 -1334,7 +1334,7 @@@ static ssize_t tun_get_user(struct tun_ skb_reset_network_header(skb); skb_probe_transport_header(skb, 0);
- rxhash = skb_get_hash(skb); + rxhash = __skb_get_hash_symmetric(skb); #ifndef CONFIG_4KSTACKS tun_rx_batched(tun, tfile, skb, more); #else @@@ -1510,9 -1510,8 +1510,8 @@@ out
static ssize_t tun_do_read(struct tun_struct *tun, struct tun_file *tfile, struct iov_iter *to, - int noblock) + int noblock, struct sk_buff *skb) { - struct sk_buff *skb; ssize_t ret; int err;
@@@ -1521,10 -1520,12 +1520,12 @@@ if (!iov_iter_count(to)) return 0;
- /* Read frames from ring */ - skb = tun_ring_recv(tfile, noblock, &err); - if (!skb) - return err; + if (!skb) { + /* Read frames from ring */ + skb = tun_ring_recv(tfile, noblock, &err); + if (!skb) + return err; + }
ret = tun_put_user(tun, tfile, skb, to); if (unlikely(ret < 0)) @@@ -1544,7 -1545,7 +1545,7 @@@ static ssize_t tun_chr_read_iter(struc
if (!tun) return -EBADFD; - ret = tun_do_read(tun, tfile, to, file->f_flags & O_NONBLOCK); + ret = tun_do_read(tun, tfile, to, file->f_flags & O_NONBLOCK, NULL); ret = min_t(ssize_t, ret, len); if (ret > 0) iocb->ki_pos = ret; @@@ -1560,6 -1561,7 +1561,6 @@@ static void tun_free_netdev(struct net_ free_percpu(tun->pcpu_stats); tun_flow_uninit(tun); security_tun_dev_free_security(tun->security); - free_netdev(dev); }
static void tun_setup(struct net_device *dev) @@@ -1570,8 -1572,7 +1571,8 @@@ tun->group = INVALID_GID;
dev->ethtool_ops = &tun_ethtool_ops; - dev->destructor = tun_free_netdev; + dev->needs_free_netdev = true; + dev->priv_destructor = tun_free_netdev; /* We prefer our own queue length */ dev->tx_queue_len = TUN_READQ_SIZE; } @@@ -1646,7 -1647,8 +1647,8 @@@ static int tun_recvmsg(struct socket *s SOL_PACKET, TUN_TX_TIMESTAMP); goto out; } - ret = tun_do_read(tun, tfile, &m->msg_iter, flags & MSG_DONTWAIT); + ret = tun_do_read(tun, tfile, &m->msg_iter, flags & MSG_DONTWAIT, + m->msg_control); if (ret > (ssize_t)total_len) { m->msg_flags |= MSG_TRUNC; ret = flags & MSG_TRUNC ? ret : total_len; @@@ -2626,6 -2628,19 +2628,19 @@@ struct socket *tun_get_socket(struct fi } EXPORT_SYMBOL_GPL(tun_get_socket);
+ struct skb_array *tun_get_skb_array(struct file *file) + { + struct tun_file *tfile; + + if (file->f_op != &tun_fops) + return ERR_PTR(-EINVAL); + tfile = file->private_data; + if (!tfile) + return ERR_PTR(-EBADFD); + return &tfile->tx_array; + } + EXPORT_SYMBOL_GPL(tun_get_skb_array); + module_init(tun_init); module_exit(tun_cleanup); MODULE_DESCRIPTION(DRV_DESCRIPTION); diff --combined drivers/net/usb/r8152.c index 1a419a45e2a2,5a02053181d1..8589303b4bf1 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@@ -394,6 -394,7 +394,7 @@@
/* OCP_PHY_STATUS */ #define PHY_STAT_MASK 0x0007 + #define PHY_STAT_EXT_INIT 2 #define PHY_STAT_LAN_ON 3 #define PHY_STAT_PWRDN 5
@@@ -841,12 -842,6 +842,6 @@@ int pla_ocp_write(struct r8152 *tp, u1 }
static inline - int usb_ocp_read(struct r8152 *tp, u16 index, u16 size, void *data) - { - return generic_ocp_read(tp, index, size, data, MCU_TYPE_USB); - } - - static inline int usb_ocp_write(struct r8152 *tp, u16 index, u16 byteen, u16 size, void *data) { return generic_ocp_write(tp, index, byteen, size, data, MCU_TYPE_USB); @@@ -1818,6 -1813,10 +1813,10 @@@ static int rx_bottom(struct r8152 *tp, unsigned int pkt_len; struct sk_buff *skb;
+ /* limite the skb numbers for rx_queue */ + if (unlikely(skb_queue_len(&tp->rx_queue) >= 1000)) + break; + pkt_len = le32_to_cpu(rx_desc->opts1) & RX_LEN_MASK; if (pkt_len < ETH_ZLEN) break; @@@ -1939,7 -1938,8 +1938,8 @@@ static int r8152_poll(struct napi_struc bottom_half(tp);
if (work_done < budget) { - napi_complete(napi); + if (!napi_complete_done(napi, work_done)) + goto out; if (!list_empty(&tp->rx_done)) napi_schedule(napi); else if (!skb_queue_empty(&tp->tx_queue) && @@@ -1947,6 -1947,7 +1947,7 @@@ napi_schedule(napi); }
+ out: return work_done; }
@@@ -2268,7 -2269,6 +2269,6 @@@ static int rtl8153_enable(struct r8152 if (test_bit(RTL8152_UNPLUG, &tp->flags)) return -ENODEV;
- usb_disable_lpm(tp->udev); set_tx_qlen(tp); rtl_set_eee_plus(tp); r8153_set_rx_early_timeout(tp); @@@ -2434,6 -2434,29 +2434,29 @@@ static void __rtl_set_wol(struct r8152 device_set_wakeup_enable(&tp->udev->dev, false); }
+ static void r8153_mac_clk_spd(struct r8152 *tp, bool enable) + { + /* MAC clock speed down */ + if (enable) { + ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL, + ALDPS_SPDWN_RATIO); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL2, + EEE_SPDWN_RATIO); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, + PKT_AVAIL_SPDWN_EN | SUSPEND_SPDWN_EN | + U1U2_SPDWN_EN | L1_SPDWN_EN); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, + PWRSAVE_SPDWN_EN | RXDV_SPDWN_EN | TX10MIDLE_EN | + TP100_SPDWN_EN | TP500_SPDWN_EN | EEE_SPDWN_EN | + TP1000_SPDWN_EN); + } else { + ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL, 0); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL2, 0); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, 0); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, 0); + } + } + static void r8153_u1u2en(struct r8152 *tp, bool enable) { u8 u1u2[8]; @@@ -2451,13 -2474,35 +2474,35 @@@ static void r8153_u2p3en(struct r8152 * u32 ocp_data;
ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_U2P3_CTRL); - if (enable && tp->version != RTL_VER_03 && tp->version != RTL_VER_04) + if (enable) ocp_data |= U2P3_ENABLE; else ocp_data &= ~U2P3_ENABLE; ocp_write_word(tp, MCU_TYPE_USB, USB_U2P3_CTRL, ocp_data); }
+ static u16 r8153_phy_status(struct r8152 *tp, u16 desired) + { + u16 data; + int i; + + for (i = 0; i < 500; i++) { + data = ocp_reg_read(tp, OCP_PHY_STATUS); + data &= PHY_STAT_MASK; + if (desired) { + if (data == desired) + break; + } else if (data == PHY_STAT_LAN_ON || data == PHY_STAT_PWRDN || + data == PHY_STAT_EXT_INIT) { + break; + } + + msleep(20); + } + + return data; + } + static void r8153_power_cut_en(struct r8152 *tp, bool enable) { u32 ocp_data; @@@ -2512,13 -2557,26 +2557,26 @@@ static void rtl_runtime_suspend_enable(
static void rtl8153_runtime_enable(struct r8152 *tp, bool enable) { - rtl_runtime_suspend_enable(tp, enable); - if (enable) { r8153_u1u2en(tp, false); r8153_u2p3en(tp, false); + r8153_mac_clk_spd(tp, true); + rtl_runtime_suspend_enable(tp, true); } else { - r8153_u2p3en(tp, true); + rtl_runtime_suspend_enable(tp, false); + r8153_mac_clk_spd(tp, false); + + switch (tp->version) { + case RTL_VER_03: + case RTL_VER_04: + break; + case RTL_VER_05: + case RTL_VER_06: + default: + r8153_u2p3en(tp, true); + break; + } + r8153_u1u2en(tp, true); } } @@@ -2784,9 -2842,15 +2842,15 @@@ static void r8153_aldps_en(struct r815 data |= EN_ALDPS; ocp_reg_write(tp, OCP_POWER_CFG, data); } else { + int i; + data &= ~EN_ALDPS; ocp_reg_write(tp, OCP_POWER_CFG, data); - msleep(20); + for (i = 0; i < 20; i++) { + usleep_range(1000, 2000); + if (ocp_read_word(tp, MCU_TYPE_PLA, 0xe000) & 0x0100) + break; + } } }
@@@ -2857,6 -2921,17 +2921,17 @@@ static void r8153_hw_phy_cfg(struct r81 r8153_aldps_en(tp, true); r8152b_enable_fc(tp);
+ switch (tp->version) { + case RTL_VER_03: + case RTL_VER_04: + break; + case RTL_VER_05: + case RTL_VER_06: + default: + r8153_u2p3en(tp, true); + break; + } + set_bit(PHY_RESET, &tp->flags); }
@@@ -2865,6 -2940,7 +2940,7 @@@ static void r8153_first_init(struct r81 u32 ocp_data; int i;
+ r8153_mac_clk_spd(tp, false); rxdy_gated_en(tp, true); r8153_teredo_off(tp);
@@@ -2919,11 -2995,6 +2995,6 @@@ ocp_write_word(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL2, RXFIFO_THR3_NORMAL); /* TX share fifo free credit full threshold */ ocp_write_dword(tp, MCU_TYPE_PLA, PLA_TXFIFO_CTRL, TXFIFO_THR_NORMAL2); - - /* rx aggregation */ - ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_USB_CTRL); - ocp_data &= ~(RX_AGG_DISABLE | RX_ZERO_EN); - ocp_write_word(tp, MCU_TYPE_USB, USB_USB_CTRL, ocp_data); }
static void r8153_enter_oob(struct r8152 *tp) @@@ -2931,6 -3002,8 +3002,8 @@@ u32 ocp_data; int i;
+ r8153_mac_clk_spd(tp, true); + ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); ocp_data &= ~NOW_IS_OOB; ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data); @@@ -2986,7 -3059,6 +3059,6 @@@ static void rtl8153_disable(struct r815 rtl_disable(tp); rtl_reset_bmu(tp); r8153_aldps_en(tp, true); - usb_enable_lpm(tp->udev); }
static int rtl8152_set_speed(struct r8152 *tp, u8 autoneg, u16 speed, u8 duplex) @@@ -3105,12 -3177,23 +3177,23 @@@ static void rtl8153_up(struct r8152 *tp return;
r8153_u1u2en(tp, false); + r8153_u2p3en(tp, false); r8153_aldps_en(tp, false); r8153_first_init(tp); r8153_aldps_en(tp, true); - r8153_u2p3en(tp, true); + + switch (tp->version) { + case RTL_VER_03: + case RTL_VER_04: + break; + case RTL_VER_05: + case RTL_VER_06: + default: + r8153_u2p3en(tp, true); + break; + } + r8153_u1u2en(tp, true); - usb_enable_lpm(tp->udev); }
static void rtl8153_down(struct r8152 *tp) @@@ -3426,12 -3509,7 +3509,7 @@@ static void r8153_init(struct r8152 *tp msleep(20); }
- for (i = 0; i < 500; i++) { - ocp_data = ocp_reg_read(tp, OCP_PHY_STATUS) & PHY_STAT_MASK; - if (ocp_data == PHY_STAT_LAN_ON || ocp_data == PHY_STAT_PWRDN) - break; - msleep(20); - } + data = r8153_phy_status(tp, 0);
if (tp->version == RTL_VER_03 || tp->version == RTL_VER_04 || tp->version == RTL_VER_05) @@@ -3443,14 -3521,8 +3521,8 @@@ r8152_mdio_write(tp, MII_BMCR, data); }
- for (i = 0; i < 500; i++) { - ocp_data = ocp_reg_read(tp, OCP_PHY_STATUS) & PHY_STAT_MASK; - if (ocp_data == PHY_STAT_LAN_ON) - break; - msleep(20); - } + data = r8153_phy_status(tp, PHY_STAT_LAN_ON);
- usb_disable_lpm(tp->udev); r8153_u2p3en(tp, false);
if (tp->version == RTL_VER_04) { @@@ -3510,15 -3582,28 +3582,28 @@@
r8153_power_cut_en(tp, false); r8153_u1u2en(tp, true); + r8153_mac_clk_spd(tp, false); + usb_enable_lpm(tp->udev);
- /* MAC clock speed down */ - ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL, 0); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL2, 0); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, 0); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, 0); + /* rx aggregation */ + ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_USB_CTRL); + ocp_data &= ~(RX_AGG_DISABLE | RX_ZERO_EN); + ocp_write_word(tp, MCU_TYPE_USB, USB_USB_CTRL, ocp_data);
rtl_tally_reset(tp); - r8153_u2p3en(tp, true); + + switch (tp->udev->speed) { + case USB_SPEED_SUPER: + case USB_SPEED_SUPER_PLUS: + tp->coalesce = COALESCE_SUPER; + break; + case USB_SPEED_HIGH: + tp->coalesce = COALESCE_HIGH; + break; + default: + tp->coalesce = COALESCE_SLOW; + break; + } }
static int rtl8152_pre_reset(struct usb_interface *intf) @@@ -3703,11 -3788,8 +3788,8 @@@ static int rtl8152_resume(struct usb_in
mutex_lock(&tp->control);
- if (!test_bit(SELECTIVE_SUSPEND, &tp->flags)) { - tp->rtl_ops.init(tp); - queue_delayed_work(system_long_wq, &tp->hw_phy_work, 0); + if (!test_bit(SELECTIVE_SUSPEND, &tp->flags)) netif_device_attach(netdev); - }
if (netif_running(netdev) && netdev->flags & IFF_UP) { if (test_bit(SELECTIVE_SUSPEND, &tp->flags)) { @@@ -3753,6 -3835,10 +3835,10 @@@ static int rtl8152_reset_resume(struct struct r8152 *tp = usb_get_intfdata(intf);
clear_bit(SELECTIVE_SUSPEND, &tp->flags); + mutex_lock(&tp->control); + tp->rtl_ops.init(tp); + queue_delayed_work(system_long_wq, &tp->hw_phy_work, 0); + mutex_unlock(&tp->control); return rtl8152_resume(intf); }
@@@ -3841,7 -3927,7 +3927,7 @@@ int rtl8152_get_link_ksettings(struct n
mutex_lock(&tp->control);
- ret = mii_ethtool_get_link_ksettings(&tp->mii, cmd); + mii_ethtool_get_link_ksettings(&tp->mii, cmd);
mutex_unlock(&tp->control);
@@@ -4368,8 -4454,6 +4454,8 @@@ static u8 rtl_get_version(struct usb_in break; }
+ dev_dbg(&intf->dev, "Detected version 0x%04x\n", version); + return version; }
@@@ -4466,19 -4550,6 +4552,6 @@@ static int rtl8152_probe(struct usb_int tp->mii.reg_num_mask = 0x1f; tp->mii.phy_id = R8152_PHY_ID;
- switch (udev->speed) { - case USB_SPEED_SUPER: - case USB_SPEED_SUPER_PLUS: - tp->coalesce = COALESCE_SUPER; - break; - case USB_SPEED_HIGH: - tp->coalesce = COALESCE_HIGH; - break; - default: - tp->coalesce = COALESCE_SLOW; - break; - } - tp->autoneg = AUTONEG_ENABLE; tp->speed = tp->mii.supports_gmii ? SPEED_1000 : SPEED_100; tp->duplex = DUPLEX_FULL; diff --combined drivers/net/vxlan.c index 5fa798a5c9a6,e045c34ffbeb..25b70cad055c --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c @@@ -970,7 -970,7 +970,7 @@@ static bool vxlan_snoop(struct net_devi return false;
/* Don't migrate static entries, drop packets */ - if (f->state & NUD_NOARP) + if (f->state & (NUD_PERMANENT | NUD_NOARP)) return true;
if (net_ratelimit()) @@@ -1077,10 -1077,10 +1077,10 @@@ static void vxlan_sock_release(struct v #if IS_ENABLED(CONFIG_IPV6) struct vxlan_sock *sock6 = rtnl_dereference(vxlan->vn6_sock);
- rcu_assign_pointer(vxlan->vn6_sock, NULL); + RCU_INIT_POINTER(vxlan->vn6_sock, NULL); #endif
- rcu_assign_pointer(vxlan->vn4_sock, NULL); + RCU_INIT_POINTER(vxlan->vn4_sock, NULL); synchronize_net();
vxlan_vs_del_dev(vxlan); @@@ -2611,7 -2611,7 +2611,7 @@@ static void vxlan_setup(struct net_devi eth_hw_addr_random(dev); ether_setup(dev);
- dev->destructor = free_netdev; + dev->needs_free_netdev = true; SET_NETDEV_DEVTYPE(dev, &vxlan_type);
dev->features |= NETIF_F_LLTX; diff --combined drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c index 617199c0e5a0,a2bf11fc8ecc..b8f042146fc9 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c @@@ -4674,9 -4674,6 +4674,6 @@@ static int brcmf_cfg80211_stop_ap(struc err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 0); if (err < 0) brcmf_err("setting AP mode failed %d\n", err); - err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 0); - if (err < 0) - brcmf_err("setting INFRA mode failed %d\n", err); if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) brcmf_fil_iovar_int_set(ifp, "mbss", 0); brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY, @@@ -5225,6 -5222,7 +5222,6 @@@ void brcmf_cfg80211_free_netdev(struct
if (vif) brcmf_free_vif(vif); - free_netdev(ndev); }
static bool brcmf_is_linkup(const struct brcmf_event_msg *e) @@@ -6377,16 -6375,6 +6374,6 @@@ err return -ENOMEM; }
- static void brcmf_wiphy_pno_params(struct wiphy *wiphy) - { - /* scheduled scan settings */ - wiphy->max_sched_scan_reqs = 1; - wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT; - wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT; - wiphy->max_sched_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX; - wiphy->max_sched_scan_plan_interval = BRCMF_PNO_SCHED_SCAN_MAX_PERIOD; - } - #ifdef CONFIG_PM static const struct wiphy_wowlan_support brcmf_wowlan_support = { .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT, @@@ -6433,6 -6421,7 +6420,7 @@@ static int brcmf_setup_wiphy(struct wip const struct ieee80211_iface_combination *combo; struct ieee80211_supported_band *band; u16 max_interfaces = 0; + bool gscan; __le32 bandlist[3]; u32 n_bands; int err, i; @@@ -6482,9 -6471,10 +6470,10 @@@ wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM; wiphy->mgmt_stypes = brcmf_txrx_stypes; wiphy->max_remain_on_channel_duration = 5000; - if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO)) - brcmf_wiphy_pno_params(wiphy); - + if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO)) { + gscan = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_GSCAN); + brcmf_pno_wiphy_params(wiphy, gscan); + } /* vendor commands/events support */ wiphy->vendor_commands = brcmf_vendor_cmds; wiphy->n_vendor_commands = BRCMF_VNDR_CMDS_LAST - 1; diff --combined drivers/net/wireless/marvell/mwifiex/main.c index 39b6b5e3f6e0,2c42191293c3..f2600b827e81 --- a/drivers/net/wireless/marvell/mwifiex/main.c +++ b/drivers/net/wireless/marvell/mwifiex/main.c @@@ -44,6 -44,10 +44,10 @@@ bool mfg_mode module_param(mfg_mode, bool, 0); MODULE_PARM_DESC(mfg_mode, "manufacturing mode enable:1, disable:0");
+ bool aggr_ctrl; + module_param(aggr_ctrl, bool, 0000); + MODULE_PARM_DESC(aggr_ctrl, "usb tx aggreataon enable:1, disable:0"); + /* * This function registers the device and performs all the necessary * initializations. @@@ -1280,7 -1284,7 +1284,7 @@@ void mwifiex_init_priv_params(struct mw struct net_device *dev) { dev->netdev_ops = &mwifiex_netdev_ops; - dev->destructor = free_netdev; + dev->needs_free_netdev = true; /* Initialize private structure */ priv->current_key_index = 0; priv->media_connected = false; diff --combined drivers/net/wireless/quantenna/qtnfmac/core.c index 000000000000,c5ac252464f4..f053532c0e87 mode 000000,100644..100644 --- a/drivers/net/wireless/quantenna/qtnfmac/core.c +++ b/drivers/net/wireless/quantenna/qtnfmac/core.c @@@ -1,0 -1,618 +1,618 @@@ + /* + * Copyright (c) 2015-2016 Quantenna Communications, Inc. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + + #include <linux/kernel.h> + #include <linux/module.h> + #include <linux/if_ether.h> + + #include "core.h" + #include "bus.h" + #include "trans.h" + #include "commands.h" + #include "cfg80211.h" + #include "event.h" + #include "util.h" + + #define QTNF_DMP_MAX_LEN 48 + #define QTNF_PRIMARY_VIF_IDX 0 + + struct qtnf_frame_meta_info { + u8 magic_s; + u8 ifidx; + u8 macid; + u8 magic_e; + } __packed; + + struct qtnf_wmac *qtnf_core_get_mac(const struct qtnf_bus *bus, u8 macid) + { + struct qtnf_wmac *mac = NULL; + + if (unlikely(macid >= QTNF_MAX_MAC)) { + pr_err("invalid MAC index %u\n", macid); + return NULL; + } + + mac = bus->mac[macid]; + + if (unlikely(!mac)) { + pr_err("MAC%u: not initialized\n", macid); + return NULL; + } + + return mac; + } + + /* Netdev handler for open. + */ + static int qtnf_netdev_open(struct net_device *ndev) + { + netif_carrier_off(ndev); + qtnf_netdev_updown(ndev, 1); + return 0; + } + + /* Netdev handler for close. + */ + static int qtnf_netdev_close(struct net_device *ndev) + { + netif_carrier_off(ndev); + qtnf_virtual_intf_cleanup(ndev); + qtnf_netdev_updown(ndev, 0); + return 0; + } + + /* Netdev handler for data transmission. + */ + static int + qtnf_netdev_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev) + { + struct qtnf_vif *vif; + struct qtnf_wmac *mac; + + vif = qtnf_netdev_get_priv(ndev); + + if (unlikely(skb->dev != ndev)) { + pr_err_ratelimited("invalid skb->dev"); + dev_kfree_skb_any(skb); + return 0; + } + + if (unlikely(vif->wdev.iftype == NL80211_IFTYPE_UNSPECIFIED)) { + pr_err_ratelimited("%s: VIF not initialized\n", ndev->name); + dev_kfree_skb_any(skb); + return 0; + } + + mac = vif->mac; + if (unlikely(!mac)) { + pr_err_ratelimited("%s: NULL mac pointer", ndev->name); + dev_kfree_skb_any(skb); + return 0; + } + + if (!skb->len || (skb->len > ETH_FRAME_LEN)) { + pr_err_ratelimited("%s: invalid skb len %d\n", ndev->name, + skb->len); + dev_kfree_skb_any(skb); + ndev->stats.tx_dropped++; + return 0; + } + + /* tx path is enabled: reset vif timeout */ + vif->cons_tx_timeout_cnt = 0; + + return qtnf_bus_data_tx(mac->bus, skb); + } + + /* Netdev handler for getting stats. + */ + static struct net_device_stats *qtnf_netdev_get_stats(struct net_device *dev) + { + return &dev->stats; + } + + /* Netdev handler for transmission timeout. + */ + static void qtnf_netdev_tx_timeout(struct net_device *ndev) + { + struct qtnf_vif *vif = qtnf_netdev_get_priv(ndev); + struct qtnf_wmac *mac; + struct qtnf_bus *bus; + + if (unlikely(!vif || !vif->mac || !vif->mac->bus)) + return; + + mac = vif->mac; + bus = mac->bus; + + pr_warn("VIF%u.%u: Tx timeout- %lu\n", mac->macid, vif->vifid, jiffies); + + qtnf_bus_data_tx_timeout(bus, ndev); + ndev->stats.tx_errors++; + + if (++vif->cons_tx_timeout_cnt > QTNF_TX_TIMEOUT_TRSHLD) { + pr_err("Tx timeout threshold exceeded !\n"); + pr_err("schedule interface %s reset !\n", netdev_name(ndev)); + queue_work(bus->workqueue, &vif->reset_work); + } + } + + /* Network device ops handlers */ + const struct net_device_ops qtnf_netdev_ops = { + .ndo_open = qtnf_netdev_open, + .ndo_stop = qtnf_netdev_close, + .ndo_start_xmit = qtnf_netdev_hard_start_xmit, + .ndo_tx_timeout = qtnf_netdev_tx_timeout, + .ndo_get_stats = qtnf_netdev_get_stats, + }; + + static int qtnf_mac_init_single_band(struct wiphy *wiphy, + struct qtnf_wmac *mac, + enum nl80211_band band) + { + int ret; + + wiphy->bands[band] = kzalloc(sizeof(*wiphy->bands[band]), GFP_KERNEL); + if (!wiphy->bands[band]) + return -ENOMEM; + + wiphy->bands[band]->band = band; + + ret = qtnf_cmd_get_mac_chan_info(mac, wiphy->bands[band]); + if (ret) { + pr_err("MAC%u: band %u: failed to get chans info: %d\n", + mac->macid, band, ret); + return ret; + } + + qtnf_band_init_rates(wiphy->bands[band]); + qtnf_band_setup_htvht_caps(&mac->macinfo, wiphy->bands[band]); + + return 0; + } + + static int qtnf_mac_init_bands(struct qtnf_wmac *mac) + { + struct wiphy *wiphy = priv_to_wiphy(mac); + int ret = 0; + + if (mac->macinfo.bands_cap & QLINK_BAND_2GHZ) { + ret = qtnf_mac_init_single_band(wiphy, mac, NL80211_BAND_2GHZ); + if (ret) + goto out; + } + + if (mac->macinfo.bands_cap & QLINK_BAND_5GHZ) { + ret = qtnf_mac_init_single_band(wiphy, mac, NL80211_BAND_5GHZ); + if (ret) + goto out; + } + + if (mac->macinfo.bands_cap & QLINK_BAND_60GHZ) + ret = qtnf_mac_init_single_band(wiphy, mac, NL80211_BAND_60GHZ); + + out: + return ret; + } + + struct qtnf_vif *qtnf_mac_get_free_vif(struct qtnf_wmac *mac) + { + struct qtnf_vif *vif; + int i; + + for (i = 0; i < QTNF_MAX_INTF; i++) { + vif = &mac->iflist[i]; + if (vif->wdev.iftype == NL80211_IFTYPE_UNSPECIFIED) + return vif; + } + + return NULL; + } + + struct qtnf_vif *qtnf_mac_get_base_vif(struct qtnf_wmac *mac) + { + struct qtnf_vif *vif; + + vif = &mac->iflist[QTNF_PRIMARY_VIF_IDX]; + + if (vif->wdev.iftype == NL80211_IFTYPE_UNSPECIFIED) + return NULL; + + return vif; + } + + static void qtnf_vif_reset_handler(struct work_struct *work) + { + struct qtnf_vif *vif = container_of(work, struct qtnf_vif, reset_work); + + rtnl_lock(); + + if (vif->wdev.iftype == NL80211_IFTYPE_UNSPECIFIED) { + rtnl_unlock(); + return; + } + + /* stop tx completely */ + netif_tx_stop_all_queues(vif->netdev); + if (netif_carrier_ok(vif->netdev)) + netif_carrier_off(vif->netdev); + + qtnf_cfg80211_vif_reset(vif); + + rtnl_unlock(); + } + + static void qtnf_mac_init_primary_intf(struct qtnf_wmac *mac) + { + struct qtnf_vif *vif = &mac->iflist[QTNF_PRIMARY_VIF_IDX]; + + vif->wdev.iftype = NL80211_IFTYPE_AP; + vif->bss_priority = QTNF_DEF_BSS_PRIORITY; + vif->wdev.wiphy = priv_to_wiphy(mac); + INIT_WORK(&vif->reset_work, qtnf_vif_reset_handler); + vif->cons_tx_timeout_cnt = 0; + } + + static struct qtnf_wmac *qtnf_core_mac_alloc(struct qtnf_bus *bus, + unsigned int macid) + { + struct wiphy *wiphy; + struct qtnf_wmac *mac; + unsigned int i; + + wiphy = qtnf_wiphy_allocate(bus); + if (!wiphy) + return ERR_PTR(-ENOMEM); + + mac = wiphy_priv(wiphy); + + mac->macid = macid; + mac->bus = bus; + + for (i = 0; i < QTNF_MAX_INTF; i++) { + memset(&mac->iflist[i], 0, sizeof(struct qtnf_vif)); + mac->iflist[i].wdev.iftype = NL80211_IFTYPE_UNSPECIFIED; + mac->iflist[i].mac = mac; + mac->iflist[i].vifid = i; + qtnf_sta_list_init(&mac->iflist[i].sta_list); + } + + qtnf_mac_init_primary_intf(mac); + bus->mac[macid] = mac; + + return mac; + } + + int qtnf_core_net_attach(struct qtnf_wmac *mac, struct qtnf_vif *vif, + const char *name, unsigned char name_assign_type, + enum nl80211_iftype iftype) + { + struct wiphy *wiphy = priv_to_wiphy(mac); + struct net_device *dev; + void *qdev_vif; + int ret; + + dev = alloc_netdev_mqs(sizeof(struct qtnf_vif *), name, + name_assign_type, ether_setup, 1, 1); + if (!dev) { + memset(&vif->wdev, 0, sizeof(vif->wdev)); + vif->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED; + return -ENOMEM; + } + + vif->netdev = dev; + + dev->netdev_ops = &qtnf_netdev_ops; - dev->destructor = free_netdev; ++ dev->needs_free_netdev = true; + dev_net_set(dev, wiphy_net(wiphy)); + dev->ieee80211_ptr = &vif->wdev; + dev->ieee80211_ptr->iftype = iftype; + ether_addr_copy(dev->dev_addr, vif->mac_addr); + SET_NETDEV_DEV(dev, wiphy_dev(wiphy)); + dev->flags |= IFF_BROADCAST | IFF_MULTICAST; + dev->watchdog_timeo = QTNF_DEF_WDOG_TIMEOUT; + dev->tx_queue_len = 100; + + qdev_vif = netdev_priv(dev); + *((void **)qdev_vif) = vif; + + SET_NETDEV_DEV(dev, mac->bus->dev); + + ret = register_netdevice(dev); + if (ret) { + free_netdev(dev); + vif->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED; + } + + return ret; + } + + static void qtnf_core_mac_detach(struct qtnf_bus *bus, unsigned int macid) + { + struct qtnf_wmac *mac; + struct wiphy *wiphy; + struct qtnf_vif *vif; + unsigned int i; + enum nl80211_band band; + + mac = bus->mac[macid]; + + if (!mac) + return; + + wiphy = priv_to_wiphy(mac); + + for (i = 0; i < QTNF_MAX_INTF; i++) { + vif = &mac->iflist[i]; + rtnl_lock(); + if (vif->netdev && + vif->wdev.iftype != NL80211_IFTYPE_UNSPECIFIED) { + qtnf_virtual_intf_cleanup(vif->netdev); + qtnf_del_virtual_intf(wiphy, &vif->wdev); + } + rtnl_unlock(); + qtnf_sta_list_free(&vif->sta_list); + } + + if (mac->wiphy_registered) + wiphy_unregister(wiphy); + + for (band = NL80211_BAND_2GHZ; band < NUM_NL80211_BANDS; ++band) { + if (!wiphy->bands[band]) + continue; + + kfree(wiphy->bands[band]->channels); + wiphy->bands[band]->n_channels = 0; + + kfree(wiphy->bands[band]); + wiphy->bands[band] = NULL; + } + + kfree(mac->macinfo.limits); + kfree(wiphy->iface_combinations); + wiphy_free(wiphy); + bus->mac[macid] = NULL; + } + + static int qtnf_core_mac_attach(struct qtnf_bus *bus, unsigned int macid) + { + struct qtnf_wmac *mac; + struct qtnf_vif *vif; + int ret; + + if (!(bus->hw_info.mac_bitmap & BIT(macid))) { + pr_info("MAC%u is not active in FW\n", macid); + return 0; + } + + mac = qtnf_core_mac_alloc(bus, macid); + if (IS_ERR(mac)) { + pr_err("MAC%u allocation failed\n", macid); + return PTR_ERR(mac); + } + + ret = qtnf_cmd_get_mac_info(mac); + if (ret) { + pr_err("MAC%u: failed to get info\n", macid); + goto error; + } + + vif = qtnf_mac_get_base_vif(mac); + if (!vif) { + pr_err("MAC%u: primary VIF is not ready\n", macid); + ret = -EFAULT; + goto error; + } + + ret = qtnf_cmd_send_add_intf(vif, NL80211_IFTYPE_AP, vif->mac_addr); + if (ret) { + pr_err("MAC%u: failed to add VIF\n", macid); + goto error; + } + + ret = qtnf_cmd_send_get_phy_params(mac); + if (ret) { + pr_err("MAC%u: failed to get PHY settings\n", macid); + goto error; + } + + ret = qtnf_mac_init_bands(mac); + if (ret) { + pr_err("MAC%u: failed to init bands\n", macid); + goto error; + } + + ret = qtnf_wiphy_register(&bus->hw_info, mac); + if (ret) { + pr_err("MAC%u: wiphy registration failed\n", macid); + goto error; + } + + mac->wiphy_registered = 1; + + rtnl_lock(); + + ret = qtnf_core_net_attach(mac, vif, "wlan%d", NET_NAME_ENUM, + NL80211_IFTYPE_AP); + rtnl_unlock(); + + if (ret) { + pr_err("MAC%u: failed to attach netdev\n", macid); + vif->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED; + vif->netdev = NULL; + goto error; + } + + pr_debug("MAC%u initialized\n", macid); + + return 0; + + error: + qtnf_core_mac_detach(bus, macid); + return ret; + } + + int qtnf_core_attach(struct qtnf_bus *bus) + { + unsigned int i; + int ret; + + qtnf_trans_init(bus); + + bus->fw_state = QTNF_FW_STATE_BOOT_DONE; + qtnf_bus_data_rx_start(bus); + + bus->workqueue = alloc_ordered_workqueue("QTNF_BUS", 0); + if (!bus->workqueue) { + pr_err("failed to alloc main workqueue\n"); + ret = -ENOMEM; + goto error; + } + + INIT_WORK(&bus->event_work, qtnf_event_work_handler); + + ret = qtnf_cmd_send_init_fw(bus); + if (ret) { + pr_err("failed to init FW: %d\n", ret); + goto error; + } + + bus->fw_state = QTNF_FW_STATE_ACTIVE; + + ret = qtnf_cmd_get_hw_info(bus); + if (ret) { + pr_err("failed to get HW info: %d\n", ret); + goto error; + } + + if (bus->hw_info.ql_proto_ver != QLINK_PROTO_VER) { + pr_err("qlink version mismatch %u != %u\n", + QLINK_PROTO_VER, bus->hw_info.ql_proto_ver); + ret = -EPROTONOSUPPORT; + goto error; + } + + if (bus->hw_info.num_mac > QTNF_MAX_MAC) { + pr_err("no support for number of MACs=%u\n", + bus->hw_info.num_mac); + ret = -ERANGE; + goto error; + } + + for (i = 0; i < bus->hw_info.num_mac; i++) { + ret = qtnf_core_mac_attach(bus, i); + + if (ret) { + pr_err("MAC%u: attach failed: %d\n", i, ret); + goto error; + } + } + + return 0; + + error: + qtnf_core_detach(bus); + + return ret; + } + EXPORT_SYMBOL_GPL(qtnf_core_attach); + + void qtnf_core_detach(struct qtnf_bus *bus) + { + unsigned int macid; + + qtnf_bus_data_rx_stop(bus); + + for (macid = 0; macid < QTNF_MAX_MAC; macid++) + qtnf_core_mac_detach(bus, macid); + + if (bus->fw_state == QTNF_FW_STATE_ACTIVE) + qtnf_cmd_send_deinit_fw(bus); + + bus->fw_state = QTNF_FW_STATE_DEAD; + + if (bus->workqueue) { + flush_workqueue(bus->workqueue); + destroy_workqueue(bus->workqueue); + } + + qtnf_trans_free(bus); + } + EXPORT_SYMBOL_GPL(qtnf_core_detach); + + static inline int qtnf_is_frame_meta_magic_valid(struct qtnf_frame_meta_info *m) + { + return m->magic_s == 0xAB && m->magic_e == 0xBA; + } + + struct net_device *qtnf_classify_skb(struct qtnf_bus *bus, struct sk_buff *skb) + { + struct qtnf_frame_meta_info *meta; + struct net_device *ndev = NULL; + struct qtnf_wmac *mac; + struct qtnf_vif *vif; + + meta = (struct qtnf_frame_meta_info *) + (skb_tail_pointer(skb) - sizeof(*meta)); + + if (unlikely(!qtnf_is_frame_meta_magic_valid(meta))) { + pr_err_ratelimited("invalid magic 0x%x:0x%x\n", + meta->magic_s, meta->magic_e); + goto out; + } + + if (unlikely(meta->macid >= QTNF_MAX_MAC)) { + pr_err_ratelimited("invalid mac(%u)\n", meta->macid); + goto out; + } + + if (unlikely(meta->ifidx >= QTNF_MAX_INTF)) { + pr_err_ratelimited("invalid vif(%u)\n", meta->ifidx); + goto out; + } + + mac = bus->mac[meta->macid]; + + if (unlikely(!mac)) { + pr_err_ratelimited("mac(%d) does not exist\n", meta->macid); + goto out; + } + + vif = &mac->iflist[meta->ifidx]; + + if (unlikely(vif->wdev.iftype == NL80211_IFTYPE_UNSPECIFIED)) { + pr_err_ratelimited("vif(%u) does not exists\n", meta->ifidx); + goto out; + } + + ndev = vif->netdev; + + if (unlikely(!ndev)) { + pr_err_ratelimited("netdev for wlan%u.%u does not exists\n", + meta->macid, meta->ifidx); + goto out; + } + + __skb_trim(skb, skb->len - sizeof(*meta)); + + out: + return ndev; + } + EXPORT_SYMBOL_GPL(qtnf_classify_skb); + + MODULE_AUTHOR("Quantenna Communications"); + MODULE_DESCRIPTION("Quantenna 802.11 wireless LAN FullMAC driver."); + MODULE_LICENSE("GPL"); diff --combined drivers/scsi/cxgbi/cxgb4i/cxgb4i.c index 0aae094ab91c,9a92b5150218..397094b8bad6 --- a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c +++ b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c @@@ -806,7 -806,7 +806,7 @@@ static void do_act_establish(struct cxg
cxgbi_sock_get(csk); csk->tid = tid; - cxgb4_insert_tid(lldi->tids, csk, tid); + cxgb4_insert_tid(lldi->tids, csk, tid, csk->csk_family); cxgbi_sock_set_flag(csk, CTPF_HAS_TID);
free_atid(csk); @@@ -956,7 -956,8 +956,8 @@@ static void do_act_open_rpl(struct cxgb if (status && status != CPL_ERR_TCAM_FULL && status != CPL_ERR_CONN_EXIST && status != CPL_ERR_ARP_MISS) - cxgb4_remove_tid(lldi->tids, csk->port_id, GET_TID(rpl)); + cxgb4_remove_tid(lldi->tids, csk->port_id, GET_TID(rpl), + csk->csk_family);
cxgbi_sock_get(csk); spin_lock_bh(&csk->lock); @@@ -1590,11 -1591,13 +1591,12 @@@ static void release_offload_resources(s free_atid(csk); else if (cxgbi_sock_flag(csk, CTPF_HAS_TID)) { lldi = cxgbi_cdev_priv(csk->cdev); - cxgb4_remove_tid(lldi->tids, 0, csk->tid); + cxgb4_remove_tid(lldi->tids, 0, csk->tid, + csk->csk_family); cxgbi_sock_clear_flag(csk, CTPF_HAS_TID); cxgbi_sock_put(csk); } csk->dst = NULL; - csk->cdev = NULL; }
static int init_act_open(struct cxgbi_sock *csk) diff --combined include/linux/netdevice.h index 7dbd7daa6674,524c7776ce96..6426f28718f2 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@@ -972,7 -972,7 +972,7 @@@ struct xfrmdev_ops * with PF and querying it may introduce a theoretical security risk. * int (*ndo_set_vf_rss_query_en)(struct net_device *dev, int vf, bool setting); * int (*ndo_get_vf_port)(struct net_device *dev, int vf, struct sk_buff *skb); - * int (*ndo_setup_tc)(struct net_device *dev, u32 handle, + * int (*ndo_setup_tc)(struct net_device *dev, u32 handle, u32 chain_index, * __be16 protocol, struct tc_to_netdev *tc); * Called to setup any 'tc' scheduler, classifier or action on @dev. * This is always called from the stack with the rtnl lock held and netif @@@ -1222,7 -1222,7 +1222,7 @@@ struct net_device_ops struct net_device *dev, int vf, bool setting); int (*ndo_setup_tc)(struct net_device *dev, - u32 handle, + u32 handle, u32 chain_index, __be16 protocol, struct tc_to_netdev *tc); #if IS_ENABLED(CONFIG_FCOE) @@@ -1433,14 -1433,13 +1433,14 @@@ enum netdev_priv_flags
/** * struct net_device - The DEVICE structure. - * Actually, this whole structure is a big mistake. It mixes I/O - * data with strictly "high-level" data, and it has to know about - * almost every data structure used in the INET module. + * + * Actually, this whole structure is a big mistake. It mixes I/O + * data with strictly "high-level" data, and it has to know about + * almost every data structure used in the INET module. * * @name: This is the first field of the "visible" part of this structure * (i.e. as seen by users in the "Space.c" file). It is the name - * of the interface. + * of the interface. * * @name_hlist: Device name hash chain, please keep it close to name[] * @ifalias: SNMP alias @@@ -1597,8 -1596,8 +1597,8 @@@ * @rtnl_link_state: This enum represents the phases of creating * a new link * - * @destructor: Called from unregister, - * can be used to call free_netdev + * @needs_free_netdev: Should unregister perform free_netdev? + * @priv_destructor: Called from unregister * @npinfo: XXX: need comments on this one * @nd_net: Network namespace this network device is inside * @@@ -1825,7 -1824,7 +1825,7 @@@ struct net_device #ifdef CONFIG_NET_SCHED DECLARE_HASHTABLE (qdisc_hash, 4); #endif - unsigned long tx_queue_len; + unsigned int tx_queue_len; spinlock_t tx_global_lock; int watchdog_timeo;
@@@ -1859,8 -1858,7 +1859,8 @@@ RTNL_LINK_INITIALIZING, } rtnl_link_state:16;
- void (*destructor)(struct net_device *dev); + bool needs_free_netdev; + void (*priv_destructor)(struct net_device *dev);
#ifdef CONFIG_NETPOLL struct netpoll_info __rcu *npinfo; @@@ -2458,6 -2456,7 +2458,7 @@@ static inline int dev_recursion_level(v struct net_device *dev_get_by_index(struct net *net, int ifindex); struct net_device *__dev_get_by_index(struct net *net, int ifindex); struct net_device *dev_get_by_index_rcu(struct net *net, int ifindex); + struct net_device *dev_get_by_napi_id(unsigned int napi_id); int netdev_get_name(struct net *net, char *name, int ifindex); int dev_restart(struct net_device *dev); int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb); @@@ -2575,9 -2574,7 +2576,7 @@@ static inline void skb_gro_incr_csum_un if (__skb_gro_checksum_validate_needed(skb, zero_okay, check)) \ __ret = __skb_gro_checksum_validate_complete(skb, \ compute_pseudo(skb, proto)); \ - if (__ret) \ - __skb_mark_checksum_bad(skb); \ - else \ + if (!__ret) \ skb_gro_incr_csum_unnecessary(skb); \ __ret; \ }) @@@ -3933,6 -3930,10 +3932,10 @@@ void netdev_rss_key_fill(void *buffer,
int dev_get_nest_level(struct net_device *dev); int skb_checksum_help(struct sk_buff *skb); + int skb_crc32c_csum_help(struct sk_buff *skb); + int skb_csum_hwoffload_help(struct sk_buff *skb, + const netdev_features_t features); + struct sk_buff *__skb_gso_segment(struct sk_buff *skb, netdev_features_t features, bool tx_path); struct sk_buff *skb_mac_gso_segment(struct sk_buff *skb, @@@ -4263,11 -4264,6 +4266,11 @@@ static inline const char *netdev_name(c return dev->name; }
+static inline bool netdev_unregistering(const struct net_device *dev) +{ + return dev->reg_state == NETREG_UNREGISTERING; +} + static inline const char *netdev_reg_state(const struct net_device *dev) { switch (dev->reg_state) { diff --combined include/linux/skbuff.h index 25b1659c832a,1151b50892d1..78213b3f9552 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@@ -109,6 -109,7 +109,7 @@@ * may perform further validation in this case. * GRE: only if the checksum is present in the header. * SCTP: indicates the CRC in SCTP header has been validated. + * FCOE: indicates the CRC in FC frame has been validated. * * skb->csum_level indicates the number of consecutive checksums found in * the packet minus one that have been verified as CHECKSUM_UNNECESSARY. @@@ -126,8 -127,10 +127,10 @@@ * packet as seen by netif_rx() and fills out in skb->csum. Meaning, the * hardware doesn't need to parse L3/L4 headers to implement this. * - * Note: Even if device supports only some protocols, but is able to produce - * skb->csum, it MUST use CHECKSUM_COMPLETE, not CHECKSUM_UNNECESSARY. + * Notes: + * - Even if device supports only some protocols, but is able to produce + * skb->csum, it MUST use CHECKSUM_COMPLETE, not CHECKSUM_UNNECESSARY. + * - CHECKSUM_COMPLETE is not applicable to SCTP and FCoE protocols. * * CHECKSUM_PARTIAL: * @@@ -162,14 -165,11 +165,11 @@@ * * NETIF_F_IP_CSUM and NETIF_F_IPV6_CSUM are being deprecated in favor of * NETIF_F_HW_CSUM. New devices should use NETIF_F_HW_CSUM to indicate - * checksum offload capability. If a device has limited checksum capabilities - * (for instance can only perform NETIF_F_IP_CSUM or NETIF_F_IPV6_CSUM as - * described above) a helper function can be called to resolve - * CHECKSUM_PARTIAL. The helper functions are skb_csum_off_chk*. The helper - * function takes a spec argument that describes the protocol layer that is - * supported for checksum offload and can be called for each packet. If a - * packet does not match the specification for offload, skb_checksum_help - * is called to resolve the checksum. + * checksum offload capability. + * skb_csum_hwoffload_help() can be called to resolve CHECKSUM_PARTIAL based + * on network device checksumming capabilities: if a packet does not match + * them, skb_checksum_help or skb_crc32c_help (depending on the value of + * csum_not_inet, see item D.) is called to resolve the checksum. * * CHECKSUM_NONE: * @@@ -189,11 -189,13 +189,13 @@@ * * NETIF_F_SCTP_CRC - This feature indicates that a device is capable of * offloading the SCTP CRC in a packet. To perform this offload the stack - * will set ip_summed to CHECKSUM_PARTIAL and set csum_start and csum_offset - * accordingly. Note the there is no indication in the skbuff that the - * CHECKSUM_PARTIAL refers to an SCTP checksum, a driver that supports - * both IP checksum offload and SCTP CRC offload must verify which offload - * is configured for a packet presumably by inspecting packet headers. + * will set set csum_start and csum_offset accordingly, set ip_summed to + * CHECKSUM_PARTIAL and set csum_not_inet to 1, to provide an indication in + * the skbuff that the CHECKSUM_PARTIAL refers to CRC32c. + * A driver that supports both IP checksum offload and SCTP CRC32c offload + * must verify which offload is configured for a packet by testing the + * value of skb->csum_not_inet; skb_crc32c_csum_help is provided to resolve + * CHECKSUM_PARTIAL on skbs where csum_not_inet is set to 1. * * NETIF_F_FCOE_CRC - This feature indicates that a device is capable of * offloading the FCOE CRC in a packet. To perform this offload the stack @@@ -506,66 -508,6 +508,6 @@@ typedef unsigned int sk_buff_data_t typedef unsigned char *sk_buff_data_t; #endif
- /** - * struct skb_mstamp - multi resolution time stamps - * @stamp_us: timestamp in us resolution - * @stamp_jiffies: timestamp in jiffies - */ - struct skb_mstamp { - union { - u64 v64; - struct { - u32 stamp_us; - u32 stamp_jiffies; - }; - }; - }; - - /** - * skb_mstamp_get - get current timestamp - * @cl: place to store timestamps - */ - static inline void skb_mstamp_get(struct skb_mstamp *cl) - { - u64 val = local_clock(); - - do_div(val, NSEC_PER_USEC); - cl->stamp_us = (u32)val; - cl->stamp_jiffies = (u32)jiffies; - } - - /** - * skb_mstamp_delta - compute the difference in usec between two skb_mstamp - * @t1: pointer to newest sample - * @t0: pointer to oldest sample - */ - static inline u32 skb_mstamp_us_delta(const struct skb_mstamp *t1, - const struct skb_mstamp *t0) - { - s32 delta_us = t1->stamp_us - t0->stamp_us; - u32 delta_jiffies = t1->stamp_jiffies - t0->stamp_jiffies; - - /* If delta_us is negative, this might be because interval is too big, - * or local_clock() drift is too big : fallback using jiffies. - */ - if (delta_us <= 0 || - delta_jiffies >= (INT_MAX / (USEC_PER_SEC / HZ))) - - delta_us = jiffies_to_usecs(delta_jiffies); - - return delta_us; - } - - static inline bool skb_mstamp_after(const struct skb_mstamp *t1, - const struct skb_mstamp *t0) - { - s32 diff = t1->stamp_jiffies - t0->stamp_jiffies; - - if (!diff) - diff = t1->stamp_us - t0->stamp_us; - return diff > 0; - } - /** * struct sk_buff - socket buffer * @next: Next buffer in list @@@ -616,6 -558,7 +558,7 @@@ * @wifi_acked_valid: wifi_acked was set * @wifi_acked: whether frame was acked on wifi or not * @no_fcs: Request NIC to treat last 4 bytes as Ethernet FCS + * @csum_not_inet: use CRC32c to resolve CHECKSUM_PARTIAL * @dst_pending_confirm: need to confirm neighbour * @napi_id: id of the NAPI struct this skb came from * @secmark: security marking @@@ -646,7 -589,7 +589,7 @@@ struct sk_buff
union { ktime_t tstamp; - struct skb_mstamp skb_mstamp; + u64 skb_mstamp; }; }; struct rb_node rbnode; /* used in netem & tcp stack */ @@@ -744,7 -687,7 +687,7 @@@ __u8 csum_valid:1; __u8 csum_complete_sw:1; __u8 csum_level:2; - __u8 csum_bad:1; + __u8 csum_not_inet:1;
__u8 dst_pending_confirm:1; #ifdef CONFIG_IPV6_NDISC_NODETYPE @@@ -915,10 -858,34 +858,34 @@@ static inline bool skb_pkt_type_ok(u32 return ptype <= PACKET_OTHERHOST; }
+ static inline unsigned int skb_napi_id(const struct sk_buff *skb) + { + #ifdef CONFIG_NET_RX_BUSY_POLL + return skb->napi_id; + #else + return 0; + #endif + } + + /* decrement the reference count and return true if we can free the skb */ + static inline bool skb_unref(struct sk_buff *skb) + { + if (unlikely(!skb)) + return false; + if (likely(atomic_read(&skb->users) == 1)) + smp_rmb(); + else if (likely(!atomic_dec_and_test(&skb->users))) + return false; + + return true; + } + + void skb_release_head_state(struct sk_buff *skb); void kfree_skb(struct sk_buff *skb); void kfree_skb_list(struct sk_buff *segs); void skb_tx_error(struct sk_buff *skb); void consume_skb(struct sk_buff *skb); + void consume_stateless_skb(struct sk_buff *skb); void __kfree_skb(struct sk_buff *skb); extern struct kmem_cache *skbuff_head_cache;
@@@ -1001,10 -968,10 +968,10 @@@ struct sk_buff *skb_realloc_headroom(st unsigned int headroom); struct sk_buff *skb_copy_expand(const struct sk_buff *skb, int newheadroom, int newtailroom, gfp_t priority); - int skb_to_sgvec_nomark(struct sk_buff *skb, struct scatterlist *sg, - int offset, int len); - int skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, - int len); + int __must_check skb_to_sgvec_nomark(struct sk_buff *skb, struct scatterlist *sg, + int offset, int len); + int __must_check skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, + int offset, int len); int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer); int skb_pad(struct sk_buff *skb, int pad); #define dev_kfree_skb(a) consume_skb(a) @@@ -1937,6 -1904,15 +1904,15 @@@ static inline unsigned char *__skb_put( return tmp; }
+ static inline unsigned char *skb_put_zero(struct sk_buff *skb, unsigned int len) + { + unsigned char *tmp = skb_put(skb, len); + + memset(tmp, 0, len); + + return tmp; + } + unsigned char *skb_push(struct sk_buff *skb, unsigned int len); static inline unsigned char *__skb_push(struct sk_buff *skb, unsigned int len) { @@@ -2691,7 -2667,7 +2667,7 @@@ bool skb_page_frag_refill(unsigned int * @offset: the offset within the fragment (starting at the * fragment's own offset) * @size: the number of bytes to map - * @dir: the direction of the mapping (%PCI_DMA_*) + * @dir: the direction of the mapping (``PCI_DMA_*``) * * Maps the page associated with @frag to @device. */ @@@ -3056,6 -3032,13 +3032,13 @@@ static inline void skb_frag_list_init(s
int __skb_wait_for_more_packets(struct sock *sk, int *err, long *timeo_p, const struct sk_buff *skb); + struct sk_buff *__skb_try_recv_from_queue(struct sock *sk, + struct sk_buff_head *queue, + unsigned int flags, + void (*destructor)(struct sock *sk, + struct sk_buff *skb), + int *peeked, int *off, int *err, + struct sk_buff **last); struct sk_buff *__skb_try_recv_datagram(struct sock *sk, unsigned flags, void (*destructor)(struct sock *sk, struct sk_buff *skb), @@@ -3129,6 -3112,8 +3112,8 @@@ struct skb_checksum_ops __wsum (*combine)(__wsum csum, __wsum csum2, int offset, int len); };
+ extern const struct skb_checksum_ops *crc32c_csum_stub __read_mostly; + __wsum __skb_checksum(const struct sk_buff *skb, int offset, int len, __wsum csum, const struct skb_checksum_ops *ops); __wsum skb_checksum(const struct sk_buff *skb, int offset, int len, @@@ -3298,13 -3283,6 +3283,6 @@@ void __skb_tstamp_tx(struct sk_buff *or void skb_tstamp_tx(struct sk_buff *orig_skb, struct skb_shared_hwtstamps *hwtstamps);
- static inline void sw_tx_timestamp(struct sk_buff *skb) - { - if (skb_shinfo(skb)->tx_flags & SKBTX_SW_TSTAMP && - !(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)) - skb_tstamp_tx(skb, NULL); - } - /** * skb_tx_timestamp() - Driver hook for transmit timestamping * @@@ -3320,7 -3298,8 +3298,8 @@@ static inline void skb_tx_timestamp(struct sk_buff *skb) { skb_clone_tx_timestamp(skb); - sw_tx_timestamp(skb); + if (skb_shinfo(skb)->tx_flags & SKBTX_SW_TSTAMP) + skb_tstamp_tx(skb, NULL); }
/** @@@ -3386,21 -3365,6 +3365,6 @@@ static inline void __skb_incr_checksum_ } }
- static inline void __skb_mark_checksum_bad(struct sk_buff *skb) - { - /* Mark current checksum as bad (typically called from GRO - * path). In the case that ip_summed is CHECKSUM_NONE - * this must be the first checksum encountered in the packet. - * When ip_summed is CHECKSUM_UNNECESSARY, this is the first - * checksum after the last one validated. For UDP, a zero - * checksum can not be marked as bad. - */ - - if (skb->ip_summed == CHECKSUM_NONE || - skb->ip_summed == CHECKSUM_UNNECESSARY) - skb->csum_bad = 1; - } - /* Check if we need to perform checksum complete validation. * * Returns true if checksum complete is needed, false otherwise @@@ -3454,9 -3418,6 +3418,6 @@@ static inline __sum16 __skb_checksum_va skb->csum_valid = 1; return 0; } - } else if (skb->csum_bad) { - /* ip_summed == CHECKSUM_NONE in this case */ - return (__force __sum16)1; }
skb->csum = psum; @@@ -3516,8 -3477,7 +3477,7 @@@ static inline __wsum null_compute_pseud
static inline bool __skb_checksum_convert_check(struct sk_buff *skb) { - return (skb->ip_summed == CHECKSUM_NONE && - skb->csum_valid && !skb->csum_bad); + return (skb->ip_summed == CHECKSUM_NONE && skb->csum_valid); }
static inline void __skb_checksum_convert(struct sk_buff *skb, diff --combined include/net/sock.h index f97da141d920,858891c36f94..ac39048fbc88 --- a/include/net/sock.h +++ b/include/net/sock.h @@@ -253,6 -253,7 +253,7 @@@ struct sock_common * @sk_ll_usec: usecs to busypoll when there is no data * @sk_allocation: allocation mode * @sk_pacing_rate: Pacing rate (if supported by transport/packet scheduler) + * @sk_pacing_status: Pacing status (requested, handled by sch_fq) * @sk_max_pacing_rate: Maximum pacing rate (%SO_MAX_PACING_RATE) * @sk_sndbuf: size of send buffer in bytes * @sk_padding: unused element for alignment @@@ -396,7 -397,7 +397,7 @@@ struct sock __s32 sk_peek_off; int sk_write_pending; __u32 sk_dst_pending_confirm; - /* Note: 32bit hole on 64bit arches */ + u32 sk_pacing_status; /* see enum sk_pacing */ long sk_sndtimeo; struct timer_list sk_timer; __u32 sk_priority; @@@ -475,6 -476,12 +476,12 @@@ struct rcu_head sk_rcu; };
+ enum sk_pacing { + SK_PACING_NONE = 0, + SK_PACING_NEEDED = 1, + SK_PACING_FQ = 2, + }; + #define __sk_user_data(sk) ((*((void __rcu **)&(sk)->sk_user_data)))
#define rcu_dereference_sk_user_data(sk) rcu_dereference(__sk_user_data((sk))) @@@ -1073,6 -1080,7 +1080,7 @@@ struct proto bool (*stream_memory_free)(const struct sock *sk); /* Memory pressure */ void (*enter_memory_pressure)(struct sock *sk); + void (*leave_memory_pressure)(struct sock *sk); atomic_long_t *memory_allocated; /* Current allocated memory. */ struct percpu_counter *sockets_allocated; /* Current number of sockets. */ /* @@@ -1081,7 -1089,7 +1089,7 @@@ * All the __sk_mem_schedule() is of this nature: accounting * is strict, actions are advisory and have some latency. */ - int *memory_pressure; + unsigned long *memory_pressure; long *sysctl_mem; int *sysctl_wmem; int *sysctl_rmem; @@@ -1186,25 -1194,6 +1194,6 @@@ static inline bool sk_under_memory_pres return !!*sk->sk_prot->memory_pressure; }
- static inline void sk_leave_memory_pressure(struct sock *sk) - { - int *memory_pressure = sk->sk_prot->memory_pressure; - - if (!memory_pressure) - return; - - if (*memory_pressure) - *memory_pressure = 0; - } - - static inline void sk_enter_memory_pressure(struct sock *sk) - { - if (!sk->sk_prot->enter_memory_pressure) - return; - - sk->sk_prot->enter_memory_pressure(sk); - } - static inline long sk_memory_allocated(const struct sock *sk) { @@@ -1953,10 -1942,11 +1942,10 @@@ static inline bool sk_has_allocations(c * The purpose of the skwq_has_sleeper and sock_poll_wait is to wrap the memory * barrier call. They were added due to the race found within the tcp code. * - * Consider following tcp code paths: + * Consider following tcp code paths:: * - * CPU1 CPU2 - * - * sys_select receive packet + * CPU1 CPU2 + * sys_select receive packet * ... ... * __add_wait_queue update tp->rcv_nxt * ... ... @@@ -2034,8 -2024,8 +2023,8 @@@ void sk_reset_timer(struct sock *sk, st
void sk_stop_timer(struct sock *sk, struct timer_list *timer);
- int __sk_queue_drop_skb(struct sock *sk, struct sk_buff *skb, - unsigned int flags, + int __sk_queue_drop_skb(struct sock *sk, struct sk_buff_head *sk_queue, + struct sk_buff *skb, unsigned int flags, void (*destructor)(struct sock *sk, struct sk_buff *skb)); int __sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb); @@@ -2263,7 -2253,7 +2252,7 @@@ void __sock_tx_timestamp(__u16 tsflags * @tsflags: timestamping flags to use * @tx_flags: completed with instructions for time stamping * - * Note : callers should take care of initial *tx_flags value (usually 0) + * Note: callers should take care of initial ``*tx_flags`` value (usually 0) */ static inline void sock_tx_timestamp(const struct sock *sk, __u16 tsflags, __u8 *tx_flags) diff --combined kernel/events/core.c index 6c4e523dc1e2,51e40e4876c0..9afab55c68c2 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@@ -3636,10 -3636,10 +3636,10 @@@ static inline u64 perf_event_count(stru * will not be local and we cannot read them atomically * - must not have a pmu::count method */ - u64 perf_event_read_local(struct perf_event *event) + int perf_event_read_local(struct perf_event *event, u64 *value) { unsigned long flags; - u64 val; + int ret = 0;
/* * Disabling interrupts avoids all counter scheduling (context @@@ -3647,25 -3647,37 +3647,37 @@@ */ local_irq_save(flags);
- /* If this is a per-task event, it must be for current */ - WARN_ON_ONCE((event->attach_state & PERF_ATTACH_TASK) && - event->hw.target != current); - - /* If this is a per-CPU event, it must be for this CPU */ - WARN_ON_ONCE(!(event->attach_state & PERF_ATTACH_TASK) && - event->cpu != smp_processor_id()); - /* * It must not be an event with inherit set, we cannot read * all child counters from atomic context. */ - WARN_ON_ONCE(event->attr.inherit); + if (event->attr.inherit) { + ret = -EOPNOTSUPP; + goto out; + }
/* * It must not have a pmu::count method, those are not * NMI safe. */ - WARN_ON_ONCE(event->pmu->count); + if (event->pmu->count) { + ret = -EOPNOTSUPP; + goto out; + } + + /* If this is a per-task event, it must be for current */ + if ((event->attach_state & PERF_ATTACH_TASK) && + event->hw.target != current) { + ret = -EINVAL; + goto out; + } + + /* If this is a per-CPU event, it must be for this CPU */ + if (!(event->attach_state & PERF_ATTACH_TASK) && + event->cpu != smp_processor_id()) { + ret = -EINVAL; + goto out; + }
/* * If the event is currently on this CPU, its either a per-task event, @@@ -3675,10 -3687,11 +3687,11 @@@ if (event->oncpu == smp_processor_id()) event->pmu->read(event);
- val = local64_read(&event->count); + *value = local64_read(&event->count); + out: local_irq_restore(flags);
- return val; + return ret; }
static int perf_event_read(struct perf_event *event, bool group) @@@ -7316,21 -7329,6 +7329,21 @@@ int perf_event_account_interrupt(struc return __perf_event_account_interrupt(event, 1); }
+static bool sample_is_allowed(struct perf_event *event, struct pt_regs *regs) +{ + /* + * Due to interrupt latency (AKA "skid"), we may enter the + * kernel before taking an overflow, even if the PMU is only + * counting user events. + * To avoid leaking information to userspace, we must always + * reject kernel samples when exclude_kernel is set. + */ + if (event->attr.exclude_kernel && !user_mode(regs)) + return false; + + return true; +} + /* * Generic event overflow handling, sampling. */ @@@ -7352,12 -7350,6 +7365,12 @@@ static int __perf_event_overflow(struc ret = __perf_event_account_interrupt(event, throttle);
/* + * For security, drop the skid kernel samples if necessary. + */ + if (!sample_is_allowed(event, regs)) + return ret; + + /* * XXX event_limit might not quite work as expected on inherited * events */ @@@ -8058,12 -8050,8 +8071,8 @@@ static int perf_event_set_bpf_prog(stru bool is_kprobe, is_tracepoint; struct bpf_prog *prog;
- if (event->attr.type == PERF_TYPE_HARDWARE || - event->attr.type == PERF_TYPE_SOFTWARE) - return perf_event_set_bpf_handler(event, prog_fd); - if (event->attr.type != PERF_TYPE_TRACEPOINT) - return -EINVAL; + return perf_event_set_bpf_handler(event, prog_fd);
if (event->tp_event->prog) return -EEXIST; diff --combined net/8021q/vlan_dev.c index abc5f400fc71,56d4b6977d03..c1742322f7d2 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c @@@ -797,12 -797,6 +797,6 @@@ static const struct net_device_ops vlan .ndo_netpoll_cleanup = vlan_dev_netpoll_cleanup, #endif .ndo_fix_features = vlan_dev_fix_features, - .ndo_fdb_add = switchdev_port_fdb_add, - .ndo_fdb_del = switchdev_port_fdb_del, - .ndo_fdb_dump = switchdev_port_fdb_dump, - .ndo_bridge_setlink = switchdev_port_bridge_setlink, - .ndo_bridge_getlink = switchdev_port_bridge_getlink, - .ndo_bridge_dellink = switchdev_port_bridge_dellink, .ndo_get_lock_subclass = vlan_dev_get_lock_subclass, .ndo_get_iflink = vlan_dev_get_iflink, }; @@@ -813,6 -807,7 +807,6 @@@ static void vlan_dev_free(struct net_de
free_percpu(vlan->vlan_pcpu_stats); vlan->vlan_pcpu_stats = NULL; - free_netdev(dev); }
void vlan_setup(struct net_device *dev) @@@ -825,8 -820,7 +819,8 @@@ netif_keep_dst(dev);
dev->netdev_ops = &vlan_netdev_ops; - dev->destructor = vlan_dev_free; + dev->needs_free_netdev = true; + dev->priv_destructor = vlan_dev_free; dev->ethtool_ops = &vlan_ethtool_ops;
dev->min_mtu = 0; diff --combined net/batman-adv/distributed-arp-table.c index 000ca2f113ab,362cae2ef82a..6930d6b50f99 --- a/net/batman-adv/distributed-arp-table.c +++ b/net/batman-adv/distributed-arp-table.c @@@ -601,7 -601,7 +601,7 @@@ batadv_dat_select_candidates(struct bat BATADV_DAT_ADDR_MAX);
batadv_dbg(BATADV_DBG_DAT, bat_priv, - "dat_select_candidates(): IP=%pI4 hash(IP)=%u\n", &ip_dst, + "%s(): IP=%pI4 hash(IP)=%u\n", __func__, &ip_dst, ip_key);
for (select = 0; select < BATADV_DAT_CANDIDATES_NUM; select++) @@@ -1064,9 -1064,8 +1064,9 @@@ bool batadv_dat_snoop_outgoing_arp_requ
skb_new->protocol = eth_type_trans(skb_new, soft_iface);
- soft_iface->stats.rx_packets++; - soft_iface->stats.rx_bytes += skb->len + ETH_HLEN + hdr_size; + batadv_inc_counter(bat_priv, BATADV_CNT_RX); + batadv_add_counter(bat_priv, BATADV_CNT_RX_BYTES, + skb->len + ETH_HLEN + hdr_size);
netif_rx(skb_new); batadv_dbg(BATADV_DBG_DAT, bat_priv, "ARP request replied locally\n"); diff --combined net/batman-adv/routing.c index ae9f4d37d34f,1338b9221613..f10e3ff26f9d --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c @@@ -985,9 -985,9 +985,9 @@@ int batadv_recv_unicast_packet(struct s batadv_orig_node_put(orig_node_gw); if (is_gw) { batadv_dbg(BATADV_DBG_BLA, bat_priv, - "recv_unicast_packet(): Dropped unicast pkt received from another backbone gw %pM.\n", - orig_addr_gw); + "%s(): Dropped unicast pkt received from another backbone gw %pM.\n", + __func__, orig_addr_gw); - return NET_RX_DROP; + goto free_skb; } }
diff --combined net/caif/caif_socket.c index 21f18ea2fce4,4674d17e7c08..7506b853a84d --- a/net/caif/caif_socket.c +++ b/net/caif/caif_socket.c @@@ -754,10 -754,6 +754,10 @@@ static int caif_connect(struct socket *
lock_sock(sk);
+ err = -EINVAL; + if (addr_len < offsetofend(struct sockaddr, sa_family)) + goto out; + err = -EAFNOSUPPORT; if (uaddr->sa_family != AF_CAIF) goto out; @@@ -1103,7 -1099,7 +1103,7 @@@ static int caif_create(struct net *net }
- static struct net_proto_family caif_family_ops = { + static const struct net_proto_family caif_family_ops = { .family = PF_CAIF, .create = caif_create, .owner = THIS_MODULE, diff --combined net/core/datagram.c index 4dd594741b6d,e5311a7c70da..ef342800828f --- a/net/core/datagram.c +++ b/net/core/datagram.c @@@ -161,6 -161,45 +161,45 @@@ done return skb; }
+ struct sk_buff *__skb_try_recv_from_queue(struct sock *sk, + struct sk_buff_head *queue, + unsigned int flags, + void (*destructor)(struct sock *sk, + struct sk_buff *skb), + int *peeked, int *off, int *err, + struct sk_buff **last) + { + struct sk_buff *skb; + int _off = *off; + + *last = queue->prev; + skb_queue_walk(queue, skb) { + if (flags & MSG_PEEK) { + if (_off >= skb->len && (skb->len || _off || + skb->peeked)) { + _off -= skb->len; + continue; + } + if (!skb->len) { + skb = skb_set_peeked(skb); + if (unlikely(IS_ERR(skb))) { + *err = PTR_ERR(skb); + return NULL; + } + } + *peeked = 1; + atomic_inc(&skb->users); + } else { + __skb_unlink(skb, queue); + if (destructor) + destructor(sk, skb); + } + *off = _off; + return skb; + } + return NULL; + } + /** * __skb_try_recv_datagram - Receive a datagram skbuff * @sk: socket @@@ -181,7 -220,7 +220,7 @@@ * * This function will lock the socket if a skb is returned, so * the caller needs to unlock the socket in that case (usually by - * calling skb_free_datagram). Returns NULL with *err set to + * calling skb_free_datagram). Returns NULL with @err set to * -EAGAIN if no data was available or to some other value if an * error was detected. * @@@ -222,40 -261,14 +261,14 @@@ struct sk_buff *__skb_try_recv_datagram * Look at current nfs client by the way... * However, this function was correct in any case. 8) */ - int _off = *off; - - *last = (struct sk_buff *)queue; spin_lock_irqsave(&queue->lock, cpu_flags); - skb_queue_walk(queue, skb) { - *last = skb; - if (flags & MSG_PEEK) { - if (_off >= skb->len && (skb->len || _off || - skb->peeked)) { - _off -= skb->len; - continue; - } - if (!skb->len) { - skb = skb_set_peeked(skb); - if (IS_ERR(skb)) { - error = PTR_ERR(skb); - spin_unlock_irqrestore(&queue->lock, - cpu_flags); - goto no_packet; - } - } - *peeked = 1; - atomic_inc(&skb->users); - } else { - __skb_unlink(skb, queue); - if (destructor) - destructor(sk, skb); - } - spin_unlock_irqrestore(&queue->lock, cpu_flags); - *off = _off; - return skb; - } - + skb = __skb_try_recv_from_queue(sk, queue, flags, destructor, + peeked, off, &error, last); spin_unlock_irqrestore(&queue->lock, cpu_flags); + if (error) + goto no_packet; + if (skb) + return skb;
if (!sk_can_busy_loop(sk)) break; @@@ -317,9 -330,7 +330,7 @@@ void __skb_free_datagram_locked(struct { bool slow;
- if (likely(atomic_read(&skb->users) == 1)) - smp_rmb(); - else if (likely(!atomic_dec_and_test(&skb->users))) { + if (!skb_unref(skb)) { sk_peek_offset_bwd(sk, len); return; } @@@ -335,8 -346,8 +346,8 @@@ } EXPORT_SYMBOL(__skb_free_datagram_locked);
- int __sk_queue_drop_skb(struct sock *sk, struct sk_buff *skb, - unsigned int flags, + int __sk_queue_drop_skb(struct sock *sk, struct sk_buff_head *sk_queue, + struct sk_buff *skb, unsigned int flags, void (*destructor)(struct sock *sk, struct sk_buff *skb)) { @@@ -344,15 -355,15 +355,15 @@@
if (flags & MSG_PEEK) { err = -ENOENT; - spin_lock_bh(&sk->sk_receive_queue.lock); - if (skb == skb_peek(&sk->sk_receive_queue)) { - __skb_unlink(skb, &sk->sk_receive_queue); + spin_lock_bh(&sk_queue->lock); + if (skb == skb_peek(sk_queue)) { + __skb_unlink(skb, sk_queue); atomic_dec(&skb->users); if (destructor) destructor(sk, skb); err = 0; } - spin_unlock_bh(&sk->sk_receive_queue.lock); + spin_unlock_bh(&sk_queue->lock); }
atomic_inc(&sk->sk_drops); @@@ -383,7 -394,8 +394,8 @@@ EXPORT_SYMBOL(__sk_queue_drop_skb)
int skb_kill_datagram(struct sock *sk, struct sk_buff *skb, unsigned int flags) { - int err = __sk_queue_drop_skb(sk, skb, flags, NULL); + int err = __sk_queue_drop_skb(sk, &sk->sk_receive_queue, skb, flags, + NULL);
kfree_skb(skb); sk_mem_reclaim_partial(sk); diff --combined net/core/dev.c index 6d60149287a1,8f72f4a9c6ac..8658074ecad6 --- a/net/core/dev.c +++ b/net/core/dev.c @@@ -105,6 -105,7 +105,7 @@@ #include <net/dst.h> #include <net/dst_metadata.h> #include <net/pkt_sched.h> + #include <net/pkt_cls.h> #include <net/checksum.h> #include <net/xfrm.h> #include <linux/highmem.h> @@@ -142,6 -143,7 +143,7 @@@ #include <linux/hrtimer.h> #include <linux/netfilter_ingress.h> #include <linux/crash_dump.h> + #include <linux/sctp.h>
#include "net-sysfs.h"
@@@ -161,6 -163,7 +163,7 @@@ static int netif_rx_internal(struct sk_ static int call_netdevice_notifiers_info(unsigned long val, struct net_device *dev, struct netdev_notifier_info *info); + static struct napi_struct *napi_by_id(unsigned int napi_id);
/* * The @dev_base_head list is protected by @dev_base_lock and the rtnl @@@ -865,6 -868,31 +868,31 @@@ struct net_device *dev_get_by_index(str EXPORT_SYMBOL(dev_get_by_index);
/** + * dev_get_by_napi_id - find a device by napi_id + * @napi_id: ID of the NAPI struct + * + * Search for an interface by NAPI ID. Returns %NULL if the device + * is not found or a pointer to the device. The device has not had + * its reference counter increased so the caller must be careful + * about locking. The caller must hold RCU lock. + */ + + struct net_device *dev_get_by_napi_id(unsigned int napi_id) + { + struct napi_struct *napi; + + WARN_ON_ONCE(!rcu_read_lock_held()); + + if (napi_id < MIN_NAPI_ID) + return NULL; + + napi = napi_by_id(napi_id); + + return napi ? napi->dev : NULL; + } + EXPORT_SYMBOL(dev_get_by_napi_id); + + /** * netdev_get_name - get a netdevice name, knowing its ifindex. * @net: network namespace * @name: a pointer to the buffer where the name will be stored. @@@ -1253,9 -1281,8 +1281,9 @@@ int dev_set_alias(struct net_device *de if (!new_ifalias) return -ENOMEM; dev->ifalias = new_ifalias; + memcpy(dev->ifalias, alias, len); + dev->ifalias[len] = 0;
- strlcpy(dev->ifalias, alias, len+1); return len; }
@@@ -2612,6 -2639,47 +2640,47 @@@ out } EXPORT_SYMBOL(skb_checksum_help);
+ int skb_crc32c_csum_help(struct sk_buff *skb) + { + __le32 crc32c_csum; + int ret = 0, offset, start; + + if (skb->ip_summed != CHECKSUM_PARTIAL) + goto out; + + if (unlikely(skb_is_gso(skb))) + goto out; + + /* Before computing a checksum, we should make sure no frag could + * be modified by an external entity : checksum could be wrong. + */ + if (unlikely(skb_has_shared_frag(skb))) { + ret = __skb_linearize(skb); + if (ret) + goto out; + } + start = skb_checksum_start_offset(skb); + offset = start + offsetof(struct sctphdr, checksum); + if (WARN_ON_ONCE(offset >= skb_headlen(skb))) { + ret = -EINVAL; + goto out; + } + if (skb_cloned(skb) && + !skb_clone_writable(skb, offset + sizeof(__le32))) { + ret = pskb_expand_head(skb, 0, 0, GFP_ATOMIC); + if (ret) + goto out; + } + crc32c_csum = cpu_to_le32(~__skb_checksum(skb, start, + skb->len - start, ~(__u32)0, + crc32c_csum_stub)); + *(__le32 *)(skb->data + offset) = crc32c_csum; + skb->ip_summed = CHECKSUM_NONE; + skb->csum_not_inet = 0; + out: + return ret; + } + __be16 skb_network_protocol(struct sk_buff *skb, int *depth) { __be16 type = skb->protocol; @@@ -2954,6 -3022,17 +3023,17 @@@ static struct sk_buff *validate_xmit_vl return skb; }
+ int skb_csum_hwoffload_help(struct sk_buff *skb, + const netdev_features_t features) + { + if (unlikely(skb->csum_not_inet)) + return !!(features & NETIF_F_SCTP_CRC) ? 0 : + skb_crc32c_csum_help(skb); + + return !!(features & NETIF_F_CSUM_MASK) ? 0 : skb_checksum_help(skb); + } + EXPORT_SYMBOL(skb_csum_hwoffload_help); + static struct sk_buff *validate_xmit_skb(struct sk_buff *skb, struct net_device *dev) { netdev_features_t features; @@@ -2992,8 -3071,7 +3072,7 @@@ else skb_set_transport_header(skb, skb_checksum_start_offset(skb)); - if (!(features & NETIF_F_CSUM_MASK) && - skb_checksum_help(skb)) + if (skb_csum_hwoffload_help(skb, features)) goto out_kfree_skb; } } @@@ -3179,7 -3257,7 +3258,7 @@@ sch_handle_egress(struct sk_buff *skb, /* qdisc_skb_cb(skb)->pkt_len was already set by the caller. */ qdisc_bstats_cpu_update(cl->q, skb);
- switch (tc_classify(skb, cl, &cl_res, false)) { + switch (tcf_classify(skb, cl, &cl_res, false)) { case TC_ACT_OK: case TC_ACT_RECLASSIFY: skb->tc_index = TC_H_MIN(cl_res.classid); @@@ -3191,6 -3269,7 +3270,7 @@@ return NULL; case TC_ACT_STOLEN: case TC_ACT_QUEUED: + case TC_ACT_TRAP: *ret = NET_XMIT_SUCCESS; consume_skb(skb); return NULL; @@@ -3949,7 -4028,7 +4029,7 @@@ sch_handle_ingress(struct sk_buff *skb skb->tc_at_ingress = 1; qdisc_bstats_cpu_update(cl->q, skb);
- switch (tc_classify(skb, cl, &cl_res, false)) { + switch (tcf_classify(skb, cl, &cl_res, false)) { case TC_ACT_OK: case TC_ACT_RECLASSIFY: skb->tc_index = TC_H_MIN(cl_res.classid); @@@ -3960,6 -4039,7 +4040,7 @@@ return NULL; case TC_ACT_STOLEN: case TC_ACT_QUEUED: + case TC_ACT_TRAP: consume_skb(skb); return NULL; case TC_ACT_REDIRECT: @@@ -4637,9 -4717,6 +4718,6 @@@ static enum gro_result dev_gro_receive( if (netif_elide_gro(skb->dev)) goto normal;
- if (skb->csum_bad) - goto normal; - gro_list_prepare(napi, skb);
rcu_read_lock(); @@@ -4949,19 -5026,6 +5027,19 @@@ __sum16 __skb_gro_checksum_complete(str } EXPORT_SYMBOL(__skb_gro_checksum_complete);
+static void net_rps_send_ipi(struct softnet_data *remsd) +{ +#ifdef CONFIG_RPS + while (remsd) { + struct softnet_data *next = remsd->rps_ipi_next; + + if (cpu_online(remsd->cpu)) + smp_call_function_single_async(remsd->cpu, &remsd->csd); + remsd = next; + } +#endif +} + /* * net_rps_action_and_irq_enable sends any pending IPI's for rps. * Note: called with local irq disabled, but exits with local irq enabled. @@@ -4977,7 -5041,14 +5055,7 @@@ static void net_rps_action_and_irq_enab local_irq_enable();
/* Send pending IPI's to kick RPS processing on remote cpus. */ - while (remsd) { - struct softnet_data *next = remsd->rps_ipi_next; - - if (cpu_online(remsd->cpu)) - smp_call_function_single_async(remsd->cpu, - &remsd->csd); - remsd = next; - } + net_rps_send_ipi(remsd); } else #endif local_irq_enable(); @@@ -7015,7 -7086,7 +7093,7 @@@ static void rollback_registered_many(st
if (!dev->rtnl_link_ops || dev->rtnl_link_state == RTNL_LINK_INITIALIZED) - skb = rtmsg_ifinfo_build_skb(RTM_DELLINK, dev, ~0U, + skb = rtmsg_ifinfo_build_skb(RTM_DELLINK, dev, ~0U, 0, GFP_KERNEL);
/* @@@ -7508,8 -7579,6 +7586,8 @@@ out err_uninit: if (dev->netdev_ops->ndo_uninit) dev->netdev_ops->ndo_uninit(dev); + if (dev->priv_destructor) + dev->priv_destructor(dev); goto out; } EXPORT_SYMBOL(register_netdevice); @@@ -7717,10 -7786,8 +7795,10 @@@ void netdev_run_todo(void WARN_ON(rcu_access_pointer(dev->ip6_ptr)); WARN_ON(dev->dn_ptr);
- if (dev->destructor) - dev->destructor(dev); + if (dev->priv_destructor) + dev->priv_destructor(dev); + if (dev->needs_free_netdev) + free_netdev(dev);
/* Report a network device has been unregistered */ rtnl_lock(); @@@ -8203,7 -8270,7 +8281,7 @@@ static int dev_cpu_dead(unsigned int ol struct sk_buff **list_skb; struct sk_buff *skb; unsigned int cpu; - struct softnet_data *sd, *oldsd; + struct softnet_data *sd, *oldsd, *remsd = NULL;
local_irq_disable(); cpu = smp_processor_id(); @@@ -8244,13 -8311,6 +8322,13 @@@ raise_softirq_irqoff(NET_TX_SOFTIRQ); local_irq_enable();
+#ifdef CONFIG_RPS + remsd = oldsd->rps_ipi_list; + oldsd->rps_ipi_list = NULL; +#endif + /* send out pending IPI's on offline CPU */ + net_rps_send_ipi(remsd); + /* Process offline CPU's input_pkt_queue */ while ((skb = __skb_dequeue(&oldsd->process_queue))) { netif_rx_ni(skb); diff --combined net/core/rtnetlink.c index 5e61456f6bc7,7084f1db2446..2769ad9834d1 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@@ -941,6 -941,7 +941,7 @@@ static noinline size_t if_nlmsg_size(co + nla_total_size(MAX_PHYS_ITEM_ID_LEN) /* IFLA_PHYS_SWITCH_ID */ + nla_total_size(IFNAMSIZ) /* IFLA_PHYS_PORT_NAME */ + rtnl_xdp_size() /* IFLA_XDP */ + + nla_total_size(4) /* IFLA_EVENT */ + nla_total_size(1); /* IFLA_PROTO_DOWN */
} @@@ -1124,8 -1125,6 +1125,8 @@@ static noinline_for_stack int rtnl_fill struct ifla_vf_mac vf_mac; struct ifla_vf_info ivi;
+ memset(&ivi, 0, sizeof(ivi)); + /* Not all SR-IOV capable drivers support the * spoofcheck and "RSS query enable" query. Preset to * -1 so the user space tool can detect that the driver @@@ -1134,6 -1133,7 +1135,6 @@@ ivi.spoofchk = -1; ivi.rss_query_en = -1; ivi.trusted = -1; - memset(ivi.mac, 0, sizeof(ivi.mac)); /* The default value for VF link state is "auto" * IFLA_VF_LINK_STATE_AUTO which equals zero */ @@@ -1283,9 -1283,40 +1284,40 @@@ err_cancel return err; }
+ static u32 rtnl_get_event(unsigned long event) + { + u32 rtnl_event_type = IFLA_EVENT_NONE; + + switch (event) { + case NETDEV_REBOOT: + rtnl_event_type = IFLA_EVENT_REBOOT; + break; + case NETDEV_FEAT_CHANGE: + rtnl_event_type = IFLA_EVENT_FEATURES; + break; + case NETDEV_BONDING_FAILOVER: + rtnl_event_type = IFLA_EVENT_BONDING_FAILOVER; + break; + case NETDEV_NOTIFY_PEERS: + rtnl_event_type = IFLA_EVENT_NOTIFY_PEERS; + break; + case NETDEV_RESEND_IGMP: + rtnl_event_type = IFLA_EVENT_IGMP_RESEND; + break; + case NETDEV_CHANGEINFODATA: + rtnl_event_type = IFLA_EVENT_BONDING_OPTIONS; + break; + default: + break; + } + + return rtnl_event_type; + } + static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, int type, u32 pid, u32 seq, u32 change, - unsigned int flags, u32 ext_filter_mask) + unsigned int flags, u32 ext_filter_mask, + u32 event) { struct ifinfomsg *ifm; struct nlmsghdr *nlh; @@@ -1334,6 -1365,11 +1366,11 @@@ nla_put_u8(skb, IFLA_PROTO_DOWN, dev->proto_down)) goto nla_put_failure;
+ if (event != IFLA_EVENT_NONE) { + if (nla_put_u32(skb, IFLA_EVENT, event)) + goto nla_put_failure; + } + if (rtnl_fill_link_ifmap(skb, dev)) goto nla_put_failure;
@@@ -1468,6 -1504,7 +1505,7 @@@ static const struct nla_policy ifla_pol [IFLA_LINK_NETNSID] = { .type = NLA_S32 }, [IFLA_PROTO_DOWN] = { .type = NLA_U8 }, [IFLA_XDP] = { .type = NLA_NESTED }, + [IFLA_EVENT] = { .type = NLA_U32 }, };
static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = { @@@ -1627,7 -1664,7 +1665,7 @@@ static int rtnl_dump_ifinfo(struct sk_b NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, 0, flags, - ext_filter_mask); + ext_filter_mask, 0);
if (err < 0) { if (likely(skb->len)) @@@ -2049,8 -2086,8 +2087,8 @@@ static int do_setlink(const struct sk_b }
if (tb[IFLA_TXQLEN]) { - unsigned long value = nla_get_u32(tb[IFLA_TXQLEN]); - unsigned long orig_len = dev->tx_queue_len; + unsigned int value = nla_get_u32(tb[IFLA_TXQLEN]); + unsigned int orig_len = dev->tx_queue_len;
if (dev->tx_queue_len ^ value) { dev->tx_queue_len = value; @@@ -2737,7 -2774,7 +2775,7 @@@ static int rtnl_getlink(struct sk_buff return -ENOBUFS;
err = rtnl_fill_ifinfo(nskb, dev, RTM_NEWLINK, NETLINK_CB(skb).portid, - nlh->nlmsg_seq, 0, 0, ext_filter_mask); + nlh->nlmsg_seq, 0, 0, ext_filter_mask, 0); if (err < 0) { /* -EMSGSIZE implies BUG in if_nlmsg_size */ WARN_ON(err == -EMSGSIZE); @@@ -2809,7 -2846,8 +2847,8 @@@ static int rtnl_dump_all(struct sk_buf }
struct sk_buff *rtmsg_ifinfo_build_skb(int type, struct net_device *dev, - unsigned int change, gfp_t flags) + unsigned int change, + u32 event, gfp_t flags) { struct net *net = dev_net(dev); struct sk_buff *skb; @@@ -2820,7 -2858,7 +2859,7 @@@ if (skb == NULL) goto errout;
- err = rtnl_fill_ifinfo(skb, dev, type, 0, 0, change, 0, 0); + err = rtnl_fill_ifinfo(skb, dev, type, 0, 0, change, 0, 0, event); if (err < 0) { /* -EMSGSIZE implies BUG in if_nlmsg_size() */ WARN_ON(err == -EMSGSIZE); @@@ -2841,18 -2879,25 +2880,25 @@@ void rtmsg_ifinfo_send(struct sk_buff * rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL, flags); }
- void rtmsg_ifinfo(int type, struct net_device *dev, unsigned int change, - gfp_t flags) + static void rtmsg_ifinfo_event(int type, struct net_device *dev, + unsigned int change, u32 event, + gfp_t flags) { struct sk_buff *skb;
if (dev->reg_state != NETREG_REGISTERED) return;
- skb = rtmsg_ifinfo_build_skb(type, dev, change, flags); + skb = rtmsg_ifinfo_build_skb(type, dev, change, event, flags); if (skb) rtmsg_ifinfo_send(skb, dev, flags); } + + void rtmsg_ifinfo(int type, struct net_device *dev, unsigned int change, + gfp_t flags) + { + rtmsg_ifinfo_event(type, dev, change, rtnl_get_event(0), flags); + } EXPORT_SYMBOL(rtmsg_ifinfo);
static int nlmsg_populate_fdb_fill(struct sk_buff *skb, @@@ -4169,7 -4214,8 +4215,8 @@@ static int rtnetlink_event(struct notif case NETDEV_NOTIFY_PEERS: case NETDEV_RESEND_IGMP: case NETDEV_CHANGEINFODATA: - rtmsg_ifinfo(RTM_NEWLINK, dev, 0, GFP_KERNEL); + rtmsg_ifinfo_event(RTM_NEWLINK, dev, 0, rtnl_get_event(event), + GFP_KERNEL); break; default: break; diff --combined net/core/sock.c index 0c3fc16223f9,ad8a4bc84126..70ee22d5154d --- a/net/core/sock.c +++ b/net/core/sock.c @@@ -1038,6 -1038,10 +1038,10 @@@ set_rcvbuf #endif
case SO_MAX_PACING_RATE: + if (val != ~0U) + cmpxchg(&sk->sk_pacing_status, + SK_PACING_NONE, + SK_PACING_NEEDED); sk->sk_max_pacing_rate = val; sk->sk_pacing_rate = min(sk->sk_pacing_rate, sk->sk_max_pacing_rate); @@@ -2072,6 -2076,26 +2076,26 @@@ int sock_cmsg_send(struct sock *sk, str } EXPORT_SYMBOL(sock_cmsg_send);
+ static void sk_enter_memory_pressure(struct sock *sk) + { + if (!sk->sk_prot->enter_memory_pressure) + return; + + sk->sk_prot->enter_memory_pressure(sk); + } + + static void sk_leave_memory_pressure(struct sock *sk) + { + if (sk->sk_prot->leave_memory_pressure) { + sk->sk_prot->leave_memory_pressure(sk); + } else { + unsigned long *memory_pressure = sk->sk_prot->memory_pressure; + + if (memory_pressure && *memory_pressure) + *memory_pressure = 0; + } + } + /* On 32bit arches, an skb frag is limited to 2^15 */ #define SKB_FRAG_PAGE_ORDER get_order(32768)
@@@ -2675,12 -2699,9 +2699,12 @@@ EXPORT_SYMBOL(release_sock) * @sk: socket * * This version should be used for very small section, where process wont block - * return false if fast path is taken + * return false if fast path is taken: + * * sk_lock.slock locked, owned = 0, BH disabled - * return true if slow path is taken + * + * return true if slow path is taken: + * * sk_lock.slock unlocked, owned = 1, BH enabled */ bool lock_sock_fast(struct sock *sk) diff --combined net/ipv4/ipmr.c index 8ae425cad818,9374b99c7c17..a1199895b8a6 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@@ -101,8 -101,8 +101,8 @@@ static struct mr_table *ipmr_new_table( static void ipmr_free_table(struct mr_table *mrt);
static void ip_mr_forward(struct net *net, struct mr_table *mrt, - struct sk_buff *skb, struct mfc_cache *cache, - int local); + struct net_device *dev, struct sk_buff *skb, + struct mfc_cache *cache, int local); static int ipmr_cache_report(struct mr_table *mrt, struct sk_buff *pkt, vifi_t vifi, int assert); static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb, @@@ -501,7 -501,7 +501,7 @@@ static void reg_vif_setup(struct net_de dev->mtu = ETH_DATA_LEN - sizeof(struct iphdr) - 8; dev->flags = IFF_NOARP; dev->netdev_ops = ®_vif_netdev_ops; - dev->destructor = free_netdev; + dev->needs_free_netdev = true; dev->features |= NETIF_F_NETNS_LOCAL; }
@@@ -988,7 -988,7 +988,7 @@@ static void ipmr_cache_resolve(struct n
rtnl_unicast(skb, net, NETLINK_CB(skb).portid); } else { - ip_mr_forward(net, mrt, skb, c, 0); + ip_mr_forward(net, mrt, skb->dev, skb, c, 0); } } } @@@ -1073,7 -1073,7 +1073,7 @@@ static int ipmr_cache_report(struct mr_
/* Queue a packet for resolution. It gets locked cache entry! */ static int ipmr_cache_unresolved(struct mr_table *mrt, vifi_t vifi, - struct sk_buff *skb) + struct sk_buff *skb, struct net_device *dev) { const struct iphdr *iph = ip_hdr(skb); struct mfc_cache *c; @@@ -1130,10 -1130,6 +1130,10 @@@ kfree_skb(skb); err = -ENOBUFS; } else { + if (dev) { + skb->dev = dev; + skb->skb_iif = dev->ifindex; + } skb_queue_tail(&c->mfc_un.unres.unresolved, skb); err = 0; } @@@ -1832,10 -1828,10 +1832,10 @@@ static int ipmr_find_vif(struct mr_tabl
/* "local" means that we should preserve one skb (for local delivery) */ static void ip_mr_forward(struct net *net, struct mr_table *mrt, - struct sk_buff *skb, struct mfc_cache *cache, - int local) + struct net_device *dev, struct sk_buff *skb, + struct mfc_cache *cache, int local) { - int true_vifi = ipmr_find_vif(mrt, skb->dev); + int true_vifi = ipmr_find_vif(mrt, dev); int psend = -1; int vif, ct;
@@@ -1857,7 -1853,13 +1857,7 @@@ }
/* Wrong interface: drop packet and (maybe) send PIM assert. */ - if (mrt->vif_table[vif].dev != skb->dev) { - struct net_device *mdev; - - mdev = l3mdev_master_dev_rcu(mrt->vif_table[vif].dev); - if (mdev == skb->dev) - goto forward; - + if (mrt->vif_table[vif].dev != dev) { if (rt_is_output_route(skb_rtable(skb))) { /* It is our own packet, looped back. * Very complicated situation... @@@ -2051,7 -2053,7 +2051,7 @@@ int ip_mr_input(struct sk_buff *skb read_lock(&mrt_lock); vif = ipmr_find_vif(mrt, dev); if (vif >= 0) { - int err2 = ipmr_cache_unresolved(mrt, vif, skb); + int err2 = ipmr_cache_unresolved(mrt, vif, skb, dev); read_unlock(&mrt_lock);
return err2; @@@ -2062,7 -2064,7 +2062,7 @@@ }
read_lock(&mrt_lock); - ip_mr_forward(net, mrt, skb, cache, local); + ip_mr_forward(net, mrt, dev, skb, cache, local); read_unlock(&mrt_lock);
if (local) @@@ -2236,7 -2238,7 +2236,7 @@@ int ipmr_get_route(struct net *net, str iph->saddr = saddr; iph->daddr = daddr; iph->version = 0; - err = ipmr_cache_unresolved(mrt, vif, skb2); + err = ipmr_cache_unresolved(mrt, vif, skb2, dev); read_unlock(&mrt_lock); rcu_read_unlock(); return err; @@@ -2526,6 -2528,129 +2526,129 @@@ static int ipmr_rtm_route(struct sk_buf return ipmr_mfc_delete(tbl, &mfcc, parent); }
+ static bool ipmr_fill_table(struct mr_table *mrt, struct sk_buff *skb) + { + u32 queue_len = atomic_read(&mrt->cache_resolve_queue_len); + + if (nla_put_u32(skb, IPMRA_TABLE_ID, mrt->id) || + nla_put_u32(skb, IPMRA_TABLE_CACHE_RES_QUEUE_LEN, queue_len) || + nla_put_s32(skb, IPMRA_TABLE_MROUTE_REG_VIF_NUM, + mrt->mroute_reg_vif_num) || + nla_put_u8(skb, IPMRA_TABLE_MROUTE_DO_ASSERT, + mrt->mroute_do_assert) || + nla_put_u8(skb, IPMRA_TABLE_MROUTE_DO_PIM, mrt->mroute_do_pim)) + return false; + + return true; + } + + static bool ipmr_fill_vif(struct mr_table *mrt, u32 vifid, struct sk_buff *skb) + { + struct nlattr *vif_nest; + struct vif_device *vif; + + /* if the VIF doesn't exist just continue */ + if (!VIF_EXISTS(mrt, vifid)) + return true; + + vif = &mrt->vif_table[vifid]; + vif_nest = nla_nest_start(skb, IPMRA_VIF); + if (!vif_nest) + return false; + if (nla_put_u32(skb, IPMRA_VIFA_IFINDEX, vif->dev->ifindex) || + nla_put_u32(skb, IPMRA_VIFA_VIF_ID, vifid) || + nla_put_u16(skb, IPMRA_VIFA_FLAGS, vif->flags) || + nla_put_u64_64bit(skb, IPMRA_VIFA_BYTES_IN, vif->bytes_in, + IPMRA_VIFA_PAD) || + nla_put_u64_64bit(skb, IPMRA_VIFA_BYTES_OUT, vif->bytes_out, + IPMRA_VIFA_PAD) || + nla_put_u64_64bit(skb, IPMRA_VIFA_PACKETS_IN, vif->pkt_in, + IPMRA_VIFA_PAD) || + nla_put_u64_64bit(skb, IPMRA_VIFA_PACKETS_OUT, vif->pkt_out, + IPMRA_VIFA_PAD) || + nla_put_be32(skb, IPMRA_VIFA_LOCAL_ADDR, vif->local) || + nla_put_be32(skb, IPMRA_VIFA_REMOTE_ADDR, vif->remote)) { + nla_nest_cancel(skb, vif_nest); + return false; + } + nla_nest_end(skb, vif_nest); + + return true; + } + + static int ipmr_rtm_dumplink(struct sk_buff *skb, struct netlink_callback *cb) + { + struct net *net = sock_net(skb->sk); + struct nlmsghdr *nlh = NULL; + unsigned int t = 0, s_t; + unsigned int e = 0, s_e; + struct mr_table *mrt; + + s_t = cb->args[0]; + s_e = cb->args[1]; + + ipmr_for_each_table(mrt, net) { + struct nlattr *vifs, *af; + struct ifinfomsg *hdr; + u32 i; + + if (t < s_t) + goto skip_table; + nlh = nlmsg_put(skb, NETLINK_CB(cb->skb).portid, + cb->nlh->nlmsg_seq, RTM_NEWLINK, + sizeof(*hdr), NLM_F_MULTI); + if (!nlh) + break; + + hdr = nlmsg_data(nlh); + memset(hdr, 0, sizeof(*hdr)); + hdr->ifi_family = RTNL_FAMILY_IPMR; + + af = nla_nest_start(skb, IFLA_AF_SPEC); + if (!af) { + nlmsg_cancel(skb, nlh); + goto out; + } + + if (!ipmr_fill_table(mrt, skb)) { + nlmsg_cancel(skb, nlh); + goto out; + } + + vifs = nla_nest_start(skb, IPMRA_TABLE_VIFS); + if (!vifs) { + nla_nest_end(skb, af); + nlmsg_end(skb, nlh); + goto out; + } + for (i = 0; i < mrt->maxvif; i++) { + if (e < s_e) + goto skip_entry; + if (!ipmr_fill_vif(mrt, i, skb)) { + nla_nest_end(skb, vifs); + nla_nest_end(skb, af); + nlmsg_end(skb, nlh); + goto out; + } + skip_entry: + e++; + } + s_e = 0; + e = 0; + nla_nest_end(skb, vifs); + nla_nest_end(skb, af); + nlmsg_end(skb, nlh); + skip_table: + t++; + } + + out: + cb->args[1] = e; + cb->args[0] = t; + + return skb->len; + } + #ifdef CONFIG_PROC_FS /* The /proc interfaces to multicast routing : * /proc/net/ip_mr_cache & /proc/net/ip_mr_vif @@@ -2868,6 -2993,9 +2991,9 @@@ int __init ip_mr_init(void ipmr_rtm_route, NULL, NULL); rtnl_register(RTNL_FAMILY_IPMR, RTM_DELROUTE, ipmr_rtm_route, NULL, NULL); + + rtnl_register(RTNL_FAMILY_IPMR, RTM_GETLINK, + NULL, ipmr_rtm_dumplink, NULL); return 0;
#ifdef CONFIG_IP_PIMSM_V2 diff --combined net/ipv6/route.c index 7cebd954d5bb,9d9b5bbea153..18fe6e2b88d5 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@@ -938,14 -938,15 +938,15 @@@ EXPORT_SYMBOL(rt6_lookup) */
static int __ip6_ins_rt(struct rt6_info *rt, struct nl_info *info, - struct mx6_config *mxc) + struct mx6_config *mxc, + struct netlink_ext_ack *extack) { int err; struct fib6_table *table;
table = rt->rt6i_table; write_lock_bh(&table->tb6_lock); - err = fib6_add(&table->tb6_root, rt, info, mxc); + err = fib6_add(&table->tb6_root, rt, info, mxc, extack); write_unlock_bh(&table->tb6_lock);
return err; @@@ -956,7 -957,7 +957,7 @@@ int ip6_ins_rt(struct rt6_info *rt struct nl_info info = { .nl_net = dev_net(rt->dst.dev), }; struct mx6_config mxc = { .mx = NULL, };
- return __ip6_ins_rt(rt, &info, &mxc); + return __ip6_ins_rt(rt, &info, &mxc, NULL); }
static struct rt6_info *ip6_rt_cache_alloc(struct rt6_info *ort, @@@ -1844,7 -1845,8 +1845,8 @@@ static struct rt6_info *ip6_nh_lookup_t return rt; }
- static struct rt6_info *ip6_route_info_create(struct fib6_config *cfg) + static struct rt6_info *ip6_route_info_create(struct fib6_config *cfg, + struct netlink_ext_ack *extack) { struct net *net = cfg->fc_nlinfo.nl_net; struct rt6_info *rt = NULL; @@@ -1855,14 -1857,25 +1857,25 @@@ int err = -EINVAL;
/* RTF_PCPU is an internal flag; can not be set by userspace */ - if (cfg->fc_flags & RTF_PCPU) + if (cfg->fc_flags & RTF_PCPU) { + NL_SET_ERR_MSG(extack, "Userspace can not set RTF_PCPU"); goto out; + }
- if (cfg->fc_dst_len > 128 || cfg->fc_src_len > 128) + if (cfg->fc_dst_len > 128) { + NL_SET_ERR_MSG(extack, "Invalid prefix length"); + goto out; + } + if (cfg->fc_src_len > 128) { + NL_SET_ERR_MSG(extack, "Invalid source address length"); goto out; + } #ifndef CONFIG_IPV6_SUBTREES - if (cfg->fc_src_len) + if (cfg->fc_src_len) { + NL_SET_ERR_MSG(extack, + "Specifying source address requires IPV6_SUBTREES to be enabled"); goto out; + } #endif if (cfg->fc_ifindex) { err = -ENODEV; @@@ -1926,7 -1939,7 +1939,7 @@@
err = lwtunnel_build_state(cfg->fc_encap_type, cfg->fc_encap, AF_INET6, cfg, - &lwtstate); + &lwtstate, extack); if (err) goto out; rt->dst.lwtstate = lwtstate_get(lwtstate); @@@ -2013,9 -2026,10 +2026,10 @@@ err = -EINVAL; if (ipv6_chk_addr_and_flags(net, gw_addr, gwa_type & IPV6_ADDR_LINKLOCAL ? - dev : NULL, 0, 0)) + dev : NULL, 0, 0)) { + NL_SET_ERR_MSG(extack, "Invalid gateway address"); goto out; - + } rt->rt6i_gateway = *gw_addr;
if (gwa_type != (IPV6_ADDR_LINKLOCAL|IPV6_ADDR_UNICAST)) { @@@ -2031,8 -2045,11 +2045,11 @@@ addressing */ if (!(gwa_type & (IPV6_ADDR_UNICAST | - IPV6_ADDR_MAPPED))) + IPV6_ADDR_MAPPED))) { + NL_SET_ERR_MSG(extack, + "Invalid gateway address"); goto out; + }
if (cfg->fc_table) { grt = ip6_nh_lookup_table(net, cfg, gw_addr); @@@ -2072,8 -2089,14 +2089,14 @@@ goto out; } err = -EINVAL; - if (!dev || (dev->flags & IFF_LOOPBACK)) + if (!dev) { + NL_SET_ERR_MSG(extack, "Egress device not specified"); + goto out; + } else if (dev->flags & IFF_LOOPBACK) { + NL_SET_ERR_MSG(extack, + "Egress device can not be loopback device for this route"); goto out; + } }
err = -ENODEV; @@@ -2082,6 -2105,7 +2105,7 @@@
if (!ipv6_addr_any(&cfg->fc_prefsrc)) { if (!ipv6_chk_addr(net, &cfg->fc_prefsrc, dev, 0)) { + NL_SET_ERR_MSG(extack, "Invalid source address"); err = -EINVAL; goto out; } @@@ -2111,13 -2135,14 +2135,14 @@@ out return ERR_PTR(err); }
- int ip6_route_add(struct fib6_config *cfg) + int ip6_route_add(struct fib6_config *cfg, + struct netlink_ext_ack *extack) { struct mx6_config mxc = { .mx = NULL, }; struct rt6_info *rt; int err;
- rt = ip6_route_info_create(cfg); + rt = ip6_route_info_create(cfg, extack); if (IS_ERR(rt)) { err = PTR_ERR(rt); rt = NULL; @@@ -2128,7 -2153,7 +2153,7 @@@ if (err) goto out;
- err = __ip6_ins_rt(rt, &cfg->fc_nlinfo, &mxc); + err = __ip6_ins_rt(rt, &cfg->fc_nlinfo, &mxc, extack);
kfree(mxc.mx);
@@@ -2222,7 -2247,8 +2247,8 @@@ out_put return err; }
- static int ip6_route_del(struct fib6_config *cfg) + static int ip6_route_del(struct fib6_config *cfg, + struct netlink_ext_ack *extack) { struct fib6_table *table; struct fib6_node *fn; @@@ -2230,8 -2256,10 +2256,10 @@@ int err = -ESRCH;
table = fib6_get_table(cfg->fc_nlinfo.nl_net, cfg->fc_table); - if (!table) + if (!table) { + NL_SET_ERR_MSG(extack, "FIB table does not exist"); return err; + }
read_lock_bh(&table->tb6_lock);
@@@ -2483,7 -2511,7 +2511,7 @@@ static struct rt6_info *rt6_add_route_i if (!prefixlen) cfg.fc_flags |= RTF_DEFAULT;
- ip6_route_add(&cfg); + ip6_route_add(&cfg, NULL);
return rt6_get_route_info(net, prefix, prefixlen, gwaddr, dev); } @@@ -2529,7 -2557,7 +2557,7 @@@ struct rt6_info *rt6_add_dflt_router(co
cfg.fc_gateway = *gwaddr;
- if (!ip6_route_add(&cfg)) { + if (!ip6_route_add(&cfg, NULL)) { struct fib6_table *table;
table = fib6_get_table(dev_net(dev), cfg.fc_table); @@@ -2622,10 -2650,10 +2650,10 @@@ int ipv6_route_ioctl(struct net *net, u rtnl_lock(); switch (cmd) { case SIOCADDRT: - err = ip6_route_add(&cfg); + err = ip6_route_add(&cfg, NULL); break; case SIOCDELRT: - err = ip6_route_del(&cfg); + err = ip6_route_del(&cfg, NULL); break; default: err = -EINVAL; @@@ -2804,7 -2832,6 +2832,7 @@@ static int fib6_ifdown(struct rt6_info if ((rt->dst.dev == dev || !dev) && rt != adn->net->ipv6.ip6_null_entry && (rt->rt6i_nsiblings == 0 || + (dev && netdev_unregistering(dev)) || !rt->rt6i_idev->cnf.ignore_routes_with_linkdown)) return -1;
@@@ -2904,7 -2931,8 +2932,8 @@@ static const struct nla_policy rtm_ipv6 };
static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh, - struct fib6_config *cfg) + struct fib6_config *cfg, + struct netlink_ext_ack *extack) { struct rtmsg *rtm; struct nlattr *tb[RTA_MAX+1]; @@@ -2988,7 -3016,7 +3017,7 @@@ cfg->fc_mp_len = nla_len(tb[RTA_MULTIPATH]);
err = lwtunnel_valid_encap_type_attr(cfg->fc_mp, - cfg->fc_mp_len); + cfg->fc_mp_len, extack); if (err < 0) goto errout; } @@@ -3007,7 -3035,7 +3036,7 @@@ if (tb[RTA_ENCAP_TYPE]) { cfg->fc_encap_type = nla_get_u16(tb[RTA_ENCAP_TYPE]);
- err = lwtunnel_valid_encap_type(cfg->fc_encap_type); + err = lwtunnel_valid_encap_type(cfg->fc_encap_type, extack); if (err < 0) goto errout; } @@@ -3098,7 -3126,8 +3127,8 @@@ static void ip6_route_mpath_notify(stru inet6_rt_notify(RTM_NEWROUTE, rt, info, nlflags); }
- static int ip6_route_multipath_add(struct fib6_config *cfg) + static int ip6_route_multipath_add(struct fib6_config *cfg, + struct netlink_ext_ack *extack) { struct rt6_info *rt_notif = NULL, *rt_last = NULL; struct nl_info *info = &cfg->fc_nlinfo; @@@ -3146,7 -3175,7 +3176,7 @@@ r_cfg.fc_encap_type = nla_get_u16(nla); }
- rt = ip6_route_info_create(&r_cfg); + rt = ip6_route_info_create(&r_cfg, extack); if (IS_ERR(rt)) { err = PTR_ERR(rt); rt = NULL; @@@ -3171,7 -3200,7 +3201,7 @@@ err_nh = NULL; list_for_each_entry(nh, &rt6_nh_list, next) { rt_last = nh->rt6_info; - err = __ip6_ins_rt(nh->rt6_info, info, &nh->mxc); + err = __ip6_ins_rt(nh->rt6_info, info, &nh->mxc, extack); /* save reference to first route for notification */ if (!rt_notif && !err) rt_notif = nh->rt6_info; @@@ -3213,7 -3242,7 +3243,7 @@@ add_errout list_for_each_entry(nh, &rt6_nh_list, next) { if (err_nh == nh) break; - ip6_route_del(&nh->r_cfg); + ip6_route_del(&nh->r_cfg, extack); }
cleanup: @@@ -3228,7 -3257,8 +3258,8 @@@ return err; }
- static int ip6_route_multipath_del(struct fib6_config *cfg) + static int ip6_route_multipath_del(struct fib6_config *cfg, + struct netlink_ext_ack *extack) { struct fib6_config r_cfg; struct rtnexthop *rtnh; @@@ -3255,7 -3285,7 +3286,7 @@@ r_cfg.fc_flags |= RTF_GATEWAY; } } - err = ip6_route_del(&r_cfg); + err = ip6_route_del(&r_cfg, extack); if (err) last_err = err;
@@@ -3271,15 -3301,15 +3302,15 @@@ static int inet6_rtm_delroute(struct sk struct fib6_config cfg; int err;
- err = rtm_to_fib6_config(skb, nlh, &cfg); + err = rtm_to_fib6_config(skb, nlh, &cfg, extack); if (err < 0) return err;
if (cfg.fc_mp) - return ip6_route_multipath_del(&cfg); + return ip6_route_multipath_del(&cfg, extack); else { cfg.fc_delete_all_nh = 1; - return ip6_route_del(&cfg); + return ip6_route_del(&cfg, extack); } }
@@@ -3289,14 -3319,14 +3320,14 @@@ static int inet6_rtm_newroute(struct sk struct fib6_config cfg; int err;
- err = rtm_to_fib6_config(skb, nlh, &cfg); + err = rtm_to_fib6_config(skb, nlh, &cfg, extack); if (err < 0) return err;
if (cfg.fc_mp) - return ip6_route_multipath_add(&cfg); + return ip6_route_multipath_add(&cfg, extack); else - return ip6_route_add(&cfg); + return ip6_route_add(&cfg, extack); }
static size_t rt6_nlmsg_size(struct rt6_info *rt) @@@ -3577,11 -3607,13 +3608,13 @@@ static int inet6_rtm_getroute(struct sk { struct net *net = sock_net(in_skb->sk); struct nlattr *tb[RTA_MAX+1]; + int err, iif = 0, oif = 0; + struct dst_entry *dst; struct rt6_info *rt; struct sk_buff *skb; struct rtmsg *rtm; struct flowi6 fl6; - int err, iif = 0, oif = 0; + bool fibmatch;
err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_ipv6_policy, extack); @@@ -3592,6 -3624,7 +3625,7 @@@ memset(&fl6, 0, sizeof(fl6)); rtm = nlmsg_data(nlh); fl6.flowlabel = ip6_make_flowinfo(rtm->rtm_tos, 0); + fibmatch = !!(rtm->rtm_flags & RTM_F_FIB_MATCH);
if (tb[RTA_SRC]) { if (nla_len(tb[RTA_SRC]) < sizeof(struct in6_addr)) @@@ -3637,12 -3670,23 +3671,23 @@@ if (!ipv6_addr_any(&fl6.saddr)) flags |= RT6_LOOKUP_F_HAS_SADDR;
- rt = (struct rt6_info *)ip6_route_input_lookup(net, dev, &fl6, - flags); + if (!fibmatch) + dst = ip6_route_input_lookup(net, dev, &fl6, flags); } else { fl6.flowi6_oif = oif;
- rt = (struct rt6_info *)ip6_route_output(net, NULL, &fl6); + if (!fibmatch) + dst = ip6_route_output(net, NULL, &fl6); + } + + if (fibmatch) + dst = ip6_route_lookup(net, &fl6, 0); + + rt = container_of(dst, struct rt6_info, dst); + if (rt->dst.error) { + err = rt->dst.error; + ip6_rt_put(rt); + goto errout; }
if (rt == net->ipv6.ip6_null_entry) { @@@ -3659,10 -3703,14 +3704,14 @@@ }
skb_dst_set(skb, &rt->dst); - - err = rt6_fill_node(net, skb, rt, &fl6.daddr, &fl6.saddr, iif, - RTM_NEWROUTE, NETLINK_CB(in_skb).portid, - nlh->nlmsg_seq, 0); + if (fibmatch) + err = rt6_fill_node(net, skb, rt, NULL, NULL, iif, + RTM_NEWROUTE, NETLINK_CB(in_skb).portid, + nlh->nlmsg_seq, 0); + else + err = rt6_fill_node(net, skb, rt, &fl6.daddr, &fl6.saddr, iif, + RTM_NEWROUTE, NETLINK_CB(in_skb).portid, + nlh->nlmsg_seq, 0); if (err < 0) { kfree_skb(skb); goto errout; diff --combined net/mac80211/cfg.c index 4a388fe8c2d1,6980a936a437..f9eb2486d550 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@@ -902,8 -902,6 +902,8 @@@ static int ieee80211_start_ap(struct wi default: return -EINVAL; } + sdata->u.ap.req_smps = sdata->smps_mode; + sdata->needed_rx_chains = sdata->local->rx_chains;
sdata->vif.bss_conf.beacon_int = params->beacon_interval; @@@ -1876,6 -1874,7 +1876,7 @@@ static int copy_mesh_setup(struct ieee8 ifmsh->user_mpm = setup->user_mpm; ifmsh->mesh_auth_id = setup->auth_id; ifmsh->security = IEEE80211_MESH_SEC_NONE; + ifmsh->userspace_handles_dfs = setup->userspace_handles_dfs; if (setup->is_authenticated) ifmsh->security |= IEEE80211_MESH_SEC_AUTHED; if (setup->is_secure) diff --combined net/mac80211/ieee80211_i.h index 5e002f62c235,392fbab73c04..2197c62a0a6e --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@@ -643,6 -643,8 +643,8 @@@ struct ieee80211_if_mesh unsigned long wrkq_flags; unsigned long mbss_changed;
+ bool userspace_handles_dfs; + u8 mesh_id[IEEE80211_MAX_MESH_ID_LEN]; size_t mesh_id_len; /* Active Path Selection Protocol Identifier */ @@@ -1029,17 -1031,6 +1031,6 @@@ ieee80211_vif_get_shift(struct ieee8021 return shift; }
- struct ieee80211_rx_agg { - u8 addr[ETH_ALEN]; - u16 tid; - }; - - enum sdata_queue_type { - IEEE80211_SDATA_QUEUE_TYPE_FRAME = 0, - IEEE80211_SDATA_QUEUE_RX_AGG_START = 3, - IEEE80211_SDATA_QUEUE_RX_AGG_STOP = 4, - }; - enum { IEEE80211_RX_MSG = 1, IEEE80211_TX_STATUS_MSG = 2, @@@ -1432,6 -1423,7 +1423,7 @@@ struct ieee80211_csa_ie u8 count; u8 ttl; u16 pre_value; + u16 reason_code; };
/* Parsed Information Elements */ @@@ -1531,7 -1523,7 +1523,7 @@@ ieee80211_have_rx_timestamp(struct ieee return true; /* can't handle non-legacy preamble yet */ if (status->flag & RX_FLAG_MACTIME_PLCP_START && - status->encoding != RX_ENC_LEGACY) + status->encoding == RX_ENC_LEGACY) return true; return false; } @@@ -2057,6 -2049,8 +2049,8 @@@ u8 *ieee80211_ie_build_ht_cap(u8 *pos, u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap, const struct cfg80211_chan_def *chandef, u16 prot_mode, bool rifs_mode); + void ieee80211_ie_build_wide_bw_cs(u8 *pos, + const struct cfg80211_chan_def *chandef); u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap, u32 cap); u8 *ieee80211_ie_build_vht_oper(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap, diff --combined net/mac80211/iface.c index f5f50150ba1c,6ac0a0198d19..9228ac73c429 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@@ -1213,6 -1213,7 +1213,6 @@@ static const struct net_device_ops ieee static void ieee80211_if_free(struct net_device *dev) { free_percpu(dev->tstats); - free_netdev(dev); }
static void ieee80211_if_setup(struct net_device *dev) @@@ -1220,8 -1221,7 +1220,8 @@@ ether_setup(dev); dev->priv_flags &= ~IFF_TX_SKB_SHARING; dev->netdev_ops = &ieee80211_dataif_ops; - dev->destructor = ieee80211_if_free; + dev->needs_free_netdev = true; + dev->priv_destructor = ieee80211_if_free; }
static void ieee80211_if_setup_no_queue(struct net_device *dev) @@@ -1237,7 -1237,6 +1237,6 @@@ static void ieee80211_iface_work(struc struct ieee80211_local *local = sdata->local; struct sk_buff *skb; struct sta_info *sta; - struct ieee80211_rx_agg *rx_agg;
if (!ieee80211_sdata_running(sdata)) return; @@@ -1252,28 -1251,8 +1251,8 @@@ while ((skb = skb_dequeue(&sdata->skb_queue))) { struct ieee80211_mgmt *mgmt = (void *)skb->data;
- if (skb->pkt_type == IEEE80211_SDATA_QUEUE_RX_AGG_START) { - rx_agg = (void *)&skb->cb; - mutex_lock(&local->sta_mtx); - sta = sta_info_get_bss(sdata, rx_agg->addr); - if (sta) - __ieee80211_start_rx_ba_session(sta, - 0, 0, 0, 1, rx_agg->tid, - IEEE80211_MAX_AMPDU_BUF, - false, true); - mutex_unlock(&local->sta_mtx); - } else if (skb->pkt_type == IEEE80211_SDATA_QUEUE_RX_AGG_STOP) { - rx_agg = (void *)&skb->cb; - mutex_lock(&local->sta_mtx); - sta = sta_info_get_bss(sdata, rx_agg->addr); - if (sta) - __ieee80211_stop_rx_ba_session(sta, - rx_agg->tid, - WLAN_BACK_RECIPIENT, 0, - false); - mutex_unlock(&local->sta_mtx); - } else if (ieee80211_is_action(mgmt->frame_control) && - mgmt->u.action.category == WLAN_CATEGORY_BACK) { + if (ieee80211_is_action(mgmt->frame_control) && + mgmt->u.action.category == WLAN_CATEGORY_BACK) { int len = skb->len;
mutex_lock(&local->sta_mtx); @@@ -1816,7 -1795,6 +1795,7 @@@ int ieee80211_if_add(struct ieee80211_l ret = dev_alloc_name(ndev, ndev->name); if (ret < 0) { ieee80211_if_free(ndev); + free_netdev(ndev); return ret; }
@@@ -1906,7 -1884,7 +1885,7 @@@
ret = register_netdevice(ndev); if (ret) { - ieee80211_if_free(ndev); + free_netdev(ndev); return ret; } } diff --combined net/mac80211/mlme.c index cc8e6ea1b27e,1ae9be090309..1929bce8e518 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@@ -601,7 -601,7 +601,7 @@@ static void ieee80211_send_assoc(struc struct ieee80211_supported_band *sband; struct ieee80211_chanctx_conf *chanctx_conf; struct ieee80211_channel *chan; - u32 rate_flags, rates = 0; + u32 rates = 0;
sdata_assert_lock(sdata);
@@@ -612,6 -612,7 +612,6 @@@ return; } chan = chanctx_conf->def.chan; - rate_flags = ieee80211_chandef_rate_flags(&chanctx_conf->def); rcu_read_unlock(); sband = local->hw.wiphy->bands[chan->band]; shift = ieee80211_vif_get_shift(&sdata->vif); @@@ -635,6 -636,9 +635,6 @@@ */ rates_len = 0; for (i = 0; i < sband->n_bitrates; i++) { - if ((rate_flags & sband->bitrates[i].flags) - != rate_flags) - continue; rates |= BIT(i); rates_len++; } @@@ -1122,7 -1126,6 +1122,6 @@@ ieee80211_sta_process_chanswitch(struc return;
current_band = cbss->channel->band; - memset(&csa_ie, 0, sizeof(csa_ie)); res = ieee80211_parse_ch_switch_ie(sdata, elems, current_band, ifmgd->flags, ifmgd->associated->bssid, &csa_ie); @@@ -2814,7 -2817,7 +2813,7 @@@ static void ieee80211_get_rates(struct u32 *rates, u32 *basic_rates, bool *have_higher_than_11mbit, int *min_rate, int *min_rate_index, - int shift, u32 rate_flags) + int shift) { int i, j;
@@@ -2842,6 -2845,8 +2841,6 @@@ int brate;
br = &sband->bitrates[j]; - if ((rate_flags & br->flags) != rate_flags) - continue;
brate = DIV_ROUND_UP(br->bitrate, (1 << shift) * 5); if (brate == rate) { @@@ -4392,32 -4397,40 +4391,32 @@@ static int ieee80211_prep_connection(st return -ENOMEM; }
- if (new_sta || override) { - err = ieee80211_prep_channel(sdata, cbss); - if (err) { - if (new_sta) - sta_info_free(local, new_sta); - return -EINVAL; - } - } - + /* + * Set up the information for the new channel before setting the + * new channel. We can't - completely race-free - change the basic + * rates bitmap and the channel (sband) that it refers to, but if + * we set it up before we at least avoid calling into the driver's + * bss_info_changed() method with invalid information (since we do + * call that from changing the channel - only for IDLE and perhaps + * some others, but ...). + * + * So to avoid that, just set up all the new information before the + * channel, but tell the driver to apply it only afterwards, since + * it might need the new channel for that. + */ if (new_sta) { u32 rates = 0, basic_rates = 0; bool have_higher_than_11mbit; int min_rate = INT_MAX, min_rate_index = -1; - struct ieee80211_chanctx_conf *chanctx_conf; const struct cfg80211_bss_ies *ies; int shift = ieee80211_vif_get_shift(&sdata->vif); - u32 rate_flags; - - rcu_read_lock(); - chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); - if (WARN_ON(!chanctx_conf)) { - rcu_read_unlock(); - sta_info_free(local, new_sta); - return -EINVAL; - } - rate_flags = ieee80211_chandef_rate_flags(&chanctx_conf->def); - rcu_read_unlock();
ieee80211_get_rates(sband, bss->supp_rates, bss->supp_rates_len, &rates, &basic_rates, &have_higher_than_11mbit, &min_rate, &min_rate_index, - shift, rate_flags); + shift);
/* * This used to be a workaround for basic rates missing @@@ -4475,22 -4488,8 +4474,22 @@@ sdata->vif.bss_conf.sync_dtim_count = 0; } rcu_read_unlock(); + }
- /* tell driver about BSSID, basic rates and timing */ + if (new_sta || override) { + err = ieee80211_prep_channel(sdata, cbss); + if (err) { + if (new_sta) + sta_info_free(local, new_sta); + return -EINVAL; + } + } + + if (new_sta) { + /* + * tell driver about BSSID, basic rates and timing + * this was set up above, before setting the channel + */ ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID | BSS_CHANGED_BASIC_RATES | BSS_CHANGED_BEACON_INT); diff --combined net/mac80211/rx.c index 3674fe3d67dc,8c7d932fd09b..004a2283c5d9 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@@ -237,7 -237,6 +237,6 @@@ static void ieee80211_handle_mu_mimo_mo if (!skb) return;
- skb->pkt_type = IEEE80211_SDATA_QUEUE_TYPE_FRAME; skb_queue_tail(&sdata->skb_queue, skb); ieee80211_queue_work(&sdata->local->hw, &sdata->work); } @@@ -1217,7 -1216,6 +1216,6 @@@ static void ieee80211_rx_reorder_ampdu( /* if this mpdu is fragmented - terminate rx aggregation session */ sc = le16_to_cpu(hdr->seq_ctrl); if (sc & IEEE80211_SCTL_FRAG) { - skb->pkt_type = IEEE80211_SDATA_QUEUE_TYPE_FRAME; skb_queue_tail(&rx->sdata->skb_queue, skb); ieee80211_queue_work(&local->hw, &rx->sdata->work); return; @@@ -1613,16 -1611,12 +1611,16 @@@ ieee80211_rx_h_sta_process(struct ieee8 */ if (!ieee80211_hw_check(&sta->local->hw, AP_LINK_PS) && !ieee80211_has_morefrags(hdr->frame_control) && + !ieee80211_is_back_req(hdr->frame_control) && !(status->rx_flags & IEEE80211_RX_DEFERRED_RELEASE) && (rx->sdata->vif.type == NL80211_IFTYPE_AP || rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN) && - /* PM bit is only checked in frames where it isn't reserved, + /* + * PM bit is only checked in frames where it isn't reserved, * in AP mode it's reserved in non-bufferable management frames * (cf. IEEE 802.11-2012 8.2.4.1.7 Power Management field) + * BAR frames should be ignored as specified in + * IEEE 802.11-2012 10.2.1.2. */ (!ieee80211_is_mgmt(hdr->frame_control) || ieee80211_is_bufferable_mmpdu(hdr->frame_control))) { @@@ -3104,7 -3098,6 +3102,6 @@@ ieee80211_rx_h_action(struct ieee80211_ return RX_QUEUED;
queue: - rx->skb->pkt_type = IEEE80211_SDATA_QUEUE_TYPE_FRAME; skb_queue_tail(&sdata->skb_queue, rx->skb); ieee80211_queue_work(&local->hw, &sdata->work); if (rx->sta) @@@ -3250,7 -3243,6 +3247,6 @@@ ieee80211_rx_h_mgmt(struct ieee80211_rx }
/* queue up frame and kick off work to process it */ - rx->skb->pkt_type = IEEE80211_SDATA_QUEUE_TYPE_FRAME; skb_queue_tail(&sdata->skb_queue, rx->skb); ieee80211_queue_work(&rx->local->hw, &sdata->work); if (rx->sta) diff --combined net/sctp/socket.c index 30aa0a529215,32d5495e793c..039a93175adf --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@@ -103,7 -103,7 +103,7 @@@ static int sctp_autobind(struct sock *s static void sctp_sock_migrate(struct sock *, struct sock *, struct sctp_association *, sctp_socket_type_t);
- static int sctp_memory_pressure; + static unsigned long sctp_memory_pressure; static atomic_long_t sctp_memory_allocated; struct percpu_counter sctp_sockets_allocated;
@@@ -1494,7 -1494,7 +1494,7 @@@ static void sctp_close(struct sock *sk
pr_debug("%s: sk:%p, timeout:%ld\n", __func__, sk, timeout);
- lock_sock(sk); + lock_sock_nested(sk, SINGLE_DEPTH_NESTING); sk->sk_shutdown = SHUTDOWN_MASK; sk->sk_state = SCTP_SS_CLOSING;
@@@ -1544,7 -1544,7 +1544,7 @@@ * held and that should be grabbed before socket lock. */ spin_lock_bh(&net->sctp.addr_wq_lock); - bh_lock_sock(sk); + bh_lock_sock_nested(sk);
/* Hold the sock, since sk_common_release() will put sock_put() * and we have just a little more cleanup. @@@ -1920,7 -1920,7 +1920,7 @@@ static int sctp_sendmsg(struct sock *sk }
/* Check for invalid stream. */ - if (sinfo->sinfo_stream >= asoc->stream->outcnt) { + if (sinfo->sinfo_stream >= asoc->stream.outcnt) { err = -EINVAL; goto out_free; } @@@ -4497,8 -4497,8 +4497,8 @@@ int sctp_get_sctp_info(struct sock *sk info->sctpi_rwnd = asoc->a_rwnd; info->sctpi_unackdata = asoc->unack_data; info->sctpi_penddata = sctp_tsnmap_pending(&asoc->peer.tsn_map); - info->sctpi_instrms = asoc->stream->incnt; - info->sctpi_outstrms = asoc->stream->outcnt; + info->sctpi_instrms = asoc->stream.incnt; + info->sctpi_outstrms = asoc->stream.outcnt; list_for_each(pos, &asoc->base.inqueue.in_chunk_list) info->sctpi_inqueue++; list_for_each(pos, &asoc->outqueue.out_chunk_list) @@@ -4622,13 -4622,13 +4622,13 @@@ int sctp_for_each_endpoint(int (*cb)(st
for (head = sctp_ep_hashtable; hash < sctp_ep_hashsize; hash++, head++) { - read_lock(&head->lock); + read_lock_bh(&head->lock); sctp_for_each_hentry(epb, &head->chain) { err = cb(sctp_ep(epb), p); if (err) break; } - read_unlock(&head->lock); + read_unlock_bh(&head->lock); }
return err; @@@ -4727,8 -4727,8 +4727,8 @@@ static int sctp_getsockopt_sctp_status( status.sstat_unackdata = asoc->unack_data;
status.sstat_penddata = sctp_tsnmap_pending(&asoc->peer.tsn_map); - status.sstat_instrms = asoc->stream->incnt; - status.sstat_outstrms = asoc->stream->outcnt; + status.sstat_instrms = asoc->stream.incnt; + status.sstat_outstrms = asoc->stream.outcnt; status.sstat_fragmentation_point = asoc->frag_point; status.sstat_primary.spinfo_assoc_id = sctp_assoc2id(transport->asoc); memcpy(&status.sstat_primary.spinfo_address, &transport->ipaddr, @@@ -6600,10 -6600,10 +6600,10 @@@ static int sctp_getsockopt_pr_streamsta goto out;
asoc = sctp_id2assoc(sk, params.sprstat_assoc_id); - if (!asoc || params.sprstat_sid >= asoc->stream->outcnt) + if (!asoc || params.sprstat_sid >= asoc->stream.outcnt) goto out;
- streamout = &asoc->stream->out[params.sprstat_sid]; + streamout = &asoc->stream.out[params.sprstat_sid]; if (policy == SCTP_PR_SCTP_NONE) { params.sprstat_abandoned_unsent = 0; params.sprstat_abandoned_sent = 0;
linux-merge@lists.open-mesh.org