diff options
211 files changed, 3001 insertions, 1033 deletions
diff --git a/.gitignore b/.gitignore index 7e9932e55475..42fa0d5626a9 100644 --- a/.gitignore +++ b/.gitignore | |||
| @@ -92,3 +92,6 @@ extra_certificates | |||
| 92 | signing_key.priv | 92 | signing_key.priv |
| 93 | signing_key.x509 | 93 | signing_key.x509 |
| 94 | x509.genkey | 94 | x509.genkey |
| 95 | |||
| 96 | # Kconfig presets | ||
| 97 | all.config | ||
diff --git a/Documentation/00-INDEX b/Documentation/00-INDEX index 38f8444bdd0e..07de7e19b4ce 100644 --- a/Documentation/00-INDEX +++ b/Documentation/00-INDEX | |||
| @@ -29,6 +29,8 @@ DMA-ISA-LPC.txt | |||
| 29 | - How to do DMA with ISA (and LPC) devices. | 29 | - How to do DMA with ISA (and LPC) devices. |
| 30 | DMA-attributes.txt | 30 | DMA-attributes.txt |
| 31 | - listing of the various possible attributes a DMA region can have | 31 | - listing of the various possible attributes a DMA region can have |
| 32 | dmatest.txt | ||
| 33 | - how to compile, configure and use the dmatest system. | ||
| 32 | DocBook/ | 34 | DocBook/ |
| 33 | - directory with DocBook templates etc. for kernel documentation. | 35 | - directory with DocBook templates etc. for kernel documentation. |
| 34 | EDID/ | 36 | EDID/ |
| @@ -77,6 +79,8 @@ arm/ | |||
| 77 | - directory with info about Linux on the ARM architecture. | 79 | - directory with info about Linux on the ARM architecture. |
| 78 | arm64/ | 80 | arm64/ |
| 79 | - directory with info about Linux on the 64 bit ARM architecture. | 81 | - directory with info about Linux on the 64 bit ARM architecture. |
| 82 | assoc_array.txt | ||
| 83 | - generic associative array intro. | ||
| 80 | atomic_ops.txt | 84 | atomic_ops.txt |
| 81 | - semantics and behavior of atomic and bitmask operations. | 85 | - semantics and behavior of atomic and bitmask operations. |
| 82 | auxdisplay/ | 86 | auxdisplay/ |
| @@ -87,6 +91,8 @@ bad_memory.txt | |||
| 87 | - how to use kernel parameters to exclude bad RAM regions. | 91 | - how to use kernel parameters to exclude bad RAM regions. |
| 88 | basic_profiling.txt | 92 | basic_profiling.txt |
| 89 | - basic instructions for those who wants to profile Linux kernel. | 93 | - basic instructions for those who wants to profile Linux kernel. |
| 94 | bcache.txt | ||
| 95 | - Block-layer cache on fast SSDs to improve slow (raid) I/O performance. | ||
| 90 | binfmt_misc.txt | 96 | binfmt_misc.txt |
| 91 | - info on the kernel support for extra binary formats. | 97 | - info on the kernel support for extra binary formats. |
| 92 | blackfin/ | 98 | blackfin/ |
| @@ -171,6 +177,8 @@ early-userspace/ | |||
| 171 | - info about initramfs, klibc, and userspace early during boot. | 177 | - info about initramfs, klibc, and userspace early during boot. |
| 172 | edac.txt | 178 | edac.txt |
| 173 | - information on EDAC - Error Detection And Correction | 179 | - information on EDAC - Error Detection And Correction |
| 180 | efi-stub.txt | ||
| 181 | - How to use the EFI boot stub to bypass GRUB or elilo on EFI systems. | ||
| 174 | eisa.txt | 182 | eisa.txt |
| 175 | - info on EISA bus support. | 183 | - info on EISA bus support. |
| 176 | email-clients.txt | 184 | email-clients.txt |
| @@ -195,8 +203,8 @@ futex-requeue-pi.txt | |||
| 195 | - info on requeueing of tasks from a non-PI futex to a PI futex | 203 | - info on requeueing of tasks from a non-PI futex to a PI futex |
| 196 | gcov.txt | 204 | gcov.txt |
| 197 | - use of GCC's coverage testing tool "gcov" with the Linux kernel | 205 | - use of GCC's coverage testing tool "gcov" with the Linux kernel |
| 198 | gpio.txt | 206 | gpio/ |
| 199 | - overview of GPIO (General Purpose Input/Output) access conventions. | 207 | - gpio related documentation |
| 200 | hid/ | 208 | hid/ |
| 201 | - directory with information on human interface devices | 209 | - directory with information on human interface devices |
| 202 | highuid.txt | 210 | highuid.txt |
| @@ -255,6 +263,8 @@ kernel-docs.txt | |||
| 255 | - listing of various WWW + books that document kernel internals. | 263 | - listing of various WWW + books that document kernel internals. |
| 256 | kernel-parameters.txt | 264 | kernel-parameters.txt |
| 257 | - summary listing of command line / boot prompt args for the kernel. | 265 | - summary listing of command line / boot prompt args for the kernel. |
| 266 | kernel-per-CPU-kthreads.txt | ||
| 267 | - List of all per-CPU kthreads and how they introduce jitter. | ||
| 258 | kmemcheck.txt | 268 | kmemcheck.txt |
| 259 | - info on dynamic checker that detects uses of uninitialized memory. | 269 | - info on dynamic checker that detects uses of uninitialized memory. |
| 260 | kmemleak.txt | 270 | kmemleak.txt |
| @@ -299,8 +309,6 @@ memory-devices/ | |||
| 299 | - directory with info on parts like the Texas Instruments EMIF driver | 309 | - directory with info on parts like the Texas Instruments EMIF driver |
| 300 | memory-hotplug.txt | 310 | memory-hotplug.txt |
| 301 | - Hotpluggable memory support, how to use and current status. | 311 | - Hotpluggable memory support, how to use and current status. |
| 302 | memory.txt | ||
| 303 | - info on typical Linux memory problems. | ||
| 304 | metag/ | 312 | metag/ |
| 305 | - directory with info about Linux on Meta architecture. | 313 | - directory with info about Linux on Meta architecture. |
| 306 | mips/ | 314 | mips/ |
| @@ -311,6 +319,8 @@ mmc/ | |||
| 311 | - directory with info about the MMC subsystem | 319 | - directory with info about the MMC subsystem |
| 312 | mn10300/ | 320 | mn10300/ |
| 313 | - directory with info about the mn10300 architecture port | 321 | - directory with info about the mn10300 architecture port |
| 322 | module-signing.txt | ||
| 323 | - Kernel module signing for increased security when loading modules. | ||
| 314 | mtd/ | 324 | mtd/ |
| 315 | - directory with info about memory technology devices (flash) | 325 | - directory with info about memory technology devices (flash) |
| 316 | mono.txt | 326 | mono.txt |
| @@ -343,6 +353,8 @@ pcmcia/ | |||
| 343 | - info on the Linux PCMCIA driver. | 353 | - info on the Linux PCMCIA driver. |
| 344 | percpu-rw-semaphore.txt | 354 | percpu-rw-semaphore.txt |
| 345 | - RCU based read-write semaphore optimized for locking for reading | 355 | - RCU based read-write semaphore optimized for locking for reading |
| 356 | phy.txt | ||
| 357 | - Description of the generic PHY framework. | ||
| 346 | pi-futex.txt | 358 | pi-futex.txt |
| 347 | - documentation on lightweight priority inheritance futexes. | 359 | - documentation on lightweight priority inheritance futexes. |
| 348 | pinctrl.txt | 360 | pinctrl.txt |
| @@ -431,6 +443,8 @@ sysrq.txt | |||
| 431 | - info on the magic SysRq key. | 443 | - info on the magic SysRq key. |
| 432 | target/ | 444 | target/ |
| 433 | - directory with info on generating TCM v4 fabric .ko modules | 445 | - directory with info on generating TCM v4 fabric .ko modules |
| 446 | this_cpu_ops.txt | ||
| 447 | - List rationale behind and the way to use this_cpu operations. | ||
| 434 | thermal/ | 448 | thermal/ |
| 435 | - directory with information on managing thermal issues (CPU/temp) | 449 | - directory with information on managing thermal issues (CPU/temp) |
| 436 | trace/ | 450 | trace/ |
| @@ -469,6 +483,8 @@ wimax/ | |||
| 469 | - directory with info about Intel Wireless Wimax Connections | 483 | - directory with info about Intel Wireless Wimax Connections |
| 470 | workqueue.txt | 484 | workqueue.txt |
| 471 | - information on the Concurrency Managed Workqueue implementation | 485 | - information on the Concurrency Managed Workqueue implementation |
| 486 | ww-mutex-design.txt | ||
| 487 | - Intro to Mutex wait/would deadlock handling.s | ||
| 472 | x86/x86_64/ | 488 | x86/x86_64/ |
| 473 | - directory with info on Linux support for AMD x86-64 (Hammer) machines. | 489 | - directory with info on Linux support for AMD x86-64 (Hammer) machines. |
| 474 | xtensa/ | 490 | xtensa/ |
diff --git a/Documentation/RCU/00-INDEX b/Documentation/RCU/00-INDEX index 1d7a885761f5..fa57139f50bf 100644 --- a/Documentation/RCU/00-INDEX +++ b/Documentation/RCU/00-INDEX | |||
| @@ -8,6 +8,8 @@ listRCU.txt | |||
| 8 | - Using RCU to Protect Read-Mostly Linked Lists | 8 | - Using RCU to Protect Read-Mostly Linked Lists |
| 9 | lockdep.txt | 9 | lockdep.txt |
| 10 | - RCU and lockdep checking | 10 | - RCU and lockdep checking |
| 11 | lockdep-splat.txt | ||
| 12 | - RCU Lockdep splats explained. | ||
| 11 | NMI-RCU.txt | 13 | NMI-RCU.txt |
| 12 | - Using RCU to Protect Dynamic NMI Handlers | 14 | - Using RCU to Protect Dynamic NMI Handlers |
| 13 | rcubarrier.txt | 15 | rcubarrier.txt |
diff --git a/Documentation/arm/00-INDEX b/Documentation/arm/00-INDEX index 36420e116c90..a94090cc785d 100644 --- a/Documentation/arm/00-INDEX +++ b/Documentation/arm/00-INDEX | |||
| @@ -4,6 +4,8 @@ Booting | |||
| 4 | - requirements for booting | 4 | - requirements for booting |
| 5 | Interrupts | 5 | Interrupts |
| 6 | - ARM Interrupt subsystem documentation | 6 | - ARM Interrupt subsystem documentation |
| 7 | IXP4xx | ||
| 8 | - Intel IXP4xx Network processor. | ||
| 7 | msm | 9 | msm |
| 8 | - MSM specific documentation | 10 | - MSM specific documentation |
| 9 | Netwinder | 11 | Netwinder |
| @@ -24,8 +26,16 @@ SPEAr | |||
| 24 | - ST SPEAr platform Linux Overview | 26 | - ST SPEAr platform Linux Overview |
| 25 | VFP/ | 27 | VFP/ |
| 26 | - Release notes for Linux Kernel Vector Floating Point support code | 28 | - Release notes for Linux Kernel Vector Floating Point support code |
| 29 | cluster-pm-race-avoidance.txt | ||
| 30 | - Algorithm for CPU and Cluster setup/teardown | ||
| 27 | empeg/ | 31 | empeg/ |
| 28 | - Ltd's Empeg MP3 Car Audio Player | 32 | - Ltd's Empeg MP3 Car Audio Player |
| 33 | firmware.txt | ||
| 34 | - Secure firmware registration and calling. | ||
| 35 | kernel_mode_neon.txt | ||
| 36 | - How to use NEON instructions in kernel mode | ||
| 37 | kernel_user_helpers.txt | ||
| 38 | - Helper functions in kernel space made available for userspace. | ||
| 29 | mem_alignment | 39 | mem_alignment |
| 30 | - alignment abort handler documentation | 40 | - alignment abort handler documentation |
| 31 | memory.txt | 41 | memory.txt |
| @@ -34,3 +44,7 @@ nwfpe/ | |||
| 34 | - NWFPE floating point emulator documentation | 44 | - NWFPE floating point emulator documentation |
| 35 | swp_emulation | 45 | swp_emulation |
| 36 | - SWP/SWPB emulation handler/logging description | 46 | - SWP/SWPB emulation handler/logging description |
| 47 | tcm.txt | ||
| 48 | - ARM Tightly Coupled Memory | ||
| 49 | vlocks.txt | ||
| 50 | - Voting locks, low-level mechanism relying on memory system atomic writes. | ||
diff --git a/Documentation/blackfin/00-INDEX b/Documentation/blackfin/00-INDEX index 2df0365f2dff..c54fcdd4ae9f 100644 --- a/Documentation/blackfin/00-INDEX +++ b/Documentation/blackfin/00-INDEX | |||
| @@ -1,8 +1,10 @@ | |||
| 1 | 00-INDEX | 1 | 00-INDEX |
| 2 | - This file | 2 | - This file |
| 3 | 3 | Makefile | |
| 4 | - Makefile for gptimers example file. | ||
| 4 | bfin-gpio-notes.txt | 5 | bfin-gpio-notes.txt |
| 5 | - Notes in developing/using bfin-gpio driver. | 6 | - Notes in developing/using bfin-gpio driver. |
| 6 | |||
| 7 | bfin-spi-notes.txt | 7 | bfin-spi-notes.txt |
| 8 | - Notes for using bfin spi bus driver. | 8 | - Notes for using bfin spi bus driver. |
| 9 | gptimers-example.c | ||
| 10 | - gptimers example | ||
diff --git a/Documentation/block/00-INDEX b/Documentation/block/00-INDEX index 929d9904f74b..e840b47613f7 100644 --- a/Documentation/block/00-INDEX +++ b/Documentation/block/00-INDEX | |||
| @@ -14,6 +14,8 @@ deadline-iosched.txt | |||
| 14 | - Deadline IO scheduler tunables | 14 | - Deadline IO scheduler tunables |
| 15 | ioprio.txt | 15 | ioprio.txt |
| 16 | - Block io priorities (in CFQ scheduler) | 16 | - Block io priorities (in CFQ scheduler) |
| 17 | null_blk.txt | ||
| 18 | - Null block for block-layer benchmarking. | ||
| 17 | queue-sysfs.txt | 19 | queue-sysfs.txt |
| 18 | - Queue's sysfs entries | 20 | - Queue's sysfs entries |
| 19 | request.txt | 21 | request.txt |
diff --git a/Documentation/devicetree/00-INDEX b/Documentation/devicetree/00-INDEX index b78f691fd847..8c4102c6a5e7 100644 --- a/Documentation/devicetree/00-INDEX +++ b/Documentation/devicetree/00-INDEX | |||
| @@ -8,3 +8,5 @@ https://lists.ozlabs.org/listinfo/devicetree-discuss | |||
| 8 | - this file | 8 | - this file |
| 9 | booting-without-of.txt | 9 | booting-without-of.txt |
| 10 | - Booting Linux without Open Firmware, describes history and format of device trees. | 10 | - Booting Linux without Open Firmware, describes history and format of device trees. |
| 11 | usage-model.txt | ||
| 12 | - How Linux uses DT and what DT aims to solve. \ No newline at end of file | ||
diff --git a/Documentation/devicetree/bindings/net/allwinner,sun4i-emac.txt b/Documentation/devicetree/bindings/net/allwinner,sun4i-emac.txt index b90bfcd138ff..863d5b8155c7 100644 --- a/Documentation/devicetree/bindings/net/allwinner,sun4i-emac.txt +++ b/Documentation/devicetree/bindings/net/allwinner,sun4i-emac.txt | |||
| @@ -1,7 +1,8 @@ | |||
| 1 | * Allwinner EMAC ethernet controller | 1 | * Allwinner EMAC ethernet controller |
| 2 | 2 | ||
| 3 | Required properties: | 3 | Required properties: |
| 4 | - compatible: should be "allwinner,sun4i-emac". | 4 | - compatible: should be "allwinner,sun4i-a10-emac" (Deprecated: |
| 5 | "allwinner,sun4i-emac") | ||
| 5 | - reg: address and length of the register set for the device. | 6 | - reg: address and length of the register set for the device. |
| 6 | - interrupts: interrupt for the device | 7 | - interrupts: interrupt for the device |
| 7 | - phy: A phandle to a phy node defining the PHY address (as the reg | 8 | - phy: A phandle to a phy node defining the PHY address (as the reg |
| @@ -14,7 +15,7 @@ Optional properties: | |||
| 14 | Example: | 15 | Example: |
| 15 | 16 | ||
| 16 | emac: ethernet@01c0b000 { | 17 | emac: ethernet@01c0b000 { |
| 17 | compatible = "allwinner,sun4i-emac"; | 18 | compatible = "allwinner,sun4i-a10-emac"; |
| 18 | reg = <0x01c0b000 0x1000>; | 19 | reg = <0x01c0b000 0x1000>; |
| 19 | interrupts = <55>; | 20 | interrupts = <55>; |
| 20 | clocks = <&ahb_gates 17>; | 21 | clocks = <&ahb_gates 17>; |
diff --git a/Documentation/devicetree/bindings/net/allwinner,sun4i-mdio.txt b/Documentation/devicetree/bindings/net/allwinner,sun4i-mdio.txt index 00b9f9a3ec1d..4ec56413779d 100644 --- a/Documentation/devicetree/bindings/net/allwinner,sun4i-mdio.txt +++ b/Documentation/devicetree/bindings/net/allwinner,sun4i-mdio.txt | |||
| @@ -1,7 +1,8 @@ | |||
| 1 | * Allwinner A10 MDIO Ethernet Controller interface | 1 | * Allwinner A10 MDIO Ethernet Controller interface |
| 2 | 2 | ||
| 3 | Required properties: | 3 | Required properties: |
| 4 | - compatible: should be "allwinner,sun4i-mdio". | 4 | - compatible: should be "allwinner,sun4i-a10-mdio" |
| 5 | (Deprecated: "allwinner,sun4i-mdio"). | ||
| 5 | - reg: address and length of the register set for the device. | 6 | - reg: address and length of the register set for the device. |
| 6 | 7 | ||
| 7 | Optional properties: | 8 | Optional properties: |
| @@ -9,7 +10,7 @@ Optional properties: | |||
| 9 | 10 | ||
| 10 | Example at the SoC level: | 11 | Example at the SoC level: |
| 11 | mdio@01c0b080 { | 12 | mdio@01c0b080 { |
| 12 | compatible = "allwinner,sun4i-mdio"; | 13 | compatible = "allwinner,sun4i-a10-mdio"; |
| 13 | reg = <0x01c0b080 0x14>; | 14 | reg = <0x01c0b080 0x14>; |
| 14 | #address-cells = <1>; | 15 | #address-cells = <1>; |
| 15 | #size-cells = <0>; | 16 | #size-cells = <0>; |
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index 3f900cd51bf0..40ce2df0e0e9 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt | |||
| @@ -8,6 +8,7 @@ ad Avionic Design GmbH | |||
| 8 | adi Analog Devices, Inc. | 8 | adi Analog Devices, Inc. |
| 9 | aeroflexgaisler Aeroflex Gaisler AB | 9 | aeroflexgaisler Aeroflex Gaisler AB |
| 10 | ak Asahi Kasei Corp. | 10 | ak Asahi Kasei Corp. |
| 11 | allwinner Allwinner Technology Co., Ltd. | ||
| 11 | altr Altera Corp. | 12 | altr Altera Corp. |
| 12 | amcc Applied Micro Circuits Corporation (APM, formally AMCC) | 13 | amcc Applied Micro Circuits Corporation (APM, formally AMCC) |
| 13 | amstaos AMS-Taos Inc. | 14 | amstaos AMS-Taos Inc. |
| @@ -40,6 +41,7 @@ gmt Global Mixed-mode Technology, Inc. | |||
| 40 | gumstix Gumstix, Inc. | 41 | gumstix Gumstix, Inc. |
| 41 | haoyu Haoyu Microelectronic Co. Ltd. | 42 | haoyu Haoyu Microelectronic Co. Ltd. |
| 42 | hisilicon Hisilicon Limited. | 43 | hisilicon Hisilicon Limited. |
| 44 | honeywell Honeywell | ||
| 43 | hp Hewlett Packard | 45 | hp Hewlett Packard |
| 44 | ibm International Business Machines (IBM) | 46 | ibm International Business Machines (IBM) |
| 45 | idt Integrated Device Technologies, Inc. | 47 | idt Integrated Device Technologies, Inc. |
| @@ -55,6 +57,7 @@ maxim Maxim Integrated Products | |||
| 55 | microchip Microchip Technology Inc. | 57 | microchip Microchip Technology Inc. |
| 56 | mosaixtech Mosaix Technologies, Inc. | 58 | mosaixtech Mosaix Technologies, Inc. |
| 57 | national National Semiconductor | 59 | national National Semiconductor |
| 60 | neonode Neonode Inc. | ||
| 58 | nintendo Nintendo | 61 | nintendo Nintendo |
| 59 | nvidia NVIDIA | 62 | nvidia NVIDIA |
| 60 | nxp NXP Semiconductors | 63 | nxp NXP Semiconductors |
| @@ -64,7 +67,7 @@ phytec PHYTEC Messtechnik GmbH | |||
| 64 | picochip Picochip Ltd | 67 | picochip Picochip Ltd |
| 65 | powervr PowerVR (deprecated, use img) | 68 | powervr PowerVR (deprecated, use img) |
| 66 | qca Qualcomm Atheros, Inc. | 69 | qca Qualcomm Atheros, Inc. |
| 67 | qcom Qualcomm, Inc. | 70 | qcom Qualcomm Technologies, Inc |
| 68 | ralink Mediatek/Ralink Technology Corp. | 71 | ralink Mediatek/Ralink Technology Corp. |
| 69 | ramtron Ramtron International | 72 | ramtron Ramtron International |
| 70 | realtek Realtek Semiconductor Corp. | 73 | realtek Realtek Semiconductor Corp. |
| @@ -78,6 +81,7 @@ silabs Silicon Laboratories | |||
| 78 | simtek | 81 | simtek |
| 79 | sirf SiRF Technology, Inc. | 82 | sirf SiRF Technology, Inc. |
| 80 | snps Synopsys, Inc. | 83 | snps Synopsys, Inc. |
| 84 | spansion Spansion Inc. | ||
| 81 | st STMicroelectronics | 85 | st STMicroelectronics |
| 82 | ste ST-Ericsson | 86 | ste ST-Ericsson |
| 83 | stericsson ST-Ericsson | 87 | stericsson ST-Ericsson |
diff --git a/Documentation/fb/00-INDEX b/Documentation/fb/00-INDEX index 30a70542e823..fe85e7c5907a 100644 --- a/Documentation/fb/00-INDEX +++ b/Documentation/fb/00-INDEX | |||
| @@ -5,6 +5,8 @@ please mail me. | |||
| 5 | 5 | ||
| 6 | 00-INDEX | 6 | 00-INDEX |
| 7 | - this file. | 7 | - this file. |
| 8 | api.txt | ||
| 9 | - The frame buffer API between applications and buffer devices. | ||
| 8 | arkfb.txt | 10 | arkfb.txt |
| 9 | - info on the fbdev driver for ARK Logic chips. | 11 | - info on the fbdev driver for ARK Logic chips. |
| 10 | aty128fb.txt | 12 | aty128fb.txt |
| @@ -51,12 +53,16 @@ sh7760fb.txt | |||
| 51 | - info on the SH7760/SH7763 integrated LCDC Framebuffer driver. | 53 | - info on the SH7760/SH7763 integrated LCDC Framebuffer driver. |
| 52 | sisfb.txt | 54 | sisfb.txt |
| 53 | - info on the framebuffer device driver for various SiS chips. | 55 | - info on the framebuffer device driver for various SiS chips. |
| 56 | sm501.txt | ||
| 57 | - info on the framebuffer device driver for sm501 videoframebuffer. | ||
| 54 | sstfb.txt | 58 | sstfb.txt |
| 55 | - info on the frame buffer driver for 3dfx' Voodoo Graphics boards. | 59 | - info on the frame buffer driver for 3dfx' Voodoo Graphics boards. |
| 56 | tgafb.txt | 60 | tgafb.txt |
| 57 | - info on the TGA (DECChip 21030) frame buffer driver. | 61 | - info on the TGA (DECChip 21030) frame buffer driver. |
| 58 | tridentfb.txt | 62 | tridentfb.txt |
| 59 | info on the framebuffer driver for some Trident chip based cards. | 63 | info on the framebuffer driver for some Trident chip based cards. |
| 64 | udlfb.txt | ||
| 65 | - Driver for DisplayLink USB 2.0 chips. | ||
| 60 | uvesafb.txt | 66 | uvesafb.txt |
| 61 | - info on the userspace VESA (VBE2+ compliant) frame buffer device. | 67 | - info on the userspace VESA (VBE2+ compliant) frame buffer device. |
| 62 | vesafb.txt | 68 | vesafb.txt |
diff --git a/Documentation/filesystems/00-INDEX b/Documentation/filesystems/00-INDEX index 632211cbdd56..ac28149aede4 100644 --- a/Documentation/filesystems/00-INDEX +++ b/Documentation/filesystems/00-INDEX | |||
| @@ -2,6 +2,8 @@ | |||
| 2 | - this file (info on some of the filesystems supported by linux). | 2 | - this file (info on some of the filesystems supported by linux). |
| 3 | Locking | 3 | Locking |
| 4 | - info on locking rules as they pertain to Linux VFS. | 4 | - info on locking rules as they pertain to Linux VFS. |
| 5 | Makefile | ||
| 6 | - Makefile for building the filsystems-part of DocBook. | ||
| 5 | 9p.txt | 7 | 9p.txt |
| 6 | - 9p (v9fs) is an implementation of the Plan 9 remote fs protocol. | 8 | - 9p (v9fs) is an implementation of the Plan 9 remote fs protocol. |
| 7 | adfs.txt | 9 | adfs.txt |
diff --git a/Documentation/filesystems/nfs/00-INDEX b/Documentation/filesystems/nfs/00-INDEX index 66eb6c8c5334..53f3b596ac0d 100644 --- a/Documentation/filesystems/nfs/00-INDEX +++ b/Documentation/filesystems/nfs/00-INDEX | |||
| @@ -12,6 +12,8 @@ nfs41-server.txt | |||
| 12 | - info on the Linux server implementation of NFSv4 minor version 1. | 12 | - info on the Linux server implementation of NFSv4 minor version 1. |
| 13 | nfs-rdma.txt | 13 | nfs-rdma.txt |
| 14 | - how to install and setup the Linux NFS/RDMA client and server software | 14 | - how to install and setup the Linux NFS/RDMA client and server software |
| 15 | nfsd-admin-interfaces.txt | ||
| 16 | - Administrative interfaces for nfsd. | ||
| 15 | nfsroot.txt | 17 | nfsroot.txt |
| 16 | - short guide on setting up a diskless box with NFS root filesystem. | 18 | - short guide on setting up a diskless box with NFS root filesystem. |
| 17 | pnfs.txt | 19 | pnfs.txt |
| @@ -20,5 +22,5 @@ rpc-cache.txt | |||
| 20 | - introduction to the caching mechanisms in the sunrpc layer. | 22 | - introduction to the caching mechanisms in the sunrpc layer. |
| 21 | idmapper.txt | 23 | idmapper.txt |
| 22 | - information for configuring request-keys to be used by idmapper | 24 | - information for configuring request-keys to be used by idmapper |
| 23 | knfsd-rpcgss.txt | 25 | rpc-server-gss.txt |
| 24 | - Information on GSS authentication support in the NFS Server | 26 | - Information on GSS authentication support in the NFS Server |
diff --git a/Documentation/ide/00-INDEX b/Documentation/ide/00-INDEX index d6b778842b75..22f98ca79539 100644 --- a/Documentation/ide/00-INDEX +++ b/Documentation/ide/00-INDEX | |||
| @@ -10,3 +10,5 @@ ide-tape.txt | |||
| 10 | - info on the IDE ATAPI streaming tape driver | 10 | - info on the IDE ATAPI streaming tape driver |
| 11 | ide.txt | 11 | ide.txt |
| 12 | - important info for users of ATA devices (IDE/EIDE disks and CD-ROMS). | 12 | - important info for users of ATA devices (IDE/EIDE disks and CD-ROMS). |
| 13 | warm-plug-howto.txt | ||
| 14 | - using sysfs to remove and add IDE devices. \ No newline at end of file | ||
diff --git a/Documentation/laptops/00-INDEX b/Documentation/laptops/00-INDEX index fa688538e757..d13b9a9a9e00 100644 --- a/Documentation/laptops/00-INDEX +++ b/Documentation/laptops/00-INDEX | |||
| @@ -1,13 +1,15 @@ | |||
| 1 | 00-INDEX | 1 | 00-INDEX |
| 2 | - This file | 2 | - This file |
| 3 | acer-wmi.txt | 3 | Makefile |
| 4 | - information on the Acer Laptop WMI Extras driver. | 4 | - Makefile for building dslm example program. |
| 5 | asus-laptop.txt | 5 | asus-laptop.txt |
| 6 | - information on the Asus Laptop Extras driver. | 6 | - information on the Asus Laptop Extras driver. |
| 7 | disk-shock-protection.txt | 7 | disk-shock-protection.txt |
| 8 | - information on hard disk shock protection. | 8 | - information on hard disk shock protection. |
| 9 | dslm.c | 9 | dslm.c |
| 10 | - Simple Disk Sleep Monitor program | 10 | - Simple Disk Sleep Monitor program |
| 11 | hpfall.c | ||
| 12 | - (HP) laptop accelerometer program for disk protection. | ||
| 11 | laptop-mode.txt | 13 | laptop-mode.txt |
| 12 | - how to conserve battery power using laptop-mode. | 14 | - how to conserve battery power using laptop-mode. |
| 13 | sony-laptop.txt | 15 | sony-laptop.txt |
diff --git a/Documentation/leds/00-INDEX b/Documentation/leds/00-INDEX index 1ecd1596633e..b4ef1f34e25f 100644 --- a/Documentation/leds/00-INDEX +++ b/Documentation/leds/00-INDEX | |||
| @@ -1,3 +1,7 @@ | |||
| 1 | 00-INDEX | ||
| 2 | - This file | ||
| 3 | leds-blinkm.txt | ||
| 4 | - Driver for BlinkM LED-devices. | ||
| 1 | leds-class.txt | 5 | leds-class.txt |
| 2 | - documents LED handling under Linux. | 6 | - documents LED handling under Linux. |
| 3 | leds-lp3944.txt | 7 | leds-lp3944.txt |
| @@ -12,3 +16,7 @@ leds-lp55xx.txt | |||
| 12 | - description about lp55xx common driver. | 16 | - description about lp55xx common driver. |
| 13 | leds-lm3556.txt | 17 | leds-lm3556.txt |
| 14 | - notes on how to use the leds-lm3556 driver. | 18 | - notes on how to use the leds-lm3556 driver. |
| 19 | ledtrig-oneshot.txt | ||
| 20 | - One-shot LED trigger for both sporadic and dense events. | ||
| 21 | ledtrig-transient.txt | ||
| 22 | - LED Transient Trigger, one shot timer activation. | ||
diff --git a/Documentation/m68k/00-INDEX b/Documentation/m68k/00-INDEX index a014e9f00765..2be8c6b00e74 100644 --- a/Documentation/m68k/00-INDEX +++ b/Documentation/m68k/00-INDEX | |||
| @@ -1,5 +1,7 @@ | |||
| 1 | 00-INDEX | 1 | 00-INDEX |
| 2 | - this file | 2 | - this file |
| 3 | README.buddha | ||
| 4 | - Amiga Buddha and Catweasel IDE Driver | ||
| 3 | kernel-options.txt | 5 | kernel-options.txt |
| 4 | - command line options for Linux/m68k | 6 | - command line options for Linux/m68k |
| 5 | 7 | ||
diff --git a/Documentation/networking/00-INDEX b/Documentation/networking/00-INDEX index f11580f8719a..557b6ef70c26 100644 --- a/Documentation/networking/00-INDEX +++ b/Documentation/networking/00-INDEX | |||
| @@ -6,8 +6,14 @@ | |||
| 6 | - information on the 3Com Etherlink III Series Ethernet cards. | 6 | - information on the 3Com Etherlink III Series Ethernet cards. |
| 7 | 6pack.txt | 7 | 6pack.txt |
| 8 | - info on the 6pack protocol, an alternative to KISS for AX.25 | 8 | - info on the 6pack protocol, an alternative to KISS for AX.25 |
| 9 | DLINK.txt | 9 | LICENSE.qla3xxx |
| 10 | - info on the D-Link DE-600/DE-620 parallel port pocket adapters | 10 | - GPLv2 for QLogic Linux Networking HBA Driver |
| 11 | LICENSE.qlge | ||
| 12 | - GPLv2 for QLogic Linux qlge NIC Driver | ||
| 13 | LICENSE.qlcnic | ||
| 14 | - GPLv2 for QLogic Linux qlcnic NIC Driver | ||
| 15 | Makefile | ||
| 16 | - Makefile for docsrc. | ||
| 11 | PLIP.txt | 17 | PLIP.txt |
| 12 | - PLIP: The Parallel Line Internet Protocol device driver | 18 | - PLIP: The Parallel Line Internet Protocol device driver |
| 13 | README.ipw2100 | 19 | README.ipw2100 |
| @@ -17,7 +23,7 @@ README.ipw2200 | |||
| 17 | README.sb1000 | 23 | README.sb1000 |
| 18 | - info on General Instrument/NextLevel SURFboard1000 cable modem. | 24 | - info on General Instrument/NextLevel SURFboard1000 cable modem. |
| 19 | alias.txt | 25 | alias.txt |
| 20 | - info on using alias network devices | 26 | - info on using alias network devices. |
| 21 | arcnet-hardware.txt | 27 | arcnet-hardware.txt |
| 22 | - tons of info on ARCnet, hubs, jumper settings for ARCnet cards, etc. | 28 | - tons of info on ARCnet, hubs, jumper settings for ARCnet cards, etc. |
| 23 | arcnet.txt | 29 | arcnet.txt |
| @@ -80,7 +86,7 @@ framerelay.txt | |||
| 80 | - info on using Frame Relay/Data Link Connection Identifier (DLCI). | 86 | - info on using Frame Relay/Data Link Connection Identifier (DLCI). |
| 81 | gen_stats.txt | 87 | gen_stats.txt |
| 82 | - Generic networking statistics for netlink users. | 88 | - Generic networking statistics for netlink users. |
| 83 | generic_hdlc.txt | 89 | generic-hdlc.txt |
| 84 | - The generic High Level Data Link Control (HDLC) layer. | 90 | - The generic High Level Data Link Control (HDLC) layer. |
| 85 | generic_netlink.txt | 91 | generic_netlink.txt |
| 86 | - info on Generic Netlink | 92 | - info on Generic Netlink |
| @@ -88,6 +94,8 @@ gianfar.txt | |||
| 88 | - Gianfar Ethernet Driver. | 94 | - Gianfar Ethernet Driver. |
| 89 | i40e.txt | 95 | i40e.txt |
| 90 | - README for the Intel Ethernet Controller XL710 Driver (i40e). | 96 | - README for the Intel Ethernet Controller XL710 Driver (i40e). |
| 97 | i40evf.txt | ||
| 98 | - Short note on the Driver for the Intel(R) XL710 X710 Virtual Function | ||
| 91 | ieee802154.txt | 99 | ieee802154.txt |
| 92 | - Linux IEEE 802.15.4 implementation, API and drivers | 100 | - Linux IEEE 802.15.4 implementation, API and drivers |
| 93 | igb.txt | 101 | igb.txt |
| @@ -102,6 +110,8 @@ ipddp.txt | |||
| 102 | - AppleTalk-IP Decapsulation and AppleTalk-IP Encapsulation | 110 | - AppleTalk-IP Decapsulation and AppleTalk-IP Encapsulation |
| 103 | iphase.txt | 111 | iphase.txt |
| 104 | - Interphase PCI ATM (i)Chip IA Linux driver info. | 112 | - Interphase PCI ATM (i)Chip IA Linux driver info. |
| 113 | ipsec.txt | ||
| 114 | - Note on not compressing IPSec payload and resulting failed policy check. | ||
| 105 | ipv6.txt | 115 | ipv6.txt |
| 106 | - Options to the ipv6 kernel module. | 116 | - Options to the ipv6 kernel module. |
| 107 | ipvs-sysctl.txt | 117 | ipvs-sysctl.txt |
| @@ -120,6 +130,8 @@ lapb-module.txt | |||
| 120 | - programming information of the LAPB module. | 130 | - programming information of the LAPB module. |
| 121 | ltpc.txt | 131 | ltpc.txt |
| 122 | - the Apple or Farallon LocalTalk PC card driver | 132 | - the Apple or Farallon LocalTalk PC card driver |
| 133 | mac80211-auth-assoc-deauth.txt | ||
| 134 | - authentication and association / deauth-disassoc with max80211 | ||
| 123 | mac80211-injection.txt | 135 | mac80211-injection.txt |
| 124 | - HOWTO use packet injection with mac80211 | 136 | - HOWTO use packet injection with mac80211 |
| 125 | multiqueue.txt | 137 | multiqueue.txt |
| @@ -134,6 +146,10 @@ netdevices.txt | |||
| 134 | - info on network device driver functions exported to the kernel. | 146 | - info on network device driver functions exported to the kernel. |
| 135 | netif-msg.txt | 147 | netif-msg.txt |
| 136 | - Design of the network interface message level setting (NETIF_MSG_*). | 148 | - Design of the network interface message level setting (NETIF_MSG_*). |
| 149 | netlink_mmap.txt | ||
| 150 | - memory mapped I/O with netlink | ||
| 151 | nf_conntrack-sysctl.txt | ||
| 152 | - list of netfilter-sysctl knobs. | ||
| 137 | nfc.txt | 153 | nfc.txt |
| 138 | - The Linux Near Field Communication (NFS) subsystem. | 154 | - The Linux Near Field Communication (NFS) subsystem. |
| 139 | openvswitch.txt | 155 | openvswitch.txt |
| @@ -176,7 +192,7 @@ skfp.txt | |||
| 176 | - SysKonnect FDDI (SK-5xxx, Compaq Netelligent) driver info. | 192 | - SysKonnect FDDI (SK-5xxx, Compaq Netelligent) driver info. |
| 177 | smc9.txt | 193 | smc9.txt |
| 178 | - the driver for SMC's 9000 series of Ethernet cards | 194 | - the driver for SMC's 9000 series of Ethernet cards |
| 179 | spider-net.txt | 195 | spider_net.txt |
| 180 | - README for the Spidernet Driver (as found in PS3 / Cell BE). | 196 | - README for the Spidernet Driver (as found in PS3 / Cell BE). |
| 181 | stmmac.txt | 197 | stmmac.txt |
| 182 | - README for the STMicro Synopsys Ethernet driver. | 198 | - README for the STMicro Synopsys Ethernet driver. |
| @@ -188,6 +204,8 @@ tcp.txt | |||
| 188 | - short blurb on how TCP output takes place. | 204 | - short blurb on how TCP output takes place. |
| 189 | tcp-thin.txt | 205 | tcp-thin.txt |
| 190 | - kernel tuning options for low rate 'thin' TCP streams. | 206 | - kernel tuning options for low rate 'thin' TCP streams. |
| 207 | team.txt | ||
| 208 | - pointer to information for ethernet teaming devices. | ||
| 191 | tlan.txt | 209 | tlan.txt |
| 192 | - ThunderLAN (Compaq Netelligent 10/100, Olicom OC-2xxx) driver info. | 210 | - ThunderLAN (Compaq Netelligent 10/100, Olicom OC-2xxx) driver info. |
| 193 | tproxy.txt | 211 | tproxy.txt |
| @@ -200,6 +218,8 @@ vortex.txt | |||
| 200 | - info on using 3Com Vortex (3c590, 3c592, 3c595, 3c597) Ethernet cards. | 218 | - info on using 3Com Vortex (3c590, 3c592, 3c595, 3c597) Ethernet cards. |
| 201 | vxge.txt | 219 | vxge.txt |
| 202 | - README for the Neterion X3100 PCIe Server Adapter. | 220 | - README for the Neterion X3100 PCIe Server Adapter. |
| 221 | vxlan.txt | ||
| 222 | - Virtual extensible LAN overview | ||
| 203 | x25.txt | 223 | x25.txt |
| 204 | - general info on X.25 development. | 224 | - general info on X.25 development. |
| 205 | x25-iface.txt | 225 | x25-iface.txt |
diff --git a/Documentation/power/00-INDEX b/Documentation/power/00-INDEX index a4d682f54231..ad04cc8097ed 100644 --- a/Documentation/power/00-INDEX +++ b/Documentation/power/00-INDEX | |||
| @@ -4,6 +4,8 @@ apm-acpi.txt | |||
| 4 | - basic info about the APM and ACPI support. | 4 | - basic info about the APM and ACPI support. |
| 5 | basic-pm-debugging.txt | 5 | basic-pm-debugging.txt |
| 6 | - Debugging suspend and resume | 6 | - Debugging suspend and resume |
| 7 | charger-manager.txt | ||
| 8 | - Battery charger management. | ||
| 7 | devices.txt | 9 | devices.txt |
| 8 | - How drivers interact with system-wide power management | 10 | - How drivers interact with system-wide power management |
| 9 | drivers-testing.txt | 11 | drivers-testing.txt |
| @@ -22,6 +24,8 @@ pm_qos_interface.txt | |||
| 22 | - info on Linux PM Quality of Service interface | 24 | - info on Linux PM Quality of Service interface |
| 23 | power_supply_class.txt | 25 | power_supply_class.txt |
| 24 | - Tells userspace about battery, UPS, AC or DC power supply properties | 26 | - Tells userspace about battery, UPS, AC or DC power supply properties |
| 27 | runtime_pm.txt | ||
| 28 | - Power management framework for I/O devices. | ||
| 25 | s2ram.txt | 29 | s2ram.txt |
| 26 | - How to get suspend to ram working (and debug it when it isn't) | 30 | - How to get suspend to ram working (and debug it when it isn't) |
| 27 | states.txt | 31 | states.txt |
| @@ -38,7 +42,5 @@ tricks.txt | |||
| 38 | - How to trick software suspend (to disk) into working when it isn't | 42 | - How to trick software suspend (to disk) into working when it isn't |
| 39 | userland-swsusp.txt | 43 | userland-swsusp.txt |
| 40 | - Experimental implementation of software suspend in userspace | 44 | - Experimental implementation of software suspend in userspace |
| 41 | video_extension.txt | ||
| 42 | - ACPI video extensions | ||
| 43 | video.txt | 45 | video.txt |
| 44 | - Video issues during resume from suspend | 46 | - Video issues during resume from suspend |
diff --git a/Documentation/ptp/testptp.c b/Documentation/ptp/testptp.c index a74d0a84d329..4aba0436da65 100644 --- a/Documentation/ptp/testptp.c +++ b/Documentation/ptp/testptp.c | |||
| @@ -117,6 +117,7 @@ static void usage(char *progname) | |||
| 117 | " -f val adjust the ptp clock frequency by 'val' ppb\n" | 117 | " -f val adjust the ptp clock frequency by 'val' ppb\n" |
| 118 | " -g get the ptp clock time\n" | 118 | " -g get the ptp clock time\n" |
| 119 | " -h prints this message\n" | 119 | " -h prints this message\n" |
| 120 | " -i val index for event/trigger\n" | ||
| 120 | " -k val measure the time offset between system and phc clock\n" | 121 | " -k val measure the time offset between system and phc clock\n" |
| 121 | " for 'val' times (Maximum 25)\n" | 122 | " for 'val' times (Maximum 25)\n" |
| 122 | " -p val enable output with a period of 'val' nanoseconds\n" | 123 | " -p val enable output with a period of 'val' nanoseconds\n" |
| @@ -154,6 +155,7 @@ int main(int argc, char *argv[]) | |||
| 154 | int capabilities = 0; | 155 | int capabilities = 0; |
| 155 | int extts = 0; | 156 | int extts = 0; |
| 156 | int gettime = 0; | 157 | int gettime = 0; |
| 158 | int index = 0; | ||
| 157 | int oneshot = 0; | 159 | int oneshot = 0; |
| 158 | int pct_offset = 0; | 160 | int pct_offset = 0; |
| 159 | int n_samples = 0; | 161 | int n_samples = 0; |
| @@ -167,7 +169,7 @@ int main(int argc, char *argv[]) | |||
| 167 | 169 | ||
| 168 | progname = strrchr(argv[0], '/'); | 170 | progname = strrchr(argv[0], '/'); |
| 169 | progname = progname ? 1+progname : argv[0]; | 171 | progname = progname ? 1+progname : argv[0]; |
| 170 | while (EOF != (c = getopt(argc, argv, "a:A:cd:e:f:ghk:p:P:sSt:v"))) { | 172 | while (EOF != (c = getopt(argc, argv, "a:A:cd:e:f:ghi:k:p:P:sSt:v"))) { |
| 171 | switch (c) { | 173 | switch (c) { |
| 172 | case 'a': | 174 | case 'a': |
| 173 | oneshot = atoi(optarg); | 175 | oneshot = atoi(optarg); |
| @@ -190,6 +192,9 @@ int main(int argc, char *argv[]) | |||
| 190 | case 'g': | 192 | case 'g': |
| 191 | gettime = 1; | 193 | gettime = 1; |
| 192 | break; | 194 | break; |
| 195 | case 'i': | ||
| 196 | index = atoi(optarg); | ||
| 197 | break; | ||
| 193 | case 'k': | 198 | case 'k': |
| 194 | pct_offset = 1; | 199 | pct_offset = 1; |
| 195 | n_samples = atoi(optarg); | 200 | n_samples = atoi(optarg); |
| @@ -301,7 +306,7 @@ int main(int argc, char *argv[]) | |||
| 301 | 306 | ||
| 302 | if (extts) { | 307 | if (extts) { |
| 303 | memset(&extts_request, 0, sizeof(extts_request)); | 308 | memset(&extts_request, 0, sizeof(extts_request)); |
| 304 | extts_request.index = 0; | 309 | extts_request.index = index; |
| 305 | extts_request.flags = PTP_ENABLE_FEATURE; | 310 | extts_request.flags = PTP_ENABLE_FEATURE; |
| 306 | if (ioctl(fd, PTP_EXTTS_REQUEST, &extts_request)) { | 311 | if (ioctl(fd, PTP_EXTTS_REQUEST, &extts_request)) { |
| 307 | perror("PTP_EXTTS_REQUEST"); | 312 | perror("PTP_EXTTS_REQUEST"); |
| @@ -375,7 +380,7 @@ int main(int argc, char *argv[]) | |||
| 375 | return -1; | 380 | return -1; |
| 376 | } | 381 | } |
| 377 | memset(&perout_request, 0, sizeof(perout_request)); | 382 | memset(&perout_request, 0, sizeof(perout_request)); |
| 378 | perout_request.index = 0; | 383 | perout_request.index = index; |
| 379 | perout_request.start.sec = ts.tv_sec + 2; | 384 | perout_request.start.sec = ts.tv_sec + 2; |
| 380 | perout_request.start.nsec = 0; | 385 | perout_request.start.nsec = 0; |
| 381 | perout_request.period.sec = 0; | 386 | perout_request.period.sec = 0; |
diff --git a/Documentation/s390/00-INDEX b/Documentation/s390/00-INDEX index 3a2b96302ecc..10c874ebdfe5 100644 --- a/Documentation/s390/00-INDEX +++ b/Documentation/s390/00-INDEX | |||
| @@ -16,11 +16,13 @@ Debugging390.txt | |||
| 16 | - hints for debugging on s390 systems. | 16 | - hints for debugging on s390 systems. |
| 17 | driver-model.txt | 17 | driver-model.txt |
| 18 | - information on s390 devices and the driver model. | 18 | - information on s390 devices and the driver model. |
| 19 | kvm.txt | ||
| 20 | - ioctl calls to /dev/kvm on s390. | ||
| 19 | monreader.txt | 21 | monreader.txt |
| 20 | - information on accessing the z/VM monitor stream from Linux. | 22 | - information on accessing the z/VM monitor stream from Linux. |
| 23 | qeth.txt | ||
| 24 | - HiperSockets Bridge Port Support. | ||
| 21 | s390dbf.txt | 25 | s390dbf.txt |
| 22 | - information on using the s390 debug feature. | 26 | - information on using the s390 debug feature. |
| 23 | TAPE | 27 | zfcpdump.txt |
| 24 | - information on the driver for channel-attached tapes. | ||
| 25 | zfcpdump | ||
| 26 | - information on the s390 SCSI dump tool. | 28 | - information on the s390 SCSI dump tool. |
diff --git a/Documentation/scheduler/00-INDEX b/Documentation/scheduler/00-INDEX index 46702e4f89c9..eccf7ad2e7f9 100644 --- a/Documentation/scheduler/00-INDEX +++ b/Documentation/scheduler/00-INDEX | |||
| @@ -2,6 +2,8 @@ | |||
| 2 | - this file. | 2 | - this file. |
| 3 | sched-arch.txt | 3 | sched-arch.txt |
| 4 | - CPU Scheduler implementation hints for architecture specific code. | 4 | - CPU Scheduler implementation hints for architecture specific code. |
| 5 | sched-bwc.txt | ||
| 6 | - CFS bandwidth control overview. | ||
| 5 | sched-design-CFS.txt | 7 | sched-design-CFS.txt |
| 6 | - goals, design and implementation of the Completely Fair Scheduler. | 8 | - goals, design and implementation of the Completely Fair Scheduler. |
| 7 | sched-domains.txt | 9 | sched-domains.txt |
diff --git a/Documentation/scsi/00-INDEX b/Documentation/scsi/00-INDEX index 2044be565d93..c4b978a72f78 100644 --- a/Documentation/scsi/00-INDEX +++ b/Documentation/scsi/00-INDEX | |||
| @@ -36,6 +36,8 @@ NinjaSCSI.txt | |||
| 36 | - info on WorkBiT NinjaSCSI-32/32Bi driver | 36 | - info on WorkBiT NinjaSCSI-32/32Bi driver |
| 37 | aacraid.txt | 37 | aacraid.txt |
| 38 | - Driver supporting Adaptec RAID controllers | 38 | - Driver supporting Adaptec RAID controllers |
| 39 | advansys.txt | ||
| 40 | - List of Advansys Host Adapters | ||
| 39 | aha152x.txt | 41 | aha152x.txt |
| 40 | - info on driver for Adaptec AHA152x based adapters | 42 | - info on driver for Adaptec AHA152x based adapters |
| 41 | aic79xx.txt | 43 | aic79xx.txt |
| @@ -44,6 +46,12 @@ aic7xxx.txt | |||
| 44 | - info on driver for Adaptec controllers | 46 | - info on driver for Adaptec controllers |
| 45 | arcmsr_spec.txt | 47 | arcmsr_spec.txt |
| 46 | - ARECA FIRMWARE SPEC (for IOP331 adapter) | 48 | - ARECA FIRMWARE SPEC (for IOP331 adapter) |
| 49 | bfa.txt | ||
| 50 | - Brocade FC/FCOE adapter driver. | ||
| 51 | bnx2fc.txt | ||
| 52 | - FCoE hardware offload for Broadcom network interfaces. | ||
| 53 | cxgb3i.txt | ||
| 54 | - Chelsio iSCSI Linux Driver | ||
| 47 | dc395x.txt | 55 | dc395x.txt |
| 48 | - README file for the dc395x SCSI driver | 56 | - README file for the dc395x SCSI driver |
| 49 | dpti.txt | 57 | dpti.txt |
| @@ -52,18 +60,24 @@ dtc3x80.txt | |||
| 52 | - info on driver for DTC 2x80 based adapters | 60 | - info on driver for DTC 2x80 based adapters |
| 53 | g_NCR5380.txt | 61 | g_NCR5380.txt |
| 54 | - info on driver for NCR5380 and NCR53c400 based adapters | 62 | - info on driver for NCR5380 and NCR53c400 based adapters |
| 63 | hpsa.txt | ||
| 64 | - HP Smart Array Controller SCSI driver. | ||
| 55 | hptiop.txt | 65 | hptiop.txt |
| 56 | - HIGHPOINT ROCKETRAID 3xxx RAID DRIVER | 66 | - HIGHPOINT ROCKETRAID 3xxx RAID DRIVER |
| 57 | in2000.txt | 67 | in2000.txt |
| 58 | - info on in2000 driver | 68 | - info on in2000 driver |
| 59 | libsas.txt | 69 | libsas.txt |
| 60 | - Serial Attached SCSI management layer. | 70 | - Serial Attached SCSI management layer. |
| 71 | link_power_management_policy.txt | ||
| 72 | - Link power management options. | ||
| 61 | lpfc.txt | 73 | lpfc.txt |
| 62 | - LPFC driver release notes | 74 | - LPFC driver release notes |
| 63 | megaraid.txt | 75 | megaraid.txt |
| 64 | - Common Management Module, shared code handling ioctls for LSI drivers | 76 | - Common Management Module, shared code handling ioctls for LSI drivers |
| 65 | ncr53c8xx.txt | 77 | ncr53c8xx.txt |
| 66 | - info on driver for NCR53c8xx based adapters | 78 | - info on driver for NCR53c8xx based adapters |
| 79 | osd.txt | ||
| 80 | Object-Based Storage Device, command set introduction. | ||
| 67 | osst.txt | 81 | osst.txt |
| 68 | - info on driver for OnStream SC-x0 SCSI tape | 82 | - info on driver for OnStream SC-x0 SCSI tape |
| 69 | ppa.txt | 83 | ppa.txt |
| @@ -74,6 +88,8 @@ scsi-changer.txt | |||
| 74 | - README for the SCSI media changer driver | 88 | - README for the SCSI media changer driver |
| 75 | scsi-generic.txt | 89 | scsi-generic.txt |
| 76 | - info on the sg driver for generic (non-disk/CD/tape) SCSI devices. | 90 | - info on the sg driver for generic (non-disk/CD/tape) SCSI devices. |
| 91 | scsi-parameters.txt | ||
| 92 | - List of SCSI-parameters to pass to the kernel at module load-time. | ||
| 77 | scsi.txt | 93 | scsi.txt |
| 78 | - short blurb on using SCSI support as a module. | 94 | - short blurb on using SCSI support as a module. |
| 79 | scsi_mid_low_api.txt | 95 | scsi_mid_low_api.txt |
diff --git a/Documentation/serial/00-INDEX b/Documentation/serial/00-INDEX index 1f1b22fbd739..f9c6b5ed03e7 100644 --- a/Documentation/serial/00-INDEX +++ b/Documentation/serial/00-INDEX | |||
| @@ -4,10 +4,12 @@ README.cycladesZ | |||
| 4 | - info on Cyclades-Z firmware loading. | 4 | - info on Cyclades-Z firmware loading. |
| 5 | digiepca.txt | 5 | digiepca.txt |
| 6 | - info on Digi Intl. {PC,PCI,EISA}Xx and Xem series cards. | 6 | - info on Digi Intl. {PC,PCI,EISA}Xx and Xem series cards. |
| 7 | hayes-esp.txt | 7 | driver |
| 8 | - info on using the Hayes ESP serial driver. | 8 | - intro to the low level serial driver. |
| 9 | moxa-smartio | 9 | moxa-smartio |
| 10 | - file with info on installing/using Moxa multiport serial driver. | 10 | - file with info on installing/using Moxa multiport serial driver. |
| 11 | n_gsm.txt | ||
| 12 | - GSM 0710 tty multiplexer howto. | ||
| 11 | riscom8.txt | 13 | riscom8.txt |
| 12 | - notes on using the RISCom/8 multi-port serial driver. | 14 | - notes on using the RISCom/8 multi-port serial driver. |
| 13 | rocket.txt | 15 | rocket.txt |
diff --git a/Documentation/spi/00-INDEX b/Documentation/spi/00-INDEX new file mode 100644 index 000000000000..a128fa835512 --- /dev/null +++ b/Documentation/spi/00-INDEX | |||
| @@ -0,0 +1,22 @@ | |||
| 1 | 00-INDEX | ||
| 2 | - this file. | ||
| 3 | Makefile | ||
| 4 | - Makefile for the example sourcefiles. | ||
| 5 | butterfly | ||
| 6 | - AVR Butterfly SPI driver overview and pin configuration. | ||
| 7 | ep93xx_spi | ||
| 8 | - Basic EP93xx SPI driver configuration. | ||
| 9 | pxa2xx | ||
| 10 | - PXA2xx SPI master controller build by spi_message fifo wq | ||
| 11 | spidev | ||
| 12 | - Intro to the userspace API for spi devices | ||
| 13 | spidev_fdx.c | ||
| 14 | - spidev example file | ||
| 15 | spi-lm70llp | ||
| 16 | - Connecting an LM70-LLP sensor to the kernel via the SPI subsys. | ||
| 17 | spi-sc18is602 | ||
| 18 | - NXP SC18IS602/603 I2C-bus to SPI bridge | ||
| 19 | spi-summary | ||
| 20 | - (Linux) SPI overview. If unsure about SPI or SPI in Linux, start here. | ||
| 21 | spidev_test.c | ||
| 22 | - SPI testing utility. | ||
diff --git a/Documentation/timers/00-INDEX b/Documentation/timers/00-INDEX index ef2ccbf77fa2..6d042dc1cce0 100644 --- a/Documentation/timers/00-INDEX +++ b/Documentation/timers/00-INDEX | |||
| @@ -8,6 +8,8 @@ hpet_example.c | |||
| 8 | - sample hpet timer test program | 8 | - sample hpet timer test program |
| 9 | hrtimers.txt | 9 | hrtimers.txt |
| 10 | - subsystem for high-resolution kernel timers | 10 | - subsystem for high-resolution kernel timers |
| 11 | Makefile | ||
| 12 | - Build and link hpet_example | ||
| 11 | NO_HZ.txt | 13 | NO_HZ.txt |
| 12 | - Summary of the different methods for the scheduler clock-interrupts management. | 14 | - Summary of the different methods for the scheduler clock-interrupts management. |
| 13 | timers-howto.txt | 15 | timers-howto.txt |
diff --git a/Documentation/virtual/kvm/00-INDEX b/Documentation/virtual/kvm/00-INDEX index 641ec9220179..fee9f2bf9c64 100644 --- a/Documentation/virtual/kvm/00-INDEX +++ b/Documentation/virtual/kvm/00-INDEX | |||
| @@ -20,5 +20,7 @@ ppc-pv.txt | |||
| 20 | - the paravirtualization interface on PowerPC. | 20 | - the paravirtualization interface on PowerPC. |
| 21 | review-checklist.txt | 21 | review-checklist.txt |
| 22 | - review checklist for KVM patches. | 22 | - review checklist for KVM patches. |
| 23 | s390-diag.txt | ||
| 24 | - Diagnose hypercall description (for IBM S/390) | ||
| 23 | timekeeping.txt | 25 | timekeeping.txt |
| 24 | - timekeeping virtualization for x86-based architectures. | 26 | - timekeeping virtualization for x86-based architectures. |
diff --git a/Documentation/vm/00-INDEX b/Documentation/vm/00-INDEX index a39d06680e1c..081c49777abb 100644 --- a/Documentation/vm/00-INDEX +++ b/Documentation/vm/00-INDEX | |||
| @@ -16,8 +16,6 @@ hwpoison.txt | |||
| 16 | - explains what hwpoison is | 16 | - explains what hwpoison is |
| 17 | ksm.txt | 17 | ksm.txt |
| 18 | - how to use the Kernel Samepage Merging feature. | 18 | - how to use the Kernel Samepage Merging feature. |
| 19 | locking | ||
| 20 | - info on how locking and synchronization is done in the Linux vm code. | ||
| 21 | numa | 19 | numa |
| 22 | - information about NUMA specific code in the Linux vm. | 20 | - information about NUMA specific code in the Linux vm. |
| 23 | numa_memory_policy.txt | 21 | numa_memory_policy.txt |
| @@ -32,6 +30,8 @@ slub.txt | |||
| 32 | - a short users guide for SLUB. | 30 | - a short users guide for SLUB. |
| 33 | soft-dirty.txt | 31 | soft-dirty.txt |
| 34 | - short explanation for soft-dirty PTEs | 32 | - short explanation for soft-dirty PTEs |
| 33 | split_page_table_lock | ||
| 34 | - Separate per-table lock to improve scalability of the old page_table_lock. | ||
| 35 | transhuge.txt | 35 | transhuge.txt |
| 36 | - Transparent Hugepage Support, alternative way of using hugepages. | 36 | - Transparent Hugepage Support, alternative way of using hugepages. |
| 37 | unevictable-lru.txt | 37 | unevictable-lru.txt |
diff --git a/Documentation/w1/masters/00-INDEX b/Documentation/w1/masters/00-INDEX index d63fa024ac05..8330cf9325f0 100644 --- a/Documentation/w1/masters/00-INDEX +++ b/Documentation/w1/masters/00-INDEX | |||
| @@ -4,7 +4,9 @@ ds2482 | |||
| 4 | - The Maxim/Dallas Semiconductor DS2482 provides 1-wire busses. | 4 | - The Maxim/Dallas Semiconductor DS2482 provides 1-wire busses. |
| 5 | ds2490 | 5 | ds2490 |
| 6 | - The Maxim/Dallas Semiconductor DS2490 builds USB <-> W1 bridges. | 6 | - The Maxim/Dallas Semiconductor DS2490 builds USB <-> W1 bridges. |
| 7 | mxc_w1 | 7 | mxc-w1 |
| 8 | - W1 master controller driver found on Freescale MX2/MX3 SoCs | 8 | - W1 master controller driver found on Freescale MX2/MX3 SoCs |
| 9 | omap-hdq | ||
| 10 | - HDQ/1-wire module of TI OMAP 2430/3430. | ||
| 9 | w1-gpio | 11 | w1-gpio |
| 10 | - GPIO 1-wire bus master driver. | 12 | - GPIO 1-wire bus master driver. |
diff --git a/Documentation/w1/slaves/00-INDEX b/Documentation/w1/slaves/00-INDEX index 75613c9ac4db..6e18c70c3474 100644 --- a/Documentation/w1/slaves/00-INDEX +++ b/Documentation/w1/slaves/00-INDEX | |||
| @@ -4,3 +4,5 @@ w1_therm | |||
| 4 | - The Maxim/Dallas Semiconductor ds18*20 temperature sensor. | 4 | - The Maxim/Dallas Semiconductor ds18*20 temperature sensor. |
| 5 | w1_ds2423 | 5 | w1_ds2423 |
| 6 | - The Maxim/Dallas Semiconductor ds2423 counter device. | 6 | - The Maxim/Dallas Semiconductor ds2423 counter device. |
| 7 | w1_ds28e04 | ||
| 8 | - The Maxim/Dallas Semiconductor ds28e04 eeprom. | ||
diff --git a/Documentation/x86/00-INDEX b/Documentation/x86/00-INDEX index f37b46d34861..692264456f0f 100644 --- a/Documentation/x86/00-INDEX +++ b/Documentation/x86/00-INDEX | |||
| @@ -1,6 +1,20 @@ | |||
| 1 | 00-INDEX | 1 | 00-INDEX |
| 2 | - this file | 2 | - this file |
| 3 | mtrr.txt | 3 | boot.txt |
| 4 | - how to use x86 Memory Type Range Registers to increase performance | 4 | - List of boot protocol versions |
| 5 | early-microcode.txt | ||
| 6 | - How to load microcode from an initrd-CPIO archive early to fix CPU issues. | ||
| 7 | earlyprintk.txt | ||
| 8 | - Using earlyprintk with a USB2 debug port key. | ||
| 9 | entry_64.txt | ||
| 10 | - Describe (some of the) kernel entry points for x86. | ||
| 5 | exception-tables.txt | 11 | exception-tables.txt |
| 6 | - why and how Linux kernel uses exception tables on x86 | 12 | - why and how Linux kernel uses exception tables on x86 |
| 13 | mtrr.txt | ||
| 14 | - how to use x86 Memory Type Range Registers to increase performance | ||
| 15 | pat.txt | ||
| 16 | - Page Attribute Table intro and API | ||
| 17 | usb-legacy-support.txt | ||
| 18 | - how to fix/avoid quirks when using emulated PS/2 mouse/keyboard. | ||
| 19 | zero-page.txt | ||
| 20 | - layout of the first page of memory. | ||
diff --git a/MAINTAINERS b/MAINTAINERS index b2cf5cfb4d29..091b50edaf35 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -7196,7 +7196,7 @@ S: Maintained | |||
| 7196 | F: drivers/net/ethernet/rdc/r6040.c | 7196 | F: drivers/net/ethernet/rdc/r6040.c |
| 7197 | 7197 | ||
| 7198 | RDS - RELIABLE DATAGRAM SOCKETS | 7198 | RDS - RELIABLE DATAGRAM SOCKETS |
| 7199 | M: Venkat Venkatsubra <venkat.x.venkatsubra@oracle.com> | 7199 | M: Chien Yen <chien.yen@oracle.com> |
| 7200 | L: rds-devel@oss.oracle.com (moderated for non-subscribers) | 7200 | L: rds-devel@oss.oracle.com (moderated for non-subscribers) |
| 7201 | S: Supported | 7201 | S: Supported |
| 7202 | F: net/rds/ | 7202 | F: net/rds/ |
diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi index 040bb0eba152..10666ca8aee1 100644 --- a/arch/arm/boot/dts/sun4i-a10.dtsi +++ b/arch/arm/boot/dts/sun4i-a10.dtsi | |||
| @@ -315,7 +315,7 @@ | |||
| 315 | ranges; | 315 | ranges; |
| 316 | 316 | ||
| 317 | emac: ethernet@01c0b000 { | 317 | emac: ethernet@01c0b000 { |
| 318 | compatible = "allwinner,sun4i-emac"; | 318 | compatible = "allwinner,sun4i-a10-emac"; |
| 319 | reg = <0x01c0b000 0x1000>; | 319 | reg = <0x01c0b000 0x1000>; |
| 320 | interrupts = <55>; | 320 | interrupts = <55>; |
| 321 | clocks = <&ahb_gates 17>; | 321 | clocks = <&ahb_gates 17>; |
| @@ -323,7 +323,7 @@ | |||
| 323 | }; | 323 | }; |
| 324 | 324 | ||
| 325 | mdio@01c0b080 { | 325 | mdio@01c0b080 { |
| 326 | compatible = "allwinner,sun4i-mdio"; | 326 | compatible = "allwinner,sun4i-a10-mdio"; |
| 327 | reg = <0x01c0b080 0x14>; | 327 | reg = <0x01c0b080 0x14>; |
| 328 | status = "disabled"; | 328 | status = "disabled"; |
| 329 | #address-cells = <1>; | 329 | #address-cells = <1>; |
diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi index ea16054857a4..64961595e8d6 100644 --- a/arch/arm/boot/dts/sun5i-a10s.dtsi +++ b/arch/arm/boot/dts/sun5i-a10s.dtsi | |||
| @@ -278,7 +278,7 @@ | |||
| 278 | ranges; | 278 | ranges; |
| 279 | 279 | ||
| 280 | emac: ethernet@01c0b000 { | 280 | emac: ethernet@01c0b000 { |
| 281 | compatible = "allwinner,sun4i-emac"; | 281 | compatible = "allwinner,sun4i-a10-emac"; |
| 282 | reg = <0x01c0b000 0x1000>; | 282 | reg = <0x01c0b000 0x1000>; |
| 283 | interrupts = <55>; | 283 | interrupts = <55>; |
| 284 | clocks = <&ahb_gates 17>; | 284 | clocks = <&ahb_gates 17>; |
| @@ -286,7 +286,7 @@ | |||
| 286 | }; | 286 | }; |
| 287 | 287 | ||
| 288 | mdio@01c0b080 { | 288 | mdio@01c0b080 { |
| 289 | compatible = "allwinner,sun4i-mdio"; | 289 | compatible = "allwinner,sun4i-a10-mdio"; |
| 290 | reg = <0x01c0b080 0x14>; | 290 | reg = <0x01c0b080 0x14>; |
| 291 | status = "disabled"; | 291 | status = "disabled"; |
| 292 | #address-cells = <1>; | 292 | #address-cells = <1>; |
diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi index 119f066f0d98..9ff09484847b 100644 --- a/arch/arm/boot/dts/sun7i-a20.dtsi +++ b/arch/arm/boot/dts/sun7i-a20.dtsi | |||
| @@ -340,7 +340,7 @@ | |||
| 340 | ranges; | 340 | ranges; |
| 341 | 341 | ||
| 342 | emac: ethernet@01c0b000 { | 342 | emac: ethernet@01c0b000 { |
| 343 | compatible = "allwinner,sun4i-emac"; | 343 | compatible = "allwinner,sun4i-a10-emac"; |
| 344 | reg = <0x01c0b000 0x1000>; | 344 | reg = <0x01c0b000 0x1000>; |
| 345 | interrupts = <0 55 4>; | 345 | interrupts = <0 55 4>; |
| 346 | clocks = <&ahb_gates 17>; | 346 | clocks = <&ahb_gates 17>; |
| @@ -348,7 +348,7 @@ | |||
| 348 | }; | 348 | }; |
| 349 | 349 | ||
| 350 | mdio@01c0b080 { | 350 | mdio@01c0b080 { |
| 351 | compatible = "allwinner,sun4i-mdio"; | 351 | compatible = "allwinner,sun4i-a10-mdio"; |
| 352 | reg = <0x01c0b080 0x14>; | 352 | reg = <0x01c0b080 0x14>; |
| 353 | status = "disabled"; | 353 | status = "disabled"; |
| 354 | #address-cells = <1>; | 354 | #address-cells = <1>; |
diff --git a/arch/microblaze/include/asm/delay.h b/arch/microblaze/include/asm/delay.h index 05b7d39e4391..66fc24c24238 100644 --- a/arch/microblaze/include/asm/delay.h +++ b/arch/microblaze/include/asm/delay.h | |||
| @@ -13,6 +13,8 @@ | |||
| 13 | #ifndef _ASM_MICROBLAZE_DELAY_H | 13 | #ifndef _ASM_MICROBLAZE_DELAY_H |
| 14 | #define _ASM_MICROBLAZE_DELAY_H | 14 | #define _ASM_MICROBLAZE_DELAY_H |
| 15 | 15 | ||
| 16 | #include <linux/param.h> | ||
| 17 | |||
| 16 | extern inline void __delay(unsigned long loops) | 18 | extern inline void __delay(unsigned long loops) |
| 17 | { | 19 | { |
| 18 | asm volatile ("# __delay \n\t" \ | 20 | asm volatile ("# __delay \n\t" \ |
diff --git a/arch/microblaze/include/asm/io.h b/arch/microblaze/include/asm/io.h index a2cea7206077..3fbb7f1db3bc 100644 --- a/arch/microblaze/include/asm/io.h +++ b/arch/microblaze/include/asm/io.h | |||
| @@ -89,6 +89,11 @@ static inline unsigned int readl(const volatile void __iomem *addr) | |||
| 89 | { | 89 | { |
| 90 | return le32_to_cpu(*(volatile unsigned int __force *)addr); | 90 | return le32_to_cpu(*(volatile unsigned int __force *)addr); |
| 91 | } | 91 | } |
| 92 | #define readq readq | ||
| 93 | static inline u64 readq(const volatile void __iomem *addr) | ||
| 94 | { | ||
| 95 | return le64_to_cpu(__raw_readq(addr)); | ||
| 96 | } | ||
| 92 | static inline void writeb(unsigned char v, volatile void __iomem *addr) | 97 | static inline void writeb(unsigned char v, volatile void __iomem *addr) |
| 93 | { | 98 | { |
| 94 | *(volatile unsigned char __force *)addr = v; | 99 | *(volatile unsigned char __force *)addr = v; |
| @@ -101,6 +106,7 @@ static inline void writel(unsigned int v, volatile void __iomem *addr) | |||
| 101 | { | 106 | { |
| 102 | *(volatile unsigned int __force *)addr = cpu_to_le32(v); | 107 | *(volatile unsigned int __force *)addr = cpu_to_le32(v); |
| 103 | } | 108 | } |
| 109 | #define writeq(b, addr) __raw_writeq(cpu_to_le64(b), addr) | ||
| 104 | 110 | ||
| 105 | /* ioread and iowrite variants. thease are for now same as __raw_ | 111 | /* ioread and iowrite variants. thease are for now same as __raw_ |
| 106 | * variants of accessors. we might check for endianess in the feature | 112 | * variants of accessors. we might check for endianess in the feature |
diff --git a/arch/microblaze/kernel/head.S b/arch/microblaze/kernel/head.S index b7fb0438458c..17645b2e2f07 100644 --- a/arch/microblaze/kernel/head.S +++ b/arch/microblaze/kernel/head.S | |||
| @@ -66,7 +66,7 @@ real_start: | |||
| 66 | mts rmsr, r0 | 66 | mts rmsr, r0 |
| 67 | /* Disable stack protection from bootloader */ | 67 | /* Disable stack protection from bootloader */ |
| 68 | mts rslr, r0 | 68 | mts rslr, r0 |
| 69 | addi r8, r0, 0xFFFFFFF | 69 | addi r8, r0, 0xFFFFFFFF |
| 70 | mts rshr, r8 | 70 | mts rshr, r8 |
| 71 | /* | 71 | /* |
| 72 | * According to Xilinx, msrclr instruction behaves like 'mfs rX,rpc' | 72 | * According to Xilinx, msrclr instruction behaves like 'mfs rX,rpc' |
diff --git a/arch/s390/appldata/appldata_base.c b/arch/s390/appldata/appldata_base.c index 4c4a1cef5208..47c8630c93cd 100644 --- a/arch/s390/appldata/appldata_base.c +++ b/arch/s390/appldata/appldata_base.c | |||
| @@ -529,6 +529,7 @@ static int __init appldata_init(void) | |||
| 529 | { | 529 | { |
| 530 | int rc; | 530 | int rc; |
| 531 | 531 | ||
| 532 | init_virt_timer(&appldata_timer); | ||
| 532 | appldata_timer.function = appldata_timer_function; | 533 | appldata_timer.function = appldata_timer_function; |
| 533 | appldata_timer.data = (unsigned long) &appldata_work; | 534 | appldata_timer.data = (unsigned long) &appldata_work; |
| 534 | 535 | ||
diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S index b9e25ae2579c..d7c00507568a 100644 --- a/arch/s390/kernel/head64.S +++ b/arch/s390/kernel/head64.S | |||
| @@ -59,7 +59,7 @@ ENTRY(startup_continue) | |||
| 59 | .quad 0 # cr12: tracing off | 59 | .quad 0 # cr12: tracing off |
| 60 | .quad 0 # cr13: home space segment table | 60 | .quad 0 # cr13: home space segment table |
| 61 | .quad 0xc0000000 # cr14: machine check handling off | 61 | .quad 0xc0000000 # cr14: machine check handling off |
| 62 | .quad 0 # cr15: linkage stack operations | 62 | .quad .Llinkage_stack # cr15: linkage stack operations |
| 63 | .Lpcmsk:.quad 0x0000000180000000 | 63 | .Lpcmsk:.quad 0x0000000180000000 |
| 64 | .L4malign:.quad 0xffffffffffc00000 | 64 | .L4malign:.quad 0xffffffffffc00000 |
| 65 | .Lscan2g:.quad 0x80000000 + 0x20000 - 8 # 2GB + 128K - 8 | 65 | .Lscan2g:.quad 0x80000000 + 0x20000 - 8 # 2GB + 128K - 8 |
| @@ -67,12 +67,15 @@ ENTRY(startup_continue) | |||
| 67 | .Lparmaddr: | 67 | .Lparmaddr: |
| 68 | .quad PARMAREA | 68 | .quad PARMAREA |
| 69 | .align 64 | 69 | .align 64 |
| 70 | .Lduct: .long 0,0,0,0,.Lduald,0,0,0 | 70 | .Lduct: .long 0,.Laste,.Laste,0,.Lduald,0,0,0 |
| 71 | .long 0,0,0,0,0,0,0,0 | 71 | .long 0,0,0,0,0,0,0,0 |
| 72 | .Laste: .quad 0,0xffffffffffffffff,0,0,0,0,0,0 | ||
| 72 | .align 128 | 73 | .align 128 |
| 73 | .Lduald:.rept 8 | 74 | .Lduald:.rept 8 |
| 74 | .long 0x80000000,0,0,0 # invalid access-list entries | 75 | .long 0x80000000,0,0,0 # invalid access-list entries |
| 75 | .endr | 76 | .endr |
| 77 | .Llinkage_stack: | ||
| 78 | .long 0,0,0x89000000,0,0,0,0x8a000000,0 | ||
| 76 | 79 | ||
| 77 | ENTRY(_ehead) | 80 | ENTRY(_ehead) |
| 78 | 81 | ||
diff --git a/arch/s390/mm/page-states.c b/arch/s390/mm/page-states.c index a90d45e9dfb0..27c50f4d90cb 100644 --- a/arch/s390/mm/page-states.c +++ b/arch/s390/mm/page-states.c | |||
| @@ -12,6 +12,8 @@ | |||
| 12 | #include <linux/mm.h> | 12 | #include <linux/mm.h> |
| 13 | #include <linux/gfp.h> | 13 | #include <linux/gfp.h> |
| 14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
| 15 | #include <asm/setup.h> | ||
| 16 | #include <asm/ipl.h> | ||
| 15 | 17 | ||
| 16 | #define ESSA_SET_STABLE 1 | 18 | #define ESSA_SET_STABLE 1 |
| 17 | #define ESSA_SET_UNUSED 2 | 19 | #define ESSA_SET_UNUSED 2 |
| @@ -41,6 +43,14 @@ void __init cmma_init(void) | |||
| 41 | 43 | ||
| 42 | if (!cmma_flag) | 44 | if (!cmma_flag) |
| 43 | return; | 45 | return; |
| 46 | /* | ||
| 47 | * Disable CMM for dump, otherwise the tprot based memory | ||
| 48 | * detection can fail because of unstable pages. | ||
| 49 | */ | ||
| 50 | if (OLDMEM_BASE || ipl_info.type == IPL_TYPE_FCP_DUMP) { | ||
| 51 | cmma_flag = 0; | ||
| 52 | return; | ||
| 53 | } | ||
| 44 | asm volatile( | 54 | asm volatile( |
| 45 | " .insn rrf,0xb9ab0000,%1,%1,0,0\n" | 55 | " .insn rrf,0xb9ab0000,%1,%1,0,0\n" |
| 46 | "0: la %0,0\n" | 56 | "0: la %0,0\n" |
diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index bbc8b12fa443..5ad38ad07890 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h | |||
| @@ -445,10 +445,20 @@ static inline int pte_same(pte_t a, pte_t b) | |||
| 445 | return a.pte == b.pte; | 445 | return a.pte == b.pte; |
| 446 | } | 446 | } |
| 447 | 447 | ||
| 448 | static inline int pteval_present(pteval_t pteval) | ||
| 449 | { | ||
| 450 | /* | ||
| 451 | * Yes Linus, _PAGE_PROTNONE == _PAGE_NUMA. Expressing it this | ||
| 452 | * way clearly states that the intent is that protnone and numa | ||
| 453 | * hinting ptes are considered present for the purposes of | ||
| 454 | * pagetable operations like zapping, protection changes, gup etc. | ||
| 455 | */ | ||
| 456 | return pteval & (_PAGE_PRESENT | _PAGE_PROTNONE | _PAGE_NUMA); | ||
| 457 | } | ||
| 458 | |||
| 448 | static inline int pte_present(pte_t a) | 459 | static inline int pte_present(pte_t a) |
| 449 | { | 460 | { |
| 450 | return pte_flags(a) & (_PAGE_PRESENT | _PAGE_PROTNONE | | 461 | return pteval_present(pte_flags(a)); |
| 451 | _PAGE_NUMA); | ||
| 452 | } | 462 | } |
| 453 | 463 | ||
| 454 | #define pte_accessible pte_accessible | 464 | #define pte_accessible pte_accessible |
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index 2423ef04ffea..256282e7888b 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c | |||
| @@ -365,7 +365,7 @@ void xen_ptep_modify_prot_commit(struct mm_struct *mm, unsigned long addr, | |||
| 365 | /* Assume pteval_t is equivalent to all the other *val_t types. */ | 365 | /* Assume pteval_t is equivalent to all the other *val_t types. */ |
| 366 | static pteval_t pte_mfn_to_pfn(pteval_t val) | 366 | static pteval_t pte_mfn_to_pfn(pteval_t val) |
| 367 | { | 367 | { |
| 368 | if (val & _PAGE_PRESENT) { | 368 | if (pteval_present(val)) { |
| 369 | unsigned long mfn = (val & PTE_PFN_MASK) >> PAGE_SHIFT; | 369 | unsigned long mfn = (val & PTE_PFN_MASK) >> PAGE_SHIFT; |
| 370 | unsigned long pfn = mfn_to_pfn(mfn); | 370 | unsigned long pfn = mfn_to_pfn(mfn); |
| 371 | 371 | ||
| @@ -381,7 +381,7 @@ static pteval_t pte_mfn_to_pfn(pteval_t val) | |||
| 381 | 381 | ||
| 382 | static pteval_t pte_pfn_to_mfn(pteval_t val) | 382 | static pteval_t pte_pfn_to_mfn(pteval_t val) |
| 383 | { | 383 | { |
| 384 | if (val & _PAGE_PRESENT) { | 384 | if (pteval_present(val)) { |
| 385 | unsigned long pfn = (val & PTE_PFN_MASK) >> PAGE_SHIFT; | 385 | unsigned long pfn = (val & PTE_PFN_MASK) >> PAGE_SHIFT; |
| 386 | pteval_t flags = val & PTE_FLAGS_MASK; | 386 | pteval_t flags = val & PTE_FLAGS_MASK; |
| 387 | unsigned long mfn; | 387 | unsigned long mfn; |
diff --git a/drivers/edac/edac_mc_sysfs.c b/drivers/edac/edac_mc_sysfs.c index 51c0362acf5c..8ec1747b1c39 100644 --- a/drivers/edac/edac_mc_sysfs.c +++ b/drivers/edac/edac_mc_sysfs.c | |||
| @@ -61,7 +61,7 @@ static int edac_set_poll_msec(const char *val, struct kernel_param *kp) | |||
| 61 | ret = kstrtol(val, 0, &l); | 61 | ret = kstrtol(val, 0, &l); |
| 62 | if (ret) | 62 | if (ret) |
| 63 | return ret; | 63 | return ret; |
| 64 | if ((int)l != l) | 64 | if (!l || ((int)l != l)) |
| 65 | return -EINVAL; | 65 | return -EINVAL; |
| 66 | *((int *)kp->arg) = l; | 66 | *((int *)kp->arg) = l; |
| 67 | 67 | ||
diff --git a/drivers/isdn/hisax/q931.c b/drivers/isdn/hisax/q931.c index af1b020a81f1..b420f8bd862e 100644 --- a/drivers/isdn/hisax/q931.c +++ b/drivers/isdn/hisax/q931.c | |||
| @@ -810,7 +810,7 @@ prfeatureind(char *dest, u_char *p) | |||
| 810 | dp += sprintf(dp, " octet 3 "); | 810 | dp += sprintf(dp, " octet 3 "); |
| 811 | dp += prbits(dp, *p, 8, 8); | 811 | dp += prbits(dp, *p, 8, 8); |
| 812 | *dp++ = '\n'; | 812 | *dp++ = '\n'; |
| 813 | if (!(*p++ & 80)) { | 813 | if (!(*p++ & 0x80)) { |
| 814 | dp += sprintf(dp, " octet 4 "); | 814 | dp += sprintf(dp, " octet 4 "); |
| 815 | dp += prbits(dp, *p++, 8, 8); | 815 | dp += prbits(dp, *p++, 8, 8); |
| 816 | *dp++ = '\n'; | 816 | *dp++ = '\n'; |
diff --git a/drivers/md/bcache/extents.c b/drivers/md/bcache/extents.c index c3ead586dc27..416d1a3e028e 100644 --- a/drivers/md/bcache/extents.c +++ b/drivers/md/bcache/extents.c | |||
| @@ -194,7 +194,7 @@ err: | |||
| 194 | mutex_unlock(&b->c->bucket_lock); | 194 | mutex_unlock(&b->c->bucket_lock); |
| 195 | bch_extent_to_text(buf, sizeof(buf), k); | 195 | bch_extent_to_text(buf, sizeof(buf), k); |
| 196 | btree_bug(b, | 196 | btree_bug(b, |
| 197 | "inconsistent btree pointer %s: bucket %li pin %i prio %i gen %i last_gc %i mark %llu gc_gen %i", | 197 | "inconsistent btree pointer %s: bucket %zi pin %i prio %i gen %i last_gc %i mark %llu gc_gen %i", |
| 198 | buf, PTR_BUCKET_NR(b->c, k, i), atomic_read(&g->pin), | 198 | buf, PTR_BUCKET_NR(b->c, k, i), atomic_read(&g->pin), |
| 199 | g->prio, g->gen, g->last_gc, GC_MARK(g), g->gc_gen); | 199 | g->prio, g->gen, g->last_gc, GC_MARK(g), g->gc_gen); |
| 200 | return true; | 200 | return true; |
diff --git a/drivers/message/i2o/i2o_config.c b/drivers/message/i2o/i2o_config.c index a60c188c2bd9..04bd3b6de401 100644 --- a/drivers/message/i2o/i2o_config.c +++ b/drivers/message/i2o/i2o_config.c | |||
| @@ -754,19 +754,19 @@ static long i2o_cfg_compat_ioctl(struct file *file, unsigned cmd, | |||
| 754 | unsigned long arg) | 754 | unsigned long arg) |
| 755 | { | 755 | { |
| 756 | int ret; | 756 | int ret; |
| 757 | mutex_lock(&i2o_cfg_mutex); | ||
| 758 | switch (cmd) { | 757 | switch (cmd) { |
| 759 | case I2OGETIOPS: | 758 | case I2OGETIOPS: |
| 760 | ret = i2o_cfg_ioctl(file, cmd, arg); | 759 | ret = i2o_cfg_ioctl(file, cmd, arg); |
| 761 | break; | 760 | break; |
| 762 | case I2OPASSTHRU32: | 761 | case I2OPASSTHRU32: |
| 762 | mutex_lock(&i2o_cfg_mutex); | ||
| 763 | ret = i2o_cfg_passthru32(file, cmd, arg); | 763 | ret = i2o_cfg_passthru32(file, cmd, arg); |
| 764 | mutex_unlock(&i2o_cfg_mutex); | ||
| 764 | break; | 765 | break; |
| 765 | default: | 766 | default: |
| 766 | ret = -ENOIOCTLCMD; | 767 | ret = -ENOIOCTLCMD; |
| 767 | break; | 768 | break; |
| 768 | } | 769 | } |
| 769 | mutex_unlock(&i2o_cfg_mutex); | ||
| 770 | return ret; | 770 | return ret; |
| 771 | } | 771 | } |
| 772 | 772 | ||
diff --git a/drivers/misc/sgi-gru/grukdump.c b/drivers/misc/sgi-gru/grukdump.c index 9b2062d17327..2bef3f76032a 100644 --- a/drivers/misc/sgi-gru/grukdump.c +++ b/drivers/misc/sgi-gru/grukdump.c | |||
| @@ -139,8 +139,11 @@ static int gru_dump_context(struct gru_state *gru, int ctxnum, | |||
| 139 | 139 | ||
| 140 | ubuf += sizeof(hdr); | 140 | ubuf += sizeof(hdr); |
| 141 | ubufcch = ubuf; | 141 | ubufcch = ubuf; |
| 142 | if (gru_user_copy_handle(&ubuf, cch)) | 142 | if (gru_user_copy_handle(&ubuf, cch)) { |
| 143 | goto fail; | 143 | if (cch_locked) |
| 144 | unlock_cch_handle(cch); | ||
| 145 | return -EFAULT; | ||
| 146 | } | ||
| 144 | if (cch_locked) | 147 | if (cch_locked) |
| 145 | ubufcch->delresp = 0; | 148 | ubufcch->delresp = 0; |
| 146 | bytes = sizeof(hdr) + GRU_CACHE_LINE_BYTES; | 149 | bytes = sizeof(hdr) + GRU_CACHE_LINE_BYTES; |
| @@ -179,10 +182,6 @@ static int gru_dump_context(struct gru_state *gru, int ctxnum, | |||
| 179 | ret = -EFAULT; | 182 | ret = -EFAULT; |
| 180 | 183 | ||
| 181 | return ret ? ret : bytes; | 184 | return ret ? ret : bytes; |
| 182 | |||
| 183 | fail: | ||
| 184 | unlock_cch_handle(cch); | ||
| 185 | return -EFAULT; | ||
| 186 | } | 185 | } |
| 187 | 186 | ||
| 188 | int gru_dump_chiplet_request(unsigned long arg) | 187 | int gru_dump_chiplet_request(unsigned long arg) |
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 4c08018d7333..71ba18efa15b 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
| @@ -1270,9 +1270,13 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
| 1270 | 1270 | ||
| 1271 | if (slave_ops->ndo_set_mac_address == NULL) { | 1271 | if (slave_ops->ndo_set_mac_address == NULL) { |
| 1272 | if (!bond_has_slaves(bond)) { | 1272 | if (!bond_has_slaves(bond)) { |
| 1273 | pr_warning("%s: Warning: The first slave device specified does not support setting the MAC address. Setting fail_over_mac to active.", | 1273 | pr_warn("%s: Warning: The first slave device specified does not support setting the MAC address.\n", |
| 1274 | bond_dev->name); | 1274 | bond_dev->name); |
| 1275 | bond->params.fail_over_mac = BOND_FOM_ACTIVE; | 1275 | if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) { |
| 1276 | bond->params.fail_over_mac = BOND_FOM_ACTIVE; | ||
| 1277 | pr_warn("%s: Setting fail_over_mac to active for active-backup mode.\n", | ||
| 1278 | bond_dev->name); | ||
| 1279 | } | ||
| 1276 | } else if (bond->params.fail_over_mac != BOND_FOM_ACTIVE) { | 1280 | } else if (bond->params.fail_over_mac != BOND_FOM_ACTIVE) { |
| 1277 | pr_err("%s: Error: The slave device specified does not support setting the MAC address, but fail_over_mac is not set to active.\n", | 1281 | pr_err("%s: Error: The slave device specified does not support setting the MAC address, but fail_over_mac is not set to active.\n", |
| 1278 | bond_dev->name); | 1282 | bond_dev->name); |
| @@ -1315,7 +1319,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
| 1315 | */ | 1319 | */ |
| 1316 | memcpy(new_slave->perm_hwaddr, slave_dev->dev_addr, ETH_ALEN); | 1320 | memcpy(new_slave->perm_hwaddr, slave_dev->dev_addr, ETH_ALEN); |
| 1317 | 1321 | ||
| 1318 | if (!bond->params.fail_over_mac) { | 1322 | if (!bond->params.fail_over_mac || |
| 1323 | bond->params.mode != BOND_MODE_ACTIVEBACKUP) { | ||
| 1319 | /* | 1324 | /* |
| 1320 | * Set slave to master's mac address. The application already | 1325 | * Set slave to master's mac address. The application already |
| 1321 | * set the master's mac address to that of the first slave | 1326 | * set the master's mac address to that of the first slave |
| @@ -1505,7 +1510,6 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
| 1505 | slave_dev->npinfo = bond->dev->npinfo; | 1510 | slave_dev->npinfo = bond->dev->npinfo; |
| 1506 | if (slave_dev->npinfo) { | 1511 | if (slave_dev->npinfo) { |
| 1507 | if (slave_enable_netpoll(new_slave)) { | 1512 | if (slave_enable_netpoll(new_slave)) { |
| 1508 | read_unlock(&bond->lock); | ||
| 1509 | pr_info("Error, %s: master_dev is using netpoll, " | 1513 | pr_info("Error, %s: master_dev is using netpoll, " |
| 1510 | "but new slave device does not support netpoll.\n", | 1514 | "but new slave device does not support netpoll.\n", |
| 1511 | bond_dev->name); | 1515 | bond_dev->name); |
| @@ -1579,7 +1583,8 @@ err_close: | |||
| 1579 | dev_close(slave_dev); | 1583 | dev_close(slave_dev); |
| 1580 | 1584 | ||
| 1581 | err_restore_mac: | 1585 | err_restore_mac: |
| 1582 | if (!bond->params.fail_over_mac) { | 1586 | if (!bond->params.fail_over_mac || |
| 1587 | bond->params.mode != BOND_MODE_ACTIVEBACKUP) { | ||
| 1583 | /* XXX TODO - fom follow mode needs to change master's | 1588 | /* XXX TODO - fom follow mode needs to change master's |
| 1584 | * MAC if this slave's MAC is in use by the bond, or at | 1589 | * MAC if this slave's MAC is in use by the bond, or at |
| 1585 | * least print a warning. | 1590 | * least print a warning. |
| @@ -1672,7 +1677,8 @@ static int __bond_release_one(struct net_device *bond_dev, | |||
| 1672 | 1677 | ||
| 1673 | bond->current_arp_slave = NULL; | 1678 | bond->current_arp_slave = NULL; |
| 1674 | 1679 | ||
| 1675 | if (!all && !bond->params.fail_over_mac) { | 1680 | if (!all && (!bond->params.fail_over_mac || |
| 1681 | bond->params.mode != BOND_MODE_ACTIVEBACKUP)) { | ||
| 1676 | if (ether_addr_equal_64bits(bond_dev->dev_addr, slave->perm_hwaddr) && | 1682 | if (ether_addr_equal_64bits(bond_dev->dev_addr, slave->perm_hwaddr) && |
| 1677 | bond_has_slaves(bond)) | 1683 | bond_has_slaves(bond)) |
| 1678 | pr_warn("%s: Warning: the permanent HWaddr of %s - %pM - is still in use by %s. Set the HWaddr of %s to a different address to avoid conflicts.\n", | 1684 | pr_warn("%s: Warning: the permanent HWaddr of %s - %pM - is still in use by %s. Set the HWaddr of %s to a different address to avoid conflicts.\n", |
| @@ -1769,7 +1775,8 @@ static int __bond_release_one(struct net_device *bond_dev, | |||
| 1769 | /* close slave before restoring its mac address */ | 1775 | /* close slave before restoring its mac address */ |
| 1770 | dev_close(slave_dev); | 1776 | dev_close(slave_dev); |
| 1771 | 1777 | ||
| 1772 | if (bond->params.fail_over_mac != BOND_FOM_ACTIVE) { | 1778 | if (bond->params.fail_over_mac != BOND_FOM_ACTIVE || |
| 1779 | bond->params.mode != BOND_MODE_ACTIVEBACKUP) { | ||
| 1773 | /* restore original ("permanent") mac address */ | 1780 | /* restore original ("permanent") mac address */ |
| 1774 | memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN); | 1781 | memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN); |
| 1775 | addr.sa_family = slave_dev->type; | 1782 | addr.sa_family = slave_dev->type; |
| @@ -3431,7 +3438,8 @@ static int bond_set_mac_address(struct net_device *bond_dev, void *addr) | |||
| 3431 | /* If fail_over_mac is enabled, do nothing and return success. | 3438 | /* If fail_over_mac is enabled, do nothing and return success. |
| 3432 | * Returning an error causes ifenslave to fail. | 3439 | * Returning an error causes ifenslave to fail. |
| 3433 | */ | 3440 | */ |
| 3434 | if (bond->params.fail_over_mac) | 3441 | if (bond->params.fail_over_mac && |
| 3442 | bond->params.mode == BOND_MODE_ACTIVEBACKUP) | ||
| 3435 | return 0; | 3443 | return 0; |
| 3436 | 3444 | ||
| 3437 | if (!is_valid_ether_addr(sa->sa_data)) | 3445 | if (!is_valid_ether_addr(sa->sa_data)) |
diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig index d447b881bbde..9e7d95dae2c7 100644 --- a/drivers/net/can/Kconfig +++ b/drivers/net/can/Kconfig | |||
| @@ -104,7 +104,7 @@ config CAN_JANZ_ICAN3 | |||
| 104 | 104 | ||
| 105 | config CAN_FLEXCAN | 105 | config CAN_FLEXCAN |
| 106 | tristate "Support for Freescale FLEXCAN based chips" | 106 | tristate "Support for Freescale FLEXCAN based chips" |
| 107 | depends on (ARM && CPU_LITTLE_ENDIAN) || PPC | 107 | depends on ARM || PPC |
| 108 | ---help--- | 108 | ---help--- |
| 109 | Say Y here if you want to support for Freescale FlexCAN. | 109 | Say Y here if you want to support for Freescale FlexCAN. |
| 110 | 110 | ||
diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c index 13a909822e25..fc59bc6f040b 100644 --- a/drivers/net/can/dev.c +++ b/drivers/net/can/dev.c | |||
| @@ -323,19 +323,10 @@ void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev, | |||
| 323 | } | 323 | } |
| 324 | 324 | ||
| 325 | if (!priv->echo_skb[idx]) { | 325 | if (!priv->echo_skb[idx]) { |
| 326 | struct sock *srcsk = skb->sk; | ||
| 327 | 326 | ||
| 328 | if (atomic_read(&skb->users) != 1) { | 327 | skb = can_create_echo_skb(skb); |
| 329 | struct sk_buff *old_skb = skb; | 328 | if (!skb) |
| 330 | 329 | return; | |
| 331 | skb = skb_clone(old_skb, GFP_ATOMIC); | ||
| 332 | kfree_skb(old_skb); | ||
| 333 | if (!skb) | ||
| 334 | return; | ||
| 335 | } else | ||
| 336 | skb_orphan(skb); | ||
| 337 | |||
| 338 | skb->sk = srcsk; | ||
| 339 | 330 | ||
| 340 | /* make settings for echo to reduce code in irq context */ | 331 | /* make settings for echo to reduce code in irq context */ |
| 341 | skb->protocol = htons(ETH_P_CAN); | 332 | skb->protocol = htons(ETH_P_CAN); |
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index aaed97bee471..320bef2dba42 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c | |||
| @@ -235,9 +235,12 @@ static const struct can_bittiming_const flexcan_bittiming_const = { | |||
| 235 | }; | 235 | }; |
| 236 | 236 | ||
| 237 | /* | 237 | /* |
| 238 | * Abstract off the read/write for arm versus ppc. | 238 | * Abstract off the read/write for arm versus ppc. This |
| 239 | * assumes that PPC uses big-endian registers and everything | ||
| 240 | * else uses little-endian registers, independent of CPU | ||
| 241 | * endianess. | ||
| 239 | */ | 242 | */ |
| 240 | #if defined(__BIG_ENDIAN) | 243 | #if defined(CONFIG_PPC) |
| 241 | static inline u32 flexcan_read(void __iomem *addr) | 244 | static inline u32 flexcan_read(void __iomem *addr) |
| 242 | { | 245 | { |
| 243 | return in_be32(addr); | 246 | return in_be32(addr); |
diff --git a/drivers/net/can/janz-ican3.c b/drivers/net/can/janz-ican3.c index e24e6690d672..71594e5676fd 100644 --- a/drivers/net/can/janz-ican3.c +++ b/drivers/net/can/janz-ican3.c | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include <linux/netdevice.h> | 18 | #include <linux/netdevice.h> |
| 19 | #include <linux/can.h> | 19 | #include <linux/can.h> |
| 20 | #include <linux/can/dev.h> | 20 | #include <linux/can/dev.h> |
| 21 | #include <linux/can/skb.h> | ||
| 21 | #include <linux/can/error.h> | 22 | #include <linux/can/error.h> |
| 22 | 23 | ||
| 23 | #include <linux/mfd/janz.h> | 24 | #include <linux/mfd/janz.h> |
| @@ -1133,20 +1134,9 @@ static void ican3_handle_message(struct ican3_dev *mod, struct ican3_msg *msg) | |||
| 1133 | */ | 1134 | */ |
| 1134 | static void ican3_put_echo_skb(struct ican3_dev *mod, struct sk_buff *skb) | 1135 | static void ican3_put_echo_skb(struct ican3_dev *mod, struct sk_buff *skb) |
| 1135 | { | 1136 | { |
| 1136 | struct sock *srcsk = skb->sk; | 1137 | skb = can_create_echo_skb(skb); |
| 1137 | 1138 | if (!skb) | |
| 1138 | if (atomic_read(&skb->users) != 1) { | 1139 | return; |
| 1139 | struct sk_buff *old_skb = skb; | ||
| 1140 | |||
| 1141 | skb = skb_clone(old_skb, GFP_ATOMIC); | ||
| 1142 | kfree_skb(old_skb); | ||
| 1143 | if (!skb) | ||
| 1144 | return; | ||
| 1145 | } else { | ||
| 1146 | skb_orphan(skb); | ||
| 1147 | } | ||
| 1148 | |||
| 1149 | skb->sk = srcsk; | ||
| 1150 | 1140 | ||
| 1151 | /* save this skb for tx interrupt echo handling */ | 1141 | /* save this skb for tx interrupt echo handling */ |
| 1152 | skb_queue_tail(&mod->echoq, skb); | 1142 | skb_queue_tail(&mod->echoq, skb); |
| @@ -1322,7 +1312,7 @@ static int ican3_napi(struct napi_struct *napi, int budget) | |||
| 1322 | 1312 | ||
| 1323 | /* process all communication messages */ | 1313 | /* process all communication messages */ |
| 1324 | while (true) { | 1314 | while (true) { |
| 1325 | struct ican3_msg msg; | 1315 | struct ican3_msg uninitialized_var(msg); |
| 1326 | ret = ican3_recv_msg(mod, &msg); | 1316 | ret = ican3_recv_msg(mod, &msg); |
| 1327 | if (ret) | 1317 | if (ret) |
| 1328 | break; | 1318 | break; |
diff --git a/drivers/net/can/vcan.c b/drivers/net/can/vcan.c index 0a2a5ee79a17..4e94057ef5cf 100644 --- a/drivers/net/can/vcan.c +++ b/drivers/net/can/vcan.c | |||
| @@ -46,6 +46,7 @@ | |||
| 46 | #include <linux/if_ether.h> | 46 | #include <linux/if_ether.h> |
| 47 | #include <linux/can.h> | 47 | #include <linux/can.h> |
| 48 | #include <linux/can/dev.h> | 48 | #include <linux/can/dev.h> |
| 49 | #include <linux/can/skb.h> | ||
| 49 | #include <linux/slab.h> | 50 | #include <linux/slab.h> |
| 50 | #include <net/rtnetlink.h> | 51 | #include <net/rtnetlink.h> |
| 51 | 52 | ||
| @@ -109,25 +110,23 @@ static netdev_tx_t vcan_tx(struct sk_buff *skb, struct net_device *dev) | |||
| 109 | stats->rx_packets++; | 110 | stats->rx_packets++; |
| 110 | stats->rx_bytes += cfd->len; | 111 | stats->rx_bytes += cfd->len; |
| 111 | } | 112 | } |
| 112 | kfree_skb(skb); | 113 | consume_skb(skb); |
| 113 | return NETDEV_TX_OK; | 114 | return NETDEV_TX_OK; |
| 114 | } | 115 | } |
| 115 | 116 | ||
| 116 | /* perform standard echo handling for CAN network interfaces */ | 117 | /* perform standard echo handling for CAN network interfaces */ |
| 117 | 118 | ||
| 118 | if (loop) { | 119 | if (loop) { |
| 119 | struct sock *srcsk = skb->sk; | ||
| 120 | 120 | ||
| 121 | skb = skb_share_check(skb, GFP_ATOMIC); | 121 | skb = can_create_echo_skb(skb); |
| 122 | if (!skb) | 122 | if (!skb) |
| 123 | return NETDEV_TX_OK; | 123 | return NETDEV_TX_OK; |
| 124 | 124 | ||
| 125 | /* receive with packet counting */ | 125 | /* receive with packet counting */ |
| 126 | skb->sk = srcsk; | ||
| 127 | vcan_rx(skb, dev); | 126 | vcan_rx(skb, dev); |
| 128 | } else { | 127 | } else { |
| 129 | /* no looped packets => no counting */ | 128 | /* no looped packets => no counting */ |
| 130 | kfree_skb(skb); | 129 | consume_skb(skb); |
| 131 | } | 130 | } |
| 132 | return NETDEV_TX_OK; | 131 | return NETDEV_TX_OK; |
| 133 | } | 132 | } |
diff --git a/drivers/net/ethernet/3com/3c59x.c b/drivers/net/ethernet/3com/3c59x.c index 0f4241c6e97e..238ccea965c8 100644 --- a/drivers/net/ethernet/3com/3c59x.c +++ b/drivers/net/ethernet/3com/3c59x.c | |||
| @@ -3294,7 +3294,6 @@ static int __init vortex_init(void) | |||
| 3294 | 3294 | ||
| 3295 | static void __exit vortex_eisa_cleanup(void) | 3295 | static void __exit vortex_eisa_cleanup(void) |
| 3296 | { | 3296 | { |
| 3297 | struct vortex_private *vp; | ||
| 3298 | void __iomem *ioaddr; | 3297 | void __iomem *ioaddr; |
| 3299 | 3298 | ||
| 3300 | #ifdef CONFIG_EISA | 3299 | #ifdef CONFIG_EISA |
| @@ -3303,7 +3302,6 @@ static void __exit vortex_eisa_cleanup(void) | |||
| 3303 | #endif | 3302 | #endif |
| 3304 | 3303 | ||
| 3305 | if (compaq_net_device) { | 3304 | if (compaq_net_device) { |
| 3306 | vp = netdev_priv(compaq_net_device); | ||
| 3307 | ioaddr = ioport_map(compaq_net_device->base_addr, | 3305 | ioaddr = ioport_map(compaq_net_device->base_addr, |
| 3308 | VORTEX_TOTAL_SIZE); | 3306 | VORTEX_TOTAL_SIZE); |
| 3309 | 3307 | ||
diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.c b/drivers/net/ethernet/allwinner/sun4i-emac.c index 0cc21437478c..511f6eecd58b 100644 --- a/drivers/net/ethernet/allwinner/sun4i-emac.c +++ b/drivers/net/ethernet/allwinner/sun4i-emac.c | |||
| @@ -929,6 +929,9 @@ static int emac_resume(struct platform_device *dev) | |||
| 929 | } | 929 | } |
| 930 | 930 | ||
| 931 | static const struct of_device_id emac_of_match[] = { | 931 | static const struct of_device_id emac_of_match[] = { |
| 932 | {.compatible = "allwinner,sun4i-a10-emac",}, | ||
| 933 | |||
| 934 | /* Deprecated */ | ||
| 932 | {.compatible = "allwinner,sun4i-emac",}, | 935 | {.compatible = "allwinner,sun4i-emac",}, |
| 933 | {}, | 936 | {}, |
| 934 | }; | 937 | }; |
diff --git a/drivers/net/ethernet/atheros/alx/main.c b/drivers/net/ethernet/atheros/alx/main.c index e92ffd6e1c15..2e45f6ec1bf0 100644 --- a/drivers/net/ethernet/atheros/alx/main.c +++ b/drivers/net/ethernet/atheros/alx/main.c | |||
| @@ -1292,6 +1292,7 @@ static int alx_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 1292 | alx = netdev_priv(netdev); | 1292 | alx = netdev_priv(netdev); |
| 1293 | spin_lock_init(&alx->hw.mdio_lock); | 1293 | spin_lock_init(&alx->hw.mdio_lock); |
| 1294 | spin_lock_init(&alx->irq_lock); | 1294 | spin_lock_init(&alx->irq_lock); |
| 1295 | spin_lock_init(&alx->stats_lock); | ||
| 1295 | alx->dev = netdev; | 1296 | alx->dev = netdev; |
| 1296 | alx->hw.pdev = pdev; | 1297 | alx->hw.pdev = pdev; |
| 1297 | alx->msg_enable = NETIF_MSG_LINK | NETIF_MSG_HW | NETIF_MSG_IFUP | | 1298 | alx->msg_enable = NETIF_MSG_LINK | NETIF_MSG_HW | NETIF_MSG_IFUP | |
diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c index 9d2dedadf2df..cda25ac45b47 100644 --- a/drivers/net/ethernet/broadcom/bnx2.c +++ b/drivers/net/ethernet/broadcom/bnx2.c | |||
| @@ -85,7 +85,7 @@ MODULE_FIRMWARE(FW_RV2P_FILE_09_Ax); | |||
| 85 | 85 | ||
| 86 | static int disable_msi = 0; | 86 | static int disable_msi = 0; |
| 87 | 87 | ||
| 88 | module_param(disable_msi, int, 0); | 88 | module_param(disable_msi, int, S_IRUGO); |
| 89 | MODULE_PARM_DESC(disable_msi, "Disable Message Signaled Interrupt (MSI)"); | 89 | MODULE_PARM_DESC(disable_msi, "Disable Message Signaled Interrupt (MSI)"); |
| 90 | 90 | ||
| 91 | typedef enum { | 91 | typedef enum { |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h index 17d1689aec6b..bfc58d488bb5 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h | |||
| @@ -936,7 +936,7 @@ static inline int bnx2x_func_start(struct bnx2x *bp) | |||
| 936 | else /* CHIP_IS_E1X */ | 936 | else /* CHIP_IS_E1X */ |
| 937 | start_params->network_cos_mode = FW_WRR; | 937 | start_params->network_cos_mode = FW_WRR; |
| 938 | 938 | ||
| 939 | start_params->gre_tunnel_mode = IPGRE_TUNNEL; | 939 | start_params->gre_tunnel_mode = L2GRE_TUNNEL; |
| 940 | start_params->gre_tunnel_rss = GRE_INNER_HEADERS_RSS; | 940 | start_params->gre_tunnel_rss = GRE_INNER_HEADERS_RSS; |
| 941 | 941 | ||
| 942 | return bnx2x_func_state_change(bp, &func_params); | 942 | return bnx2x_func_state_change(bp, &func_params); |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index c9c445e7b4a5..7d4382286457 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | |||
| @@ -95,29 +95,29 @@ MODULE_FIRMWARE(FW_FILE_NAME_E1H); | |||
| 95 | MODULE_FIRMWARE(FW_FILE_NAME_E2); | 95 | MODULE_FIRMWARE(FW_FILE_NAME_E2); |
| 96 | 96 | ||
| 97 | int bnx2x_num_queues; | 97 | int bnx2x_num_queues; |
| 98 | module_param_named(num_queues, bnx2x_num_queues, int, 0); | 98 | module_param_named(num_queues, bnx2x_num_queues, int, S_IRUGO); |
| 99 | MODULE_PARM_DESC(num_queues, | 99 | MODULE_PARM_DESC(num_queues, |
| 100 | " Set number of queues (default is as a number of CPUs)"); | 100 | " Set number of queues (default is as a number of CPUs)"); |
| 101 | 101 | ||
| 102 | static int disable_tpa; | 102 | static int disable_tpa; |
| 103 | module_param(disable_tpa, int, 0); | 103 | module_param(disable_tpa, int, S_IRUGO); |
| 104 | MODULE_PARM_DESC(disable_tpa, " Disable the TPA (LRO) feature"); | 104 | MODULE_PARM_DESC(disable_tpa, " Disable the TPA (LRO) feature"); |
| 105 | 105 | ||
| 106 | static int int_mode; | 106 | static int int_mode; |
| 107 | module_param(int_mode, int, 0); | 107 | module_param(int_mode, int, S_IRUGO); |
| 108 | MODULE_PARM_DESC(int_mode, " Force interrupt mode other than MSI-X " | 108 | MODULE_PARM_DESC(int_mode, " Force interrupt mode other than MSI-X " |
| 109 | "(1 INT#x; 2 MSI)"); | 109 | "(1 INT#x; 2 MSI)"); |
| 110 | 110 | ||
| 111 | static int dropless_fc; | 111 | static int dropless_fc; |
| 112 | module_param(dropless_fc, int, 0); | 112 | module_param(dropless_fc, int, S_IRUGO); |
| 113 | MODULE_PARM_DESC(dropless_fc, " Pause on exhausted host ring"); | 113 | MODULE_PARM_DESC(dropless_fc, " Pause on exhausted host ring"); |
| 114 | 114 | ||
| 115 | static int mrrs = -1; | 115 | static int mrrs = -1; |
| 116 | module_param(mrrs, int, 0); | 116 | module_param(mrrs, int, S_IRUGO); |
| 117 | MODULE_PARM_DESC(mrrs, " Force Max Read Req Size (0..3) (for debug)"); | 117 | MODULE_PARM_DESC(mrrs, " Force Max Read Req Size (0..3) (for debug)"); |
| 118 | 118 | ||
| 119 | static int debug; | 119 | static int debug; |
| 120 | module_param(debug, int, 0); | 120 | module_param(debug, int, S_IRUGO); |
| 121 | MODULE_PARM_DESC(debug, " Default debug msglevel"); | 121 | MODULE_PARM_DESC(debug, " Default debug msglevel"); |
| 122 | 122 | ||
| 123 | struct workqueue_struct *bnx2x_wq; | 123 | struct workqueue_struct *bnx2x_wq; |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c index aec5ef2ed7ce..e42f48df6e94 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c | |||
| @@ -1446,12 +1446,12 @@ static void bnx2x_vf_igu_reset(struct bnx2x *bp, struct bnx2x_virtf *vf) | |||
| 1446 | if (vf->cfg_flags & VF_CFG_INT_SIMD) | 1446 | if (vf->cfg_flags & VF_CFG_INT_SIMD) |
| 1447 | val |= IGU_VF_CONF_SINGLE_ISR_EN; | 1447 | val |= IGU_VF_CONF_SINGLE_ISR_EN; |
| 1448 | val &= ~IGU_VF_CONF_PARENT_MASK; | 1448 | val &= ~IGU_VF_CONF_PARENT_MASK; |
| 1449 | val |= BP_FUNC(bp) << IGU_VF_CONF_PARENT_SHIFT; /* parent PF */ | 1449 | val |= (BP_ABS_FUNC(bp) >> 1) << IGU_VF_CONF_PARENT_SHIFT; |
| 1450 | REG_WR(bp, IGU_REG_VF_CONFIGURATION, val); | 1450 | REG_WR(bp, IGU_REG_VF_CONFIGURATION, val); |
| 1451 | 1451 | ||
| 1452 | DP(BNX2X_MSG_IOV, | 1452 | DP(BNX2X_MSG_IOV, |
| 1453 | "value in IGU_REG_VF_CONFIGURATION of vf %d after write %x\n", | 1453 | "value in IGU_REG_VF_CONFIGURATION of vf %d after write is 0x%08x\n", |
| 1454 | vf->abs_vfid, REG_RD(bp, IGU_REG_VF_CONFIGURATION)); | 1454 | vf->abs_vfid, val); |
| 1455 | 1455 | ||
| 1456 | bnx2x_pretend_func(bp, BP_ABS_FUNC(bp)); | 1456 | bnx2x_pretend_func(bp, BP_ABS_FUNC(bp)); |
| 1457 | 1457 | ||
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index e2ca03e23dc1..3167ed6593b0 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c | |||
| @@ -2609,13 +2609,14 @@ static int tg3_phy_reset_5703_4_5(struct tg3 *tp) | |||
| 2609 | 2609 | ||
| 2610 | tg3_writephy(tp, MII_CTRL1000, phy9_orig); | 2610 | tg3_writephy(tp, MII_CTRL1000, phy9_orig); |
| 2611 | 2611 | ||
| 2612 | if (!tg3_readphy(tp, MII_TG3_EXT_CTRL, ®32)) { | 2612 | err = tg3_readphy(tp, MII_TG3_EXT_CTRL, ®32); |
| 2613 | reg32 &= ~0x3000; | 2613 | if (err) |
| 2614 | tg3_writephy(tp, MII_TG3_EXT_CTRL, reg32); | 2614 | return err; |
| 2615 | } else if (!err) | ||
| 2616 | err = -EBUSY; | ||
| 2617 | 2615 | ||
| 2618 | return err; | 2616 | reg32 &= ~0x3000; |
| 2617 | tg3_writephy(tp, MII_TG3_EXT_CTRL, reg32); | ||
| 2618 | |||
| 2619 | return 0; | ||
| 2619 | } | 2620 | } |
| 2620 | 2621 | ||
| 2621 | static void tg3_carrier_off(struct tg3 *tp) | 2622 | static void tg3_carrier_off(struct tg3 *tp) |
| @@ -14113,12 +14114,12 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu) | |||
| 14113 | 14114 | ||
| 14114 | tg3_netif_stop(tp); | 14115 | tg3_netif_stop(tp); |
| 14115 | 14116 | ||
| 14117 | tg3_set_mtu(dev, tp, new_mtu); | ||
| 14118 | |||
| 14116 | tg3_full_lock(tp, 1); | 14119 | tg3_full_lock(tp, 1); |
| 14117 | 14120 | ||
| 14118 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); | 14121 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
| 14119 | 14122 | ||
| 14120 | tg3_set_mtu(dev, tp, new_mtu); | ||
| 14121 | |||
| 14122 | /* Reset PHY, otherwise the read DMA engine will be in a mode that | 14123 | /* Reset PHY, otherwise the read DMA engine will be in a mode that |
| 14123 | * breaks all requests to 256 bytes. | 14124 | * breaks all requests to 256 bytes. |
| 14124 | */ | 14125 | */ |
diff --git a/drivers/net/ethernet/ethoc.c b/drivers/net/ethernet/ethoc.c index 4de8cfd149cf..55e0fa03dc90 100644 --- a/drivers/net/ethernet/ethoc.c +++ b/drivers/net/ethernet/ethoc.c | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | 13 | ||
| 14 | #include <linux/dma-mapping.h> | 14 | #include <linux/dma-mapping.h> |
| 15 | #include <linux/etherdevice.h> | 15 | #include <linux/etherdevice.h> |
| 16 | #include <linux/clk.h> | ||
| 16 | #include <linux/crc32.h> | 17 | #include <linux/crc32.h> |
| 17 | #include <linux/interrupt.h> | 18 | #include <linux/interrupt.h> |
| 18 | #include <linux/io.h> | 19 | #include <linux/io.h> |
| @@ -51,6 +52,7 @@ MODULE_PARM_DESC(buffer_size, "DMA buffer allocation size"); | |||
| 51 | #define ETH_HASH0 0x48 | 52 | #define ETH_HASH0 0x48 |
| 52 | #define ETH_HASH1 0x4c | 53 | #define ETH_HASH1 0x4c |
| 53 | #define ETH_TXCTRL 0x50 | 54 | #define ETH_TXCTRL 0x50 |
| 55 | #define ETH_END 0x54 | ||
| 54 | 56 | ||
| 55 | /* mode register */ | 57 | /* mode register */ |
| 56 | #define MODER_RXEN (1 << 0) /* receive enable */ | 58 | #define MODER_RXEN (1 << 0) /* receive enable */ |
| @@ -179,6 +181,7 @@ MODULE_PARM_DESC(buffer_size, "DMA buffer allocation size"); | |||
| 179 | * @membase: pointer to buffer memory region | 181 | * @membase: pointer to buffer memory region |
| 180 | * @dma_alloc: dma allocated buffer size | 182 | * @dma_alloc: dma allocated buffer size |
| 181 | * @io_region_size: I/O memory region size | 183 | * @io_region_size: I/O memory region size |
| 184 | * @num_bd: number of buffer descriptors | ||
| 182 | * @num_tx: number of send buffers | 185 | * @num_tx: number of send buffers |
| 183 | * @cur_tx: last send buffer written | 186 | * @cur_tx: last send buffer written |
| 184 | * @dty_tx: last buffer actually sent | 187 | * @dty_tx: last buffer actually sent |
| @@ -199,6 +202,7 @@ struct ethoc { | |||
| 199 | int dma_alloc; | 202 | int dma_alloc; |
| 200 | resource_size_t io_region_size; | 203 | resource_size_t io_region_size; |
| 201 | 204 | ||
| 205 | unsigned int num_bd; | ||
| 202 | unsigned int num_tx; | 206 | unsigned int num_tx; |
| 203 | unsigned int cur_tx; | 207 | unsigned int cur_tx; |
| 204 | unsigned int dty_tx; | 208 | unsigned int dty_tx; |
| @@ -216,6 +220,7 @@ struct ethoc { | |||
| 216 | 220 | ||
| 217 | struct phy_device *phy; | 221 | struct phy_device *phy; |
| 218 | struct mii_bus *mdio; | 222 | struct mii_bus *mdio; |
| 223 | struct clk *clk; | ||
| 219 | s8 phy_id; | 224 | s8 phy_id; |
| 220 | }; | 225 | }; |
| 221 | 226 | ||
| @@ -688,6 +693,11 @@ static int ethoc_mdio_probe(struct net_device *dev) | |||
| 688 | } | 693 | } |
| 689 | 694 | ||
| 690 | priv->phy = phy; | 695 | priv->phy = phy; |
| 696 | phy->advertising &= ~(ADVERTISED_1000baseT_Full | | ||
| 697 | ADVERTISED_1000baseT_Half); | ||
| 698 | phy->supported &= ~(SUPPORTED_1000baseT_Full | | ||
| 699 | SUPPORTED_1000baseT_Half); | ||
| 700 | |||
| 691 | return 0; | 701 | return 0; |
| 692 | } | 702 | } |
| 693 | 703 | ||
| @@ -890,6 +900,102 @@ out: | |||
| 890 | return NETDEV_TX_OK; | 900 | return NETDEV_TX_OK; |
| 891 | } | 901 | } |
| 892 | 902 | ||
| 903 | static int ethoc_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) | ||
| 904 | { | ||
| 905 | struct ethoc *priv = netdev_priv(dev); | ||
| 906 | struct phy_device *phydev = priv->phy; | ||
| 907 | |||
| 908 | if (!phydev) | ||
| 909 | return -EOPNOTSUPP; | ||
| 910 | |||
| 911 | return phy_ethtool_gset(phydev, cmd); | ||
| 912 | } | ||
| 913 | |||
| 914 | static int ethoc_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) | ||
| 915 | { | ||
| 916 | struct ethoc *priv = netdev_priv(dev); | ||
| 917 | struct phy_device *phydev = priv->phy; | ||
| 918 | |||
| 919 | if (!phydev) | ||
| 920 | return -EOPNOTSUPP; | ||
| 921 | |||
| 922 | return phy_ethtool_sset(phydev, cmd); | ||
| 923 | } | ||
| 924 | |||
| 925 | static int ethoc_get_regs_len(struct net_device *netdev) | ||
| 926 | { | ||
| 927 | return ETH_END; | ||
| 928 | } | ||
| 929 | |||
| 930 | static void ethoc_get_regs(struct net_device *dev, struct ethtool_regs *regs, | ||
| 931 | void *p) | ||
| 932 | { | ||
| 933 | struct ethoc *priv = netdev_priv(dev); | ||
| 934 | u32 *regs_buff = p; | ||
| 935 | unsigned i; | ||
| 936 | |||
| 937 | regs->version = 0; | ||
| 938 | for (i = 0; i < ETH_END / sizeof(u32); ++i) | ||
| 939 | regs_buff[i] = ethoc_read(priv, i * sizeof(u32)); | ||
| 940 | } | ||
| 941 | |||
| 942 | static void ethoc_get_ringparam(struct net_device *dev, | ||
| 943 | struct ethtool_ringparam *ring) | ||
| 944 | { | ||
| 945 | struct ethoc *priv = netdev_priv(dev); | ||
| 946 | |||
| 947 | ring->rx_max_pending = priv->num_bd - 1; | ||
| 948 | ring->rx_mini_max_pending = 0; | ||
| 949 | ring->rx_jumbo_max_pending = 0; | ||
| 950 | ring->tx_max_pending = priv->num_bd - 1; | ||
| 951 | |||
| 952 | ring->rx_pending = priv->num_rx; | ||
| 953 | ring->rx_mini_pending = 0; | ||
| 954 | ring->rx_jumbo_pending = 0; | ||
| 955 | ring->tx_pending = priv->num_tx; | ||
| 956 | } | ||
| 957 | |||
| 958 | static int ethoc_set_ringparam(struct net_device *dev, | ||
| 959 | struct ethtool_ringparam *ring) | ||
| 960 | { | ||
| 961 | struct ethoc *priv = netdev_priv(dev); | ||
| 962 | |||
| 963 | if (ring->tx_pending < 1 || ring->rx_pending < 1 || | ||
| 964 | ring->tx_pending + ring->rx_pending > priv->num_bd) | ||
| 965 | return -EINVAL; | ||
| 966 | if (ring->rx_mini_pending || ring->rx_jumbo_pending) | ||
| 967 | return -EINVAL; | ||
| 968 | |||
| 969 | if (netif_running(dev)) { | ||
| 970 | netif_tx_disable(dev); | ||
| 971 | ethoc_disable_rx_and_tx(priv); | ||
| 972 | ethoc_disable_irq(priv, INT_MASK_TX | INT_MASK_RX); | ||
| 973 | synchronize_irq(dev->irq); | ||
| 974 | } | ||
| 975 | |||
| 976 | priv->num_tx = rounddown_pow_of_two(ring->tx_pending); | ||
| 977 | priv->num_rx = ring->rx_pending; | ||
| 978 | ethoc_init_ring(priv, dev->mem_start); | ||
| 979 | |||
| 980 | if (netif_running(dev)) { | ||
| 981 | ethoc_enable_irq(priv, INT_MASK_TX | INT_MASK_RX); | ||
| 982 | ethoc_enable_rx_and_tx(priv); | ||
| 983 | netif_wake_queue(dev); | ||
| 984 | } | ||
| 985 | return 0; | ||
| 986 | } | ||
| 987 | |||
| 988 | const struct ethtool_ops ethoc_ethtool_ops = { | ||
| 989 | .get_settings = ethoc_get_settings, | ||
| 990 | .set_settings = ethoc_set_settings, | ||
| 991 | .get_regs_len = ethoc_get_regs_len, | ||
| 992 | .get_regs = ethoc_get_regs, | ||
| 993 | .get_link = ethtool_op_get_link, | ||
| 994 | .get_ringparam = ethoc_get_ringparam, | ||
| 995 | .set_ringparam = ethoc_set_ringparam, | ||
| 996 | .get_ts_info = ethtool_op_get_ts_info, | ||
| 997 | }; | ||
| 998 | |||
| 893 | static const struct net_device_ops ethoc_netdev_ops = { | 999 | static const struct net_device_ops ethoc_netdev_ops = { |
| 894 | .ndo_open = ethoc_open, | 1000 | .ndo_open = ethoc_open, |
| 895 | .ndo_stop = ethoc_stop, | 1001 | .ndo_stop = ethoc_stop, |
| @@ -917,6 +1023,8 @@ static int ethoc_probe(struct platform_device *pdev) | |||
| 917 | int num_bd; | 1023 | int num_bd; |
| 918 | int ret = 0; | 1024 | int ret = 0; |
| 919 | bool random_mac = false; | 1025 | bool random_mac = false; |
| 1026 | struct ethoc_platform_data *pdata = dev_get_platdata(&pdev->dev); | ||
| 1027 | u32 eth_clkfreq = pdata ? pdata->eth_clkfreq : 0; | ||
| 920 | 1028 | ||
| 921 | /* allocate networking device */ | 1029 | /* allocate networking device */ |
| 922 | netdev = alloc_etherdev(sizeof(struct ethoc)); | 1030 | netdev = alloc_etherdev(sizeof(struct ethoc)); |
| @@ -1016,6 +1124,7 @@ static int ethoc_probe(struct platform_device *pdev) | |||
| 1016 | ret = -ENODEV; | 1124 | ret = -ENODEV; |
| 1017 | goto error; | 1125 | goto error; |
| 1018 | } | 1126 | } |
| 1127 | priv->num_bd = num_bd; | ||
| 1019 | /* num_tx must be a power of two */ | 1128 | /* num_tx must be a power of two */ |
| 1020 | priv->num_tx = rounddown_pow_of_two(num_bd >> 1); | 1129 | priv->num_tx = rounddown_pow_of_two(num_bd >> 1); |
| 1021 | priv->num_rx = num_bd - priv->num_tx; | 1130 | priv->num_rx = num_bd - priv->num_tx; |
| @@ -1030,8 +1139,7 @@ static int ethoc_probe(struct platform_device *pdev) | |||
| 1030 | } | 1139 | } |
| 1031 | 1140 | ||
| 1032 | /* Allow the platform setup code to pass in a MAC address. */ | 1141 | /* Allow the platform setup code to pass in a MAC address. */ |
| 1033 | if (dev_get_platdata(&pdev->dev)) { | 1142 | if (pdata) { |
| 1034 | struct ethoc_platform_data *pdata = dev_get_platdata(&pdev->dev); | ||
| 1035 | memcpy(netdev->dev_addr, pdata->hwaddr, IFHWADDRLEN); | 1143 | memcpy(netdev->dev_addr, pdata->hwaddr, IFHWADDRLEN); |
| 1036 | priv->phy_id = pdata->phy_id; | 1144 | priv->phy_id = pdata->phy_id; |
| 1037 | } else { | 1145 | } else { |
| @@ -1069,6 +1177,27 @@ static int ethoc_probe(struct platform_device *pdev) | |||
| 1069 | if (random_mac) | 1177 | if (random_mac) |
| 1070 | netdev->addr_assign_type = NET_ADDR_RANDOM; | 1178 | netdev->addr_assign_type = NET_ADDR_RANDOM; |
| 1071 | 1179 | ||
| 1180 | /* Allow the platform setup code to adjust MII management bus clock. */ | ||
| 1181 | if (!eth_clkfreq) { | ||
| 1182 | struct clk *clk = devm_clk_get(&pdev->dev, NULL); | ||
| 1183 | |||
| 1184 | if (!IS_ERR(clk)) { | ||
| 1185 | priv->clk = clk; | ||
| 1186 | clk_prepare_enable(clk); | ||
| 1187 | eth_clkfreq = clk_get_rate(clk); | ||
| 1188 | } | ||
| 1189 | } | ||
| 1190 | if (eth_clkfreq) { | ||
| 1191 | u32 clkdiv = MIIMODER_CLKDIV(eth_clkfreq / 2500000 + 1); | ||
| 1192 | |||
| 1193 | if (!clkdiv) | ||
| 1194 | clkdiv = 2; | ||
| 1195 | dev_dbg(&pdev->dev, "setting MII clkdiv to %u\n", clkdiv); | ||
| 1196 | ethoc_write(priv, MIIMODER, | ||
| 1197 | (ethoc_read(priv, MIIMODER) & MIIMODER_NOPRE) | | ||
| 1198 | clkdiv); | ||
| 1199 | } | ||
| 1200 | |||
| 1072 | /* register MII bus */ | 1201 | /* register MII bus */ |
| 1073 | priv->mdio = mdiobus_alloc(); | 1202 | priv->mdio = mdiobus_alloc(); |
| 1074 | if (!priv->mdio) { | 1203 | if (!priv->mdio) { |
| @@ -1111,6 +1240,7 @@ static int ethoc_probe(struct platform_device *pdev) | |||
| 1111 | netdev->netdev_ops = ðoc_netdev_ops; | 1240 | netdev->netdev_ops = ðoc_netdev_ops; |
| 1112 | netdev->watchdog_timeo = ETHOC_TIMEOUT; | 1241 | netdev->watchdog_timeo = ETHOC_TIMEOUT; |
| 1113 | netdev->features |= 0; | 1242 | netdev->features |= 0; |
| 1243 | netdev->ethtool_ops = ðoc_ethtool_ops; | ||
| 1114 | 1244 | ||
| 1115 | /* setup NAPI */ | 1245 | /* setup NAPI */ |
| 1116 | netif_napi_add(netdev, &priv->napi, ethoc_poll, 64); | 1246 | netif_napi_add(netdev, &priv->napi, ethoc_poll, 64); |
| @@ -1133,6 +1263,8 @@ free_mdio: | |||
| 1133 | kfree(priv->mdio->irq); | 1263 | kfree(priv->mdio->irq); |
| 1134 | mdiobus_free(priv->mdio); | 1264 | mdiobus_free(priv->mdio); |
| 1135 | free: | 1265 | free: |
| 1266 | if (priv->clk) | ||
| 1267 | clk_disable_unprepare(priv->clk); | ||
| 1136 | free_netdev(netdev); | 1268 | free_netdev(netdev); |
| 1137 | out: | 1269 | out: |
| 1138 | return ret; | 1270 | return ret; |
| @@ -1157,6 +1289,8 @@ static int ethoc_remove(struct platform_device *pdev) | |||
| 1157 | kfree(priv->mdio->irq); | 1289 | kfree(priv->mdio->irq); |
| 1158 | mdiobus_free(priv->mdio); | 1290 | mdiobus_free(priv->mdio); |
| 1159 | } | 1291 | } |
| 1292 | if (priv->clk) | ||
| 1293 | clk_disable_unprepare(priv->clk); | ||
| 1160 | unregister_netdev(netdev); | 1294 | unregister_netdev(netdev); |
| 1161 | free_netdev(netdev); | 1295 | free_netdev(netdev); |
| 1162 | } | 1296 | } |
diff --git a/drivers/net/ethernet/intel/e100.c b/drivers/net/ethernet/intel/e100.c index cbaba4442d4b..bf7a01ef9a57 100644 --- a/drivers/net/ethernet/intel/e100.c +++ b/drivers/net/ethernet/intel/e100.c | |||
| @@ -3034,7 +3034,7 @@ static void __e100_shutdown(struct pci_dev *pdev, bool *enable_wake) | |||
| 3034 | *enable_wake = false; | 3034 | *enable_wake = false; |
| 3035 | } | 3035 | } |
| 3036 | 3036 | ||
| 3037 | pci_disable_device(pdev); | 3037 | pci_clear_master(pdev); |
| 3038 | } | 3038 | } |
| 3039 | 3039 | ||
| 3040 | static int __e100_power_off(struct pci_dev *pdev, bool wake) | 3040 | static int __e100_power_off(struct pci_dev *pdev, bool wake) |
diff --git a/drivers/net/ethernet/neterion/vxge/vxge-main.c b/drivers/net/ethernet/neterion/vxge/vxge-main.c index 1ded50ca1600..e46e8698e630 100644 --- a/drivers/net/ethernet/neterion/vxge/vxge-main.c +++ b/drivers/net/ethernet/neterion/vxge/vxge-main.c | |||
| @@ -726,9 +726,6 @@ static int vxge_learn_mac(struct vxgedev *vdev, u8 *mac_header) | |||
| 726 | int vpath_idx = 0; | 726 | int vpath_idx = 0; |
| 727 | enum vxge_hw_status status = VXGE_HW_OK; | 727 | enum vxge_hw_status status = VXGE_HW_OK; |
| 728 | struct vxge_vpath *vpath = NULL; | 728 | struct vxge_vpath *vpath = NULL; |
| 729 | struct __vxge_hw_device *hldev; | ||
| 730 | |||
| 731 | hldev = pci_get_drvdata(vdev->pdev); | ||
| 732 | 729 | ||
| 733 | mac_address = (u8 *)&mac_addr; | 730 | mac_address = (u8 *)&mac_addr; |
| 734 | memcpy(mac_address, mac_header, ETH_ALEN); | 731 | memcpy(mac_address, mac_header, ETH_ALEN); |
| @@ -2443,9 +2440,6 @@ static void vxge_rem_msix_isr(struct vxgedev *vdev) | |||
| 2443 | 2440 | ||
| 2444 | static void vxge_rem_isr(struct vxgedev *vdev) | 2441 | static void vxge_rem_isr(struct vxgedev *vdev) |
| 2445 | { | 2442 | { |
| 2446 | struct __vxge_hw_device *hldev; | ||
| 2447 | hldev = pci_get_drvdata(vdev->pdev); | ||
| 2448 | |||
| 2449 | #ifdef CONFIG_PCI_MSI | 2443 | #ifdef CONFIG_PCI_MSI |
| 2450 | if (vdev->config.intr_type == MSI_X) { | 2444 | if (vdev->config.intr_type == MSI_X) { |
| 2451 | vxge_rem_msix_isr(vdev); | 2445 | vxge_rem_msix_isr(vdev); |
diff --git a/drivers/net/ethernet/sfc/tx.c b/drivers/net/ethernet/sfc/tx.c index c49d1fb16965..75d11fa4eb0a 100644 --- a/drivers/net/ethernet/sfc/tx.c +++ b/drivers/net/ethernet/sfc/tx.c | |||
| @@ -429,7 +429,9 @@ netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb) | |||
| 429 | } | 429 | } |
| 430 | 430 | ||
| 431 | /* Transfer ownership of the skb to the final buffer */ | 431 | /* Transfer ownership of the skb to the final buffer */ |
| 432 | #ifdef EFX_USE_PIO | ||
| 432 | finish_packet: | 433 | finish_packet: |
| 434 | #endif | ||
| 433 | buffer->skb = skb; | 435 | buffer->skb = skb; |
| 434 | buffer->flags = EFX_TX_BUF_SKB | dma_flags; | 436 | buffer->flags = EFX_TX_BUF_SKB | dma_flags; |
| 435 | 437 | ||
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index bde63e3af96f..1d860ce914ed 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c | |||
| @@ -1878,8 +1878,18 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data, | |||
| 1878 | mdio_node = of_find_node_by_phandle(be32_to_cpup(parp)); | 1878 | mdio_node = of_find_node_by_phandle(be32_to_cpup(parp)); |
| 1879 | phyid = be32_to_cpup(parp+1); | 1879 | phyid = be32_to_cpup(parp+1); |
| 1880 | mdio = of_find_device_by_node(mdio_node); | 1880 | mdio = of_find_device_by_node(mdio_node); |
| 1881 | snprintf(slave_data->phy_id, sizeof(slave_data->phy_id), | 1881 | |
| 1882 | PHY_ID_FMT, mdio->name, phyid); | 1882 | if (strncmp(mdio->name, "gpio", 4) == 0) { |
| 1883 | /* GPIO bitbang MDIO driver attached */ | ||
| 1884 | struct mii_bus *bus = dev_get_drvdata(&mdio->dev); | ||
| 1885 | |||
| 1886 | snprintf(slave_data->phy_id, sizeof(slave_data->phy_id), | ||
| 1887 | PHY_ID_FMT, bus->id, phyid); | ||
| 1888 | } else { | ||
| 1889 | /* davinci MDIO driver attached */ | ||
| 1890 | snprintf(slave_data->phy_id, sizeof(slave_data->phy_id), | ||
| 1891 | PHY_ID_FMT, mdio->name, phyid); | ||
| 1892 | } | ||
| 1883 | 1893 | ||
| 1884 | mac_addr = of_get_mac_address(slave_node); | 1894 | mac_addr = of_get_mac_address(slave_node); |
| 1885 | if (mac_addr) | 1895 | if (mac_addr) |
diff --git a/drivers/net/irda/Kconfig b/drivers/net/irda/Kconfig index 2dc82f1d2e70..3da44d5d9149 100644 --- a/drivers/net/irda/Kconfig +++ b/drivers/net/irda/Kconfig | |||
| @@ -210,13 +210,6 @@ config KINGSUN_DONGLE | |||
| 210 | To compile it as a module, choose M here: the module will be called | 210 | To compile it as a module, choose M here: the module will be called |
| 211 | kingsun-sir. | 211 | kingsun-sir. |
| 212 | 212 | ||
| 213 | config EP7211_DONGLE | ||
| 214 | tristate "Cirrus Logic clps711x I/R support" | ||
| 215 | depends on IRTTY_SIR && ARCH_CLPS711X && IRDA | ||
| 216 | help | ||
| 217 | Say Y here if you want to build support for the Cirrus logic | ||
| 218 | EP7211 chipset's infrared module. | ||
| 219 | |||
| 220 | config KSDAZZLE_DONGLE | 213 | config KSDAZZLE_DONGLE |
| 221 | tristate "KingSun Dazzle IrDA-USB dongle" | 214 | tristate "KingSun Dazzle IrDA-USB dongle" |
| 222 | depends on IRDA && USB | 215 | depends on IRDA && USB |
diff --git a/drivers/net/irda/Makefile b/drivers/net/irda/Makefile index dfc64537f62f..be8ab5b9a4a2 100644 --- a/drivers/net/irda/Makefile +++ b/drivers/net/irda/Makefile | |||
| @@ -35,7 +35,6 @@ obj-$(CONFIG_MCP2120_DONGLE) += mcp2120-sir.o | |||
| 35 | obj-$(CONFIG_ACT200L_DONGLE) += act200l-sir.o | 35 | obj-$(CONFIG_ACT200L_DONGLE) += act200l-sir.o |
| 36 | obj-$(CONFIG_MA600_DONGLE) += ma600-sir.o | 36 | obj-$(CONFIG_MA600_DONGLE) += ma600-sir.o |
| 37 | obj-$(CONFIG_TOIM3232_DONGLE) += toim3232-sir.o | 37 | obj-$(CONFIG_TOIM3232_DONGLE) += toim3232-sir.o |
| 38 | obj-$(CONFIG_EP7211_DONGLE) += ep7211-sir.o | ||
| 39 | obj-$(CONFIG_KINGSUN_DONGLE) += kingsun-sir.o | 38 | obj-$(CONFIG_KINGSUN_DONGLE) += kingsun-sir.o |
| 40 | obj-$(CONFIG_KSDAZZLE_DONGLE) += ksdazzle-sir.o | 39 | obj-$(CONFIG_KSDAZZLE_DONGLE) += ksdazzle-sir.o |
| 41 | obj-$(CONFIG_KS959_DONGLE) += ks959-sir.o | 40 | obj-$(CONFIG_KS959_DONGLE) += ks959-sir.o |
diff --git a/drivers/net/irda/ep7211-sir.c b/drivers/net/irda/ep7211-sir.c deleted file mode 100644 index 5fe1f4dd3369..000000000000 --- a/drivers/net/irda/ep7211-sir.c +++ /dev/null | |||
| @@ -1,70 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * IR port driver for the Cirrus Logic CLPS711X processors | ||
| 3 | * | ||
| 4 | * Copyright 2001, Blue Mug Inc. All rights reserved. | ||
| 5 | * Copyright 2007, Samuel Ortiz <samuel@sortiz.org> | ||
| 6 | */ | ||
| 7 | |||
| 8 | #include <linux/module.h> | ||
| 9 | #include <linux/platform_device.h> | ||
| 10 | |||
| 11 | #include <mach/hardware.h> | ||
| 12 | |||
| 13 | #include "sir-dev.h" | ||
| 14 | |||
| 15 | static int clps711x_dongle_open(struct sir_dev *dev) | ||
| 16 | { | ||
| 17 | unsigned int syscon; | ||
| 18 | |||
| 19 | /* Turn on the SIR encoder. */ | ||
| 20 | syscon = clps_readl(SYSCON1); | ||
| 21 | syscon |= SYSCON1_SIREN; | ||
| 22 | clps_writel(syscon, SYSCON1); | ||
| 23 | |||
| 24 | return 0; | ||
| 25 | } | ||
| 26 | |||
| 27 | static int clps711x_dongle_close(struct sir_dev *dev) | ||
| 28 | { | ||
| 29 | unsigned int syscon; | ||
| 30 | |||
| 31 | /* Turn off the SIR encoder. */ | ||
| 32 | syscon = clps_readl(SYSCON1); | ||
| 33 | syscon &= ~SYSCON1_SIREN; | ||
| 34 | clps_writel(syscon, SYSCON1); | ||
| 35 | |||
| 36 | return 0; | ||
| 37 | } | ||
| 38 | |||
| 39 | static struct dongle_driver clps711x_dongle = { | ||
| 40 | .owner = THIS_MODULE, | ||
| 41 | .driver_name = "EP7211 IR driver", | ||
| 42 | .type = IRDA_EP7211_DONGLE, | ||
| 43 | .open = clps711x_dongle_open, | ||
| 44 | .close = clps711x_dongle_close, | ||
| 45 | }; | ||
| 46 | |||
| 47 | static int clps711x_sir_probe(struct platform_device *pdev) | ||
| 48 | { | ||
| 49 | return irda_register_dongle(&clps711x_dongle); | ||
| 50 | } | ||
| 51 | |||
| 52 | static int clps711x_sir_remove(struct platform_device *pdev) | ||
| 53 | { | ||
| 54 | return irda_unregister_dongle(&clps711x_dongle); | ||
| 55 | } | ||
| 56 | |||
| 57 | static struct platform_driver clps711x_sir_driver = { | ||
| 58 | .driver = { | ||
| 59 | .name = "sir-clps711x", | ||
| 60 | .owner = THIS_MODULE, | ||
| 61 | }, | ||
| 62 | .probe = clps711x_sir_probe, | ||
| 63 | .remove = clps711x_sir_remove, | ||
| 64 | }; | ||
| 65 | module_platform_driver(clps711x_sir_driver); | ||
| 66 | |||
| 67 | MODULE_AUTHOR("Samuel Ortiz <samuel@sortiz.org>"); | ||
| 68 | MODULE_DESCRIPTION("EP7211 IR dongle driver"); | ||
| 69 | MODULE_LICENSE("GPL"); | ||
| 70 | MODULE_ALIAS("irda-dongle-13"); /* IRDA_EP7211_DONGLE */ | ||
diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c index 547725fa8671..9414fa272160 100644 --- a/drivers/net/phy/dp83640.c +++ b/drivers/net/phy/dp83640.c | |||
| @@ -437,7 +437,10 @@ static int ptp_dp83640_enable(struct ptp_clock_info *ptp, | |||
| 437 | if (on) { | 437 | if (on) { |
| 438 | gpio_num = gpio_tab[EXTTS0_GPIO + index]; | 438 | gpio_num = gpio_tab[EXTTS0_GPIO + index]; |
| 439 | evnt |= (gpio_num & EVNT_GPIO_MASK) << EVNT_GPIO_SHIFT; | 439 | evnt |= (gpio_num & EVNT_GPIO_MASK) << EVNT_GPIO_SHIFT; |
| 440 | evnt |= EVNT_RISE; | 440 | if (rq->extts.flags & PTP_FALLING_EDGE) |
| 441 | evnt |= EVNT_FALL; | ||
| 442 | else | ||
| 443 | evnt |= EVNT_RISE; | ||
| 441 | } | 444 | } |
| 442 | ext_write(0, phydev, PAGE5, PTP_EVNT, evnt); | 445 | ext_write(0, phydev, PAGE5, PTP_EVNT, evnt); |
| 443 | return 0; | 446 | return 0; |
| @@ -1058,6 +1061,13 @@ static void dp83640_remove(struct phy_device *phydev) | |||
| 1058 | kfree(dp83640); | 1061 | kfree(dp83640); |
| 1059 | } | 1062 | } |
| 1060 | 1063 | ||
| 1064 | static int dp83640_config_init(struct phy_device *phydev) | ||
| 1065 | { | ||
| 1066 | enable_status_frames(phydev, true); | ||
| 1067 | ext_write(0, phydev, PAGE4, PTP_CTL, PTP_ENABLE); | ||
| 1068 | return 0; | ||
| 1069 | } | ||
| 1070 | |||
| 1061 | static int dp83640_ack_interrupt(struct phy_device *phydev) | 1071 | static int dp83640_ack_interrupt(struct phy_device *phydev) |
| 1062 | { | 1072 | { |
| 1063 | int err = phy_read(phydev, MII_DP83640_MISR); | 1073 | int err = phy_read(phydev, MII_DP83640_MISR); |
| @@ -1195,11 +1205,6 @@ static int dp83640_hwtstamp(struct phy_device *phydev, struct ifreq *ifr) | |||
| 1195 | 1205 | ||
| 1196 | mutex_lock(&dp83640->clock->extreg_lock); | 1206 | mutex_lock(&dp83640->clock->extreg_lock); |
| 1197 | 1207 | ||
| 1198 | if (dp83640->hwts_tx_en || dp83640->hwts_rx_en) { | ||
| 1199 | enable_status_frames(phydev, true); | ||
| 1200 | ext_write(0, phydev, PAGE4, PTP_CTL, PTP_ENABLE); | ||
| 1201 | } | ||
| 1202 | |||
| 1203 | ext_write(0, phydev, PAGE5, PTP_TXCFG0, txcfg0); | 1208 | ext_write(0, phydev, PAGE5, PTP_TXCFG0, txcfg0); |
| 1204 | ext_write(0, phydev, PAGE5, PTP_RXCFG0, rxcfg0); | 1209 | ext_write(0, phydev, PAGE5, PTP_RXCFG0, rxcfg0); |
| 1205 | 1210 | ||
| @@ -1281,6 +1286,7 @@ static void dp83640_txtstamp(struct phy_device *phydev, | |||
| 1281 | } | 1286 | } |
| 1282 | /* fall through */ | 1287 | /* fall through */ |
| 1283 | case HWTSTAMP_TX_ON: | 1288 | case HWTSTAMP_TX_ON: |
| 1289 | skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; | ||
| 1284 | skb_queue_tail(&dp83640->tx_queue, skb); | 1290 | skb_queue_tail(&dp83640->tx_queue, skb); |
| 1285 | schedule_work(&dp83640->ts_work); | 1291 | schedule_work(&dp83640->ts_work); |
| 1286 | break; | 1292 | break; |
| @@ -1330,6 +1336,7 @@ static struct phy_driver dp83640_driver = { | |||
| 1330 | .flags = PHY_HAS_INTERRUPT, | 1336 | .flags = PHY_HAS_INTERRUPT, |
| 1331 | .probe = dp83640_probe, | 1337 | .probe = dp83640_probe, |
| 1332 | .remove = dp83640_remove, | 1338 | .remove = dp83640_remove, |
| 1339 | .config_init = dp83640_config_init, | ||
| 1333 | .config_aneg = genphy_config_aneg, | 1340 | .config_aneg = genphy_config_aneg, |
| 1334 | .read_status = genphy_read_status, | 1341 | .read_status = genphy_read_status, |
| 1335 | .ack_interrupt = dp83640_ack_interrupt, | 1342 | .ack_interrupt = dp83640_ack_interrupt, |
diff --git a/drivers/net/phy/mdio-sun4i.c b/drivers/net/phy/mdio-sun4i.c index bb88bc7d81fb..9367acc84fbb 100644 --- a/drivers/net/phy/mdio-sun4i.c +++ b/drivers/net/phy/mdio-sun4i.c | |||
| @@ -170,6 +170,9 @@ static int sun4i_mdio_remove(struct platform_device *pdev) | |||
| 170 | } | 170 | } |
| 171 | 171 | ||
| 172 | static const struct of_device_id sun4i_mdio_dt_ids[] = { | 172 | static const struct of_device_id sun4i_mdio_dt_ids[] = { |
| 173 | { .compatible = "allwinner,sun4i-a10-mdio" }, | ||
| 174 | |||
| 175 | /* Deprecated */ | ||
| 173 | { .compatible = "allwinner,sun4i-mdio" }, | 176 | { .compatible = "allwinner,sun4i-mdio" }, |
| 174 | { } | 177 | { } |
| 175 | }; | 178 | }; |
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index 4b03e63639b7..82514e72b3d8 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c | |||
| @@ -719,7 +719,7 @@ int phy_resume(struct phy_device *phydev) | |||
| 719 | static int genphy_config_advert(struct phy_device *phydev) | 719 | static int genphy_config_advert(struct phy_device *phydev) |
| 720 | { | 720 | { |
| 721 | u32 advertise; | 721 | u32 advertise; |
| 722 | int oldadv, adv; | 722 | int oldadv, adv, bmsr; |
| 723 | int err, changed = 0; | 723 | int err, changed = 0; |
| 724 | 724 | ||
| 725 | /* Only allow advertising what this PHY supports */ | 725 | /* Only allow advertising what this PHY supports */ |
| @@ -744,26 +744,36 @@ static int genphy_config_advert(struct phy_device *phydev) | |||
| 744 | changed = 1; | 744 | changed = 1; |
| 745 | } | 745 | } |
| 746 | 746 | ||
| 747 | bmsr = phy_read(phydev, MII_BMSR); | ||
| 748 | if (bmsr < 0) | ||
| 749 | return bmsr; | ||
| 750 | |||
| 751 | /* Per 802.3-2008, Section 22.2.4.2.16 Extended status all | ||
| 752 | * 1000Mbits/sec capable PHYs shall have the BMSR_ESTATEN bit set to a | ||
| 753 | * logical 1. | ||
| 754 | */ | ||
| 755 | if (!(bmsr & BMSR_ESTATEN)) | ||
| 756 | return changed; | ||
| 757 | |||
| 747 | /* Configure gigabit if it's supported */ | 758 | /* Configure gigabit if it's supported */ |
| 759 | adv = phy_read(phydev, MII_CTRL1000); | ||
| 760 | if (adv < 0) | ||
| 761 | return adv; | ||
| 762 | |||
| 763 | oldadv = adv; | ||
| 764 | adv &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF); | ||
| 765 | |||
| 748 | if (phydev->supported & (SUPPORTED_1000baseT_Half | | 766 | if (phydev->supported & (SUPPORTED_1000baseT_Half | |
| 749 | SUPPORTED_1000baseT_Full)) { | 767 | SUPPORTED_1000baseT_Full)) { |
| 750 | adv = phy_read(phydev, MII_CTRL1000); | ||
| 751 | if (adv < 0) | ||
| 752 | return adv; | ||
| 753 | |||
| 754 | oldadv = adv; | ||
| 755 | adv &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF); | ||
| 756 | adv |= ethtool_adv_to_mii_ctrl1000_t(advertise); | 768 | adv |= ethtool_adv_to_mii_ctrl1000_t(advertise); |
| 757 | 769 | if (adv != oldadv) | |
| 758 | if (adv != oldadv) { | ||
| 759 | err = phy_write(phydev, MII_CTRL1000, adv); | ||
| 760 | |||
| 761 | if (err < 0) | ||
| 762 | return err; | ||
| 763 | changed = 1; | 770 | changed = 1; |
| 764 | } | ||
| 765 | } | 771 | } |
| 766 | 772 | ||
| 773 | err = phy_write(phydev, MII_CTRL1000, adv); | ||
| 774 | if (err < 0) | ||
| 775 | return err; | ||
| 776 | |||
| 767 | return changed; | 777 | return changed; |
| 768 | } | 778 | } |
| 769 | 779 | ||
diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig index 6b638a066c1d..409499fdb157 100644 --- a/drivers/net/usb/Kconfig +++ b/drivers/net/usb/Kconfig | |||
| @@ -292,6 +292,22 @@ config USB_NET_SR9700 | |||
| 292 | This option adds support for CoreChip-sz SR9700 based USB 1.1 | 292 | This option adds support for CoreChip-sz SR9700 based USB 1.1 |
| 293 | 10/100 Ethernet adapters. | 293 | 10/100 Ethernet adapters. |
| 294 | 294 | ||
| 295 | config USB_NET_SR9800 | ||
| 296 | tristate "CoreChip-sz SR9800 based USB 2.0 10/100 ethernet devices" | ||
| 297 | depends on USB_USBNET | ||
| 298 | select CRC32 | ||
| 299 | default y | ||
| 300 | ---help--- | ||
| 301 | Say Y if you want to use one of the following 100Mbps USB Ethernet | ||
| 302 | device based on the CoreChip-sz SR9800 chip. | ||
| 303 | |||
| 304 | This driver makes the adapter appear as a normal Ethernet interface, | ||
| 305 | typically on eth0, if it is the only ethernet device, or perhaps on | ||
| 306 | eth1, if you have a PCI or ISA ethernet card installed. | ||
| 307 | |||
| 308 | To compile this driver as a module, choose M here: the | ||
| 309 | module will be called sr9800. | ||
| 310 | |||
| 295 | config USB_NET_SMSC75XX | 311 | config USB_NET_SMSC75XX |
| 296 | tristate "SMSC LAN75XX based USB 2.0 gigabit ethernet devices" | 312 | tristate "SMSC LAN75XX based USB 2.0 gigabit ethernet devices" |
| 297 | depends on USB_USBNET | 313 | depends on USB_USBNET |
diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile index b17b5e88bbaf..433f0a00c683 100644 --- a/drivers/net/usb/Makefile +++ b/drivers/net/usb/Makefile | |||
| @@ -15,6 +15,7 @@ obj-$(CONFIG_USB_NET_CDCETHER) += cdc_ether.o r815x.o | |||
| 15 | obj-$(CONFIG_USB_NET_CDC_EEM) += cdc_eem.o | 15 | obj-$(CONFIG_USB_NET_CDC_EEM) += cdc_eem.o |
| 16 | obj-$(CONFIG_USB_NET_DM9601) += dm9601.o | 16 | obj-$(CONFIG_USB_NET_DM9601) += dm9601.o |
| 17 | obj-$(CONFIG_USB_NET_SR9700) += sr9700.o | 17 | obj-$(CONFIG_USB_NET_SR9700) += sr9700.o |
| 18 | obj-$(CONFIG_USB_NET_SR9800) += sr9800.o | ||
| 18 | obj-$(CONFIG_USB_NET_SMSC75XX) += smsc75xx.o | 19 | obj-$(CONFIG_USB_NET_SMSC75XX) += smsc75xx.o |
| 19 | obj-$(CONFIG_USB_NET_SMSC95XX) += smsc95xx.o | 20 | obj-$(CONFIG_USB_NET_SMSC95XX) += smsc95xx.o |
| 20 | obj-$(CONFIG_USB_NET_GL620A) += gl620a.o | 21 | obj-$(CONFIG_USB_NET_GL620A) += gl620a.o |
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 1a482344b3f5..660bd5ea9fc0 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c | |||
| @@ -1201,16 +1201,18 @@ static void hso_std_serial_read_bulk_callback(struct urb *urb) | |||
| 1201 | struct hso_serial *serial = urb->context; | 1201 | struct hso_serial *serial = urb->context; |
| 1202 | int status = urb->status; | 1202 | int status = urb->status; |
| 1203 | 1203 | ||
| 1204 | D4("\n--- Got serial_read_bulk callback %02x ---", status); | ||
| 1205 | |||
| 1204 | /* sanity check */ | 1206 | /* sanity check */ |
| 1205 | if (!serial) { | 1207 | if (!serial) { |
| 1206 | D1("serial == NULL"); | 1208 | D1("serial == NULL"); |
| 1207 | return; | 1209 | return; |
| 1208 | } else if (status) { | 1210 | } |
| 1211 | if (status) { | ||
| 1209 | handle_usb_error(status, __func__, serial->parent); | 1212 | handle_usb_error(status, __func__, serial->parent); |
| 1210 | return; | 1213 | return; |
| 1211 | } | 1214 | } |
| 1212 | 1215 | ||
| 1213 | D4("\n--- Got serial_read_bulk callback %02x ---", status); | ||
| 1214 | D1("Actual length = %d\n", urb->actual_length); | 1216 | D1("Actual length = %d\n", urb->actual_length); |
| 1215 | DUMP1(urb->transfer_buffer, urb->actual_length); | 1217 | DUMP1(urb->transfer_buffer, urb->actual_length); |
| 1216 | 1218 | ||
| @@ -1218,25 +1220,13 @@ static void hso_std_serial_read_bulk_callback(struct urb *urb) | |||
| 1218 | if (serial->port.count == 0) | 1220 | if (serial->port.count == 0) |
| 1219 | return; | 1221 | return; |
| 1220 | 1222 | ||
| 1221 | if (status == 0) { | 1223 | if (serial->parent->port_spec & HSO_INFO_CRC_BUG) |
| 1222 | if (serial->parent->port_spec & HSO_INFO_CRC_BUG) | 1224 | fix_crc_bug(urb, serial->in_endp->wMaxPacketSize); |
| 1223 | fix_crc_bug(urb, serial->in_endp->wMaxPacketSize); | 1225 | /* Valid data, handle RX data */ |
| 1224 | /* Valid data, handle RX data */ | 1226 | spin_lock(&serial->serial_lock); |
| 1225 | spin_lock(&serial->serial_lock); | 1227 | serial->rx_urb_filled[hso_urb_to_index(serial, urb)] = 1; |
| 1226 | serial->rx_urb_filled[hso_urb_to_index(serial, urb)] = 1; | 1228 | put_rxbuf_data_and_resubmit_bulk_urb(serial); |
| 1227 | put_rxbuf_data_and_resubmit_bulk_urb(serial); | 1229 | spin_unlock(&serial->serial_lock); |
| 1228 | spin_unlock(&serial->serial_lock); | ||
| 1229 | } else if (status == -ENOENT || status == -ECONNRESET) { | ||
| 1230 | /* Unlinked - check for throttled port. */ | ||
| 1231 | D2("Port %d, successfully unlinked urb", serial->minor); | ||
| 1232 | spin_lock(&serial->serial_lock); | ||
| 1233 | serial->rx_urb_filled[hso_urb_to_index(serial, urb)] = 0; | ||
| 1234 | hso_resubmit_rx_bulk_urb(serial, urb); | ||
| 1235 | spin_unlock(&serial->serial_lock); | ||
| 1236 | } else { | ||
| 1237 | D2("Port %d, status = %d for read urb", serial->minor, status); | ||
| 1238 | return; | ||
| 1239 | } | ||
| 1240 | } | 1230 | } |
| 1241 | 1231 | ||
| 1242 | /* | 1232 | /* |
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index 23bdd5b9274d..ff5c87128ffe 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c | |||
| @@ -712,6 +712,7 @@ static const struct usb_device_id products[] = { | |||
| 712 | {QMI_FIXED_INTF(0x19d2, 0x1255, 3)}, | 712 | {QMI_FIXED_INTF(0x19d2, 0x1255, 3)}, |
| 713 | {QMI_FIXED_INTF(0x19d2, 0x1255, 4)}, | 713 | {QMI_FIXED_INTF(0x19d2, 0x1255, 4)}, |
| 714 | {QMI_FIXED_INTF(0x19d2, 0x1256, 4)}, | 714 | {QMI_FIXED_INTF(0x19d2, 0x1256, 4)}, |
| 715 | {QMI_FIXED_INTF(0x19d2, 0x1270, 5)}, /* ZTE MF667 */ | ||
| 715 | {QMI_FIXED_INTF(0x19d2, 0x1401, 2)}, | 716 | {QMI_FIXED_INTF(0x19d2, 0x1401, 2)}, |
| 716 | {QMI_FIXED_INTF(0x19d2, 0x1402, 2)}, /* ZTE MF60 */ | 717 | {QMI_FIXED_INTF(0x19d2, 0x1402, 2)}, /* ZTE MF60 */ |
| 717 | {QMI_FIXED_INTF(0x19d2, 0x1424, 2)}, | 718 | {QMI_FIXED_INTF(0x19d2, 0x1424, 2)}, |
| @@ -723,6 +724,7 @@ static const struct usb_device_id products[] = { | |||
| 723 | {QMI_FIXED_INTF(0x1199, 0x68a2, 8)}, /* Sierra Wireless MC7710 in QMI mode */ | 724 | {QMI_FIXED_INTF(0x1199, 0x68a2, 8)}, /* Sierra Wireless MC7710 in QMI mode */ |
| 724 | {QMI_FIXED_INTF(0x1199, 0x68a2, 19)}, /* Sierra Wireless MC7710 in QMI mode */ | 725 | {QMI_FIXED_INTF(0x1199, 0x68a2, 19)}, /* Sierra Wireless MC7710 in QMI mode */ |
| 725 | {QMI_FIXED_INTF(0x1199, 0x901c, 8)}, /* Sierra Wireless EM7700 */ | 726 | {QMI_FIXED_INTF(0x1199, 0x901c, 8)}, /* Sierra Wireless EM7700 */ |
| 727 | {QMI_FIXED_INTF(0x1199, 0x9051, 8)}, /* Netgear AirCard 340U */ | ||
| 726 | {QMI_FIXED_INTF(0x1bbb, 0x011e, 4)}, /* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */ | 728 | {QMI_FIXED_INTF(0x1bbb, 0x011e, 4)}, /* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */ |
| 727 | {QMI_FIXED_INTF(0x2357, 0x0201, 4)}, /* TP-LINK HSUPA Modem MA180 */ | 729 | {QMI_FIXED_INTF(0x2357, 0x0201, 4)}, /* TP-LINK HSUPA Modem MA180 */ |
| 728 | {QMI_FIXED_INTF(0x2357, 0x9000, 4)}, /* TP-LINK MA260 */ | 730 | {QMI_FIXED_INTF(0x2357, 0x9000, 4)}, /* TP-LINK MA260 */ |
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index e8fac732c6f1..d89dbe395ad2 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c | |||
| @@ -2273,22 +2273,21 @@ static int rtl8152_open(struct net_device *netdev) | |||
| 2273 | struct r8152 *tp = netdev_priv(netdev); | 2273 | struct r8152 *tp = netdev_priv(netdev); |
| 2274 | int res = 0; | 2274 | int res = 0; |
| 2275 | 2275 | ||
| 2276 | rtl8152_set_speed(tp, AUTONEG_ENABLE, | ||
| 2277 | tp->mii.supports_gmii ? SPEED_1000 : SPEED_100, | ||
| 2278 | DUPLEX_FULL); | ||
| 2279 | tp->speed = 0; | ||
| 2280 | netif_carrier_off(netdev); | ||
| 2281 | netif_start_queue(netdev); | ||
| 2282 | set_bit(WORK_ENABLE, &tp->flags); | ||
| 2276 | res = usb_submit_urb(tp->intr_urb, GFP_KERNEL); | 2283 | res = usb_submit_urb(tp->intr_urb, GFP_KERNEL); |
| 2277 | if (res) { | 2284 | if (res) { |
| 2278 | if (res == -ENODEV) | 2285 | if (res == -ENODEV) |
| 2279 | netif_device_detach(tp->netdev); | 2286 | netif_device_detach(tp->netdev); |
| 2280 | netif_warn(tp, ifup, netdev, "intr_urb submit failed: %d\n", | 2287 | netif_warn(tp, ifup, netdev, "intr_urb submit failed: %d\n", |
| 2281 | res); | 2288 | res); |
| 2282 | return res; | ||
| 2283 | } | 2289 | } |
| 2284 | 2290 | ||
| 2285 | rtl8152_set_speed(tp, AUTONEG_ENABLE, | ||
| 2286 | tp->mii.supports_gmii ? SPEED_1000 : SPEED_100, | ||
| 2287 | DUPLEX_FULL); | ||
| 2288 | tp->speed = 0; | ||
| 2289 | netif_carrier_off(netdev); | ||
| 2290 | netif_start_queue(netdev); | ||
| 2291 | set_bit(WORK_ENABLE, &tp->flags); | ||
| 2292 | 2291 | ||
| 2293 | return res; | 2292 | return res; |
| 2294 | } | 2293 | } |
| @@ -2298,8 +2297,8 @@ static int rtl8152_close(struct net_device *netdev) | |||
| 2298 | struct r8152 *tp = netdev_priv(netdev); | 2297 | struct r8152 *tp = netdev_priv(netdev); |
| 2299 | int res = 0; | 2298 | int res = 0; |
| 2300 | 2299 | ||
| 2301 | usb_kill_urb(tp->intr_urb); | ||
| 2302 | clear_bit(WORK_ENABLE, &tp->flags); | 2300 | clear_bit(WORK_ENABLE, &tp->flags); |
| 2301 | usb_kill_urb(tp->intr_urb); | ||
| 2303 | cancel_delayed_work_sync(&tp->schedule); | 2302 | cancel_delayed_work_sync(&tp->schedule); |
| 2304 | netif_stop_queue(netdev); | 2303 | netif_stop_queue(netdev); |
| 2305 | tasklet_disable(&tp->tl); | 2304 | tasklet_disable(&tp->tl); |
diff --git a/drivers/net/usb/sr9800.c b/drivers/net/usb/sr9800.c new file mode 100644 index 000000000000..4175eb9fdeca --- /dev/null +++ b/drivers/net/usb/sr9800.c | |||
| @@ -0,0 +1,870 @@ | |||
| 1 | /* CoreChip-sz SR9800 one chip USB 2.0 Ethernet Devices | ||
| 2 | * | ||
| 3 | * Author : Liu Junliang <liujunliang_ljl@163.com> | ||
| 4 | * | ||
| 5 | * Based on asix_common.c, asix_devices.c | ||
| 6 | * | ||
| 7 | * This file is licensed under the terms of the GNU General Public License | ||
| 8 | * version 2. This program is licensed "as is" without any warranty of any | ||
| 9 | * kind, whether express or implied.* | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include <linux/module.h> | ||
| 13 | #include <linux/kmod.h> | ||
| 14 | #include <linux/init.h> | ||
| 15 | #include <linux/netdevice.h> | ||
| 16 | #include <linux/etherdevice.h> | ||
| 17 | #include <linux/ethtool.h> | ||
| 18 | #include <linux/workqueue.h> | ||
| 19 | #include <linux/mii.h> | ||
| 20 | #include <linux/usb.h> | ||
| 21 | #include <linux/crc32.h> | ||
| 22 | #include <linux/usb/usbnet.h> | ||
| 23 | #include <linux/slab.h> | ||
| 24 | #include <linux/if_vlan.h> | ||
| 25 | |||
| 26 | #include "sr9800.h" | ||
| 27 | |||
| 28 | static int sr_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, | ||
| 29 | u16 size, void *data) | ||
| 30 | { | ||
| 31 | int err; | ||
| 32 | |||
| 33 | err = usbnet_read_cmd(dev, cmd, SR_REQ_RD_REG, value, index, | ||
| 34 | data, size); | ||
| 35 | if ((err != size) && (err >= 0)) | ||
| 36 | err = -EINVAL; | ||
| 37 | |||
| 38 | return err; | ||
| 39 | } | ||
| 40 | |||
| 41 | static int sr_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, | ||
| 42 | u16 size, void *data) | ||
| 43 | { | ||
| 44 | int err; | ||
| 45 | |||
| 46 | err = usbnet_write_cmd(dev, cmd, SR_REQ_WR_REG, value, index, | ||
| 47 | data, size); | ||
| 48 | if ((err != size) && (err >= 0)) | ||
| 49 | err = -EINVAL; | ||
| 50 | |||
| 51 | return err; | ||
| 52 | } | ||
| 53 | |||
| 54 | static void | ||
| 55 | sr_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, u16 index, | ||
| 56 | u16 size, void *data) | ||
| 57 | { | ||
| 58 | usbnet_write_cmd_async(dev, cmd, SR_REQ_WR_REG, value, index, data, | ||
| 59 | size); | ||
| 60 | } | ||
| 61 | |||
| 62 | static int sr_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | ||
| 63 | { | ||
| 64 | int offset = 0; | ||
| 65 | |||
| 66 | while (offset + sizeof(u32) < skb->len) { | ||
| 67 | struct sk_buff *sr_skb; | ||
| 68 | u16 size; | ||
| 69 | u32 header = get_unaligned_le32(skb->data + offset); | ||
| 70 | |||
| 71 | offset += sizeof(u32); | ||
| 72 | /* get the packet length */ | ||
| 73 | size = (u16) (header & 0x7ff); | ||
| 74 | if (size != ((~header >> 16) & 0x07ff)) { | ||
| 75 | netdev_err(dev->net, "%s : Bad Header Length\n", | ||
| 76 | __func__); | ||
| 77 | return 0; | ||
| 78 | } | ||
| 79 | |||
| 80 | if ((size > dev->net->mtu + ETH_HLEN + VLAN_HLEN) || | ||
| 81 | (size + offset > skb->len)) { | ||
| 82 | netdev_err(dev->net, "%s : Bad RX Length %d\n", | ||
| 83 | __func__, size); | ||
| 84 | return 0; | ||
| 85 | } | ||
| 86 | sr_skb = netdev_alloc_skb_ip_align(dev->net, size); | ||
| 87 | if (!sr_skb) | ||
| 88 | return 0; | ||
| 89 | |||
| 90 | skb_put(sr_skb, size); | ||
| 91 | memcpy(sr_skb->data, skb->data + offset, size); | ||
| 92 | usbnet_skb_return(dev, sr_skb); | ||
| 93 | |||
| 94 | offset += (size + 1) & 0xfffe; | ||
| 95 | } | ||
| 96 | |||
| 97 | if (skb->len != offset) { | ||
| 98 | netdev_err(dev->net, "%s : Bad SKB Length %d\n", __func__, | ||
| 99 | skb->len); | ||
| 100 | return 0; | ||
| 101 | } | ||
| 102 | |||
| 103 | return 1; | ||
| 104 | } | ||
| 105 | |||
| 106 | static struct sk_buff *sr_tx_fixup(struct usbnet *dev, struct sk_buff *skb, | ||
| 107 | gfp_t flags) | ||
| 108 | { | ||
| 109 | int headroom = skb_headroom(skb); | ||
| 110 | int tailroom = skb_tailroom(skb); | ||
| 111 | u32 padbytes = 0xffff0000; | ||
| 112 | u32 packet_len; | ||
| 113 | int padlen; | ||
| 114 | |||
| 115 | padlen = ((skb->len + 4) % (dev->maxpacket - 1)) ? 0 : 4; | ||
| 116 | |||
| 117 | if ((!skb_cloned(skb)) && ((headroom + tailroom) >= (4 + padlen))) { | ||
| 118 | if ((headroom < 4) || (tailroom < padlen)) { | ||
| 119 | skb->data = memmove(skb->head + 4, skb->data, | ||
| 120 | skb->len); | ||
| 121 | skb_set_tail_pointer(skb, skb->len); | ||
| 122 | } | ||
| 123 | } else { | ||
| 124 | struct sk_buff *skb2; | ||
| 125 | skb2 = skb_copy_expand(skb, 4, padlen, flags); | ||
| 126 | dev_kfree_skb_any(skb); | ||
| 127 | skb = skb2; | ||
| 128 | if (!skb) | ||
| 129 | return NULL; | ||
| 130 | } | ||
| 131 | |||
| 132 | skb_push(skb, 4); | ||
| 133 | packet_len = (((skb->len - 4) ^ 0x0000ffff) << 16) + (skb->len - 4); | ||
| 134 | cpu_to_le32s(&packet_len); | ||
| 135 | skb_copy_to_linear_data(skb, &packet_len, sizeof(packet_len)); | ||
| 136 | |||
| 137 | if (padlen) { | ||
| 138 | cpu_to_le32s(&padbytes); | ||
| 139 | memcpy(skb_tail_pointer(skb), &padbytes, sizeof(padbytes)); | ||
| 140 | skb_put(skb, sizeof(padbytes)); | ||
| 141 | } | ||
| 142 | |||
| 143 | return skb; | ||
| 144 | } | ||
| 145 | |||
| 146 | static void sr_status(struct usbnet *dev, struct urb *urb) | ||
| 147 | { | ||
| 148 | struct sr9800_int_data *event; | ||
| 149 | int link; | ||
| 150 | |||
| 151 | if (urb->actual_length < 8) | ||
| 152 | return; | ||
| 153 | |||
| 154 | event = urb->transfer_buffer; | ||
| 155 | link = event->link & 0x01; | ||
| 156 | if (netif_carrier_ok(dev->net) != link) { | ||
| 157 | usbnet_link_change(dev, link, 1); | ||
| 158 | netdev_dbg(dev->net, "Link Status is: %d\n", link); | ||
| 159 | } | ||
| 160 | |||
| 161 | return; | ||
| 162 | } | ||
| 163 | |||
| 164 | static inline int sr_set_sw_mii(struct usbnet *dev) | ||
| 165 | { | ||
| 166 | int ret; | ||
| 167 | |||
| 168 | ret = sr_write_cmd(dev, SR_CMD_SET_SW_MII, 0x0000, 0, 0, NULL); | ||
| 169 | if (ret < 0) | ||
| 170 | netdev_err(dev->net, "Failed to enable software MII access\n"); | ||
| 171 | return ret; | ||
| 172 | } | ||
| 173 | |||
| 174 | static inline int sr_set_hw_mii(struct usbnet *dev) | ||
| 175 | { | ||
| 176 | int ret; | ||
| 177 | |||
| 178 | ret = sr_write_cmd(dev, SR_CMD_SET_HW_MII, 0x0000, 0, 0, NULL); | ||
| 179 | if (ret < 0) | ||
| 180 | netdev_err(dev->net, "Failed to enable hardware MII access\n"); | ||
| 181 | return ret; | ||
| 182 | } | ||
| 183 | |||
| 184 | static inline int sr_get_phy_addr(struct usbnet *dev) | ||
| 185 | { | ||
| 186 | u8 buf[2]; | ||
| 187 | int ret; | ||
| 188 | |||
| 189 | ret = sr_read_cmd(dev, SR_CMD_READ_PHY_ID, 0, 0, 2, buf); | ||
| 190 | if (ret < 0) { | ||
| 191 | netdev_err(dev->net, "%s : Error reading PHYID register:%02x\n", | ||
| 192 | __func__, ret); | ||
| 193 | goto out; | ||
| 194 | } | ||
| 195 | netdev_dbg(dev->net, "%s : returning 0x%04x\n", __func__, | ||
| 196 | *((__le16 *)buf)); | ||
| 197 | |||
| 198 | ret = buf[1]; | ||
| 199 | |||
| 200 | out: | ||
| 201 | return ret; | ||
| 202 | } | ||
| 203 | |||
| 204 | static int sr_sw_reset(struct usbnet *dev, u8 flags) | ||
| 205 | { | ||
| 206 | int ret; | ||
| 207 | |||
| 208 | ret = sr_write_cmd(dev, SR_CMD_SW_RESET, flags, 0, 0, NULL); | ||
| 209 | if (ret < 0) | ||
| 210 | netdev_err(dev->net, "Failed to send software reset:%02x\n", | ||
| 211 | ret); | ||
| 212 | |||
| 213 | return ret; | ||
| 214 | } | ||
| 215 | |||
| 216 | static u16 sr_read_rx_ctl(struct usbnet *dev) | ||
| 217 | { | ||
| 218 | __le16 v; | ||
| 219 | int ret; | ||
| 220 | |||
| 221 | ret = sr_read_cmd(dev, SR_CMD_READ_RX_CTL, 0, 0, 2, &v); | ||
| 222 | if (ret < 0) { | ||
| 223 | netdev_err(dev->net, "Error reading RX_CTL register:%02x\n", | ||
| 224 | ret); | ||
| 225 | goto out; | ||
| 226 | } | ||
| 227 | |||
| 228 | ret = le16_to_cpu(v); | ||
| 229 | out: | ||
| 230 | return ret; | ||
| 231 | } | ||
| 232 | |||
| 233 | static int sr_write_rx_ctl(struct usbnet *dev, u16 mode) | ||
| 234 | { | ||
| 235 | int ret; | ||
| 236 | |||
| 237 | netdev_dbg(dev->net, "%s : mode = 0x%04x\n", __func__, mode); | ||
| 238 | ret = sr_write_cmd(dev, SR_CMD_WRITE_RX_CTL, mode, 0, 0, NULL); | ||
| 239 | if (ret < 0) | ||
| 240 | netdev_err(dev->net, | ||
| 241 | "Failed to write RX_CTL mode to 0x%04x:%02x\n", | ||
| 242 | mode, ret); | ||
| 243 | |||
| 244 | return ret; | ||
| 245 | } | ||
| 246 | |||
| 247 | static u16 sr_read_medium_status(struct usbnet *dev) | ||
| 248 | { | ||
| 249 | __le16 v; | ||
| 250 | int ret; | ||
| 251 | |||
| 252 | ret = sr_read_cmd(dev, SR_CMD_READ_MEDIUM_STATUS, 0, 0, 2, &v); | ||
| 253 | if (ret < 0) { | ||
| 254 | netdev_err(dev->net, | ||
| 255 | "Error reading Medium Status register:%02x\n", ret); | ||
| 256 | return ret; /* TODO: callers not checking for error ret */ | ||
| 257 | } | ||
| 258 | |||
| 259 | return le16_to_cpu(v); | ||
| 260 | } | ||
| 261 | |||
| 262 | static int sr_write_medium_mode(struct usbnet *dev, u16 mode) | ||
| 263 | { | ||
| 264 | int ret; | ||
| 265 | |||
| 266 | netdev_dbg(dev->net, "%s : mode = 0x%04x\n", __func__, mode); | ||
| 267 | ret = sr_write_cmd(dev, SR_CMD_WRITE_MEDIUM_MODE, mode, 0, 0, NULL); | ||
| 268 | if (ret < 0) | ||
| 269 | netdev_err(dev->net, | ||
| 270 | "Failed to write Medium Mode mode to 0x%04x:%02x\n", | ||
| 271 | mode, ret); | ||
| 272 | return ret; | ||
| 273 | } | ||
| 274 | |||
| 275 | static int sr_write_gpio(struct usbnet *dev, u16 value, int sleep) | ||
| 276 | { | ||
| 277 | int ret; | ||
| 278 | |||
| 279 | netdev_dbg(dev->net, "%s : value = 0x%04x\n", __func__, value); | ||
| 280 | ret = sr_write_cmd(dev, SR_CMD_WRITE_GPIOS, value, 0, 0, NULL); | ||
| 281 | if (ret < 0) | ||
| 282 | netdev_err(dev->net, "Failed to write GPIO value 0x%04x:%02x\n", | ||
| 283 | value, ret); | ||
| 284 | if (sleep) | ||
| 285 | msleep(sleep); | ||
| 286 | |||
| 287 | return ret; | ||
| 288 | } | ||
| 289 | |||
| 290 | /* SR9800 have a 16-bit RX_CTL value */ | ||
| 291 | static void sr_set_multicast(struct net_device *net) | ||
| 292 | { | ||
| 293 | struct usbnet *dev = netdev_priv(net); | ||
| 294 | struct sr_data *data = (struct sr_data *)&dev->data; | ||
| 295 | u16 rx_ctl = SR_DEFAULT_RX_CTL; | ||
| 296 | |||
| 297 | if (net->flags & IFF_PROMISC) { | ||
| 298 | rx_ctl |= SR_RX_CTL_PRO; | ||
| 299 | } else if (net->flags & IFF_ALLMULTI || | ||
| 300 | netdev_mc_count(net) > SR_MAX_MCAST) { | ||
| 301 | rx_ctl |= SR_RX_CTL_AMALL; | ||
| 302 | } else if (netdev_mc_empty(net)) { | ||
| 303 | /* just broadcast and directed */ | ||
| 304 | } else { | ||
| 305 | /* We use the 20 byte dev->data | ||
| 306 | * for our 8 byte filter buffer | ||
| 307 | * to avoid allocating memory that | ||
| 308 | * is tricky to free later | ||
| 309 | */ | ||
| 310 | struct netdev_hw_addr *ha; | ||
| 311 | u32 crc_bits; | ||
| 312 | |||
| 313 | memset(data->multi_filter, 0, SR_MCAST_FILTER_SIZE); | ||
| 314 | |||
| 315 | /* Build the multicast hash filter. */ | ||
| 316 | netdev_for_each_mc_addr(ha, net) { | ||
| 317 | crc_bits = ether_crc(ETH_ALEN, ha->addr) >> 26; | ||
| 318 | data->multi_filter[crc_bits >> 3] |= | ||
| 319 | 1 << (crc_bits & 7); | ||
| 320 | } | ||
| 321 | |||
| 322 | sr_write_cmd_async(dev, SR_CMD_WRITE_MULTI_FILTER, 0, 0, | ||
| 323 | SR_MCAST_FILTER_SIZE, data->multi_filter); | ||
| 324 | |||
| 325 | rx_ctl |= SR_RX_CTL_AM; | ||
| 326 | } | ||
| 327 | |||
| 328 | sr_write_cmd_async(dev, SR_CMD_WRITE_RX_CTL, rx_ctl, 0, 0, NULL); | ||
| 329 | } | ||
| 330 | |||
| 331 | static int sr_mdio_read(struct net_device *net, int phy_id, int loc) | ||
| 332 | { | ||
| 333 | struct usbnet *dev = netdev_priv(net); | ||
| 334 | __le16 res; | ||
| 335 | |||
| 336 | mutex_lock(&dev->phy_mutex); | ||
| 337 | sr_set_sw_mii(dev); | ||
| 338 | sr_read_cmd(dev, SR_CMD_READ_MII_REG, phy_id, (__u16)loc, 2, &res); | ||
| 339 | sr_set_hw_mii(dev); | ||
| 340 | mutex_unlock(&dev->phy_mutex); | ||
| 341 | |||
| 342 | netdev_dbg(dev->net, | ||
| 343 | "%s : phy_id=0x%02x, loc=0x%02x, returns=0x%04x\n", __func__, | ||
| 344 | phy_id, loc, le16_to_cpu(res)); | ||
| 345 | |||
| 346 | return le16_to_cpu(res); | ||
| 347 | } | ||
| 348 | |||
| 349 | static void | ||
| 350 | sr_mdio_write(struct net_device *net, int phy_id, int loc, int val) | ||
| 351 | { | ||
| 352 | struct usbnet *dev = netdev_priv(net); | ||
| 353 | __le16 res = cpu_to_le16(val); | ||
| 354 | |||
| 355 | netdev_dbg(dev->net, | ||
| 356 | "%s : phy_id=0x%02x, loc=0x%02x, val=0x%04x\n", __func__, | ||
| 357 | phy_id, loc, val); | ||
| 358 | mutex_lock(&dev->phy_mutex); | ||
| 359 | sr_set_sw_mii(dev); | ||
| 360 | sr_write_cmd(dev, SR_CMD_WRITE_MII_REG, phy_id, (__u16)loc, 2, &res); | ||
| 361 | sr_set_hw_mii(dev); | ||
| 362 | mutex_unlock(&dev->phy_mutex); | ||
| 363 | } | ||
| 364 | |||
| 365 | /* Get the PHY Identifier from the PHYSID1 & PHYSID2 MII registers */ | ||
| 366 | static u32 sr_get_phyid(struct usbnet *dev) | ||
| 367 | { | ||
| 368 | int phy_reg; | ||
| 369 | u32 phy_id; | ||
| 370 | int i; | ||
| 371 | |||
| 372 | /* Poll for the rare case the FW or phy isn't ready yet. */ | ||
| 373 | for (i = 0; i < 100; i++) { | ||
| 374 | phy_reg = sr_mdio_read(dev->net, dev->mii.phy_id, MII_PHYSID1); | ||
| 375 | if (phy_reg != 0 && phy_reg != 0xFFFF) | ||
| 376 | break; | ||
| 377 | mdelay(1); | ||
| 378 | } | ||
| 379 | |||
| 380 | if (phy_reg <= 0 || phy_reg == 0xFFFF) | ||
| 381 | return 0; | ||
| 382 | |||
| 383 | phy_id = (phy_reg & 0xffff) << 16; | ||
| 384 | |||
| 385 | phy_reg = sr_mdio_read(dev->net, dev->mii.phy_id, MII_PHYSID2); | ||
| 386 | if (phy_reg < 0) | ||
| 387 | return 0; | ||
| 388 | |||
| 389 | phy_id |= (phy_reg & 0xffff); | ||
| 390 | |||
| 391 | return phy_id; | ||
| 392 | } | ||
| 393 | |||
| 394 | static void | ||
| 395 | sr_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) | ||
| 396 | { | ||
| 397 | struct usbnet *dev = netdev_priv(net); | ||
| 398 | u8 opt; | ||
| 399 | |||
| 400 | if (sr_read_cmd(dev, SR_CMD_READ_MONITOR_MODE, 0, 0, 1, &opt) < 0) { | ||
| 401 | wolinfo->supported = 0; | ||
| 402 | wolinfo->wolopts = 0; | ||
| 403 | return; | ||
| 404 | } | ||
| 405 | wolinfo->supported = WAKE_PHY | WAKE_MAGIC; | ||
| 406 | wolinfo->wolopts = 0; | ||
| 407 | if (opt & SR_MONITOR_LINK) | ||
| 408 | wolinfo->wolopts |= WAKE_PHY; | ||
| 409 | if (opt & SR_MONITOR_MAGIC) | ||
| 410 | wolinfo->wolopts |= WAKE_MAGIC; | ||
| 411 | } | ||
| 412 | |||
| 413 | static int | ||
| 414 | sr_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) | ||
| 415 | { | ||
| 416 | struct usbnet *dev = netdev_priv(net); | ||
| 417 | u8 opt = 0; | ||
| 418 | |||
| 419 | if (wolinfo->wolopts & WAKE_PHY) | ||
| 420 | opt |= SR_MONITOR_LINK; | ||
| 421 | if (wolinfo->wolopts & WAKE_MAGIC) | ||
| 422 | opt |= SR_MONITOR_MAGIC; | ||
| 423 | |||
| 424 | if (sr_write_cmd(dev, SR_CMD_WRITE_MONITOR_MODE, | ||
| 425 | opt, 0, 0, NULL) < 0) | ||
| 426 | return -EINVAL; | ||
| 427 | |||
| 428 | return 0; | ||
| 429 | } | ||
| 430 | |||
| 431 | static int sr_get_eeprom_len(struct net_device *net) | ||
| 432 | { | ||
| 433 | struct usbnet *dev = netdev_priv(net); | ||
| 434 | struct sr_data *data = (struct sr_data *)&dev->data; | ||
| 435 | |||
| 436 | return data->eeprom_len; | ||
| 437 | } | ||
| 438 | |||
| 439 | static int sr_get_eeprom(struct net_device *net, | ||
| 440 | struct ethtool_eeprom *eeprom, u8 *data) | ||
| 441 | { | ||
| 442 | struct usbnet *dev = netdev_priv(net); | ||
| 443 | __le16 *ebuf = (__le16 *)data; | ||
| 444 | int ret; | ||
| 445 | int i; | ||
| 446 | |||
| 447 | /* Crude hack to ensure that we don't overwrite memory | ||
| 448 | * if an odd length is supplied | ||
| 449 | */ | ||
| 450 | if (eeprom->len % 2) | ||
| 451 | return -EINVAL; | ||
| 452 | |||
| 453 | eeprom->magic = SR_EEPROM_MAGIC; | ||
| 454 | |||
| 455 | /* sr9800 returns 2 bytes from eeprom on read */ | ||
| 456 | for (i = 0; i < eeprom->len / 2; i++) { | ||
| 457 | ret = sr_read_cmd(dev, SR_CMD_READ_EEPROM, eeprom->offset + i, | ||
| 458 | 0, 2, &ebuf[i]); | ||
| 459 | if (ret < 0) | ||
| 460 | return -EINVAL; | ||
| 461 | } | ||
| 462 | return 0; | ||
| 463 | } | ||
| 464 | |||
| 465 | static void sr_get_drvinfo(struct net_device *net, | ||
| 466 | struct ethtool_drvinfo *info) | ||
| 467 | { | ||
| 468 | struct usbnet *dev = netdev_priv(net); | ||
| 469 | struct sr_data *data = (struct sr_data *)&dev->data; | ||
| 470 | |||
| 471 | /* Inherit standard device info */ | ||
| 472 | usbnet_get_drvinfo(net, info); | ||
| 473 | strncpy(info->driver, DRIVER_NAME, sizeof(info->driver)); | ||
| 474 | strncpy(info->version, DRIVER_VERSION, sizeof(info->version)); | ||
| 475 | info->eedump_len = data->eeprom_len; | ||
| 476 | } | ||
| 477 | |||
| 478 | static u32 sr_get_link(struct net_device *net) | ||
| 479 | { | ||
| 480 | struct usbnet *dev = netdev_priv(net); | ||
| 481 | |||
| 482 | return mii_link_ok(&dev->mii); | ||
| 483 | } | ||
| 484 | |||
| 485 | static int sr_ioctl(struct net_device *net, struct ifreq *rq, int cmd) | ||
| 486 | { | ||
| 487 | struct usbnet *dev = netdev_priv(net); | ||
| 488 | |||
| 489 | return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL); | ||
| 490 | } | ||
| 491 | |||
| 492 | static int sr_set_mac_address(struct net_device *net, void *p) | ||
| 493 | { | ||
| 494 | struct usbnet *dev = netdev_priv(net); | ||
| 495 | struct sr_data *data = (struct sr_data *)&dev->data; | ||
| 496 | struct sockaddr *addr = p; | ||
| 497 | |||
| 498 | if (netif_running(net)) | ||
| 499 | return -EBUSY; | ||
| 500 | if (!is_valid_ether_addr(addr->sa_data)) | ||
| 501 | return -EADDRNOTAVAIL; | ||
| 502 | |||
| 503 | memcpy(net->dev_addr, addr->sa_data, ETH_ALEN); | ||
| 504 | |||
| 505 | /* We use the 20 byte dev->data | ||
| 506 | * for our 6 byte mac buffer | ||
| 507 | * to avoid allocating memory that | ||
| 508 | * is tricky to free later | ||
| 509 | */ | ||
| 510 | memcpy(data->mac_addr, addr->sa_data, ETH_ALEN); | ||
| 511 | sr_write_cmd_async(dev, SR_CMD_WRITE_NODE_ID, 0, 0, ETH_ALEN, | ||
| 512 | data->mac_addr); | ||
| 513 | |||
| 514 | return 0; | ||
| 515 | } | ||
| 516 | |||
| 517 | static const struct ethtool_ops sr9800_ethtool_ops = { | ||
| 518 | .get_drvinfo = sr_get_drvinfo, | ||
| 519 | .get_link = sr_get_link, | ||
| 520 | .get_msglevel = usbnet_get_msglevel, | ||
| 521 | .set_msglevel = usbnet_set_msglevel, | ||
| 522 | .get_wol = sr_get_wol, | ||
| 523 | .set_wol = sr_set_wol, | ||
| 524 | .get_eeprom_len = sr_get_eeprom_len, | ||
| 525 | .get_eeprom = sr_get_eeprom, | ||
| 526 | .get_settings = usbnet_get_settings, | ||
| 527 | .set_settings = usbnet_set_settings, | ||
| 528 | .nway_reset = usbnet_nway_reset, | ||
| 529 | }; | ||
| 530 | |||
| 531 | static int sr9800_link_reset(struct usbnet *dev) | ||
| 532 | { | ||
| 533 | struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET }; | ||
| 534 | u16 mode; | ||
| 535 | |||
| 536 | mii_check_media(&dev->mii, 1, 1); | ||
| 537 | mii_ethtool_gset(&dev->mii, &ecmd); | ||
| 538 | mode = SR9800_MEDIUM_DEFAULT; | ||
| 539 | |||
| 540 | if (ethtool_cmd_speed(&ecmd) != SPEED_100) | ||
| 541 | mode &= ~SR_MEDIUM_PS; | ||
| 542 | |||
| 543 | if (ecmd.duplex != DUPLEX_FULL) | ||
| 544 | mode &= ~SR_MEDIUM_FD; | ||
| 545 | |||
| 546 | netdev_dbg(dev->net, "%s : speed: %u duplex: %d mode: 0x%04x\n", | ||
| 547 | __func__, ethtool_cmd_speed(&ecmd), ecmd.duplex, mode); | ||
| 548 | |||
| 549 | sr_write_medium_mode(dev, mode); | ||
| 550 | |||
| 551 | return 0; | ||
| 552 | } | ||
| 553 | |||
| 554 | |||
| 555 | static int sr9800_set_default_mode(struct usbnet *dev) | ||
| 556 | { | ||
| 557 | u16 rx_ctl; | ||
| 558 | int ret; | ||
| 559 | |||
| 560 | sr_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET); | ||
| 561 | sr_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE, | ||
| 562 | ADVERTISE_ALL | ADVERTISE_CSMA); | ||
| 563 | mii_nway_restart(&dev->mii); | ||
| 564 | |||
| 565 | ret = sr_write_medium_mode(dev, SR9800_MEDIUM_DEFAULT); | ||
| 566 | if (ret < 0) | ||
| 567 | goto out; | ||
| 568 | |||
| 569 | ret = sr_write_cmd(dev, SR_CMD_WRITE_IPG012, | ||
| 570 | SR9800_IPG0_DEFAULT | SR9800_IPG1_DEFAULT, | ||
| 571 | SR9800_IPG2_DEFAULT, 0, NULL); | ||
| 572 | if (ret < 0) { | ||
| 573 | netdev_dbg(dev->net, "Write IPG,IPG1,IPG2 failed: %d\n", ret); | ||
| 574 | goto out; | ||
| 575 | } | ||
| 576 | |||
| 577 | /* Set RX_CTL to default values with 2k buffer, and enable cactus */ | ||
| 578 | ret = sr_write_rx_ctl(dev, SR_DEFAULT_RX_CTL); | ||
| 579 | if (ret < 0) | ||
| 580 | goto out; | ||
| 581 | |||
| 582 | rx_ctl = sr_read_rx_ctl(dev); | ||
| 583 | netdev_dbg(dev->net, "RX_CTL is 0x%04x after all initializations\n", | ||
| 584 | rx_ctl); | ||
| 585 | |||
| 586 | rx_ctl = sr_read_medium_status(dev); | ||
| 587 | netdev_dbg(dev->net, "Medium Status:0x%04x after all initializations\n", | ||
| 588 | rx_ctl); | ||
| 589 | |||
| 590 | return 0; | ||
| 591 | out: | ||
| 592 | return ret; | ||
| 593 | } | ||
| 594 | |||
| 595 | static int sr9800_reset(struct usbnet *dev) | ||
| 596 | { | ||
| 597 | struct sr_data *data = (struct sr_data *)&dev->data; | ||
| 598 | int ret, embd_phy; | ||
| 599 | u16 rx_ctl; | ||
| 600 | |||
| 601 | ret = sr_write_gpio(dev, | ||
| 602 | SR_GPIO_RSE | SR_GPIO_GPO_2 | SR_GPIO_GPO2EN, 5); | ||
| 603 | if (ret < 0) | ||
| 604 | goto out; | ||
| 605 | |||
| 606 | embd_phy = ((sr_get_phy_addr(dev) & 0x1f) == 0x10 ? 1 : 0); | ||
| 607 | |||
| 608 | ret = sr_write_cmd(dev, SR_CMD_SW_PHY_SELECT, embd_phy, 0, 0, NULL); | ||
| 609 | if (ret < 0) { | ||
| 610 | netdev_dbg(dev->net, "Select PHY #1 failed: %d\n", ret); | ||
| 611 | goto out; | ||
| 612 | } | ||
| 613 | |||
| 614 | ret = sr_sw_reset(dev, SR_SWRESET_IPPD | SR_SWRESET_PRL); | ||
| 615 | if (ret < 0) | ||
| 616 | goto out; | ||
| 617 | |||
| 618 | msleep(150); | ||
| 619 | |||
| 620 | ret = sr_sw_reset(dev, SR_SWRESET_CLEAR); | ||
| 621 | if (ret < 0) | ||
| 622 | goto out; | ||
| 623 | |||
| 624 | msleep(150); | ||
| 625 | |||
| 626 | if (embd_phy) { | ||
| 627 | ret = sr_sw_reset(dev, SR_SWRESET_IPRL); | ||
| 628 | if (ret < 0) | ||
| 629 | goto out; | ||
| 630 | } else { | ||
| 631 | ret = sr_sw_reset(dev, SR_SWRESET_PRTE); | ||
| 632 | if (ret < 0) | ||
| 633 | goto out; | ||
| 634 | } | ||
| 635 | |||
| 636 | msleep(150); | ||
| 637 | rx_ctl = sr_read_rx_ctl(dev); | ||
| 638 | netdev_dbg(dev->net, "RX_CTL is 0x%04x after software reset\n", rx_ctl); | ||
| 639 | ret = sr_write_rx_ctl(dev, 0x0000); | ||
| 640 | if (ret < 0) | ||
| 641 | goto out; | ||
| 642 | |||
| 643 | rx_ctl = sr_read_rx_ctl(dev); | ||
| 644 | netdev_dbg(dev->net, "RX_CTL is 0x%04x setting to 0x0000\n", rx_ctl); | ||
| 645 | |||
| 646 | ret = sr_sw_reset(dev, SR_SWRESET_PRL); | ||
| 647 | if (ret < 0) | ||
| 648 | goto out; | ||
| 649 | |||
| 650 | msleep(150); | ||
| 651 | |||
| 652 | ret = sr_sw_reset(dev, SR_SWRESET_IPRL | SR_SWRESET_PRL); | ||
| 653 | if (ret < 0) | ||
| 654 | goto out; | ||
| 655 | |||
| 656 | msleep(150); | ||
| 657 | |||
| 658 | ret = sr9800_set_default_mode(dev); | ||
| 659 | if (ret < 0) | ||
| 660 | goto out; | ||
| 661 | |||
| 662 | /* Rewrite MAC address */ | ||
| 663 | memcpy(data->mac_addr, dev->net->dev_addr, ETH_ALEN); | ||
| 664 | ret = sr_write_cmd(dev, SR_CMD_WRITE_NODE_ID, 0, 0, ETH_ALEN, | ||
| 665 | data->mac_addr); | ||
| 666 | if (ret < 0) | ||
| 667 | goto out; | ||
| 668 | |||
| 669 | return 0; | ||
| 670 | |||
| 671 | out: | ||
| 672 | return ret; | ||
| 673 | } | ||
| 674 | |||
| 675 | static const struct net_device_ops sr9800_netdev_ops = { | ||
| 676 | .ndo_open = usbnet_open, | ||
| 677 | .ndo_stop = usbnet_stop, | ||
| 678 | .ndo_start_xmit = usbnet_start_xmit, | ||
| 679 | .ndo_tx_timeout = usbnet_tx_timeout, | ||
| 680 | .ndo_change_mtu = usbnet_change_mtu, | ||
| 681 | .ndo_set_mac_address = sr_set_mac_address, | ||
| 682 | .ndo_validate_addr = eth_validate_addr, | ||
| 683 | .ndo_do_ioctl = sr_ioctl, | ||
| 684 | .ndo_set_rx_mode = sr_set_multicast, | ||
| 685 | }; | ||
| 686 | |||
| 687 | static int sr9800_phy_powerup(struct usbnet *dev) | ||
| 688 | { | ||
| 689 | int ret; | ||
| 690 | |||
| 691 | /* set the embedded Ethernet PHY in power-down state */ | ||
| 692 | ret = sr_sw_reset(dev, SR_SWRESET_IPPD | SR_SWRESET_IPRL); | ||
| 693 | if (ret < 0) { | ||
| 694 | netdev_err(dev->net, "Failed to power down PHY : %d\n", ret); | ||
| 695 | return ret; | ||
| 696 | } | ||
| 697 | msleep(20); | ||
| 698 | |||
| 699 | /* set the embedded Ethernet PHY in power-up state */ | ||
| 700 | ret = sr_sw_reset(dev, SR_SWRESET_IPRL); | ||
| 701 | if (ret < 0) { | ||
| 702 | netdev_err(dev->net, "Failed to reset PHY: %d\n", ret); | ||
| 703 | return ret; | ||
| 704 | } | ||
| 705 | msleep(600); | ||
| 706 | |||
| 707 | /* set the embedded Ethernet PHY in reset state */ | ||
| 708 | ret = sr_sw_reset(dev, SR_SWRESET_CLEAR); | ||
| 709 | if (ret < 0) { | ||
| 710 | netdev_err(dev->net, "Failed to power up PHY: %d\n", ret); | ||
| 711 | return ret; | ||
| 712 | } | ||
| 713 | msleep(20); | ||
| 714 | |||
| 715 | /* set the embedded Ethernet PHY in power-up state */ | ||
| 716 | ret = sr_sw_reset(dev, SR_SWRESET_IPRL); | ||
| 717 | if (ret < 0) { | ||
| 718 | netdev_err(dev->net, "Failed to reset PHY: %d\n", ret); | ||
| 719 | return ret; | ||
| 720 | } | ||
| 721 | |||
| 722 | return 0; | ||
| 723 | } | ||
| 724 | |||
| 725 | static int sr9800_bind(struct usbnet *dev, struct usb_interface *intf) | ||
| 726 | { | ||
| 727 | struct sr_data *data = (struct sr_data *)&dev->data; | ||
| 728 | u16 led01_mux, led23_mux; | ||
| 729 | int ret, embd_phy; | ||
| 730 | u32 phyid; | ||
| 731 | u16 rx_ctl; | ||
| 732 | |||
| 733 | data->eeprom_len = SR9800_EEPROM_LEN; | ||
| 734 | |||
| 735 | usbnet_get_endpoints(dev, intf); | ||
| 736 | |||
| 737 | /* LED Setting Rule : | ||
| 738 | * AABB:CCDD | ||
| 739 | * AA : MFA0(LED0) | ||
| 740 | * BB : MFA1(LED1) | ||
| 741 | * CC : MFA2(LED2), Reserved for SR9800 | ||
| 742 | * DD : MFA3(LED3), Reserved for SR9800 | ||
| 743 | */ | ||
| 744 | led01_mux = (SR_LED_MUX_LINK_ACTIVE << 8) | SR_LED_MUX_LINK; | ||
| 745 | led23_mux = (SR_LED_MUX_LINK_ACTIVE << 8) | SR_LED_MUX_TX_ACTIVE; | ||
| 746 | ret = sr_write_cmd(dev, SR_CMD_LED_MUX, led01_mux, led23_mux, 0, NULL); | ||
| 747 | if (ret < 0) { | ||
| 748 | netdev_err(dev->net, "set LINK LED failed : %d\n", ret); | ||
| 749 | goto out; | ||
| 750 | } | ||
| 751 | |||
| 752 | /* Get the MAC address */ | ||
| 753 | ret = sr_read_cmd(dev, SR_CMD_READ_NODE_ID, 0, 0, ETH_ALEN, | ||
| 754 | dev->net->dev_addr); | ||
| 755 | if (ret < 0) { | ||
| 756 | netdev_dbg(dev->net, "Failed to read MAC address: %d\n", ret); | ||
| 757 | return ret; | ||
| 758 | } | ||
| 759 | netdev_dbg(dev->net, "mac addr : %pM\n", dev->net->dev_addr); | ||
| 760 | |||
| 761 | /* Initialize MII structure */ | ||
| 762 | dev->mii.dev = dev->net; | ||
| 763 | dev->mii.mdio_read = sr_mdio_read; | ||
| 764 | dev->mii.mdio_write = sr_mdio_write; | ||
| 765 | dev->mii.phy_id_mask = 0x1f; | ||
| 766 | dev->mii.reg_num_mask = 0x1f; | ||
| 767 | dev->mii.phy_id = sr_get_phy_addr(dev); | ||
| 768 | |||
| 769 | dev->net->netdev_ops = &sr9800_netdev_ops; | ||
| 770 | dev->net->ethtool_ops = &sr9800_ethtool_ops; | ||
| 771 | |||
| 772 | embd_phy = ((dev->mii.phy_id & 0x1f) == 0x10 ? 1 : 0); | ||
| 773 | /* Reset the PHY to normal operation mode */ | ||
| 774 | ret = sr_write_cmd(dev, SR_CMD_SW_PHY_SELECT, embd_phy, 0, 0, NULL); | ||
| 775 | if (ret < 0) { | ||
| 776 | netdev_dbg(dev->net, "Select PHY #1 failed: %d\n", ret); | ||
| 777 | return ret; | ||
| 778 | } | ||
| 779 | |||
| 780 | /* Init PHY routine */ | ||
| 781 | ret = sr9800_phy_powerup(dev); | ||
| 782 | if (ret < 0) | ||
| 783 | goto out; | ||
| 784 | |||
| 785 | rx_ctl = sr_read_rx_ctl(dev); | ||
| 786 | netdev_dbg(dev->net, "RX_CTL is 0x%04x after software reset\n", rx_ctl); | ||
| 787 | ret = sr_write_rx_ctl(dev, 0x0000); | ||
| 788 | if (ret < 0) | ||
| 789 | goto out; | ||
| 790 | |||
| 791 | rx_ctl = sr_read_rx_ctl(dev); | ||
| 792 | netdev_dbg(dev->net, "RX_CTL is 0x%04x setting to 0x0000\n", rx_ctl); | ||
| 793 | |||
| 794 | /* Read PHYID register *AFTER* the PHY was reset properly */ | ||
| 795 | phyid = sr_get_phyid(dev); | ||
| 796 | netdev_dbg(dev->net, "PHYID=0x%08x\n", phyid); | ||
| 797 | |||
| 798 | /* medium mode setting */ | ||
| 799 | ret = sr9800_set_default_mode(dev); | ||
| 800 | if (ret < 0) | ||
| 801 | goto out; | ||
| 802 | |||
| 803 | if (dev->udev->speed == USB_SPEED_HIGH) { | ||
| 804 | ret = sr_write_cmd(dev, SR_CMD_BULKIN_SIZE, | ||
| 805 | SR9800_BULKIN_SIZE[SR9800_MAX_BULKIN_4K].byte_cnt, | ||
| 806 | SR9800_BULKIN_SIZE[SR9800_MAX_BULKIN_4K].threshold, | ||
| 807 | 0, NULL); | ||
| 808 | if (ret < 0) { | ||
| 809 | netdev_err(dev->net, "Reset RX_CTL failed: %d\n", ret); | ||
| 810 | goto out; | ||
| 811 | } | ||
| 812 | dev->rx_urb_size = | ||
| 813 | SR9800_BULKIN_SIZE[SR9800_MAX_BULKIN_4K].size; | ||
| 814 | } else { | ||
| 815 | ret = sr_write_cmd(dev, SR_CMD_BULKIN_SIZE, | ||
| 816 | SR9800_BULKIN_SIZE[SR9800_MAX_BULKIN_2K].byte_cnt, | ||
| 817 | SR9800_BULKIN_SIZE[SR9800_MAX_BULKIN_2K].threshold, | ||
| 818 | 0, NULL); | ||
| 819 | if (ret < 0) { | ||
| 820 | netdev_err(dev->net, "Reset RX_CTL failed: %d\n", ret); | ||
| 821 | goto out; | ||
| 822 | } | ||
| 823 | dev->rx_urb_size = | ||
| 824 | SR9800_BULKIN_SIZE[SR9800_MAX_BULKIN_2K].size; | ||
| 825 | } | ||
| 826 | netdev_dbg(dev->net, "%s : setting rx_urb_size with : %ld\n", __func__, | ||
| 827 | dev->rx_urb_size); | ||
| 828 | return 0; | ||
| 829 | |||
| 830 | out: | ||
| 831 | return ret; | ||
| 832 | } | ||
| 833 | |||
| 834 | static const struct driver_info sr9800_driver_info = { | ||
| 835 | .description = "CoreChip SR9800 USB 2.0 Ethernet", | ||
| 836 | .bind = sr9800_bind, | ||
| 837 | .status = sr_status, | ||
| 838 | .link_reset = sr9800_link_reset, | ||
| 839 | .reset = sr9800_reset, | ||
| 840 | .flags = DRIVER_FLAG, | ||
| 841 | .rx_fixup = sr_rx_fixup, | ||
| 842 | .tx_fixup = sr_tx_fixup, | ||
| 843 | }; | ||
| 844 | |||
| 845 | static const struct usb_device_id products[] = { | ||
| 846 | { | ||
| 847 | USB_DEVICE(0x0fe6, 0x9800), /* SR9800 Device */ | ||
| 848 | .driver_info = (unsigned long) &sr9800_driver_info, | ||
| 849 | }, | ||
| 850 | {}, /* END */ | ||
| 851 | }; | ||
| 852 | |||
| 853 | MODULE_DEVICE_TABLE(usb, products); | ||
| 854 | |||
| 855 | static struct usb_driver sr_driver = { | ||
| 856 | .name = DRIVER_NAME, | ||
| 857 | .id_table = products, | ||
| 858 | .probe = usbnet_probe, | ||
| 859 | .suspend = usbnet_suspend, | ||
| 860 | .resume = usbnet_resume, | ||
| 861 | .disconnect = usbnet_disconnect, | ||
| 862 | .supports_autosuspend = 1, | ||
| 863 | }; | ||
| 864 | |||
| 865 | module_usb_driver(sr_driver); | ||
| 866 | |||
| 867 | MODULE_AUTHOR("Liu Junliang <liujunliang_ljl@163.com"); | ||
| 868 | MODULE_VERSION(DRIVER_VERSION); | ||
| 869 | MODULE_DESCRIPTION("SR9800 USB 2.0 USB2NET Dev : http://www.corechip-sz.com"); | ||
| 870 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/net/usb/sr9800.h b/drivers/net/usb/sr9800.h new file mode 100644 index 000000000000..18f670251275 --- /dev/null +++ b/drivers/net/usb/sr9800.h | |||
| @@ -0,0 +1,202 @@ | |||
| 1 | /* CoreChip-sz SR9800 one chip USB 2.0 Ethernet Devices | ||
| 2 | * | ||
| 3 | * Author : Liu Junliang <liujunliang_ljl@163.com> | ||
| 4 | * | ||
| 5 | * This file is licensed under the terms of the GNU General Public License | ||
| 6 | * version 2. This program is licensed "as is" without any warranty of any | ||
| 7 | * kind, whether express or implied. | ||
| 8 | */ | ||
| 9 | |||
| 10 | #ifndef _SR9800_H | ||
| 11 | #define _SR9800_H | ||
| 12 | |||
| 13 | /* SR9800 spec. command table on Linux Platform */ | ||
| 14 | |||
| 15 | /* command : Software Station Management Control Reg */ | ||
| 16 | #define SR_CMD_SET_SW_MII 0x06 | ||
| 17 | /* command : PHY Read Reg */ | ||
| 18 | #define SR_CMD_READ_MII_REG 0x07 | ||
| 19 | /* command : PHY Write Reg */ | ||
| 20 | #define SR_CMD_WRITE_MII_REG 0x08 | ||
| 21 | /* command : Hardware Station Management Control Reg */ | ||
| 22 | #define SR_CMD_SET_HW_MII 0x0a | ||
| 23 | /* command : SROM Read Reg */ | ||
| 24 | #define SR_CMD_READ_EEPROM 0x0b | ||
| 25 | /* command : SROM Write Reg */ | ||
| 26 | #define SR_CMD_WRITE_EEPROM 0x0c | ||
| 27 | /* command : SROM Write Enable Reg */ | ||
| 28 | #define SR_CMD_WRITE_ENABLE 0x0d | ||
| 29 | /* command : SROM Write Disable Reg */ | ||
| 30 | #define SR_CMD_WRITE_DISABLE 0x0e | ||
| 31 | /* command : RX Control Read Reg */ | ||
| 32 | #define SR_CMD_READ_RX_CTL 0x0f | ||
| 33 | #define SR_RX_CTL_PRO (1 << 0) | ||
| 34 | #define SR_RX_CTL_AMALL (1 << 1) | ||
| 35 | #define SR_RX_CTL_SEP (1 << 2) | ||
| 36 | #define SR_RX_CTL_AB (1 << 3) | ||
| 37 | #define SR_RX_CTL_AM (1 << 4) | ||
| 38 | #define SR_RX_CTL_AP (1 << 5) | ||
| 39 | #define SR_RX_CTL_ARP (1 << 6) | ||
| 40 | #define SR_RX_CTL_SO (1 << 7) | ||
| 41 | #define SR_RX_CTL_RH1M (1 << 8) | ||
| 42 | #define SR_RX_CTL_RH2M (1 << 9) | ||
| 43 | #define SR_RX_CTL_RH3M (1 << 10) | ||
| 44 | /* command : RX Control Write Reg */ | ||
| 45 | #define SR_CMD_WRITE_RX_CTL 0x10 | ||
| 46 | /* command : IPG0/IPG1/IPG2 Control Read Reg */ | ||
| 47 | #define SR_CMD_READ_IPG012 0x11 | ||
| 48 | /* command : IPG0/IPG1/IPG2 Control Write Reg */ | ||
| 49 | #define SR_CMD_WRITE_IPG012 0x12 | ||
| 50 | /* command : Node ID Read Reg */ | ||
| 51 | #define SR_CMD_READ_NODE_ID 0x13 | ||
| 52 | /* command : Node ID Write Reg */ | ||
| 53 | #define SR_CMD_WRITE_NODE_ID 0x14 | ||
| 54 | /* command : Multicast Filter Array Read Reg */ | ||
| 55 | #define SR_CMD_READ_MULTI_FILTER 0x15 | ||
| 56 | /* command : Multicast Filter Array Write Reg */ | ||
| 57 | #define SR_CMD_WRITE_MULTI_FILTER 0x16 | ||
| 58 | /* command : Eth/HomePNA PHY Address Reg */ | ||
| 59 | #define SR_CMD_READ_PHY_ID 0x19 | ||
| 60 | /* command : Medium Status Read Reg */ | ||
| 61 | #define SR_CMD_READ_MEDIUM_STATUS 0x1a | ||
| 62 | #define SR_MONITOR_LINK (1 << 1) | ||
| 63 | #define SR_MONITOR_MAGIC (1 << 2) | ||
| 64 | #define SR_MONITOR_HSFS (1 << 4) | ||
| 65 | /* command : Medium Status Write Reg */ | ||
| 66 | #define SR_CMD_WRITE_MEDIUM_MODE 0x1b | ||
| 67 | #define SR_MEDIUM_GM (1 << 0) | ||
| 68 | #define SR_MEDIUM_FD (1 << 1) | ||
| 69 | #define SR_MEDIUM_AC (1 << 2) | ||
| 70 | #define SR_MEDIUM_ENCK (1 << 3) | ||
| 71 | #define SR_MEDIUM_RFC (1 << 4) | ||
| 72 | #define SR_MEDIUM_TFC (1 << 5) | ||
| 73 | #define SR_MEDIUM_JFE (1 << 6) | ||
| 74 | #define SR_MEDIUM_PF (1 << 7) | ||
| 75 | #define SR_MEDIUM_RE (1 << 8) | ||
| 76 | #define SR_MEDIUM_PS (1 << 9) | ||
| 77 | #define SR_MEDIUM_RSV (1 << 10) | ||
| 78 | #define SR_MEDIUM_SBP (1 << 11) | ||
| 79 | #define SR_MEDIUM_SM (1 << 12) | ||
| 80 | /* command : Monitor Mode Status Read Reg */ | ||
| 81 | #define SR_CMD_READ_MONITOR_MODE 0x1c | ||
| 82 | /* command : Monitor Mode Status Write Reg */ | ||
| 83 | #define SR_CMD_WRITE_MONITOR_MODE 0x1d | ||
| 84 | /* command : GPIO Status Read Reg */ | ||
| 85 | #define SR_CMD_READ_GPIOS 0x1e | ||
| 86 | #define SR_GPIO_GPO0EN (1 << 0) /* GPIO0 Output enable */ | ||
| 87 | #define SR_GPIO_GPO_0 (1 << 1) /* GPIO0 Output value */ | ||
| 88 | #define SR_GPIO_GPO1EN (1 << 2) /* GPIO1 Output enable */ | ||
| 89 | #define SR_GPIO_GPO_1 (1 << 3) /* GPIO1 Output value */ | ||
| 90 | #define SR_GPIO_GPO2EN (1 << 4) /* GPIO2 Output enable */ | ||
| 91 | #define SR_GPIO_GPO_2 (1 << 5) /* GPIO2 Output value */ | ||
| 92 | #define SR_GPIO_RESERVED (1 << 6) /* Reserved */ | ||
| 93 | #define SR_GPIO_RSE (1 << 7) /* Reload serial EEPROM */ | ||
| 94 | /* command : GPIO Status Write Reg */ | ||
| 95 | #define SR_CMD_WRITE_GPIOS 0x1f | ||
| 96 | /* command : Eth PHY Power and Reset Control Reg */ | ||
| 97 | #define SR_CMD_SW_RESET 0x20 | ||
| 98 | #define SR_SWRESET_CLEAR 0x00 | ||
| 99 | #define SR_SWRESET_RR (1 << 0) | ||
| 100 | #define SR_SWRESET_RT (1 << 1) | ||
| 101 | #define SR_SWRESET_PRTE (1 << 2) | ||
| 102 | #define SR_SWRESET_PRL (1 << 3) | ||
| 103 | #define SR_SWRESET_BZ (1 << 4) | ||
| 104 | #define SR_SWRESET_IPRL (1 << 5) | ||
| 105 | #define SR_SWRESET_IPPD (1 << 6) | ||
| 106 | /* command : Software Interface Selection Status Read Reg */ | ||
| 107 | #define SR_CMD_SW_PHY_STATUS 0x21 | ||
| 108 | /* command : Software Interface Selection Status Write Reg */ | ||
| 109 | #define SR_CMD_SW_PHY_SELECT 0x22 | ||
| 110 | /* command : BULK in Buffer Size Reg */ | ||
| 111 | #define SR_CMD_BULKIN_SIZE 0x2A | ||
| 112 | /* command : LED_MUX Control Reg */ | ||
| 113 | #define SR_CMD_LED_MUX 0x70 | ||
| 114 | #define SR_LED_MUX_TX_ACTIVE (1 << 0) | ||
| 115 | #define SR_LED_MUX_RX_ACTIVE (1 << 1) | ||
| 116 | #define SR_LED_MUX_COLLISION (1 << 2) | ||
| 117 | #define SR_LED_MUX_DUP_COL (1 << 3) | ||
| 118 | #define SR_LED_MUX_DUP (1 << 4) | ||
| 119 | #define SR_LED_MUX_SPEED (1 << 5) | ||
| 120 | #define SR_LED_MUX_LINK_ACTIVE (1 << 6) | ||
| 121 | #define SR_LED_MUX_LINK (1 << 7) | ||
| 122 | |||
| 123 | /* Register Access Flags */ | ||
| 124 | #define SR_REQ_RD_REG (USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE) | ||
| 125 | #define SR_REQ_WR_REG (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE) | ||
| 126 | |||
| 127 | /* Multicast Filter Array size & Max Number */ | ||
| 128 | #define SR_MCAST_FILTER_SIZE 8 | ||
| 129 | #define SR_MAX_MCAST 64 | ||
| 130 | |||
| 131 | /* IPG0/1/2 Default Value */ | ||
| 132 | #define SR9800_IPG0_DEFAULT 0x15 | ||
| 133 | #define SR9800_IPG1_DEFAULT 0x0c | ||
| 134 | #define SR9800_IPG2_DEFAULT 0x12 | ||
| 135 | |||
| 136 | /* Medium Status Default Mode */ | ||
| 137 | #define SR9800_MEDIUM_DEFAULT \ | ||
| 138 | (SR_MEDIUM_FD | SR_MEDIUM_RFC | \ | ||
| 139 | SR_MEDIUM_TFC | SR_MEDIUM_PS | \ | ||
| 140 | SR_MEDIUM_AC | SR_MEDIUM_RE) | ||
| 141 | |||
| 142 | /* RX Control Default Setting */ | ||
| 143 | #define SR_DEFAULT_RX_CTL \ | ||
| 144 | (SR_RX_CTL_SO | SR_RX_CTL_AB | SR_RX_CTL_RH1M) | ||
| 145 | |||
| 146 | /* EEPROM Magic Number & EEPROM Size */ | ||
| 147 | #define SR_EEPROM_MAGIC 0xdeadbeef | ||
| 148 | #define SR9800_EEPROM_LEN 0xff | ||
| 149 | |||
| 150 | /* SR9800 Driver Version and Driver Name */ | ||
| 151 | #define DRIVER_VERSION "11-Nov-2013" | ||
| 152 | #define DRIVER_NAME "CoreChips" | ||
| 153 | #define DRIVER_FLAG \ | ||
| 154 | (FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR | FLAG_MULTI_PACKET) | ||
| 155 | |||
| 156 | /* SR9800 BULKIN Buffer Size */ | ||
| 157 | #define SR9800_MAX_BULKIN_2K 0 | ||
| 158 | #define SR9800_MAX_BULKIN_4K 1 | ||
| 159 | #define SR9800_MAX_BULKIN_6K 2 | ||
| 160 | #define SR9800_MAX_BULKIN_8K 3 | ||
| 161 | #define SR9800_MAX_BULKIN_16K 4 | ||
| 162 | #define SR9800_MAX_BULKIN_20K 5 | ||
| 163 | #define SR9800_MAX_BULKIN_24K 6 | ||
| 164 | #define SR9800_MAX_BULKIN_32K 7 | ||
| 165 | |||
| 166 | struct {unsigned short size, byte_cnt, threshold; } SR9800_BULKIN_SIZE[] = { | ||
| 167 | /* 2k */ | ||
| 168 | {2048, 0x8000, 0x8001}, | ||
| 169 | /* 4k */ | ||
| 170 | {4096, 0x8100, 0x8147}, | ||
| 171 | /* 6k */ | ||
| 172 | {6144, 0x8200, 0x81EB}, | ||
| 173 | /* 8k */ | ||
| 174 | {8192, 0x8300, 0x83D7}, | ||
| 175 | /* 16 */ | ||
| 176 | {16384, 0x8400, 0x851E}, | ||
| 177 | /* 20k */ | ||
| 178 | {20480, 0x8500, 0x8666}, | ||
| 179 | /* 24k */ | ||
| 180 | {24576, 0x8600, 0x87AE}, | ||
| 181 | /* 32k */ | ||
| 182 | {32768, 0x8700, 0x8A3D}, | ||
| 183 | }; | ||
| 184 | |||
| 185 | /* This structure cannot exceed sizeof(unsigned long [5]) AKA 20 bytes */ | ||
| 186 | struct sr_data { | ||
| 187 | u8 multi_filter[SR_MCAST_FILTER_SIZE]; | ||
| 188 | u8 mac_addr[ETH_ALEN]; | ||
| 189 | u8 phymode; | ||
| 190 | u8 ledmode; | ||
| 191 | u8 eeprom_len; | ||
| 192 | }; | ||
| 193 | |||
| 194 | struct sr9800_int_data { | ||
| 195 | __le16 res1; | ||
| 196 | u8 link; | ||
| 197 | __le16 res2; | ||
| 198 | u8 status; | ||
| 199 | __le16 res3; | ||
| 200 | } __packed; | ||
| 201 | |||
| 202 | #endif /* _SR9800_H */ | ||
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index 026a313c2d2d..b0f705c2378f 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c | |||
| @@ -469,7 +469,6 @@ static inline struct hlist_head *vxlan_fdb_head(struct vxlan_dev *vxlan, | |||
| 469 | /* Look up Ethernet address in forwarding table */ | 469 | /* Look up Ethernet address in forwarding table */ |
| 470 | static struct vxlan_fdb *__vxlan_find_mac(struct vxlan_dev *vxlan, | 470 | static struct vxlan_fdb *__vxlan_find_mac(struct vxlan_dev *vxlan, |
| 471 | const u8 *mac) | 471 | const u8 *mac) |
| 472 | |||
| 473 | { | 472 | { |
| 474 | struct hlist_head *head = vxlan_fdb_head(vxlan, mac); | 473 | struct hlist_head *head = vxlan_fdb_head(vxlan, mac); |
| 475 | struct vxlan_fdb *f; | 474 | struct vxlan_fdb *f; |
| @@ -596,10 +595,8 @@ static struct sk_buff **vxlan_gro_receive(struct sk_buff **head, struct sk_buff | |||
| 596 | NAPI_GRO_CB(p)->same_flow = 0; | 595 | NAPI_GRO_CB(p)->same_flow = 0; |
| 597 | continue; | 596 | continue; |
| 598 | } | 597 | } |
| 599 | goto found; | ||
| 600 | } | 598 | } |
| 601 | 599 | ||
| 602 | found: | ||
| 603 | type = eh->h_proto; | 600 | type = eh->h_proto; |
| 604 | 601 | ||
| 605 | rcu_read_lock(); | 602 | rcu_read_lock(); |
diff --git a/drivers/net/wan/dlci.c b/drivers/net/wan/dlci.c index 0d1c7592efa0..19f7cb2cdef3 100644 --- a/drivers/net/wan/dlci.c +++ b/drivers/net/wan/dlci.c | |||
| @@ -71,12 +71,9 @@ static int dlci_header(struct sk_buff *skb, struct net_device *dev, | |||
| 71 | const void *saddr, unsigned len) | 71 | const void *saddr, unsigned len) |
| 72 | { | 72 | { |
| 73 | struct frhdr hdr; | 73 | struct frhdr hdr; |
| 74 | struct dlci_local *dlp; | ||
| 75 | unsigned int hlen; | 74 | unsigned int hlen; |
| 76 | char *dest; | 75 | char *dest; |
| 77 | 76 | ||
| 78 | dlp = netdev_priv(dev); | ||
| 79 | |||
| 80 | hdr.control = FRAD_I_UI; | 77 | hdr.control = FRAD_I_UI; |
| 81 | switch (type) | 78 | switch (type) |
| 82 | { | 79 | { |
| @@ -107,11 +104,9 @@ static int dlci_header(struct sk_buff *skb, struct net_device *dev, | |||
| 107 | 104 | ||
| 108 | static void dlci_receive(struct sk_buff *skb, struct net_device *dev) | 105 | static void dlci_receive(struct sk_buff *skb, struct net_device *dev) |
| 109 | { | 106 | { |
| 110 | struct dlci_local *dlp; | ||
| 111 | struct frhdr *hdr; | 107 | struct frhdr *hdr; |
| 112 | int process, header; | 108 | int process, header; |
| 113 | 109 | ||
| 114 | dlp = netdev_priv(dev); | ||
| 115 | if (!pskb_may_pull(skb, sizeof(*hdr))) { | 110 | if (!pskb_may_pull(skb, sizeof(*hdr))) { |
| 116 | netdev_notice(dev, "invalid data no header\n"); | 111 | netdev_notice(dev, "invalid data no header\n"); |
| 117 | dev->stats.rx_errors++; | 112 | dev->stats.rx_errors++; |
diff --git a/drivers/net/wireless/ath/ar5523/ar5523.c b/drivers/net/wireless/ath/ar5523/ar5523.c index 8aa20df55e50..507d9a9ee69a 100644 --- a/drivers/net/wireless/ath/ar5523/ar5523.c +++ b/drivers/net/wireless/ath/ar5523/ar5523.c | |||
| @@ -1764,7 +1764,7 @@ static struct usb_device_id ar5523_id_table[] = { | |||
| 1764 | AR5523_DEVICE_UG(0x07d1, 0x3a07), /* D-Link / WUA-2340 rev A1 */ | 1764 | AR5523_DEVICE_UG(0x07d1, 0x3a07), /* D-Link / WUA-2340 rev A1 */ |
| 1765 | AR5523_DEVICE_UG(0x1690, 0x0712), /* Gigaset / AR5523 */ | 1765 | AR5523_DEVICE_UG(0x1690, 0x0712), /* Gigaset / AR5523 */ |
| 1766 | AR5523_DEVICE_UG(0x1690, 0x0710), /* Gigaset / SMCWUSBTG */ | 1766 | AR5523_DEVICE_UG(0x1690, 0x0710), /* Gigaset / SMCWUSBTG */ |
| 1767 | AR5523_DEVICE_UG(0x129b, 0x160c), /* Gigaset / USB stick 108 | 1767 | AR5523_DEVICE_UG(0x129b, 0x160b), /* Gigaset / USB stick 108 |
| 1768 | (CyberTAN Technology) */ | 1768 | (CyberTAN Technology) */ |
| 1769 | AR5523_DEVICE_UG(0x16ab, 0x7801), /* Globalsun / AR5523_1 */ | 1769 | AR5523_DEVICE_UG(0x16ab, 0x7801), /* Globalsun / AR5523_1 */ |
| 1770 | AR5523_DEVICE_UX(0x16ab, 0x7811), /* Globalsun / AR5523_2 */ | 1770 | AR5523_DEVICE_UX(0x16ab, 0x7811), /* Globalsun / AR5523_2 */ |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 25243cbc07f0..b8daff78b9d1 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | |||
| @@ -5065,6 +5065,10 @@ static u16 ar9003_hw_get_max_edge_power(struct ar9300_eeprom *eep, | |||
| 5065 | break; | 5065 | break; |
| 5066 | } | 5066 | } |
| 5067 | } | 5067 | } |
| 5068 | |||
| 5069 | if (is2GHz && !twiceMaxEdgePower) | ||
| 5070 | twiceMaxEdgePower = 60; | ||
| 5071 | |||
| 5068 | return twiceMaxEdgePower; | 5072 | return twiceMaxEdgePower; |
| 5069 | } | 5073 | } |
| 5070 | 5074 | ||
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 58da3468d1f0..99a203174f45 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h | |||
| @@ -262,6 +262,8 @@ enum tid_aggr_state { | |||
| 262 | struct ath9k_htc_sta { | 262 | struct ath9k_htc_sta { |
| 263 | u8 index; | 263 | u8 index; |
| 264 | enum tid_aggr_state tid_state[ATH9K_HTC_MAX_TID]; | 264 | enum tid_aggr_state tid_state[ATH9K_HTC_MAX_TID]; |
| 265 | struct work_struct rc_update_work; | ||
| 266 | struct ath9k_htc_priv *htc_priv; | ||
| 265 | }; | 267 | }; |
| 266 | 268 | ||
| 267 | #define ATH9K_HTC_RXBUF 256 | 269 | #define ATH9K_HTC_RXBUF 256 |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index f4e1de20d99c..c57d6b859c04 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c | |||
| @@ -34,6 +34,10 @@ static int ath9k_htc_btcoex_enable; | |||
| 34 | module_param_named(btcoex_enable, ath9k_htc_btcoex_enable, int, 0444); | 34 | module_param_named(btcoex_enable, ath9k_htc_btcoex_enable, int, 0444); |
| 35 | MODULE_PARM_DESC(btcoex_enable, "Enable wifi-BT coexistence"); | 35 | MODULE_PARM_DESC(btcoex_enable, "Enable wifi-BT coexistence"); |
| 36 | 36 | ||
| 37 | static int ath9k_ps_enable; | ||
| 38 | module_param_named(ps_enable, ath9k_ps_enable, int, 0444); | ||
| 39 | MODULE_PARM_DESC(ps_enable, "Enable WLAN PowerSave"); | ||
| 40 | |||
| 37 | #define CHAN2G(_freq, _idx) { \ | 41 | #define CHAN2G(_freq, _idx) { \ |
| 38 | .center_freq = (_freq), \ | 42 | .center_freq = (_freq), \ |
| 39 | .hw_value = (_idx), \ | 43 | .hw_value = (_idx), \ |
| @@ -725,12 +729,14 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv, | |||
| 725 | IEEE80211_HW_SPECTRUM_MGMT | | 729 | IEEE80211_HW_SPECTRUM_MGMT | |
| 726 | IEEE80211_HW_HAS_RATE_CONTROL | | 730 | IEEE80211_HW_HAS_RATE_CONTROL | |
| 727 | IEEE80211_HW_RX_INCLUDES_FCS | | 731 | IEEE80211_HW_RX_INCLUDES_FCS | |
| 728 | IEEE80211_HW_SUPPORTS_PS | | ||
| 729 | IEEE80211_HW_PS_NULLFUNC_STACK | | 732 | IEEE80211_HW_PS_NULLFUNC_STACK | |
| 730 | IEEE80211_HW_REPORTS_TX_ACK_STATUS | | 733 | IEEE80211_HW_REPORTS_TX_ACK_STATUS | |
| 731 | IEEE80211_HW_MFP_CAPABLE | | 734 | IEEE80211_HW_MFP_CAPABLE | |
| 732 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING; | 735 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING; |
| 733 | 736 | ||
| 737 | if (ath9k_ps_enable) | ||
| 738 | hw->flags |= IEEE80211_HW_SUPPORTS_PS; | ||
| 739 | |||
| 734 | hw->wiphy->interface_modes = | 740 | hw->wiphy->interface_modes = |
| 735 | BIT(NL80211_IFTYPE_STATION) | | 741 | BIT(NL80211_IFTYPE_STATION) | |
| 736 | BIT(NL80211_IFTYPE_ADHOC) | | 742 | BIT(NL80211_IFTYPE_ADHOC) | |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 608d739d1378..c9254a61ca52 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c | |||
| @@ -1270,18 +1270,50 @@ static void ath9k_htc_configure_filter(struct ieee80211_hw *hw, | |||
| 1270 | mutex_unlock(&priv->mutex); | 1270 | mutex_unlock(&priv->mutex); |
| 1271 | } | 1271 | } |
| 1272 | 1272 | ||
| 1273 | static void ath9k_htc_sta_rc_update_work(struct work_struct *work) | ||
| 1274 | { | ||
| 1275 | struct ath9k_htc_sta *ista = | ||
| 1276 | container_of(work, struct ath9k_htc_sta, rc_update_work); | ||
| 1277 | struct ieee80211_sta *sta = | ||
| 1278 | container_of((void *)ista, struct ieee80211_sta, drv_priv); | ||
| 1279 | struct ath9k_htc_priv *priv = ista->htc_priv; | ||
| 1280 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
| 1281 | struct ath9k_htc_target_rate trate; | ||
| 1282 | |||
| 1283 | mutex_lock(&priv->mutex); | ||
| 1284 | ath9k_htc_ps_wakeup(priv); | ||
| 1285 | |||
| 1286 | memset(&trate, 0, sizeof(struct ath9k_htc_target_rate)); | ||
| 1287 | ath9k_htc_setup_rate(priv, sta, &trate); | ||
| 1288 | if (!ath9k_htc_send_rate_cmd(priv, &trate)) | ||
| 1289 | ath_dbg(common, CONFIG, | ||
| 1290 | "Supported rates for sta: %pM updated, rate caps: 0x%X\n", | ||
| 1291 | sta->addr, be32_to_cpu(trate.capflags)); | ||
| 1292 | else | ||
| 1293 | ath_dbg(common, CONFIG, | ||
| 1294 | "Unable to update supported rates for sta: %pM\n", | ||
| 1295 | sta->addr); | ||
| 1296 | |||
| 1297 | ath9k_htc_ps_restore(priv); | ||
| 1298 | mutex_unlock(&priv->mutex); | ||
| 1299 | } | ||
| 1300 | |||
| 1273 | static int ath9k_htc_sta_add(struct ieee80211_hw *hw, | 1301 | static int ath9k_htc_sta_add(struct ieee80211_hw *hw, |
| 1274 | struct ieee80211_vif *vif, | 1302 | struct ieee80211_vif *vif, |
| 1275 | struct ieee80211_sta *sta) | 1303 | struct ieee80211_sta *sta) |
| 1276 | { | 1304 | { |
| 1277 | struct ath9k_htc_priv *priv = hw->priv; | 1305 | struct ath9k_htc_priv *priv = hw->priv; |
| 1306 | struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv; | ||
| 1278 | int ret; | 1307 | int ret; |
| 1279 | 1308 | ||
| 1280 | mutex_lock(&priv->mutex); | 1309 | mutex_lock(&priv->mutex); |
| 1281 | ath9k_htc_ps_wakeup(priv); | 1310 | ath9k_htc_ps_wakeup(priv); |
| 1282 | ret = ath9k_htc_add_station(priv, vif, sta); | 1311 | ret = ath9k_htc_add_station(priv, vif, sta); |
| 1283 | if (!ret) | 1312 | if (!ret) { |
| 1313 | INIT_WORK(&ista->rc_update_work, ath9k_htc_sta_rc_update_work); | ||
| 1314 | ista->htc_priv = priv; | ||
| 1284 | ath9k_htc_init_rate(priv, sta); | 1315 | ath9k_htc_init_rate(priv, sta); |
| 1316 | } | ||
| 1285 | ath9k_htc_ps_restore(priv); | 1317 | ath9k_htc_ps_restore(priv); |
| 1286 | mutex_unlock(&priv->mutex); | 1318 | mutex_unlock(&priv->mutex); |
| 1287 | 1319 | ||
| @@ -1293,12 +1325,13 @@ static int ath9k_htc_sta_remove(struct ieee80211_hw *hw, | |||
| 1293 | struct ieee80211_sta *sta) | 1325 | struct ieee80211_sta *sta) |
| 1294 | { | 1326 | { |
| 1295 | struct ath9k_htc_priv *priv = hw->priv; | 1327 | struct ath9k_htc_priv *priv = hw->priv; |
| 1296 | struct ath9k_htc_sta *ista; | 1328 | struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv; |
| 1297 | int ret; | 1329 | int ret; |
| 1298 | 1330 | ||
| 1331 | cancel_work_sync(&ista->rc_update_work); | ||
| 1332 | |||
| 1299 | mutex_lock(&priv->mutex); | 1333 | mutex_lock(&priv->mutex); |
| 1300 | ath9k_htc_ps_wakeup(priv); | 1334 | ath9k_htc_ps_wakeup(priv); |
| 1301 | ista = (struct ath9k_htc_sta *) sta->drv_priv; | ||
| 1302 | htc_sta_drain(priv->htc, ista->index); | 1335 | htc_sta_drain(priv->htc, ista->index); |
| 1303 | ret = ath9k_htc_remove_station(priv, vif, sta); | 1336 | ret = ath9k_htc_remove_station(priv, vif, sta); |
| 1304 | ath9k_htc_ps_restore(priv); | 1337 | ath9k_htc_ps_restore(priv); |
| @@ -1311,28 +1344,12 @@ static void ath9k_htc_sta_rc_update(struct ieee80211_hw *hw, | |||
| 1311 | struct ieee80211_vif *vif, | 1344 | struct ieee80211_vif *vif, |
| 1312 | struct ieee80211_sta *sta, u32 changed) | 1345 | struct ieee80211_sta *sta, u32 changed) |
| 1313 | { | 1346 | { |
| 1314 | struct ath9k_htc_priv *priv = hw->priv; | 1347 | struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv; |
| 1315 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
| 1316 | struct ath9k_htc_target_rate trate; | ||
| 1317 | |||
| 1318 | mutex_lock(&priv->mutex); | ||
| 1319 | ath9k_htc_ps_wakeup(priv); | ||
| 1320 | 1348 | ||
| 1321 | if (changed & IEEE80211_RC_SUPP_RATES_CHANGED) { | 1349 | if (!(changed & IEEE80211_RC_SUPP_RATES_CHANGED)) |
| 1322 | memset(&trate, 0, sizeof(struct ath9k_htc_target_rate)); | 1350 | return; |
| 1323 | ath9k_htc_setup_rate(priv, sta, &trate); | ||
| 1324 | if (!ath9k_htc_send_rate_cmd(priv, &trate)) | ||
| 1325 | ath_dbg(common, CONFIG, | ||
| 1326 | "Supported rates for sta: %pM updated, rate caps: 0x%X\n", | ||
| 1327 | sta->addr, be32_to_cpu(trate.capflags)); | ||
| 1328 | else | ||
| 1329 | ath_dbg(common, CONFIG, | ||
| 1330 | "Unable to update supported rates for sta: %pM\n", | ||
| 1331 | sta->addr); | ||
| 1332 | } | ||
| 1333 | 1351 | ||
| 1334 | ath9k_htc_ps_restore(priv); | 1352 | schedule_work(&ista->rc_update_work); |
| 1335 | mutex_unlock(&priv->mutex); | ||
| 1336 | } | 1353 | } |
| 1337 | 1354 | ||
| 1338 | static int ath9k_htc_conf_tx(struct ieee80211_hw *hw, | 1355 | static int ath9k_htc_conf_tx(struct ieee80211_hw *hw, |
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index fbf43c05713f..11eab9f01fd8 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
| @@ -1316,7 +1316,7 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type) | |||
| 1316 | if (AR_SREV_9300_20_OR_LATER(ah)) | 1316 | if (AR_SREV_9300_20_OR_LATER(ah)) |
| 1317 | udelay(50); | 1317 | udelay(50); |
| 1318 | else if (AR_SREV_9100(ah)) | 1318 | else if (AR_SREV_9100(ah)) |
| 1319 | udelay(10000); | 1319 | mdelay(10); |
| 1320 | else | 1320 | else |
| 1321 | udelay(100); | 1321 | udelay(100); |
| 1322 | 1322 | ||
| @@ -2051,9 +2051,8 @@ static bool ath9k_hw_set_power_awake(struct ath_hw *ah) | |||
| 2051 | 2051 | ||
| 2052 | REG_SET_BIT(ah, AR_RTC_FORCE_WAKE, | 2052 | REG_SET_BIT(ah, AR_RTC_FORCE_WAKE, |
| 2053 | AR_RTC_FORCE_WAKE_EN); | 2053 | AR_RTC_FORCE_WAKE_EN); |
| 2054 | |||
| 2055 | if (AR_SREV_9100(ah)) | 2054 | if (AR_SREV_9100(ah)) |
| 2056 | udelay(10000); | 2055 | mdelay(10); |
| 2057 | else | 2056 | else |
| 2058 | udelay(50); | 2057 | udelay(50); |
| 2059 | 2058 | ||
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index c36de303c8f3..1fc2e5a26b52 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
| @@ -57,6 +57,10 @@ static int ath9k_bt_ant_diversity; | |||
| 57 | module_param_named(bt_ant_diversity, ath9k_bt_ant_diversity, int, 0444); | 57 | module_param_named(bt_ant_diversity, ath9k_bt_ant_diversity, int, 0444); |
| 58 | MODULE_PARM_DESC(bt_ant_diversity, "Enable WLAN/BT RX antenna diversity"); | 58 | MODULE_PARM_DESC(bt_ant_diversity, "Enable WLAN/BT RX antenna diversity"); |
| 59 | 59 | ||
| 60 | static int ath9k_ps_enable; | ||
| 61 | module_param_named(ps_enable, ath9k_ps_enable, int, 0444); | ||
| 62 | MODULE_PARM_DESC(ps_enable, "Enable WLAN PowerSave"); | ||
| 63 | |||
| 60 | bool is_ath9k_unloaded; | 64 | bool is_ath9k_unloaded; |
| 61 | /* We use the hw_value as an index into our private channel structure */ | 65 | /* We use the hw_value as an index into our private channel structure */ |
| 62 | 66 | ||
| @@ -903,13 +907,15 @@ static void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
| 903 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | | 907 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | |
| 904 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | 908 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | |
| 905 | IEEE80211_HW_SIGNAL_DBM | | 909 | IEEE80211_HW_SIGNAL_DBM | |
| 906 | IEEE80211_HW_SUPPORTS_PS | | ||
| 907 | IEEE80211_HW_PS_NULLFUNC_STACK | | 910 | IEEE80211_HW_PS_NULLFUNC_STACK | |
| 908 | IEEE80211_HW_SPECTRUM_MGMT | | 911 | IEEE80211_HW_SPECTRUM_MGMT | |
| 909 | IEEE80211_HW_REPORTS_TX_ACK_STATUS | | 912 | IEEE80211_HW_REPORTS_TX_ACK_STATUS | |
| 910 | IEEE80211_HW_SUPPORTS_RC_TABLE | | 913 | IEEE80211_HW_SUPPORTS_RC_TABLE | |
| 911 | IEEE80211_HW_SUPPORTS_HT_CCK_RATES; | 914 | IEEE80211_HW_SUPPORTS_HT_CCK_RATES; |
| 912 | 915 | ||
| 916 | if (ath9k_ps_enable) | ||
| 917 | hw->flags |= IEEE80211_HW_SUPPORTS_PS; | ||
| 918 | |||
| 913 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) { | 919 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) { |
| 914 | hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION; | 920 | hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION; |
| 915 | 921 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c index f06f4cbe1317..725e954d8475 100644 --- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c +++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c | |||
| @@ -182,6 +182,11 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg, | |||
| 182 | 182 | ||
| 183 | for (ch_idx = 0; ch_idx < IWL_NUM_CHANNELS; ch_idx++) { | 183 | for (ch_idx = 0; ch_idx < IWL_NUM_CHANNELS; ch_idx++) { |
| 184 | ch_flags = __le16_to_cpup(nvm_ch_flags + ch_idx); | 184 | ch_flags = __le16_to_cpup(nvm_ch_flags + ch_idx); |
| 185 | |||
| 186 | if (ch_idx >= NUM_2GHZ_CHANNELS && | ||
| 187 | !data->sku_cap_band_52GHz_enable) | ||
| 188 | ch_flags &= ~NVM_CHANNEL_VALID; | ||
| 189 | |||
| 185 | if (!(ch_flags & NVM_CHANNEL_VALID)) { | 190 | if (!(ch_flags & NVM_CHANNEL_VALID)) { |
| 186 | IWL_DEBUG_EEPROM(dev, | 191 | IWL_DEBUG_EEPROM(dev, |
| 187 | "Ch. %d Flags %x [%sGHz] - No traffic\n", | 192 | "Ch. %d Flags %x [%sGHz] - No traffic\n", |
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h index 73cbba7424f2..9426905de6b2 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h | |||
| @@ -504,6 +504,7 @@ struct iwl_scan_offload_profile { | |||
| 504 | * @match_notify: clients waiting for match found notification | 504 | * @match_notify: clients waiting for match found notification |
| 505 | * @pass_match: clients waiting for the results | 505 | * @pass_match: clients waiting for the results |
| 506 | * @active_clients: active clients bitmap - enum scan_framework_client | 506 | * @active_clients: active clients bitmap - enum scan_framework_client |
| 507 | * @any_beacon_notify: clients waiting for match notification without match | ||
| 507 | */ | 508 | */ |
| 508 | struct iwl_scan_offload_profile_cfg { | 509 | struct iwl_scan_offload_profile_cfg { |
| 509 | struct iwl_scan_offload_profile profiles[IWL_SCAN_MAX_PROFILES]; | 510 | struct iwl_scan_offload_profile profiles[IWL_SCAN_MAX_PROFILES]; |
| @@ -512,7 +513,8 @@ struct iwl_scan_offload_profile_cfg { | |||
| 512 | u8 match_notify; | 513 | u8 match_notify; |
| 513 | u8 pass_match; | 514 | u8 pass_match; |
| 514 | u8 active_clients; | 515 | u8 active_clients; |
| 515 | u8 reserved[3]; | 516 | u8 any_beacon_notify; |
| 517 | u8 reserved[2]; | ||
| 516 | } __packed; | 518 | } __packed; |
| 517 | 519 | ||
| 518 | /** | 520 | /** |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index c49b5073c251..6bf9766e5982 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c | |||
| @@ -246,7 +246,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) | |||
| 246 | else | 246 | else |
| 247 | hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; | 247 | hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; |
| 248 | 248 | ||
| 249 | if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_SCHED_SCAN) { | 249 | if (0 && mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_SCHED_SCAN) { |
| 250 | hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; | 250 | hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; |
| 251 | hw->wiphy->max_sched_scan_ssids = PROBE_OPTION_MAX; | 251 | hw->wiphy->max_sched_scan_ssids = PROBE_OPTION_MAX; |
| 252 | hw->wiphy->max_match_sets = IWL_SCAN_MAX_PROFILES; | 252 | hw->wiphy->max_match_sets = IWL_SCAN_MAX_PROFILES; |
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c index 0e0007960612..742afc429c94 100644 --- a/drivers/net/wireless/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/iwlwifi/mvm/scan.c | |||
| @@ -344,7 +344,8 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm, | |||
| 344 | 344 | ||
| 345 | iwl_mvm_scan_fill_ssids(cmd, req, basic_ssid ? 1 : 0); | 345 | iwl_mvm_scan_fill_ssids(cmd, req, basic_ssid ? 1 : 0); |
| 346 | 346 | ||
| 347 | cmd->tx_cmd.tx_flags = cpu_to_le32(TX_CMD_FLG_SEQ_CTL); | 347 | cmd->tx_cmd.tx_flags = cpu_to_le32(TX_CMD_FLG_SEQ_CTL | |
| 348 | TX_CMD_FLG_BT_DIS); | ||
| 348 | cmd->tx_cmd.sta_id = mvm->aux_sta.sta_id; | 349 | cmd->tx_cmd.sta_id = mvm->aux_sta.sta_id; |
| 349 | cmd->tx_cmd.life_time = cpu_to_le32(TX_CMD_LIFE_TIME_INFINITE); | 350 | cmd->tx_cmd.life_time = cpu_to_le32(TX_CMD_LIFE_TIME_INFINITE); |
| 350 | cmd->tx_cmd.rate_n_flags = | 351 | cmd->tx_cmd.rate_n_flags = |
| @@ -807,6 +808,8 @@ int iwl_mvm_config_sched_scan_profiles(struct iwl_mvm *mvm, | |||
| 807 | profile_cfg->active_clients = SCAN_CLIENT_SCHED_SCAN; | 808 | profile_cfg->active_clients = SCAN_CLIENT_SCHED_SCAN; |
| 808 | profile_cfg->pass_match = SCAN_CLIENT_SCHED_SCAN; | 809 | profile_cfg->pass_match = SCAN_CLIENT_SCHED_SCAN; |
| 809 | profile_cfg->match_notify = SCAN_CLIENT_SCHED_SCAN; | 810 | profile_cfg->match_notify = SCAN_CLIENT_SCHED_SCAN; |
| 811 | if (!req->n_match_sets || !req->match_sets[0].ssid.ssid_len) | ||
| 812 | profile_cfg->any_beacon_notify = SCAN_CLIENT_SCHED_SCAN; | ||
| 810 | 813 | ||
| 811 | for (i = 0; i < req->n_match_sets; i++) { | 814 | for (i = 0; i < req->n_match_sets; i++) { |
| 812 | profile = &profile_cfg->profiles[i]; | 815 | profile = &profile_cfg->profiles[i]; |
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c index ec1812133235..3397f59cd4e4 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/iwlwifi/mvm/sta.c | |||
| @@ -652,7 +652,7 @@ int iwl_mvm_send_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
| 652 | { | 652 | { |
| 653 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | 653 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); |
| 654 | static const u8 _baddr[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; | 654 | static const u8 _baddr[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; |
| 655 | static const u8 *baddr = _baddr; | 655 | const u8 *baddr = _baddr; |
| 656 | 656 | ||
| 657 | lockdep_assert_held(&mvm->mutex); | 657 | lockdep_assert_held(&mvm->mutex); |
| 658 | 658 | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c index 90378c217bc7..4df12fa9d336 100644 --- a/drivers/net/wireless/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/iwlwifi/mvm/tx.c | |||
| @@ -659,8 +659,14 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, | |||
| 659 | rcu_read_lock(); | 659 | rcu_read_lock(); |
| 660 | 660 | ||
| 661 | sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]); | 661 | sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]); |
| 662 | /* | ||
| 663 | * sta can't be NULL otherwise it'd mean that the sta has been freed in | ||
| 664 | * the firmware while we still have packets for it in the Tx queues. | ||
| 665 | */ | ||
| 666 | if (WARN_ON_ONCE(!sta)) | ||
| 667 | goto out; | ||
| 662 | 668 | ||
| 663 | if (!IS_ERR_OR_NULL(sta)) { | 669 | if (!IS_ERR(sta)) { |
| 664 | mvmsta = iwl_mvm_sta_from_mac80211(sta); | 670 | mvmsta = iwl_mvm_sta_from_mac80211(sta); |
| 665 | 671 | ||
| 666 | if (tid != IWL_TID_NON_QOS) { | 672 | if (tid != IWL_TID_NON_QOS) { |
| @@ -675,7 +681,6 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, | |||
| 675 | spin_unlock_bh(&mvmsta->lock); | 681 | spin_unlock_bh(&mvmsta->lock); |
| 676 | } | 682 | } |
| 677 | } else { | 683 | } else { |
| 678 | sta = NULL; | ||
| 679 | mvmsta = NULL; | 684 | mvmsta = NULL; |
| 680 | } | 685 | } |
| 681 | 686 | ||
| @@ -683,42 +688,38 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, | |||
| 683 | * If the txq is not an AMPDU queue, there is no chance we freed | 688 | * If the txq is not an AMPDU queue, there is no chance we freed |
| 684 | * several skbs. Check that out... | 689 | * several skbs. Check that out... |
| 685 | */ | 690 | */ |
| 686 | if (txq_id < mvm->first_agg_queue && !WARN_ON(skb_freed > 1) && | 691 | if (txq_id >= mvm->first_agg_queue) |
| 687 | atomic_sub_and_test(skb_freed, &mvm->pending_frames[sta_id])) { | 692 | goto out; |
| 688 | if (mvmsta) { | 693 | |
| 689 | /* | 694 | /* We can't free more than one frame at once on a shared queue */ |
| 690 | * If there are no pending frames for this STA, notify | 695 | WARN_ON(skb_freed > 1); |
| 691 | * mac80211 that this station can go to sleep in its | 696 | |
| 692 | * STA table. | 697 | /* If we have still frames from this STA nothing to do here */ |
| 693 | */ | 698 | if (!atomic_sub_and_test(skb_freed, &mvm->pending_frames[sta_id])) |
| 694 | if (mvmsta->vif->type == NL80211_IFTYPE_AP) | 699 | goto out; |
| 695 | ieee80211_sta_block_awake(mvm->hw, sta, false); | 700 | |
| 696 | /* | 701 | if (mvmsta && mvmsta->vif->type == NL80211_IFTYPE_AP) { |
| 697 | * We might very well have taken mvmsta pointer while | 702 | /* |
| 698 | * the station was being removed. The remove flow might | 703 | * If there are no pending frames for this STA, notify |
| 699 | * have seen a pending_frame (because we didn't take | 704 | * mac80211 that this station can go to sleep in its |
| 700 | * the lock) even if now the queues are drained. So make | 705 | * STA table. |
| 701 | * really sure now that this the station is not being | 706 | * If mvmsta is not NULL, sta is valid. |
| 702 | * removed. If it is, run the drain worker to remove it. | 707 | */ |
| 703 | */ | 708 | ieee80211_sta_block_awake(mvm->hw, sta, false); |
| 704 | spin_lock_bh(&mvmsta->lock); | 709 | } |
| 705 | sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]); | 710 | |
| 706 | if (!sta || PTR_ERR(sta) == -EBUSY) { | 711 | if (PTR_ERR(sta) == -EBUSY || PTR_ERR(sta) == -ENOENT) { |
| 707 | /* | 712 | /* |
| 708 | * Station disappeared in the meantime: | 713 | * We are draining and this was the last packet - pre_rcu_remove |
| 709 | * so we are draining. | 714 | * has been called already. We might be after the |
| 710 | */ | 715 | * synchronize_net already. |
| 711 | set_bit(sta_id, mvm->sta_drained); | 716 | * Don't rely on iwl_mvm_rm_sta to see the empty Tx queues. |
| 712 | schedule_work(&mvm->sta_drained_wk); | 717 | */ |
| 713 | } | 718 | set_bit(sta_id, mvm->sta_drained); |
| 714 | spin_unlock_bh(&mvmsta->lock); | 719 | schedule_work(&mvm->sta_drained_wk); |
| 715 | } else if (!mvmsta && PTR_ERR(sta) == -EBUSY) { | ||
| 716 | /* Tx response without STA, so we are draining */ | ||
| 717 | set_bit(sta_id, mvm->sta_drained); | ||
| 718 | schedule_work(&mvm->sta_drained_wk); | ||
| 719 | } | ||
| 720 | } | 720 | } |
| 721 | 721 | ||
| 722 | out: | ||
| 722 | rcu_read_unlock(); | 723 | rcu_read_unlock(); |
| 723 | } | 724 | } |
| 724 | 725 | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c index a4a5e25623c3..86989df69356 100644 --- a/drivers/net/wireless/iwlwifi/mvm/utils.c +++ b/drivers/net/wireless/iwlwifi/mvm/utils.c | |||
| @@ -411,6 +411,8 @@ void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm) | |||
| 411 | mvm->status, table.valid); | 411 | mvm->status, table.valid); |
| 412 | } | 412 | } |
| 413 | 413 | ||
| 414 | IWL_ERR(mvm, "Loaded firmware version: %s\n", mvm->fw->fw_version); | ||
| 415 | |||
| 414 | trace_iwlwifi_dev_ucode_error(trans->dev, table.error_id, table.tsf_low, | 416 | trace_iwlwifi_dev_ucode_error(trans->dev, table.error_id, table.tsf_low, |
| 415 | table.data1, table.data2, table.data3, | 417 | table.data1, table.data2, table.data3, |
| 416 | table.blink1, table.blink2, table.ilink1, | 418 | table.blink1, table.blink2, table.ilink1, |
diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c index 3040924f5f3c..f47bcbe2945a 100644 --- a/drivers/net/wireless/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/iwlwifi/pcie/drv.c | |||
| @@ -359,20 +359,25 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { | |||
| 359 | /* 7265 Series */ | 359 | /* 7265 Series */ |
| 360 | {IWL_PCI_DEVICE(0x095A, 0x5010, iwl7265_2ac_cfg)}, | 360 | {IWL_PCI_DEVICE(0x095A, 0x5010, iwl7265_2ac_cfg)}, |
| 361 | {IWL_PCI_DEVICE(0x095A, 0x5110, iwl7265_2ac_cfg)}, | 361 | {IWL_PCI_DEVICE(0x095A, 0x5110, iwl7265_2ac_cfg)}, |
| 362 | {IWL_PCI_DEVICE(0x095A, 0x5112, iwl7265_2ac_cfg)}, | ||
| 363 | {IWL_PCI_DEVICE(0x095A, 0x5100, iwl7265_2ac_cfg)}, | ||
| 364 | {IWL_PCI_DEVICE(0x095A, 0x510A, iwl7265_2ac_cfg)}, | ||
| 362 | {IWL_PCI_DEVICE(0x095B, 0x5310, iwl7265_2ac_cfg)}, | 365 | {IWL_PCI_DEVICE(0x095B, 0x5310, iwl7265_2ac_cfg)}, |
| 363 | {IWL_PCI_DEVICE(0x095B, 0x5302, iwl7265_2ac_cfg)}, | 366 | {IWL_PCI_DEVICE(0x095B, 0x5302, iwl7265_2ac_cfg)}, |
| 364 | {IWL_PCI_DEVICE(0x095B, 0x5210, iwl7265_2ac_cfg)}, | 367 | {IWL_PCI_DEVICE(0x095B, 0x5210, iwl7265_2ac_cfg)}, |
| 365 | {IWL_PCI_DEVICE(0x095A, 0x5012, iwl7265_2ac_cfg)}, | 368 | {IWL_PCI_DEVICE(0x095A, 0x5012, iwl7265_2ac_cfg)}, |
| 366 | {IWL_PCI_DEVICE(0x095A, 0x500A, iwl7265_2ac_cfg)}, | ||
| 367 | {IWL_PCI_DEVICE(0x095A, 0x5410, iwl7265_2ac_cfg)}, | 369 | {IWL_PCI_DEVICE(0x095A, 0x5410, iwl7265_2ac_cfg)}, |
| 368 | {IWL_PCI_DEVICE(0x095A, 0x5400, iwl7265_2ac_cfg)}, | 370 | {IWL_PCI_DEVICE(0x095A, 0x5400, iwl7265_2ac_cfg)}, |
| 369 | {IWL_PCI_DEVICE(0x095A, 0x1010, iwl7265_2ac_cfg)}, | 371 | {IWL_PCI_DEVICE(0x095A, 0x1010, iwl7265_2ac_cfg)}, |
| 370 | {IWL_PCI_DEVICE(0x095A, 0x5000, iwl7265_2n_cfg)}, | 372 | {IWL_PCI_DEVICE(0x095A, 0x5000, iwl7265_2n_cfg)}, |
| 373 | {IWL_PCI_DEVICE(0x095A, 0x500A, iwl7265_2n_cfg)}, | ||
| 371 | {IWL_PCI_DEVICE(0x095B, 0x5200, iwl7265_2n_cfg)}, | 374 | {IWL_PCI_DEVICE(0x095B, 0x5200, iwl7265_2n_cfg)}, |
| 372 | {IWL_PCI_DEVICE(0x095A, 0x5002, iwl7265_n_cfg)}, | 375 | {IWL_PCI_DEVICE(0x095A, 0x5002, iwl7265_n_cfg)}, |
| 373 | {IWL_PCI_DEVICE(0x095B, 0x5202, iwl7265_n_cfg)}, | 376 | {IWL_PCI_DEVICE(0x095B, 0x5202, iwl7265_n_cfg)}, |
| 374 | {IWL_PCI_DEVICE(0x095A, 0x9010, iwl7265_2ac_cfg)}, | 377 | {IWL_PCI_DEVICE(0x095A, 0x9010, iwl7265_2ac_cfg)}, |
| 378 | {IWL_PCI_DEVICE(0x095A, 0x9012, iwl7265_2ac_cfg)}, | ||
| 375 | {IWL_PCI_DEVICE(0x095A, 0x9110, iwl7265_2ac_cfg)}, | 379 | {IWL_PCI_DEVICE(0x095A, 0x9110, iwl7265_2ac_cfg)}, |
| 380 | {IWL_PCI_DEVICE(0x095A, 0x9112, iwl7265_2ac_cfg)}, | ||
| 376 | {IWL_PCI_DEVICE(0x095A, 0x9210, iwl7265_2ac_cfg)}, | 381 | {IWL_PCI_DEVICE(0x095A, 0x9210, iwl7265_2ac_cfg)}, |
| 377 | {IWL_PCI_DEVICE(0x095A, 0x9510, iwl7265_2ac_cfg)}, | 382 | {IWL_PCI_DEVICE(0x095A, 0x9510, iwl7265_2ac_cfg)}, |
| 378 | {IWL_PCI_DEVICE(0x095A, 0x9310, iwl7265_2ac_cfg)}, | 383 | {IWL_PCI_DEVICE(0x095A, 0x9310, iwl7265_2ac_cfg)}, |
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index abc5f56f29fe..2f1cd929c6f6 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c | |||
| @@ -1877,6 +1877,11 @@ static int rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
| 1877 | EEPROM_MAC_ADDR_0)); | 1877 | EEPROM_MAC_ADDR_0)); |
| 1878 | 1878 | ||
| 1879 | /* | 1879 | /* |
| 1880 | * Disable powersaving as default. | ||
| 1881 | */ | ||
| 1882 | rt2x00dev->hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; | ||
| 1883 | |||
| 1884 | /* | ||
| 1880 | * Initialize hw_mode information. | 1885 | * Initialize hw_mode information. |
| 1881 | */ | 1886 | */ |
| 1882 | spec->supported_bands = SUPPORT_BAND_2GHZ; | 1887 | spec->supported_bands = SUPPORT_BAND_2GHZ; |
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 9f16824cd1bc..d849d590de25 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c | |||
| @@ -1706,6 +1706,11 @@ static int rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
| 1706 | IEEE80211_HW_SUPPORTS_PS | | 1706 | IEEE80211_HW_SUPPORTS_PS | |
| 1707 | IEEE80211_HW_PS_NULLFUNC_STACK; | 1707 | IEEE80211_HW_PS_NULLFUNC_STACK; |
| 1708 | 1708 | ||
| 1709 | /* | ||
| 1710 | * Disable powersaving as default. | ||
| 1711 | */ | ||
| 1712 | rt2x00dev->hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; | ||
| 1713 | |||
| 1709 | SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev); | 1714 | SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev); |
| 1710 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, | 1715 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, |
| 1711 | rt2x00_eeprom_addr(rt2x00dev, | 1716 | rt2x00_eeprom_addr(rt2x00dev, |
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index b8f5b06006c4..7f8b5d156c8c 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c | |||
| @@ -7458,10 +7458,9 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
| 7458 | u32 reg; | 7458 | u32 reg; |
| 7459 | 7459 | ||
| 7460 | /* | 7460 | /* |
| 7461 | * Disable powersaving as default on PCI devices. | 7461 | * Disable powersaving as default. |
| 7462 | */ | 7462 | */ |
| 7463 | if (rt2x00_is_pci(rt2x00dev) || rt2x00_is_soc(rt2x00dev)) | 7463 | rt2x00dev->hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; |
| 7464 | rt2x00dev->hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; | ||
| 7465 | 7464 | ||
| 7466 | /* | 7465 | /* |
| 7467 | * Initialize all hw fields. | 7466 | * Initialize all hw fields. |
diff --git a/drivers/net/wireless/rtl818x/rtl8180/dev.c b/drivers/net/wireless/rtl818x/rtl8180/dev.c index 8ec17aad0e52..3867d1470b36 100644 --- a/drivers/net/wireless/rtl818x/rtl8180/dev.c +++ b/drivers/net/wireless/rtl818x/rtl8180/dev.c | |||
| @@ -107,6 +107,7 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev) | |||
| 107 | struct rtl8180_priv *priv = dev->priv; | 107 | struct rtl8180_priv *priv = dev->priv; |
| 108 | unsigned int count = 32; | 108 | unsigned int count = 32; |
| 109 | u8 signal, agc, sq; | 109 | u8 signal, agc, sq; |
| 110 | dma_addr_t mapping; | ||
| 110 | 111 | ||
| 111 | while (count--) { | 112 | while (count--) { |
| 112 | struct rtl8180_rx_desc *entry = &priv->rx_ring[priv->rx_idx]; | 113 | struct rtl8180_rx_desc *entry = &priv->rx_ring[priv->rx_idx]; |
| @@ -128,6 +129,17 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev) | |||
| 128 | if (unlikely(!new_skb)) | 129 | if (unlikely(!new_skb)) |
| 129 | goto done; | 130 | goto done; |
| 130 | 131 | ||
| 132 | mapping = pci_map_single(priv->pdev, | ||
| 133 | skb_tail_pointer(new_skb), | ||
| 134 | MAX_RX_SIZE, PCI_DMA_FROMDEVICE); | ||
| 135 | |||
| 136 | if (pci_dma_mapping_error(priv->pdev, mapping)) { | ||
| 137 | kfree_skb(new_skb); | ||
| 138 | dev_err(&priv->pdev->dev, "RX DMA map error\n"); | ||
| 139 | |||
| 140 | goto done; | ||
| 141 | } | ||
| 142 | |||
| 131 | pci_unmap_single(priv->pdev, | 143 | pci_unmap_single(priv->pdev, |
| 132 | *((dma_addr_t *)skb->cb), | 144 | *((dma_addr_t *)skb->cb), |
| 133 | MAX_RX_SIZE, PCI_DMA_FROMDEVICE); | 145 | MAX_RX_SIZE, PCI_DMA_FROMDEVICE); |
| @@ -158,9 +170,7 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev) | |||
| 158 | 170 | ||
| 159 | skb = new_skb; | 171 | skb = new_skb; |
| 160 | priv->rx_buf[priv->rx_idx] = skb; | 172 | priv->rx_buf[priv->rx_idx] = skb; |
| 161 | *((dma_addr_t *) skb->cb) = | 173 | *((dma_addr_t *) skb->cb) = mapping; |
| 162 | pci_map_single(priv->pdev, skb_tail_pointer(skb), | ||
| 163 | MAX_RX_SIZE, PCI_DMA_FROMDEVICE); | ||
| 164 | } | 174 | } |
| 165 | 175 | ||
| 166 | done: | 176 | done: |
| @@ -266,6 +276,13 @@ static void rtl8180_tx(struct ieee80211_hw *dev, | |||
| 266 | mapping = pci_map_single(priv->pdev, skb->data, | 276 | mapping = pci_map_single(priv->pdev, skb->data, |
| 267 | skb->len, PCI_DMA_TODEVICE); | 277 | skb->len, PCI_DMA_TODEVICE); |
| 268 | 278 | ||
| 279 | if (pci_dma_mapping_error(priv->pdev, mapping)) { | ||
| 280 | kfree_skb(skb); | ||
| 281 | dev_err(&priv->pdev->dev, "TX DMA mapping error\n"); | ||
| 282 | return; | ||
| 283 | |||
| 284 | } | ||
| 285 | |||
| 269 | tx_flags = RTL818X_TX_DESC_FLAG_OWN | RTL818X_TX_DESC_FLAG_FS | | 286 | tx_flags = RTL818X_TX_DESC_FLAG_OWN | RTL818X_TX_DESC_FLAG_FS | |
| 270 | RTL818X_TX_DESC_FLAG_LS | | 287 | RTL818X_TX_DESC_FLAG_LS | |
| 271 | (ieee80211_get_tx_rate(dev, info)->hw_value << 24) | | 288 | (ieee80211_get_tx_rate(dev, info)->hw_value << 24) | |
diff --git a/drivers/net/xen-netback/common.h b/drivers/net/xen-netback/common.h index 4c76bcb9a879..ae413a2cbee7 100644 --- a/drivers/net/xen-netback/common.h +++ b/drivers/net/xen-netback/common.h | |||
| @@ -143,11 +143,7 @@ struct xenvif { | |||
| 143 | char rx_irq_name[IFNAMSIZ+4]; /* DEVNAME-rx */ | 143 | char rx_irq_name[IFNAMSIZ+4]; /* DEVNAME-rx */ |
| 144 | struct xen_netif_rx_back_ring rx; | 144 | struct xen_netif_rx_back_ring rx; |
| 145 | struct sk_buff_head rx_queue; | 145 | struct sk_buff_head rx_queue; |
| 146 | bool rx_queue_stopped; | 146 | RING_IDX rx_last_skb_slots; |
| 147 | /* Set when the RX interrupt is triggered by the frontend. | ||
| 148 | * The worker thread may need to wake the queue. | ||
| 149 | */ | ||
| 150 | bool rx_event; | ||
| 151 | 147 | ||
| 152 | /* This array is allocated seperately as it is large */ | 148 | /* This array is allocated seperately as it is large */ |
| 153 | struct gnttab_copy *grant_copy_op; | 149 | struct gnttab_copy *grant_copy_op; |
diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c index b9de31ea7fc4..7669d49a67e2 100644 --- a/drivers/net/xen-netback/interface.c +++ b/drivers/net/xen-netback/interface.c | |||
| @@ -100,7 +100,6 @@ static irqreturn_t xenvif_rx_interrupt(int irq, void *dev_id) | |||
| 100 | { | 100 | { |
| 101 | struct xenvif *vif = dev_id; | 101 | struct xenvif *vif = dev_id; |
| 102 | 102 | ||
| 103 | vif->rx_event = true; | ||
| 104 | xenvif_kick_thread(vif); | 103 | xenvif_kick_thread(vif); |
| 105 | 104 | ||
| 106 | return IRQ_HANDLED; | 105 | return IRQ_HANDLED; |
diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c index 6b62c3eb8e18..e5284bca2d90 100644 --- a/drivers/net/xen-netback/netback.c +++ b/drivers/net/xen-netback/netback.c | |||
| @@ -476,7 +476,6 @@ static void xenvif_rx_action(struct xenvif *vif) | |||
| 476 | unsigned long offset; | 476 | unsigned long offset; |
| 477 | struct skb_cb_overlay *sco; | 477 | struct skb_cb_overlay *sco; |
| 478 | bool need_to_notify = false; | 478 | bool need_to_notify = false; |
| 479 | bool ring_full = false; | ||
| 480 | 479 | ||
| 481 | struct netrx_pending_operations npo = { | 480 | struct netrx_pending_operations npo = { |
| 482 | .copy = vif->grant_copy_op, | 481 | .copy = vif->grant_copy_op, |
| @@ -486,7 +485,7 @@ static void xenvif_rx_action(struct xenvif *vif) | |||
| 486 | skb_queue_head_init(&rxq); | 485 | skb_queue_head_init(&rxq); |
| 487 | 486 | ||
| 488 | while ((skb = skb_dequeue(&vif->rx_queue)) != NULL) { | 487 | while ((skb = skb_dequeue(&vif->rx_queue)) != NULL) { |
| 489 | int max_slots_needed; | 488 | RING_IDX max_slots_needed; |
| 490 | int i; | 489 | int i; |
| 491 | 490 | ||
| 492 | /* We need a cheap worse case estimate for the number of | 491 | /* We need a cheap worse case estimate for the number of |
| @@ -509,9 +508,10 @@ static void xenvif_rx_action(struct xenvif *vif) | |||
| 509 | if (!xenvif_rx_ring_slots_available(vif, max_slots_needed)) { | 508 | if (!xenvif_rx_ring_slots_available(vif, max_slots_needed)) { |
| 510 | skb_queue_head(&vif->rx_queue, skb); | 509 | skb_queue_head(&vif->rx_queue, skb); |
| 511 | need_to_notify = true; | 510 | need_to_notify = true; |
| 512 | ring_full = true; | 511 | vif->rx_last_skb_slots = max_slots_needed; |
| 513 | break; | 512 | break; |
| 514 | } | 513 | } else |
| 514 | vif->rx_last_skb_slots = 0; | ||
| 515 | 515 | ||
| 516 | sco = (struct skb_cb_overlay *)skb->cb; | 516 | sco = (struct skb_cb_overlay *)skb->cb; |
| 517 | sco->meta_slots_used = xenvif_gop_skb(skb, &npo); | 517 | sco->meta_slots_used = xenvif_gop_skb(skb, &npo); |
| @@ -522,8 +522,6 @@ static void xenvif_rx_action(struct xenvif *vif) | |||
| 522 | 522 | ||
| 523 | BUG_ON(npo.meta_prod > ARRAY_SIZE(vif->meta)); | 523 | BUG_ON(npo.meta_prod > ARRAY_SIZE(vif->meta)); |
| 524 | 524 | ||
| 525 | vif->rx_queue_stopped = !npo.copy_prod && ring_full; | ||
| 526 | |||
| 527 | if (!npo.copy_prod) | 525 | if (!npo.copy_prod) |
| 528 | goto done; | 526 | goto done; |
| 529 | 527 | ||
| @@ -1473,8 +1471,8 @@ static struct xen_netif_rx_response *make_rx_response(struct xenvif *vif, | |||
| 1473 | 1471 | ||
| 1474 | static inline int rx_work_todo(struct xenvif *vif) | 1472 | static inline int rx_work_todo(struct xenvif *vif) |
| 1475 | { | 1473 | { |
| 1476 | return (!skb_queue_empty(&vif->rx_queue) && !vif->rx_queue_stopped) || | 1474 | return !skb_queue_empty(&vif->rx_queue) && |
| 1477 | vif->rx_event; | 1475 | xenvif_rx_ring_slots_available(vif, vif->rx_last_skb_slots); |
| 1478 | } | 1476 | } |
| 1479 | 1477 | ||
| 1480 | static inline int tx_work_todo(struct xenvif *vif) | 1478 | static inline int tx_work_todo(struct xenvif *vif) |
| @@ -1560,8 +1558,6 @@ int xenvif_kthread(void *data) | |||
| 1560 | if (!skb_queue_empty(&vif->rx_queue)) | 1558 | if (!skb_queue_empty(&vif->rx_queue)) |
| 1561 | xenvif_rx_action(vif); | 1559 | xenvif_rx_action(vif); |
| 1562 | 1560 | ||
| 1563 | vif->rx_event = false; | ||
| 1564 | |||
| 1565 | if (skb_queue_empty(&vif->rx_queue) && | 1561 | if (skb_queue_empty(&vif->rx_queue) && |
| 1566 | netif_queue_stopped(vif->dev)) | 1562 | netif_queue_stopped(vif->dev)) |
| 1567 | xenvif_start_queue(vif); | 1563 | xenvif_start_queue(vif); |
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index ff04d4f95baa..f9daa9e183f2 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c | |||
| @@ -1832,7 +1832,6 @@ static void netback_changed(struct xenbus_device *dev, | |||
| 1832 | case XenbusStateReconfiguring: | 1832 | case XenbusStateReconfiguring: |
| 1833 | case XenbusStateReconfigured: | 1833 | case XenbusStateReconfigured: |
| 1834 | case XenbusStateUnknown: | 1834 | case XenbusStateUnknown: |
| 1835 | case XenbusStateClosed: | ||
| 1836 | break; | 1835 | break; |
| 1837 | 1836 | ||
| 1838 | case XenbusStateInitWait: | 1837 | case XenbusStateInitWait: |
| @@ -1847,6 +1846,10 @@ static void netback_changed(struct xenbus_device *dev, | |||
| 1847 | netdev_notify_peers(netdev); | 1846 | netdev_notify_peers(netdev); |
| 1848 | break; | 1847 | break; |
| 1849 | 1848 | ||
| 1849 | case XenbusStateClosed: | ||
| 1850 | if (dev->state == XenbusStateClosed) | ||
| 1851 | break; | ||
| 1852 | /* Missed the backend's CLOSING state -- fallthrough */ | ||
| 1850 | case XenbusStateClosing: | 1853 | case XenbusStateClosing: |
| 1851 | xenbus_frontend_closed(dev); | 1854 | xenbus_frontend_closed(dev); |
| 1852 | break; | 1855 | break; |
diff --git a/drivers/of/address.c b/drivers/of/address.c index d3dd41c840f1..1a54f1ffaadb 100644 --- a/drivers/of/address.c +++ b/drivers/of/address.c | |||
| @@ -99,11 +99,12 @@ static unsigned int of_bus_default_get_flags(const __be32 *addr) | |||
| 99 | static int of_bus_pci_match(struct device_node *np) | 99 | static int of_bus_pci_match(struct device_node *np) |
| 100 | { | 100 | { |
| 101 | /* | 101 | /* |
| 102 | * "pciex" is PCI Express | ||
| 102 | * "vci" is for the /chaos bridge on 1st-gen PCI powermacs | 103 | * "vci" is for the /chaos bridge on 1st-gen PCI powermacs |
| 103 | * "ht" is hypertransport | 104 | * "ht" is hypertransport |
| 104 | */ | 105 | */ |
| 105 | return !strcmp(np->type, "pci") || !strcmp(np->type, "vci") || | 106 | return !strcmp(np->type, "pci") || !strcmp(np->type, "pciex") || |
| 106 | !strcmp(np->type, "ht"); | 107 | !strcmp(np->type, "vci") || !strcmp(np->type, "ht"); |
| 107 | } | 108 | } |
| 108 | 109 | ||
| 109 | static void of_bus_pci_count_cells(struct device_node *np, | 110 | static void of_bus_pci_count_cells(struct device_node *np, |
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index 88e35d85d205..8ee88c4ebd83 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c | |||
| @@ -342,8 +342,9 @@ static int cio_check_config(struct subchannel *sch, struct schib *schib) | |||
| 342 | */ | 342 | */ |
| 343 | int cio_commit_config(struct subchannel *sch) | 343 | int cio_commit_config(struct subchannel *sch) |
| 344 | { | 344 | { |
| 345 | struct schib schib; | ||
| 346 | int ccode, retry, ret = 0; | 345 | int ccode, retry, ret = 0; |
| 346 | struct schib schib; | ||
| 347 | struct irb irb; | ||
| 347 | 348 | ||
| 348 | if (stsch_err(sch->schid, &schib) || !css_sch_is_valid(&schib)) | 349 | if (stsch_err(sch->schid, &schib) || !css_sch_is_valid(&schib)) |
| 349 | return -ENODEV; | 350 | return -ENODEV; |
| @@ -367,7 +368,10 @@ int cio_commit_config(struct subchannel *sch) | |||
| 367 | ret = -EAGAIN; | 368 | ret = -EAGAIN; |
| 368 | break; | 369 | break; |
| 369 | case 1: /* status pending */ | 370 | case 1: /* status pending */ |
| 370 | return -EBUSY; | 371 | ret = -EBUSY; |
| 372 | if (tsch(sch->schid, &irb)) | ||
| 373 | return ret; | ||
| 374 | break; | ||
| 371 | case 2: /* busy */ | 375 | case 2: /* busy */ |
| 372 | udelay(100); /* allow for recovery */ | 376 | udelay(100); /* allow for recovery */ |
| 373 | ret = -EBUSY; | 377 | ret = -EBUSY; |
| @@ -403,7 +407,6 @@ EXPORT_SYMBOL_GPL(cio_update_schib); | |||
| 403 | */ | 407 | */ |
| 404 | int cio_enable_subchannel(struct subchannel *sch, u32 intparm) | 408 | int cio_enable_subchannel(struct subchannel *sch, u32 intparm) |
| 405 | { | 409 | { |
| 406 | int retry; | ||
| 407 | int ret; | 410 | int ret; |
| 408 | 411 | ||
| 409 | CIO_TRACE_EVENT(2, "ensch"); | 412 | CIO_TRACE_EVENT(2, "ensch"); |
| @@ -418,20 +421,14 @@ int cio_enable_subchannel(struct subchannel *sch, u32 intparm) | |||
| 418 | sch->config.isc = sch->isc; | 421 | sch->config.isc = sch->isc; |
| 419 | sch->config.intparm = intparm; | 422 | sch->config.intparm = intparm; |
| 420 | 423 | ||
| 421 | for (retry = 0; retry < 3; retry++) { | 424 | ret = cio_commit_config(sch); |
| 425 | if (ret == -EIO) { | ||
| 426 | /* | ||
| 427 | * Got a program check in msch. Try without | ||
| 428 | * the concurrent sense bit the next time. | ||
| 429 | */ | ||
| 430 | sch->config.csense = 0; | ||
| 422 | ret = cio_commit_config(sch); | 431 | ret = cio_commit_config(sch); |
| 423 | if (ret == -EIO) { | ||
| 424 | /* | ||
| 425 | * Got a program check in msch. Try without | ||
| 426 | * the concurrent sense bit the next time. | ||
| 427 | */ | ||
| 428 | sch->config.csense = 0; | ||
| 429 | } else if (ret == -EBUSY) { | ||
| 430 | struct irb irb; | ||
| 431 | if (tsch(sch->schid, &irb) != 0) | ||
| 432 | break; | ||
| 433 | } else | ||
| 434 | break; | ||
| 435 | } | 432 | } |
| 436 | CIO_HEX_EVENT(2, &ret, sizeof(ret)); | 433 | CIO_HEX_EVENT(2, &ret, sizeof(ret)); |
| 437 | return ret; | 434 | return ret; |
| @@ -444,7 +441,6 @@ EXPORT_SYMBOL_GPL(cio_enable_subchannel); | |||
| 444 | */ | 441 | */ |
| 445 | int cio_disable_subchannel(struct subchannel *sch) | 442 | int cio_disable_subchannel(struct subchannel *sch) |
| 446 | { | 443 | { |
| 447 | int retry; | ||
| 448 | int ret; | 444 | int ret; |
| 449 | 445 | ||
| 450 | CIO_TRACE_EVENT(2, "dissch"); | 446 | CIO_TRACE_EVENT(2, "dissch"); |
| @@ -456,16 +452,8 @@ int cio_disable_subchannel(struct subchannel *sch) | |||
| 456 | return -ENODEV; | 452 | return -ENODEV; |
| 457 | 453 | ||
| 458 | sch->config.ena = 0; | 454 | sch->config.ena = 0; |
| 455 | ret = cio_commit_config(sch); | ||
| 459 | 456 | ||
| 460 | for (retry = 0; retry < 3; retry++) { | ||
| 461 | ret = cio_commit_config(sch); | ||
| 462 | if (ret == -EBUSY) { | ||
| 463 | struct irb irb; | ||
| 464 | if (tsch(sch->schid, &irb) != 0) | ||
| 465 | break; | ||
| 466 | } else | ||
| 467 | break; | ||
| 468 | } | ||
| 469 | CIO_HEX_EVENT(2, &ret, sizeof(ret)); | 457 | CIO_HEX_EVENT(2, &ret, sizeof(ret)); |
| 470 | return ret; | 458 | return ret; |
| 471 | } | 459 | } |
diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h index 8acaae18bd11..a563e4c00590 100644 --- a/drivers/s390/cio/qdio.h +++ b/drivers/s390/cio/qdio.h | |||
| @@ -359,14 +359,12 @@ static inline int multicast_outbound(struct qdio_q *q) | |||
| 359 | #define need_siga_sync_out_after_pci(q) \ | 359 | #define need_siga_sync_out_after_pci(q) \ |
| 360 | (unlikely(q->irq_ptr->siga_flag.sync_out_after_pci)) | 360 | (unlikely(q->irq_ptr->siga_flag.sync_out_after_pci)) |
| 361 | 361 | ||
| 362 | #define for_each_input_queue(irq_ptr, q, i) \ | 362 | #define for_each_input_queue(irq_ptr, q, i) \ |
| 363 | for (i = 0, q = irq_ptr->input_qs[0]; \ | 363 | for (i = 0; i < irq_ptr->nr_input_qs && \ |
| 364 | i < irq_ptr->nr_input_qs; \ | 364 | ({ q = irq_ptr->input_qs[i]; 1; }); i++) |
| 365 | q = irq_ptr->input_qs[++i]) | 365 | #define for_each_output_queue(irq_ptr, q, i) \ |
| 366 | #define for_each_output_queue(irq_ptr, q, i) \ | 366 | for (i = 0; i < irq_ptr->nr_output_qs && \ |
| 367 | for (i = 0, q = irq_ptr->output_qs[0]; \ | 367 | ({ q = irq_ptr->output_qs[i]; 1; }); i++) |
| 368 | i < irq_ptr->nr_output_qs; \ | ||
| 369 | q = irq_ptr->output_qs[++i]) | ||
| 370 | 368 | ||
| 371 | #define prev_buf(bufnr) \ | 369 | #define prev_buf(bufnr) \ |
| 372 | ((bufnr + QDIO_MAX_BUFFERS_MASK) & QDIO_MAX_BUFFERS_MASK) | 370 | ((bufnr + QDIO_MAX_BUFFERS_MASK) & QDIO_MAX_BUFFERS_MASK) |
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c index c883a085c059..77466c4faabb 100644 --- a/drivers/s390/cio/qdio_main.c +++ b/drivers/s390/cio/qdio_main.c | |||
| @@ -996,7 +996,7 @@ static void qdio_int_handler_pci(struct qdio_irq *irq_ptr) | |||
| 996 | } | 996 | } |
| 997 | } | 997 | } |
| 998 | 998 | ||
| 999 | if (!pci_out_supported(q)) | 999 | if (!(irq_ptr->qib.ac & QIB_AC_OUTBOUND_PCI_SUPPORTED)) |
| 1000 | return; | 1000 | return; |
| 1001 | 1001 | ||
| 1002 | for_each_output_queue(irq_ptr, q, i) { | 1002 | for_each_output_queue(irq_ptr, q, i) { |
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c index 8f9b4f710d4a..c819b0bd491a 100644 --- a/fs/cifs/cifsacl.c +++ b/fs/cifs/cifsacl.c | |||
| @@ -1043,15 +1043,30 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode, | |||
| 1043 | __u32 secdesclen = 0; | 1043 | __u32 secdesclen = 0; |
| 1044 | struct cifs_ntsd *pntsd = NULL; /* acl obtained from server */ | 1044 | struct cifs_ntsd *pntsd = NULL; /* acl obtained from server */ |
| 1045 | struct cifs_ntsd *pnntsd = NULL; /* modified acl to be sent to server */ | 1045 | struct cifs_ntsd *pnntsd = NULL; /* modified acl to be sent to server */ |
| 1046 | struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); | ||
| 1047 | struct tcon_link *tlink = cifs_sb_tlink(cifs_sb); | ||
| 1048 | struct cifs_tcon *tcon; | ||
| 1049 | |||
| 1050 | if (IS_ERR(tlink)) | ||
| 1051 | return PTR_ERR(tlink); | ||
| 1052 | tcon = tlink_tcon(tlink); | ||
| 1046 | 1053 | ||
| 1047 | cifs_dbg(NOISY, "set ACL from mode for %s\n", path); | 1054 | cifs_dbg(NOISY, "set ACL from mode for %s\n", path); |
| 1048 | 1055 | ||
| 1049 | /* Get the security descriptor */ | 1056 | /* Get the security descriptor */ |
| 1050 | pntsd = get_cifs_acl(CIFS_SB(inode->i_sb), inode, path, &secdesclen); | 1057 | |
| 1058 | if (tcon->ses->server->ops->get_acl == NULL) { | ||
| 1059 | cifs_put_tlink(tlink); | ||
| 1060 | return -EOPNOTSUPP; | ||
| 1061 | } | ||
| 1062 | |||
| 1063 | pntsd = tcon->ses->server->ops->get_acl(cifs_sb, inode, path, | ||
| 1064 | &secdesclen); | ||
| 1051 | if (IS_ERR(pntsd)) { | 1065 | if (IS_ERR(pntsd)) { |
| 1052 | rc = PTR_ERR(pntsd); | 1066 | rc = PTR_ERR(pntsd); |
| 1053 | cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc); | 1067 | cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc); |
| 1054 | goto out; | 1068 | cifs_put_tlink(tlink); |
| 1069 | return rc; | ||
| 1055 | } | 1070 | } |
| 1056 | 1071 | ||
| 1057 | /* | 1072 | /* |
| @@ -1064,6 +1079,7 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode, | |||
| 1064 | pnntsd = kmalloc(secdesclen, GFP_KERNEL); | 1079 | pnntsd = kmalloc(secdesclen, GFP_KERNEL); |
| 1065 | if (!pnntsd) { | 1080 | if (!pnntsd) { |
| 1066 | kfree(pntsd); | 1081 | kfree(pntsd); |
| 1082 | cifs_put_tlink(tlink); | ||
| 1067 | return -ENOMEM; | 1083 | return -ENOMEM; |
| 1068 | } | 1084 | } |
| 1069 | 1085 | ||
| @@ -1072,14 +1088,18 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode, | |||
| 1072 | 1088 | ||
| 1073 | cifs_dbg(NOISY, "build_sec_desc rc: %d\n", rc); | 1089 | cifs_dbg(NOISY, "build_sec_desc rc: %d\n", rc); |
| 1074 | 1090 | ||
| 1091 | if (tcon->ses->server->ops->set_acl == NULL) | ||
| 1092 | rc = -EOPNOTSUPP; | ||
| 1093 | |||
| 1075 | if (!rc) { | 1094 | if (!rc) { |
| 1076 | /* Set the security descriptor */ | 1095 | /* Set the security descriptor */ |
| 1077 | rc = set_cifs_acl(pnntsd, secdesclen, inode, path, aclflag); | 1096 | rc = tcon->ses->server->ops->set_acl(pnntsd, secdesclen, inode, |
| 1097 | path, aclflag); | ||
| 1078 | cifs_dbg(NOISY, "set_cifs_acl rc: %d\n", rc); | 1098 | cifs_dbg(NOISY, "set_cifs_acl rc: %d\n", rc); |
| 1079 | } | 1099 | } |
| 1100 | cifs_put_tlink(tlink); | ||
| 1080 | 1101 | ||
| 1081 | kfree(pnntsd); | 1102 | kfree(pnntsd); |
| 1082 | kfree(pntsd); | 1103 | kfree(pntsd); |
| 1083 | out: | ||
| 1084 | return rc; | 1104 | return rc; |
| 1085 | } | 1105 | } |
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index a245d1809ed8..86dc28c7aa5c 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
| @@ -323,7 +323,8 @@ struct smb_version_operations { | |||
| 323 | /* async read from the server */ | 323 | /* async read from the server */ |
| 324 | int (*async_readv)(struct cifs_readdata *); | 324 | int (*async_readv)(struct cifs_readdata *); |
| 325 | /* async write to the server */ | 325 | /* async write to the server */ |
| 326 | int (*async_writev)(struct cifs_writedata *); | 326 | int (*async_writev)(struct cifs_writedata *, |
| 327 | void (*release)(struct kref *)); | ||
| 327 | /* sync read from the server */ | 328 | /* sync read from the server */ |
| 328 | int (*sync_read)(const unsigned int, struct cifsFileInfo *, | 329 | int (*sync_read)(const unsigned int, struct cifsFileInfo *, |
| 329 | struct cifs_io_parms *, unsigned int *, char **, | 330 | struct cifs_io_parms *, unsigned int *, char **, |
| @@ -395,6 +396,10 @@ struct smb_version_operations { | |||
| 395 | int (*set_EA)(const unsigned int, struct cifs_tcon *, const char *, | 396 | int (*set_EA)(const unsigned int, struct cifs_tcon *, const char *, |
| 396 | const char *, const void *, const __u16, | 397 | const char *, const void *, const __u16, |
| 397 | const struct nls_table *, int); | 398 | const struct nls_table *, int); |
| 399 | struct cifs_ntsd * (*get_acl)(struct cifs_sb_info *, struct inode *, | ||
| 400 | const char *, u32 *); | ||
| 401 | int (*set_acl)(struct cifs_ntsd *, __u32, struct inode *, const char *, | ||
| 402 | int); | ||
| 398 | }; | 403 | }; |
| 399 | 404 | ||
| 400 | struct smb_version_values { | 405 | struct smb_version_values { |
| @@ -1064,7 +1069,7 @@ struct cifs_writedata { | |||
| 1064 | unsigned int pagesz; | 1069 | unsigned int pagesz; |
| 1065 | unsigned int tailsz; | 1070 | unsigned int tailsz; |
| 1066 | unsigned int nr_pages; | 1071 | unsigned int nr_pages; |
| 1067 | struct page *pages[1]; | 1072 | struct page *pages[]; |
| 1068 | }; | 1073 | }; |
| 1069 | 1074 | ||
| 1070 | /* | 1075 | /* |
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 79e6e9a93a8c..d00e09dfc452 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
| @@ -488,7 +488,8 @@ void cifs_readdata_release(struct kref *refcount); | |||
| 488 | int cifs_async_readv(struct cifs_readdata *rdata); | 488 | int cifs_async_readv(struct cifs_readdata *rdata); |
| 489 | int cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid); | 489 | int cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid); |
| 490 | 490 | ||
| 491 | int cifs_async_writev(struct cifs_writedata *wdata); | 491 | int cifs_async_writev(struct cifs_writedata *wdata, |
| 492 | void (*release)(struct kref *kref)); | ||
| 492 | void cifs_writev_complete(struct work_struct *work); | 493 | void cifs_writev_complete(struct work_struct *work); |
| 493 | struct cifs_writedata *cifs_writedata_alloc(unsigned int nr_pages, | 494 | struct cifs_writedata *cifs_writedata_alloc(unsigned int nr_pages, |
| 494 | work_func_t complete); | 495 | work_func_t complete); |
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 4d881c35eeca..f3264bd7a83d 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
| @@ -1910,7 +1910,7 @@ cifs_writev_requeue(struct cifs_writedata *wdata) | |||
| 1910 | 1910 | ||
| 1911 | do { | 1911 | do { |
| 1912 | server = tlink_tcon(wdata->cfile->tlink)->ses->server; | 1912 | server = tlink_tcon(wdata->cfile->tlink)->ses->server; |
| 1913 | rc = server->ops->async_writev(wdata); | 1913 | rc = server->ops->async_writev(wdata, cifs_writedata_release); |
| 1914 | } while (rc == -EAGAIN); | 1914 | } while (rc == -EAGAIN); |
| 1915 | 1915 | ||
| 1916 | for (i = 0; i < wdata->nr_pages; i++) { | 1916 | for (i = 0; i < wdata->nr_pages; i++) { |
| @@ -1962,15 +1962,9 @@ cifs_writedata_alloc(unsigned int nr_pages, work_func_t complete) | |||
| 1962 | { | 1962 | { |
| 1963 | struct cifs_writedata *wdata; | 1963 | struct cifs_writedata *wdata; |
| 1964 | 1964 | ||
| 1965 | /* this would overflow */ | ||
| 1966 | if (nr_pages == 0) { | ||
| 1967 | cifs_dbg(VFS, "%s: called with nr_pages == 0!\n", __func__); | ||
| 1968 | return NULL; | ||
| 1969 | } | ||
| 1970 | |||
| 1971 | /* writedata + number of page pointers */ | 1965 | /* writedata + number of page pointers */ |
| 1972 | wdata = kzalloc(sizeof(*wdata) + | 1966 | wdata = kzalloc(sizeof(*wdata) + |
| 1973 | sizeof(struct page *) * (nr_pages - 1), GFP_NOFS); | 1967 | sizeof(struct page *) * nr_pages, GFP_NOFS); |
| 1974 | if (wdata != NULL) { | 1968 | if (wdata != NULL) { |
| 1975 | kref_init(&wdata->refcount); | 1969 | kref_init(&wdata->refcount); |
| 1976 | INIT_LIST_HEAD(&wdata->list); | 1970 | INIT_LIST_HEAD(&wdata->list); |
| @@ -2031,7 +2025,8 @@ cifs_writev_callback(struct mid_q_entry *mid) | |||
| 2031 | 2025 | ||
| 2032 | /* cifs_async_writev - send an async write, and set up mid to handle result */ | 2026 | /* cifs_async_writev - send an async write, and set up mid to handle result */ |
| 2033 | int | 2027 | int |
| 2034 | cifs_async_writev(struct cifs_writedata *wdata) | 2028 | cifs_async_writev(struct cifs_writedata *wdata, |
| 2029 | void (*release)(struct kref *kref)) | ||
| 2035 | { | 2030 | { |
| 2036 | int rc = -EACCES; | 2031 | int rc = -EACCES; |
| 2037 | WRITE_REQ *smb = NULL; | 2032 | WRITE_REQ *smb = NULL; |
| @@ -2105,7 +2100,7 @@ cifs_async_writev(struct cifs_writedata *wdata) | |||
| 2105 | if (rc == 0) | 2100 | if (rc == 0) |
| 2106 | cifs_stats_inc(&tcon->stats.cifs_stats.num_writes); | 2101 | cifs_stats_inc(&tcon->stats.cifs_stats.num_writes); |
| 2107 | else | 2102 | else |
| 2108 | kref_put(&wdata->refcount, cifs_writedata_release); | 2103 | kref_put(&wdata->refcount, release); |
| 2109 | 2104 | ||
| 2110 | async_writev_out: | 2105 | async_writev_out: |
| 2111 | cifs_small_buf_release(smb); | 2106 | cifs_small_buf_release(smb); |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index a7eda8ebfacc..755584684f6c 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
| @@ -2043,7 +2043,8 @@ retry: | |||
| 2043 | } | 2043 | } |
| 2044 | wdata->pid = wdata->cfile->pid; | 2044 | wdata->pid = wdata->cfile->pid; |
| 2045 | server = tlink_tcon(wdata->cfile->tlink)->ses->server; | 2045 | server = tlink_tcon(wdata->cfile->tlink)->ses->server; |
| 2046 | rc = server->ops->async_writev(wdata); | 2046 | rc = server->ops->async_writev(wdata, |
| 2047 | cifs_writedata_release); | ||
| 2047 | } while (wbc->sync_mode == WB_SYNC_ALL && rc == -EAGAIN); | 2048 | } while (wbc->sync_mode == WB_SYNC_ALL && rc == -EAGAIN); |
| 2048 | 2049 | ||
| 2049 | for (i = 0; i < nr_pages; ++i) | 2050 | for (i = 0; i < nr_pages; ++i) |
| @@ -2331,9 +2332,20 @@ size_t get_numpages(const size_t wsize, const size_t len, size_t *cur_len) | |||
| 2331 | } | 2332 | } |
| 2332 | 2333 | ||
| 2333 | static void | 2334 | static void |
| 2334 | cifs_uncached_writev_complete(struct work_struct *work) | 2335 | cifs_uncached_writedata_release(struct kref *refcount) |
| 2335 | { | 2336 | { |
| 2336 | int i; | 2337 | int i; |
| 2338 | struct cifs_writedata *wdata = container_of(refcount, | ||
| 2339 | struct cifs_writedata, refcount); | ||
| 2340 | |||
| 2341 | for (i = 0; i < wdata->nr_pages; i++) | ||
| 2342 | put_page(wdata->pages[i]); | ||
| 2343 | cifs_writedata_release(refcount); | ||
| 2344 | } | ||
| 2345 | |||
| 2346 | static void | ||
| 2347 | cifs_uncached_writev_complete(struct work_struct *work) | ||
| 2348 | { | ||
| 2337 | struct cifs_writedata *wdata = container_of(work, | 2349 | struct cifs_writedata *wdata = container_of(work, |
| 2338 | struct cifs_writedata, work); | 2350 | struct cifs_writedata, work); |
| 2339 | struct inode *inode = wdata->cfile->dentry->d_inode; | 2351 | struct inode *inode = wdata->cfile->dentry->d_inode; |
| @@ -2347,12 +2359,7 @@ cifs_uncached_writev_complete(struct work_struct *work) | |||
| 2347 | 2359 | ||
| 2348 | complete(&wdata->done); | 2360 | complete(&wdata->done); |
| 2349 | 2361 | ||
| 2350 | if (wdata->result != -EAGAIN) { | 2362 | kref_put(&wdata->refcount, cifs_uncached_writedata_release); |
| 2351 | for (i = 0; i < wdata->nr_pages; i++) | ||
| 2352 | put_page(wdata->pages[i]); | ||
| 2353 | } | ||
| 2354 | |||
| 2355 | kref_put(&wdata->refcount, cifs_writedata_release); | ||
| 2356 | } | 2363 | } |
| 2357 | 2364 | ||
| 2358 | /* attempt to send write to server, retry on any -EAGAIN errors */ | 2365 | /* attempt to send write to server, retry on any -EAGAIN errors */ |
| @@ -2370,7 +2377,8 @@ cifs_uncached_retry_writev(struct cifs_writedata *wdata) | |||
| 2370 | if (rc != 0) | 2377 | if (rc != 0) |
| 2371 | continue; | 2378 | continue; |
| 2372 | } | 2379 | } |
| 2373 | rc = server->ops->async_writev(wdata); | 2380 | rc = server->ops->async_writev(wdata, |
| 2381 | cifs_uncached_writedata_release); | ||
| 2374 | } while (rc == -EAGAIN); | 2382 | } while (rc == -EAGAIN); |
| 2375 | 2383 | ||
| 2376 | return rc; | 2384 | return rc; |
| @@ -2454,7 +2462,8 @@ cifs_iovec_write(struct file *file, const struct iovec *iov, | |||
| 2454 | wdata->tailsz = cur_len - ((nr_pages - 1) * PAGE_SIZE); | 2462 | wdata->tailsz = cur_len - ((nr_pages - 1) * PAGE_SIZE); |
| 2455 | rc = cifs_uncached_retry_writev(wdata); | 2463 | rc = cifs_uncached_retry_writev(wdata); |
| 2456 | if (rc) { | 2464 | if (rc) { |
| 2457 | kref_put(&wdata->refcount, cifs_writedata_release); | 2465 | kref_put(&wdata->refcount, |
| 2466 | cifs_uncached_writedata_release); | ||
| 2458 | break; | 2467 | break; |
| 2459 | } | 2468 | } |
| 2460 | 2469 | ||
| @@ -2496,7 +2505,7 @@ restart_loop: | |||
| 2496 | } | 2505 | } |
| 2497 | } | 2506 | } |
| 2498 | list_del_init(&wdata->list); | 2507 | list_del_init(&wdata->list); |
| 2499 | kref_put(&wdata->refcount, cifs_writedata_release); | 2508 | kref_put(&wdata->refcount, cifs_uncached_writedata_release); |
| 2500 | } | 2509 | } |
| 2501 | 2510 | ||
| 2502 | if (total_written > 0) | 2511 | if (total_written > 0) |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 9cb9679d7357..be58b8fcdb3c 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
| @@ -527,10 +527,15 @@ static int cifs_sfu_mode(struct cifs_fattr *fattr, const unsigned char *path, | |||
| 527 | return PTR_ERR(tlink); | 527 | return PTR_ERR(tlink); |
| 528 | tcon = tlink_tcon(tlink); | 528 | tcon = tlink_tcon(tlink); |
| 529 | 529 | ||
| 530 | rc = CIFSSMBQAllEAs(xid, tcon, path, "SETFILEBITS", | 530 | if (tcon->ses->server->ops->query_all_EAs == NULL) { |
| 531 | ea_value, 4 /* size of buf */, cifs_sb->local_nls, | 531 | cifs_put_tlink(tlink); |
| 532 | cifs_sb->mnt_cifs_flags & | 532 | return -EOPNOTSUPP; |
| 533 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 533 | } |
| 534 | |||
| 535 | rc = tcon->ses->server->ops->query_all_EAs(xid, tcon, path, | ||
| 536 | "SETFILEBITS", ea_value, 4 /* size of buf */, | ||
| 537 | cifs_sb->local_nls, | ||
| 538 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
| 534 | cifs_put_tlink(tlink); | 539 | cifs_put_tlink(tlink); |
| 535 | if (rc < 0) | 540 | if (rc < 0) |
| 536 | return (int)rc; | 541 | return (int)rc; |
diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c index 9ac5bfc9cc56..bfd66d84831e 100644 --- a/fs/cifs/smb1ops.c +++ b/fs/cifs/smb1ops.c | |||
| @@ -1067,6 +1067,14 @@ struct smb_version_operations smb1_operations = { | |||
| 1067 | .query_mf_symlink = cifs_query_mf_symlink, | 1067 | .query_mf_symlink = cifs_query_mf_symlink, |
| 1068 | .create_mf_symlink = cifs_create_mf_symlink, | 1068 | .create_mf_symlink = cifs_create_mf_symlink, |
| 1069 | .is_read_op = cifs_is_read_op, | 1069 | .is_read_op = cifs_is_read_op, |
| 1070 | #ifdef CONFIG_CIFS_XATTR | ||
| 1071 | .query_all_EAs = CIFSSMBQAllEAs, | ||
| 1072 | .set_EA = CIFSSMBSetEA, | ||
| 1073 | #endif /* CIFS_XATTR */ | ||
| 1074 | #ifdef CONFIG_CIFS_ACL | ||
| 1075 | .get_acl = get_cifs_acl, | ||
| 1076 | .set_acl = set_cifs_acl, | ||
| 1077 | #endif /* CIFS_ACL */ | ||
| 1070 | }; | 1078 | }; |
| 1071 | 1079 | ||
| 1072 | struct smb_version_values smb1_values = { | 1080 | struct smb_version_values smb1_values = { |
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index 2013234b73ad..a3f7a9c3cc69 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c | |||
| @@ -1890,7 +1890,8 @@ smb2_writev_callback(struct mid_q_entry *mid) | |||
| 1890 | 1890 | ||
| 1891 | /* smb2_async_writev - send an async write, and set up mid to handle result */ | 1891 | /* smb2_async_writev - send an async write, and set up mid to handle result */ |
| 1892 | int | 1892 | int |
| 1893 | smb2_async_writev(struct cifs_writedata *wdata) | 1893 | smb2_async_writev(struct cifs_writedata *wdata, |
| 1894 | void (*release)(struct kref *kref)) | ||
| 1894 | { | 1895 | { |
| 1895 | int rc = -EACCES; | 1896 | int rc = -EACCES; |
| 1896 | struct smb2_write_req *req = NULL; | 1897 | struct smb2_write_req *req = NULL; |
| @@ -1938,7 +1939,7 @@ smb2_async_writev(struct cifs_writedata *wdata) | |||
| 1938 | smb2_writev_callback, wdata, 0); | 1939 | smb2_writev_callback, wdata, 0); |
| 1939 | 1940 | ||
| 1940 | if (rc) { | 1941 | if (rc) { |
| 1941 | kref_put(&wdata->refcount, cifs_writedata_release); | 1942 | kref_put(&wdata->refcount, release); |
| 1942 | cifs_stats_fail_inc(tcon, SMB2_WRITE_HE); | 1943 | cifs_stats_fail_inc(tcon, SMB2_WRITE_HE); |
| 1943 | } | 1944 | } |
| 1944 | 1945 | ||
diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h index 93adc64666f3..0ce48db20a65 100644 --- a/fs/cifs/smb2proto.h +++ b/fs/cifs/smb2proto.h | |||
| @@ -123,7 +123,8 @@ extern int SMB2_get_srv_num(const unsigned int xid, struct cifs_tcon *tcon, | |||
| 123 | extern int smb2_async_readv(struct cifs_readdata *rdata); | 123 | extern int smb2_async_readv(struct cifs_readdata *rdata); |
| 124 | extern int SMB2_read(const unsigned int xid, struct cifs_io_parms *io_parms, | 124 | extern int SMB2_read(const unsigned int xid, struct cifs_io_parms *io_parms, |
| 125 | unsigned int *nbytes, char **buf, int *buf_type); | 125 | unsigned int *nbytes, char **buf, int *buf_type); |
| 126 | extern int smb2_async_writev(struct cifs_writedata *wdata); | 126 | extern int smb2_async_writev(struct cifs_writedata *wdata, |
| 127 | void (*release)(struct kref *kref)); | ||
| 127 | extern int SMB2_write(const unsigned int xid, struct cifs_io_parms *io_parms, | 128 | extern int SMB2_write(const unsigned int xid, struct cifs_io_parms *io_parms, |
| 128 | unsigned int *nbytes, struct kvec *iov, int n_vec); | 129 | unsigned int *nbytes, struct kvec *iov, int n_vec); |
| 129 | extern int SMB2_echo(struct TCP_Server_Info *server); | 130 | extern int SMB2_echo(struct TCP_Server_Info *server); |
diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c index 95c43bb20335..5ac836a86b18 100644 --- a/fs/cifs/xattr.c +++ b/fs/cifs/xattr.c | |||
| @@ -176,8 +176,12 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name, | |||
| 176 | rc = -ENOMEM; | 176 | rc = -ENOMEM; |
| 177 | } else { | 177 | } else { |
| 178 | memcpy(pacl, ea_value, value_size); | 178 | memcpy(pacl, ea_value, value_size); |
| 179 | rc = set_cifs_acl(pacl, value_size, | 179 | if (pTcon->ses->server->ops->set_acl) |
| 180 | direntry->d_inode, full_path, CIFS_ACL_DACL); | 180 | rc = pTcon->ses->server->ops->set_acl(pacl, |
| 181 | value_size, direntry->d_inode, | ||
| 182 | full_path, CIFS_ACL_DACL); | ||
| 183 | else | ||
| 184 | rc = -EOPNOTSUPP; | ||
| 181 | if (rc == 0) /* force revalidate of the inode */ | 185 | if (rc == 0) /* force revalidate of the inode */ |
| 182 | CIFS_I(direntry->d_inode)->time = 0; | 186 | CIFS_I(direntry->d_inode)->time = 0; |
| 183 | kfree(pacl); | 187 | kfree(pacl); |
| @@ -323,8 +327,11 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name, | |||
| 323 | u32 acllen; | 327 | u32 acllen; |
| 324 | struct cifs_ntsd *pacl; | 328 | struct cifs_ntsd *pacl; |
| 325 | 329 | ||
| 326 | pacl = get_cifs_acl(cifs_sb, direntry->d_inode, | 330 | if (pTcon->ses->server->ops->get_acl == NULL) |
| 327 | full_path, &acllen); | 331 | goto get_ea_exit; /* rc already EOPNOTSUPP */ |
| 332 | |||
| 333 | pacl = pTcon->ses->server->ops->get_acl(cifs_sb, | ||
| 334 | direntry->d_inode, full_path, &acllen); | ||
| 328 | if (IS_ERR(pacl)) { | 335 | if (IS_ERR(pacl)) { |
| 329 | rc = PTR_ERR(pacl); | 336 | rc = PTR_ERR(pacl); |
| 330 | cifs_dbg(VFS, "%s: error %zd getting sec desc\n", | 337 | cifs_dbg(VFS, "%s: error %zd getting sec desc\n", |
| @@ -34,7 +34,7 @@ static void *alloc_fdmem(size_t size) | |||
| 34 | * vmalloc() if the allocation size will be considered "large" by the VM. | 34 | * vmalloc() if the allocation size will be considered "large" by the VM. |
| 35 | */ | 35 | */ |
| 36 | if (size <= (PAGE_SIZE << PAGE_ALLOC_COSTLY_ORDER)) { | 36 | if (size <= (PAGE_SIZE << PAGE_ALLOC_COSTLY_ORDER)) { |
| 37 | void *data = kmalloc(size, GFP_KERNEL|__GFP_NOWARN); | 37 | void *data = kmalloc(size, GFP_KERNEL|__GFP_NOWARN|__GFP_NORETRY); |
| 38 | if (data != NULL) | 38 | if (data != NULL) |
| 39 | return data; | 39 | return data; |
| 40 | } | 40 | } |
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index be38b573495a..4a48fe4b84b6 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
| @@ -1846,6 +1846,11 @@ int nfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) | |||
| 1846 | GFP_KERNEL)) { | 1846 | GFP_KERNEL)) { |
| 1847 | SetPageUptodate(page); | 1847 | SetPageUptodate(page); |
| 1848 | unlock_page(page); | 1848 | unlock_page(page); |
| 1849 | /* | ||
| 1850 | * add_to_page_cache_lru() grabs an extra page refcount. | ||
| 1851 | * Drop it here to avoid leaking this page later. | ||
| 1852 | */ | ||
| 1853 | page_cache_release(page); | ||
| 1849 | } else | 1854 | } else |
| 1850 | __free_page(page); | 1855 | __free_page(page); |
| 1851 | 1856 | ||
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index aada5801567a..e2edff38be52 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c | |||
| @@ -7158,7 +7158,7 @@ int ocfs2_truncate_inline(struct inode *inode, struct buffer_head *di_bh, | |||
| 7158 | if (end > i_size_read(inode)) | 7158 | if (end > i_size_read(inode)) |
| 7159 | end = i_size_read(inode); | 7159 | end = i_size_read(inode); |
| 7160 | 7160 | ||
| 7161 | BUG_ON(start >= end); | 7161 | BUG_ON(start > end); |
| 7162 | 7162 | ||
| 7163 | if (!(OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL) || | 7163 | if (!(OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL) || |
| 7164 | !(le16_to_cpu(di->i_dyn_features) & OCFS2_INLINE_DATA_FL) || | 7164 | !(le16_to_cpu(di->i_dyn_features) & OCFS2_INLINE_DATA_FL) || |
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index d77d71ead8d1..8450262bcf2a 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
| @@ -185,6 +185,9 @@ static int ocfs2_sync_file(struct file *file, loff_t start, loff_t end, | |||
| 185 | file->f_path.dentry->d_name.name, | 185 | file->f_path.dentry->d_name.name, |
| 186 | (unsigned long long)datasync); | 186 | (unsigned long long)datasync); |
| 187 | 187 | ||
| 188 | if (ocfs2_is_hard_readonly(osb) || ocfs2_is_soft_readonly(osb)) | ||
| 189 | return -EROFS; | ||
| 190 | |||
| 188 | err = filemap_write_and_wait_range(inode->i_mapping, start, end); | 191 | err = filemap_write_and_wait_range(inode->i_mapping, start, end); |
| 189 | if (err) | 192 | if (err) |
| 190 | return err; | 193 | return err; |
| @@ -474,11 +477,6 @@ static int ocfs2_truncate_file(struct inode *inode, | |||
| 474 | goto bail; | 477 | goto bail; |
| 475 | } | 478 | } |
| 476 | 479 | ||
| 477 | /* lets handle the simple truncate cases before doing any more | ||
| 478 | * cluster locking. */ | ||
| 479 | if (new_i_size == le64_to_cpu(fe->i_size)) | ||
| 480 | goto bail; | ||
| 481 | |||
| 482 | down_write(&OCFS2_I(inode)->ip_alloc_sem); | 480 | down_write(&OCFS2_I(inode)->ip_alloc_sem); |
| 483 | 481 | ||
| 484 | ocfs2_resv_discard(&osb->osb_la_resmap, | 482 | ocfs2_resv_discard(&osb->osb_la_resmap, |
| @@ -718,7 +716,8 @@ leave: | |||
| 718 | * While a write will already be ordering the data, a truncate will not. | 716 | * While a write will already be ordering the data, a truncate will not. |
| 719 | * Thus, we need to explicitly order the zeroed pages. | 717 | * Thus, we need to explicitly order the zeroed pages. |
| 720 | */ | 718 | */ |
| 721 | static handle_t *ocfs2_zero_start_ordered_transaction(struct inode *inode) | 719 | static handle_t *ocfs2_zero_start_ordered_transaction(struct inode *inode, |
| 720 | struct buffer_head *di_bh) | ||
| 722 | { | 721 | { |
| 723 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | 722 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); |
| 724 | handle_t *handle = NULL; | 723 | handle_t *handle = NULL; |
| @@ -735,7 +734,14 @@ static handle_t *ocfs2_zero_start_ordered_transaction(struct inode *inode) | |||
| 735 | } | 734 | } |
| 736 | 735 | ||
| 737 | ret = ocfs2_jbd2_file_inode(handle, inode); | 736 | ret = ocfs2_jbd2_file_inode(handle, inode); |
| 738 | if (ret < 0) | 737 | if (ret < 0) { |
| 738 | mlog_errno(ret); | ||
| 739 | goto out; | ||
| 740 | } | ||
| 741 | |||
| 742 | ret = ocfs2_journal_access_di(handle, INODE_CACHE(inode), di_bh, | ||
| 743 | OCFS2_JOURNAL_ACCESS_WRITE); | ||
| 744 | if (ret) | ||
| 739 | mlog_errno(ret); | 745 | mlog_errno(ret); |
| 740 | 746 | ||
| 741 | out: | 747 | out: |
| @@ -751,7 +757,7 @@ out: | |||
| 751 | * to be too fragile to do exactly what we need without us having to | 757 | * to be too fragile to do exactly what we need without us having to |
| 752 | * worry about recursive locking in ->write_begin() and ->write_end(). */ | 758 | * worry about recursive locking in ->write_begin() and ->write_end(). */ |
| 753 | static int ocfs2_write_zero_page(struct inode *inode, u64 abs_from, | 759 | static int ocfs2_write_zero_page(struct inode *inode, u64 abs_from, |
| 754 | u64 abs_to) | 760 | u64 abs_to, struct buffer_head *di_bh) |
| 755 | { | 761 | { |
| 756 | struct address_space *mapping = inode->i_mapping; | 762 | struct address_space *mapping = inode->i_mapping; |
| 757 | struct page *page; | 763 | struct page *page; |
| @@ -759,6 +765,7 @@ static int ocfs2_write_zero_page(struct inode *inode, u64 abs_from, | |||
| 759 | handle_t *handle = NULL; | 765 | handle_t *handle = NULL; |
| 760 | int ret = 0; | 766 | int ret = 0; |
| 761 | unsigned zero_from, zero_to, block_start, block_end; | 767 | unsigned zero_from, zero_to, block_start, block_end; |
| 768 | struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data; | ||
| 762 | 769 | ||
| 763 | BUG_ON(abs_from >= abs_to); | 770 | BUG_ON(abs_from >= abs_to); |
| 764 | BUG_ON(abs_to > (((u64)index + 1) << PAGE_CACHE_SHIFT)); | 771 | BUG_ON(abs_to > (((u64)index + 1) << PAGE_CACHE_SHIFT)); |
| @@ -801,7 +808,8 @@ static int ocfs2_write_zero_page(struct inode *inode, u64 abs_from, | |||
| 801 | } | 808 | } |
| 802 | 809 | ||
| 803 | if (!handle) { | 810 | if (!handle) { |
| 804 | handle = ocfs2_zero_start_ordered_transaction(inode); | 811 | handle = ocfs2_zero_start_ordered_transaction(inode, |
| 812 | di_bh); | ||
| 805 | if (IS_ERR(handle)) { | 813 | if (IS_ERR(handle)) { |
| 806 | ret = PTR_ERR(handle); | 814 | ret = PTR_ERR(handle); |
| 807 | handle = NULL; | 815 | handle = NULL; |
| @@ -818,8 +826,22 @@ static int ocfs2_write_zero_page(struct inode *inode, u64 abs_from, | |||
| 818 | ret = 0; | 826 | ret = 0; |
| 819 | } | 827 | } |
| 820 | 828 | ||
| 821 | if (handle) | 829 | if (handle) { |
| 830 | /* | ||
| 831 | * fs-writeback will release the dirty pages without page lock | ||
| 832 | * whose offset are over inode size, the release happens at | ||
| 833 | * block_write_full_page_endio(). | ||
| 834 | */ | ||
| 835 | i_size_write(inode, abs_to); | ||
| 836 | inode->i_blocks = ocfs2_inode_sector_count(inode); | ||
| 837 | di->i_size = cpu_to_le64((u64)i_size_read(inode)); | ||
| 838 | inode->i_mtime = inode->i_ctime = CURRENT_TIME; | ||
| 839 | di->i_mtime = di->i_ctime = cpu_to_le64(inode->i_mtime.tv_sec); | ||
| 840 | di->i_ctime_nsec = cpu_to_le32(inode->i_mtime.tv_nsec); | ||
| 841 | di->i_mtime_nsec = di->i_ctime_nsec; | ||
| 842 | ocfs2_journal_dirty(handle, di_bh); | ||
| 822 | ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle); | 843 | ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle); |
| 844 | } | ||
| 823 | 845 | ||
| 824 | out_unlock: | 846 | out_unlock: |
| 825 | unlock_page(page); | 847 | unlock_page(page); |
| @@ -915,7 +937,7 @@ out: | |||
| 915 | * has made sure that the entire range needs zeroing. | 937 | * has made sure that the entire range needs zeroing. |
| 916 | */ | 938 | */ |
| 917 | static int ocfs2_zero_extend_range(struct inode *inode, u64 range_start, | 939 | static int ocfs2_zero_extend_range(struct inode *inode, u64 range_start, |
| 918 | u64 range_end) | 940 | u64 range_end, struct buffer_head *di_bh) |
| 919 | { | 941 | { |
| 920 | int rc = 0; | 942 | int rc = 0; |
| 921 | u64 next_pos; | 943 | u64 next_pos; |
| @@ -931,7 +953,7 @@ static int ocfs2_zero_extend_range(struct inode *inode, u64 range_start, | |||
| 931 | next_pos = (zero_pos & PAGE_CACHE_MASK) + PAGE_CACHE_SIZE; | 953 | next_pos = (zero_pos & PAGE_CACHE_MASK) + PAGE_CACHE_SIZE; |
| 932 | if (next_pos > range_end) | 954 | if (next_pos > range_end) |
| 933 | next_pos = range_end; | 955 | next_pos = range_end; |
| 934 | rc = ocfs2_write_zero_page(inode, zero_pos, next_pos); | 956 | rc = ocfs2_write_zero_page(inode, zero_pos, next_pos, di_bh); |
| 935 | if (rc < 0) { | 957 | if (rc < 0) { |
| 936 | mlog_errno(rc); | 958 | mlog_errno(rc); |
| 937 | break; | 959 | break; |
| @@ -977,7 +999,7 @@ int ocfs2_zero_extend(struct inode *inode, struct buffer_head *di_bh, | |||
| 977 | range_end = zero_to_size; | 999 | range_end = zero_to_size; |
| 978 | 1000 | ||
| 979 | ret = ocfs2_zero_extend_range(inode, range_start, | 1001 | ret = ocfs2_zero_extend_range(inode, range_start, |
| 980 | range_end); | 1002 | range_end, di_bh); |
| 981 | if (ret) { | 1003 | if (ret) { |
| 982 | mlog_errno(ret); | 1004 | mlog_errno(ret); |
| 983 | break; | 1005 | break; |
| @@ -1145,14 +1167,14 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr) | |||
| 1145 | goto bail_unlock_rw; | 1167 | goto bail_unlock_rw; |
| 1146 | } | 1168 | } |
| 1147 | 1169 | ||
| 1148 | if (size_change && attr->ia_size != i_size_read(inode)) { | 1170 | if (size_change) { |
| 1149 | status = inode_newsize_ok(inode, attr->ia_size); | 1171 | status = inode_newsize_ok(inode, attr->ia_size); |
| 1150 | if (status) | 1172 | if (status) |
| 1151 | goto bail_unlock; | 1173 | goto bail_unlock; |
| 1152 | 1174 | ||
| 1153 | inode_dio_wait(inode); | 1175 | inode_dio_wait(inode); |
| 1154 | 1176 | ||
| 1155 | if (i_size_read(inode) > attr->ia_size) { | 1177 | if (i_size_read(inode) >= attr->ia_size) { |
| 1156 | if (ocfs2_should_order_data(inode)) { | 1178 | if (ocfs2_should_order_data(inode)) { |
| 1157 | status = ocfs2_begin_ordered_truncate(inode, | 1179 | status = ocfs2_begin_ordered_truncate(inode, |
| 1158 | attr->ia_size); | 1180 | attr->ia_size); |
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index f4d609be9400..3683643f3f0e 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c | |||
| @@ -664,6 +664,7 @@ static int ocfs2_link(struct dentry *old_dentry, | |||
| 664 | struct ocfs2_super *osb = OCFS2_SB(dir->i_sb); | 664 | struct ocfs2_super *osb = OCFS2_SB(dir->i_sb); |
| 665 | struct ocfs2_dir_lookup_result lookup = { NULL, }; | 665 | struct ocfs2_dir_lookup_result lookup = { NULL, }; |
| 666 | sigset_t oldset; | 666 | sigset_t oldset; |
| 667 | u64 old_de_ino; | ||
| 667 | 668 | ||
| 668 | trace_ocfs2_link((unsigned long long)OCFS2_I(inode)->ip_blkno, | 669 | trace_ocfs2_link((unsigned long long)OCFS2_I(inode)->ip_blkno, |
| 669 | old_dentry->d_name.len, old_dentry->d_name.name, | 670 | old_dentry->d_name.len, old_dentry->d_name.name, |
| @@ -686,6 +687,22 @@ static int ocfs2_link(struct dentry *old_dentry, | |||
| 686 | goto out; | 687 | goto out; |
| 687 | } | 688 | } |
| 688 | 689 | ||
| 690 | err = ocfs2_lookup_ino_from_name(dir, old_dentry->d_name.name, | ||
| 691 | old_dentry->d_name.len, &old_de_ino); | ||
| 692 | if (err) { | ||
| 693 | err = -ENOENT; | ||
| 694 | goto out; | ||
| 695 | } | ||
| 696 | |||
| 697 | /* | ||
| 698 | * Check whether another node removed the source inode while we | ||
| 699 | * were in the vfs. | ||
| 700 | */ | ||
| 701 | if (old_de_ino != OCFS2_I(inode)->ip_blkno) { | ||
| 702 | err = -ENOENT; | ||
| 703 | goto out; | ||
| 704 | } | ||
| 705 | |||
| 689 | err = ocfs2_check_dir_for_entry(dir, dentry->d_name.name, | 706 | err = ocfs2_check_dir_for_entry(dir, dentry->d_name.name, |
| 690 | dentry->d_name.len); | 707 | dentry->d_name.len); |
| 691 | if (err) | 708 | if (err) |
diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c index 2ca7ba047f04..88d4585b30f1 100644 --- a/fs/proc/vmcore.c +++ b/fs/proc/vmcore.c | |||
| @@ -468,17 +468,24 @@ static int __init update_note_header_size_elf64(const Elf64_Ehdr *ehdr_ptr) | |||
| 468 | return rc; | 468 | return rc; |
| 469 | } | 469 | } |
| 470 | nhdr_ptr = notes_section; | 470 | nhdr_ptr = notes_section; |
| 471 | while (real_sz < max_sz) { | 471 | while (nhdr_ptr->n_namesz != 0) { |
| 472 | if (nhdr_ptr->n_namesz == 0) | ||
| 473 | break; | ||
| 474 | sz = sizeof(Elf64_Nhdr) + | 472 | sz = sizeof(Elf64_Nhdr) + |
| 475 | ((nhdr_ptr->n_namesz + 3) & ~3) + | 473 | ((nhdr_ptr->n_namesz + 3) & ~3) + |
| 476 | ((nhdr_ptr->n_descsz + 3) & ~3); | 474 | ((nhdr_ptr->n_descsz + 3) & ~3); |
| 475 | if ((real_sz + sz) > max_sz) { | ||
| 476 | pr_warn("Warning: Exceeded p_memsz, dropping PT_NOTE entry n_namesz=0x%x, n_descsz=0x%x\n", | ||
| 477 | nhdr_ptr->n_namesz, nhdr_ptr->n_descsz); | ||
| 478 | break; | ||
| 479 | } | ||
| 477 | real_sz += sz; | 480 | real_sz += sz; |
| 478 | nhdr_ptr = (Elf64_Nhdr*)((char*)nhdr_ptr + sz); | 481 | nhdr_ptr = (Elf64_Nhdr*)((char*)nhdr_ptr + sz); |
| 479 | } | 482 | } |
| 480 | kfree(notes_section); | 483 | kfree(notes_section); |
| 481 | phdr_ptr->p_memsz = real_sz; | 484 | phdr_ptr->p_memsz = real_sz; |
| 485 | if (real_sz == 0) { | ||
| 486 | pr_warn("Warning: Zero PT_NOTE entries found\n"); | ||
| 487 | return -EINVAL; | ||
| 488 | } | ||
| 482 | } | 489 | } |
| 483 | 490 | ||
| 484 | return 0; | 491 | return 0; |
| @@ -648,17 +655,24 @@ static int __init update_note_header_size_elf32(const Elf32_Ehdr *ehdr_ptr) | |||
| 648 | return rc; | 655 | return rc; |
| 649 | } | 656 | } |
| 650 | nhdr_ptr = notes_section; | 657 | nhdr_ptr = notes_section; |
| 651 | while (real_sz < max_sz) { | 658 | while (nhdr_ptr->n_namesz != 0) { |
| 652 | if (nhdr_ptr->n_namesz == 0) | ||
| 653 | break; | ||
| 654 | sz = sizeof(Elf32_Nhdr) + | 659 | sz = sizeof(Elf32_Nhdr) + |
| 655 | ((nhdr_ptr->n_namesz + 3) & ~3) + | 660 | ((nhdr_ptr->n_namesz + 3) & ~3) + |
| 656 | ((nhdr_ptr->n_descsz + 3) & ~3); | 661 | ((nhdr_ptr->n_descsz + 3) & ~3); |
| 662 | if ((real_sz + sz) > max_sz) { | ||
| 663 | pr_warn("Warning: Exceeded p_memsz, dropping PT_NOTE entry n_namesz=0x%x, n_descsz=0x%x\n", | ||
| 664 | nhdr_ptr->n_namesz, nhdr_ptr->n_descsz); | ||
| 665 | break; | ||
| 666 | } | ||
| 657 | real_sz += sz; | 667 | real_sz += sz; |
| 658 | nhdr_ptr = (Elf32_Nhdr*)((char*)nhdr_ptr + sz); | 668 | nhdr_ptr = (Elf32_Nhdr*)((char*)nhdr_ptr + sz); |
| 659 | } | 669 | } |
| 660 | kfree(notes_section); | 670 | kfree(notes_section); |
| 661 | phdr_ptr->p_memsz = real_sz; | 671 | phdr_ptr->p_memsz = real_sz; |
| 672 | if (real_sz == 0) { | ||
| 673 | pr_warn("Warning: Zero PT_NOTE entries found\n"); | ||
| 674 | return -EINVAL; | ||
| 675 | } | ||
| 662 | } | 676 | } |
| 663 | 677 | ||
| 664 | return 0; | 678 | return 0; |
diff --git a/include/linux/can/skb.h b/include/linux/can/skb.h index 2f0543f7510c..f9bbbb472663 100644 --- a/include/linux/can/skb.h +++ b/include/linux/can/skb.h | |||
| @@ -11,7 +11,9 @@ | |||
| 11 | #define CAN_SKB_H | 11 | #define CAN_SKB_H |
| 12 | 12 | ||
| 13 | #include <linux/types.h> | 13 | #include <linux/types.h> |
| 14 | #include <linux/skbuff.h> | ||
| 14 | #include <linux/can.h> | 15 | #include <linux/can.h> |
| 16 | #include <net/sock.h> | ||
| 15 | 17 | ||
| 16 | /* | 18 | /* |
| 17 | * The struct can_skb_priv is used to transport additional information along | 19 | * The struct can_skb_priv is used to transport additional information along |
| @@ -42,4 +44,40 @@ static inline void can_skb_reserve(struct sk_buff *skb) | |||
| 42 | skb_reserve(skb, sizeof(struct can_skb_priv)); | 44 | skb_reserve(skb, sizeof(struct can_skb_priv)); |
| 43 | } | 45 | } |
| 44 | 46 | ||
| 47 | static inline void can_skb_destructor(struct sk_buff *skb) | ||
| 48 | { | ||
| 49 | sock_put(skb->sk); | ||
| 50 | } | ||
| 51 | |||
| 52 | static inline void can_skb_set_owner(struct sk_buff *skb, struct sock *sk) | ||
| 53 | { | ||
| 54 | if (sk) { | ||
| 55 | sock_hold(sk); | ||
| 56 | skb->destructor = can_skb_destructor; | ||
| 57 | skb->sk = sk; | ||
| 58 | } | ||
| 59 | } | ||
| 60 | |||
| 61 | /* | ||
| 62 | * returns an unshared skb owned by the original sock to be echo'ed back | ||
| 63 | */ | ||
| 64 | static inline struct sk_buff *can_create_echo_skb(struct sk_buff *skb) | ||
| 65 | { | ||
| 66 | if (skb_shared(skb)) { | ||
| 67 | struct sk_buff *nskb = skb_clone(skb, GFP_ATOMIC); | ||
| 68 | |||
| 69 | if (likely(nskb)) { | ||
| 70 | can_skb_set_owner(nskb, skb->sk); | ||
| 71 | consume_skb(skb); | ||
| 72 | return nskb; | ||
| 73 | } else { | ||
| 74 | kfree_skb(skb); | ||
| 75 | return NULL; | ||
| 76 | } | ||
| 77 | } | ||
| 78 | |||
| 79 | /* we can assume to have an unshared skb with proper owner */ | ||
| 80 | return skb; | ||
| 81 | } | ||
| 82 | |||
| 45 | #endif /* CAN_SKB_H */ | 83 | #endif /* CAN_SKB_H */ |
diff --git a/include/linux/of.h b/include/linux/of.h index 70c64ba17fa5..435cb995904d 100644 --- a/include/linux/of.h +++ b/include/linux/of.h | |||
| @@ -169,35 +169,15 @@ static inline const char *of_node_full_name(const struct device_node *np) | |||
| 169 | 169 | ||
| 170 | extern struct device_node *of_find_node_by_name(struct device_node *from, | 170 | extern struct device_node *of_find_node_by_name(struct device_node *from, |
| 171 | const char *name); | 171 | const char *name); |
| 172 | #define for_each_node_by_name(dn, name) \ | ||
| 173 | for (dn = of_find_node_by_name(NULL, name); dn; \ | ||
| 174 | dn = of_find_node_by_name(dn, name)) | ||
| 175 | extern struct device_node *of_find_node_by_type(struct device_node *from, | 172 | extern struct device_node *of_find_node_by_type(struct device_node *from, |
| 176 | const char *type); | 173 | const char *type); |
| 177 | #define for_each_node_by_type(dn, type) \ | ||
| 178 | for (dn = of_find_node_by_type(NULL, type); dn; \ | ||
| 179 | dn = of_find_node_by_type(dn, type)) | ||
| 180 | extern struct device_node *of_find_compatible_node(struct device_node *from, | 174 | extern struct device_node *of_find_compatible_node(struct device_node *from, |
| 181 | const char *type, const char *compat); | 175 | const char *type, const char *compat); |
| 182 | #define for_each_compatible_node(dn, type, compatible) \ | ||
| 183 | for (dn = of_find_compatible_node(NULL, type, compatible); dn; \ | ||
| 184 | dn = of_find_compatible_node(dn, type, compatible)) | ||
| 185 | extern struct device_node *of_find_matching_node_and_match( | 176 | extern struct device_node *of_find_matching_node_and_match( |
| 186 | struct device_node *from, | 177 | struct device_node *from, |
| 187 | const struct of_device_id *matches, | 178 | const struct of_device_id *matches, |
| 188 | const struct of_device_id **match); | 179 | const struct of_device_id **match); |
| 189 | static inline struct device_node *of_find_matching_node( | 180 | |
| 190 | struct device_node *from, | ||
| 191 | const struct of_device_id *matches) | ||
| 192 | { | ||
| 193 | return of_find_matching_node_and_match(from, matches, NULL); | ||
| 194 | } | ||
| 195 | #define for_each_matching_node(dn, matches) \ | ||
| 196 | for (dn = of_find_matching_node(NULL, matches); dn; \ | ||
| 197 | dn = of_find_matching_node(dn, matches)) | ||
| 198 | #define for_each_matching_node_and_match(dn, matches, match) \ | ||
| 199 | for (dn = of_find_matching_node_and_match(NULL, matches, match); \ | ||
| 200 | dn; dn = of_find_matching_node_and_match(dn, matches, match)) | ||
| 201 | extern struct device_node *of_find_node_by_path(const char *path); | 181 | extern struct device_node *of_find_node_by_path(const char *path); |
| 202 | extern struct device_node *of_find_node_by_phandle(phandle handle); | 182 | extern struct device_node *of_find_node_by_phandle(phandle handle); |
| 203 | extern struct device_node *of_get_parent(const struct device_node *node); | 183 | extern struct device_node *of_get_parent(const struct device_node *node); |
| @@ -209,43 +189,11 @@ extern struct device_node *of_get_next_available_child( | |||
| 209 | 189 | ||
| 210 | extern struct device_node *of_get_child_by_name(const struct device_node *node, | 190 | extern struct device_node *of_get_child_by_name(const struct device_node *node, |
| 211 | const char *name); | 191 | const char *name); |
| 212 | #define for_each_child_of_node(parent, child) \ | ||
| 213 | for (child = of_get_next_child(parent, NULL); child != NULL; \ | ||
| 214 | child = of_get_next_child(parent, child)) | ||
| 215 | |||
| 216 | #define for_each_available_child_of_node(parent, child) \ | ||
| 217 | for (child = of_get_next_available_child(parent, NULL); child != NULL; \ | ||
| 218 | child = of_get_next_available_child(parent, child)) | ||
| 219 | |||
| 220 | static inline int of_get_child_count(const struct device_node *np) | ||
| 221 | { | ||
| 222 | struct device_node *child; | ||
| 223 | int num = 0; | ||
| 224 | |||
| 225 | for_each_child_of_node(np, child) | ||
| 226 | num++; | ||
| 227 | |||
| 228 | return num; | ||
| 229 | } | ||
| 230 | |||
| 231 | static inline int of_get_available_child_count(const struct device_node *np) | ||
| 232 | { | ||
| 233 | struct device_node *child; | ||
| 234 | int num = 0; | ||
| 235 | |||
| 236 | for_each_available_child_of_node(np, child) | ||
| 237 | num++; | ||
| 238 | |||
| 239 | return num; | ||
| 240 | } | ||
| 241 | 192 | ||
| 242 | /* cache lookup */ | 193 | /* cache lookup */ |
| 243 | extern struct device_node *of_find_next_cache_node(const struct device_node *); | 194 | extern struct device_node *of_find_next_cache_node(const struct device_node *); |
| 244 | extern struct device_node *of_find_node_with_property( | 195 | extern struct device_node *of_find_node_with_property( |
| 245 | struct device_node *from, const char *prop_name); | 196 | struct device_node *from, const char *prop_name); |
| 246 | #define for_each_node_with_property(dn, prop_name) \ | ||
| 247 | for (dn = of_find_node_with_property(NULL, prop_name); dn; \ | ||
| 248 | dn = of_find_node_with_property(dn, prop_name)) | ||
| 249 | 197 | ||
| 250 | extern struct property *of_find_property(const struct device_node *np, | 198 | extern struct property *of_find_property(const struct device_node *np, |
| 251 | const char *name, | 199 | const char *name, |
| @@ -367,42 +315,53 @@ static inline struct device_node *of_find_node_by_name(struct device_node *from, | |||
| 367 | return NULL; | 315 | return NULL; |
| 368 | } | 316 | } |
| 369 | 317 | ||
| 370 | static inline struct device_node *of_get_parent(const struct device_node *node) | 318 | static inline struct device_node *of_find_node_by_type(struct device_node *from, |
| 319 | const char *type) | ||
| 371 | { | 320 | { |
| 372 | return NULL; | 321 | return NULL; |
| 373 | } | 322 | } |
| 374 | 323 | ||
| 375 | static inline bool of_have_populated_dt(void) | 324 | static inline struct device_node *of_find_matching_node_and_match( |
| 325 | struct device_node *from, | ||
| 326 | const struct of_device_id *matches, | ||
| 327 | const struct of_device_id **match) | ||
| 376 | { | 328 | { |
| 377 | return false; | 329 | return NULL; |
| 378 | } | 330 | } |
| 379 | 331 | ||
| 380 | /* Kill an unused variable warning on a device_node pointer */ | 332 | static inline struct device_node *of_get_parent(const struct device_node *node) |
| 381 | static inline void __of_use_dn(const struct device_node *np) | ||
| 382 | { | 333 | { |
| 334 | return NULL; | ||
| 383 | } | 335 | } |
| 384 | 336 | ||
| 385 | #define for_each_child_of_node(parent, child) \ | 337 | static inline struct device_node *of_get_next_child( |
| 386 | while (__of_use_dn(parent), __of_use_dn(child), 0) | 338 | const struct device_node *node, struct device_node *prev) |
| 339 | { | ||
| 340 | return NULL; | ||
| 341 | } | ||
| 387 | 342 | ||
| 388 | #define for_each_available_child_of_node(parent, child) \ | 343 | static inline struct device_node *of_get_next_available_child( |
| 389 | while (0) | 344 | const struct device_node *node, struct device_node *prev) |
| 345 | { | ||
| 346 | return NULL; | ||
| 347 | } | ||
| 390 | 348 | ||
| 391 | static inline struct device_node *of_get_child_by_name( | 349 | static inline struct device_node *of_find_node_with_property( |
| 392 | const struct device_node *node, | 350 | struct device_node *from, const char *prop_name) |
| 393 | const char *name) | ||
| 394 | { | 351 | { |
| 395 | return NULL; | 352 | return NULL; |
| 396 | } | 353 | } |
| 397 | 354 | ||
| 398 | static inline int of_get_child_count(const struct device_node *np) | 355 | static inline bool of_have_populated_dt(void) |
| 399 | { | 356 | { |
| 400 | return 0; | 357 | return false; |
| 401 | } | 358 | } |
| 402 | 359 | ||
| 403 | static inline int of_get_available_child_count(const struct device_node *np) | 360 | static inline struct device_node *of_get_child_by_name( |
| 361 | const struct device_node *node, | ||
| 362 | const char *name) | ||
| 404 | { | 363 | { |
| 405 | return 0; | 364 | return NULL; |
| 406 | } | 365 | } |
| 407 | 366 | ||
| 408 | static inline int of_device_is_compatible(const struct device_node *device, | 367 | static inline int of_device_is_compatible(const struct device_node *device, |
| @@ -569,6 +528,13 @@ extern int of_node_to_nid(struct device_node *np); | |||
| 569 | static inline int of_node_to_nid(struct device_node *device) { return 0; } | 528 | static inline int of_node_to_nid(struct device_node *device) { return 0; } |
| 570 | #endif | 529 | #endif |
| 571 | 530 | ||
| 531 | static inline struct device_node *of_find_matching_node( | ||
| 532 | struct device_node *from, | ||
| 533 | const struct of_device_id *matches) | ||
| 534 | { | ||
| 535 | return of_find_matching_node_and_match(from, matches, NULL); | ||
| 536 | } | ||
| 537 | |||
| 572 | /** | 538 | /** |
| 573 | * of_property_read_bool - Findfrom a property | 539 | * of_property_read_bool - Findfrom a property |
| 574 | * @np: device node from which the property value is to be read. | 540 | * @np: device node from which the property value is to be read. |
| @@ -618,6 +584,55 @@ static inline int of_property_read_u32(const struct device_node *np, | |||
| 618 | s; \ | 584 | s; \ |
| 619 | s = of_prop_next_string(prop, s)) | 585 | s = of_prop_next_string(prop, s)) |
| 620 | 586 | ||
| 587 | #define for_each_node_by_name(dn, name) \ | ||
| 588 | for (dn = of_find_node_by_name(NULL, name); dn; \ | ||
| 589 | dn = of_find_node_by_name(dn, name)) | ||
| 590 | #define for_each_node_by_type(dn, type) \ | ||
| 591 | for (dn = of_find_node_by_type(NULL, type); dn; \ | ||
| 592 | dn = of_find_node_by_type(dn, type)) | ||
| 593 | #define for_each_compatible_node(dn, type, compatible) \ | ||
| 594 | for (dn = of_find_compatible_node(NULL, type, compatible); dn; \ | ||
| 595 | dn = of_find_compatible_node(dn, type, compatible)) | ||
| 596 | #define for_each_matching_node(dn, matches) \ | ||
| 597 | for (dn = of_find_matching_node(NULL, matches); dn; \ | ||
| 598 | dn = of_find_matching_node(dn, matches)) | ||
| 599 | #define for_each_matching_node_and_match(dn, matches, match) \ | ||
| 600 | for (dn = of_find_matching_node_and_match(NULL, matches, match); \ | ||
| 601 | dn; dn = of_find_matching_node_and_match(dn, matches, match)) | ||
| 602 | |||
| 603 | #define for_each_child_of_node(parent, child) \ | ||
| 604 | for (child = of_get_next_child(parent, NULL); child != NULL; \ | ||
| 605 | child = of_get_next_child(parent, child)) | ||
| 606 | #define for_each_available_child_of_node(parent, child) \ | ||
| 607 | for (child = of_get_next_available_child(parent, NULL); child != NULL; \ | ||
| 608 | child = of_get_next_available_child(parent, child)) | ||
| 609 | |||
| 610 | #define for_each_node_with_property(dn, prop_name) \ | ||
| 611 | for (dn = of_find_node_with_property(NULL, prop_name); dn; \ | ||
| 612 | dn = of_find_node_with_property(dn, prop_name)) | ||
| 613 | |||
| 614 | static inline int of_get_child_count(const struct device_node *np) | ||
| 615 | { | ||
| 616 | struct device_node *child; | ||
| 617 | int num = 0; | ||
| 618 | |||
| 619 | for_each_child_of_node(np, child) | ||
| 620 | num++; | ||
| 621 | |||
| 622 | return num; | ||
| 623 | } | ||
| 624 | |||
| 625 | static inline int of_get_available_child_count(const struct device_node *np) | ||
| 626 | { | ||
| 627 | struct device_node *child; | ||
| 628 | int num = 0; | ||
| 629 | |||
| 630 | for_each_available_child_of_node(np, child) | ||
| 631 | num++; | ||
| 632 | |||
| 633 | return num; | ||
| 634 | } | ||
| 635 | |||
| 621 | #if defined(CONFIG_PROC_FS) && defined(CONFIG_PROC_DEVICETREE) | 636 | #if defined(CONFIG_PROC_FS) && defined(CONFIG_PROC_DEVICETREE) |
| 622 | extern void proc_device_tree_add_node(struct device_node *, struct proc_dir_entry *); | 637 | extern void proc_device_tree_add_node(struct device_node *, struct proc_dir_entry *); |
| 623 | extern void proc_device_tree_add_prop(struct proc_dir_entry *pde, struct property *prop); | 638 | extern void proc_device_tree_add_prop(struct proc_dir_entry *pde, struct property *prop); |
diff --git a/include/linux/of_device.h b/include/linux/of_device.h index 8d7dd6768cb7..ef370210ffb2 100644 --- a/include/linux/of_device.h +++ b/include/linux/of_device.h | |||
| @@ -78,11 +78,13 @@ static inline int of_device_uevent_modalias(struct device *dev, | |||
| 78 | 78 | ||
| 79 | static inline void of_device_node_put(struct device *dev) { } | 79 | static inline void of_device_node_put(struct device *dev) { } |
| 80 | 80 | ||
| 81 | static inline const struct of_device_id *of_match_device( | 81 | static inline const struct of_device_id *__of_match_device( |
| 82 | const struct of_device_id *matches, const struct device *dev) | 82 | const struct of_device_id *matches, const struct device *dev) |
| 83 | { | 83 | { |
| 84 | return NULL; | 84 | return NULL; |
| 85 | } | 85 | } |
| 86 | #define of_match_device(matches, dev) \ | ||
| 87 | __of_match_device(of_match_ptr(matches), (dev)) | ||
| 86 | 88 | ||
| 87 | static inline struct device_node *of_cpu_device_node_get(int cpu) | 89 | static inline struct device_node *of_cpu_device_node_get(int cpu) |
| 88 | { | 90 | { |
diff --git a/include/linux/smp.h b/include/linux/smp.h index 3834f43f9993..6ae004e437ea 100644 --- a/include/linux/smp.h +++ b/include/linux/smp.h | |||
| @@ -188,6 +188,9 @@ static inline void kick_all_cpus_sync(void) { } | |||
| 188 | */ | 188 | */ |
| 189 | extern void arch_disable_smp_support(void); | 189 | extern void arch_disable_smp_support(void); |
| 190 | 190 | ||
| 191 | extern void arch_enable_nonboot_cpus_begin(void); | ||
| 192 | extern void arch_enable_nonboot_cpus_end(void); | ||
| 193 | |||
| 191 | void smp_setup_processor_id(void); | 194 | void smp_setup_processor_id(void); |
| 192 | 195 | ||
| 193 | #endif /* __LINUX_SMP_H */ | 196 | #endif /* __LINUX_SMP_H */ |
diff --git a/include/net/datalink.h b/include/net/datalink.h index deb7ca75db48..93cb18f729b5 100644 --- a/include/net/datalink.h +++ b/include/net/datalink.h | |||
| @@ -15,4 +15,6 @@ struct datalink_proto { | |||
| 15 | struct list_head node; | 15 | struct list_head node; |
| 16 | }; | 16 | }; |
| 17 | 17 | ||
| 18 | struct datalink_proto *make_EII_client(void); | ||
| 19 | void destroy_EII_client(struct datalink_proto *dl); | ||
| 18 | #endif | 20 | #endif |
diff --git a/include/net/dn.h b/include/net/dn.h index ccc15588d108..913b73d239f5 100644 --- a/include/net/dn.h +++ b/include/net/dn.h | |||
| @@ -200,6 +200,8 @@ static inline void dn_sk_ports_copy(struct flowidn *fld, struct dn_scp *scp) | |||
| 200 | } | 200 | } |
| 201 | 201 | ||
| 202 | unsigned int dn_mss_from_pmtu(struct net_device *dev, int mtu); | 202 | unsigned int dn_mss_from_pmtu(struct net_device *dev, int mtu); |
| 203 | void dn_register_sysctl(void); | ||
| 204 | void dn_unregister_sysctl(void); | ||
| 203 | 205 | ||
| 204 | #define DN_MENUVER_ACC 0x01 | 206 | #define DN_MENUVER_ACC 0x01 |
| 205 | #define DN_MENUVER_USR 0x02 | 207 | #define DN_MENUVER_USR 0x02 |
diff --git a/include/net/dn_route.h b/include/net/dn_route.h index b409ad6b8d7a..55df9939bca2 100644 --- a/include/net/dn_route.h +++ b/include/net/dn_route.h | |||
| @@ -20,6 +20,8 @@ int dn_route_output_sock(struct dst_entry __rcu **pprt, struct flowidn *, | |||
| 20 | struct sock *sk, int flags); | 20 | struct sock *sk, int flags); |
| 21 | int dn_cache_dump(struct sk_buff *skb, struct netlink_callback *cb); | 21 | int dn_cache_dump(struct sk_buff *skb, struct netlink_callback *cb); |
| 22 | void dn_rt_cache_flush(int delay); | 22 | void dn_rt_cache_flush(int delay); |
| 23 | int dn_route_rcv(struct sk_buff *skb, struct net_device *dev, | ||
| 24 | struct packet_type *pt, struct net_device *orig_dev); | ||
| 23 | 25 | ||
| 24 | /* Masks for flags field */ | 26 | /* Masks for flags field */ |
| 25 | #define DN_RT_F_PID 0x07 /* Mask for packet type */ | 27 | #define DN_RT_F_PID 0x07 /* Mask for packet type */ |
diff --git a/include/net/ethoc.h b/include/net/ethoc.h index 96f3789b27bc..2a2d6bb34eb8 100644 --- a/include/net/ethoc.h +++ b/include/net/ethoc.h | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | struct ethoc_platform_data { | 16 | struct ethoc_platform_data { |
| 17 | u8 hwaddr[IFHWADDRLEN]; | 17 | u8 hwaddr[IFHWADDRLEN]; |
| 18 | s8 phy_id; | 18 | s8 phy_id; |
| 19 | u32 eth_clkfreq; | ||
| 19 | }; | 20 | }; |
| 20 | 21 | ||
| 21 | #endif /* !LINUX_NET_ETHOC_H */ | 22 | #endif /* !LINUX_NET_ETHOC_H */ |
diff --git a/include/net/ipx.h b/include/net/ipx.h index 9e9e35465baf..0143180fecc9 100644 --- a/include/net/ipx.h +++ b/include/net/ipx.h | |||
| @@ -140,6 +140,17 @@ static __inline__ void ipxitf_hold(struct ipx_interface *intrfc) | |||
| 140 | } | 140 | } |
| 141 | 141 | ||
| 142 | void ipxitf_down(struct ipx_interface *intrfc); | 142 | void ipxitf_down(struct ipx_interface *intrfc); |
| 143 | struct ipx_interface *ipxitf_find_using_net(__be32 net); | ||
| 144 | int ipxitf_send(struct ipx_interface *intrfc, struct sk_buff *skb, char *node); | ||
| 145 | __be16 ipx_cksum(struct ipxhdr *packet, int length); | ||
| 146 | int ipxrtr_add_route(__be32 network, struct ipx_interface *intrfc, | ||
| 147 | unsigned char *node); | ||
| 148 | void ipxrtr_del_routes(struct ipx_interface *intrfc); | ||
| 149 | int ipxrtr_route_packet(struct sock *sk, struct sockaddr_ipx *usipx, | ||
| 150 | struct iovec *iov, size_t len, int noblock); | ||
| 151 | int ipxrtr_route_skb(struct sk_buff *skb); | ||
| 152 | struct ipx_route *ipxrtr_lookup(__be32 net); | ||
| 153 | int ipxrtr_ioctl(unsigned int cmd, void __user *arg); | ||
| 143 | 154 | ||
| 144 | static __inline__ void ipxitf_put(struct ipx_interface *intrfc) | 155 | static __inline__ void ipxitf_put(struct ipx_interface *intrfc) |
| 145 | { | 156 | { |
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h index da68c9a90ac5..991dcd94cbbf 100644 --- a/include/net/net_namespace.h +++ b/include/net/net_namespace.h | |||
| @@ -162,6 +162,14 @@ extern struct list_head net_namespace_list; | |||
| 162 | struct net *get_net_ns_by_pid(pid_t pid); | 162 | struct net *get_net_ns_by_pid(pid_t pid); |
| 163 | struct net *get_net_ns_by_fd(int pid); | 163 | struct net *get_net_ns_by_fd(int pid); |
| 164 | 164 | ||
| 165 | #ifdef CONFIG_SYSCTL | ||
| 166 | void ipx_register_sysctl(void); | ||
| 167 | void ipx_unregister_sysctl(void); | ||
| 168 | #else | ||
| 169 | #define ipx_register_sysctl() | ||
| 170 | #define ipx_unregister_sysctl() | ||
| 171 | #endif | ||
| 172 | |||
| 165 | #ifdef CONFIG_NET_NS | 173 | #ifdef CONFIG_NET_NS |
| 166 | void __put_net(struct net *net); | 174 | void __put_net(struct net *net); |
| 167 | 175 | ||
diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h index 01ea6eed1bb1..b2ac6246b7e0 100644 --- a/include/net/netfilter/nf_conntrack.h +++ b/include/net/netfilter/nf_conntrack.h | |||
| @@ -284,6 +284,8 @@ extern unsigned int nf_conntrack_max; | |||
| 284 | extern unsigned int nf_conntrack_hash_rnd; | 284 | extern unsigned int nf_conntrack_hash_rnd; |
| 285 | void init_nf_conntrack_hash_rnd(void); | 285 | void init_nf_conntrack_hash_rnd(void); |
| 286 | 286 | ||
| 287 | void nf_conntrack_tmpl_insert(struct net *net, struct nf_conn *tmpl); | ||
| 288 | |||
| 287 | #define NF_CT_STAT_INC(net, count) __this_cpu_inc((net)->ct.stat->count) | 289 | #define NF_CT_STAT_INC(net, count) __this_cpu_inc((net)->ct.stat->count) |
| 288 | #define NF_CT_STAT_INC_ATOMIC(net, count) this_cpu_inc((net)->ct.stat->count) | 290 | #define NF_CT_STAT_INC_ATOMIC(net, count) this_cpu_inc((net)->ct.stat->count) |
| 289 | 291 | ||
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h index 57c8ff7955df..e7e14ffe0f6a 100644 --- a/include/net/netfilter/nf_tables.h +++ b/include/net/netfilter/nf_tables.h | |||
| @@ -252,6 +252,7 @@ void nf_tables_unbind_set(const struct nft_ctx *ctx, struct nft_set *set, | |||
| 252 | * @owner: module reference | 252 | * @owner: module reference |
| 253 | * @policy: netlink attribute policy | 253 | * @policy: netlink attribute policy |
| 254 | * @maxattr: highest netlink attribute number | 254 | * @maxattr: highest netlink attribute number |
| 255 | * @family: address family for AF-specific types | ||
| 255 | */ | 256 | */ |
| 256 | struct nft_expr_type { | 257 | struct nft_expr_type { |
| 257 | const struct nft_expr_ops *(*select_ops)(const struct nft_ctx *, | 258 | const struct nft_expr_ops *(*select_ops)(const struct nft_ctx *, |
| @@ -262,6 +263,7 @@ struct nft_expr_type { | |||
| 262 | struct module *owner; | 263 | struct module *owner; |
| 263 | const struct nla_policy *policy; | 264 | const struct nla_policy *policy; |
| 264 | unsigned int maxattr; | 265 | unsigned int maxattr; |
| 266 | u8 family; | ||
| 265 | }; | 267 | }; |
| 266 | 268 | ||
| 267 | /** | 269 | /** |
| @@ -320,7 +322,6 @@ static inline void *nft_expr_priv(const struct nft_expr *expr) | |||
| 320 | * struct nft_rule - nf_tables rule | 322 | * struct nft_rule - nf_tables rule |
| 321 | * | 323 | * |
| 322 | * @list: used internally | 324 | * @list: used internally |
| 323 | * @rcu_head: used internally for rcu | ||
| 324 | * @handle: rule handle | 325 | * @handle: rule handle |
| 325 | * @genmask: generation mask | 326 | * @genmask: generation mask |
| 326 | * @dlen: length of expression data | 327 | * @dlen: length of expression data |
| @@ -328,7 +329,6 @@ static inline void *nft_expr_priv(const struct nft_expr *expr) | |||
| 328 | */ | 329 | */ |
| 329 | struct nft_rule { | 330 | struct nft_rule { |
| 330 | struct list_head list; | 331 | struct list_head list; |
| 331 | struct rcu_head rcu_head; | ||
| 332 | u64 handle:46, | 332 | u64 handle:46, |
| 333 | genmask:2, | 333 | genmask:2, |
| 334 | dlen:16; | 334 | dlen:16; |
| @@ -389,7 +389,6 @@ enum nft_chain_flags { | |||
| 389 | * | 389 | * |
| 390 | * @rules: list of rules in the chain | 390 | * @rules: list of rules in the chain |
| 391 | * @list: used internally | 391 | * @list: used internally |
| 392 | * @rcu_head: used internally | ||
| 393 | * @net: net namespace that this chain belongs to | 392 | * @net: net namespace that this chain belongs to |
| 394 | * @table: table that this chain belongs to | 393 | * @table: table that this chain belongs to |
| 395 | * @handle: chain handle | 394 | * @handle: chain handle |
| @@ -401,7 +400,6 @@ enum nft_chain_flags { | |||
| 401 | struct nft_chain { | 400 | struct nft_chain { |
| 402 | struct list_head rules; | 401 | struct list_head rules; |
| 403 | struct list_head list; | 402 | struct list_head list; |
| 404 | struct rcu_head rcu_head; | ||
| 405 | struct net *net; | 403 | struct net *net; |
| 406 | struct nft_table *table; | 404 | struct nft_table *table; |
| 407 | u64 handle; | 405 | u64 handle; |
| @@ -529,6 +527,9 @@ void nft_unregister_expr(struct nft_expr_type *); | |||
| 529 | #define MODULE_ALIAS_NFT_CHAIN(family, name) \ | 527 | #define MODULE_ALIAS_NFT_CHAIN(family, name) \ |
| 530 | MODULE_ALIAS("nft-chain-" __stringify(family) "-" name) | 528 | MODULE_ALIAS("nft-chain-" __stringify(family) "-" name) |
| 531 | 529 | ||
| 530 | #define MODULE_ALIAS_NFT_AF_EXPR(family, name) \ | ||
| 531 | MODULE_ALIAS("nft-expr-" __stringify(family) "-" name) | ||
| 532 | |||
| 532 | #define MODULE_ALIAS_NFT_EXPR(name) \ | 533 | #define MODULE_ALIAS_NFT_EXPR(name) \ |
| 533 | MODULE_ALIAS("nft-expr-" name) | 534 | MODULE_ALIAS("nft-expr-" name) |
| 534 | 535 | ||
diff --git a/include/net/netfilter/nft_reject.h b/include/net/netfilter/nft_reject.h new file mode 100644 index 000000000000..36b0da2d55bb --- /dev/null +++ b/include/net/netfilter/nft_reject.h | |||
| @@ -0,0 +1,25 @@ | |||
| 1 | #ifndef _NFT_REJECT_H_ | ||
| 2 | #define _NFT_REJECT_H_ | ||
| 3 | |||
| 4 | struct nft_reject { | ||
| 5 | enum nft_reject_types type:8; | ||
| 6 | u8 icmp_code; | ||
| 7 | }; | ||
| 8 | |||
| 9 | extern const struct nla_policy nft_reject_policy[]; | ||
| 10 | |||
| 11 | int nft_reject_init(const struct nft_ctx *ctx, | ||
| 12 | const struct nft_expr *expr, | ||
| 13 | const struct nlattr * const tb[]); | ||
| 14 | |||
| 15 | int nft_reject_dump(struct sk_buff *skb, const struct nft_expr *expr); | ||
| 16 | |||
| 17 | void nft_reject_ipv4_eval(const struct nft_expr *expr, | ||
| 18 | struct nft_data data[NFT_REG_MAX + 1], | ||
| 19 | const struct nft_pktinfo *pkt); | ||
| 20 | |||
| 21 | void nft_reject_ipv6_eval(const struct nft_expr *expr, | ||
| 22 | struct nft_data data[NFT_REG_MAX + 1], | ||
| 23 | const struct nft_pktinfo *pkt); | ||
| 24 | |||
| 25 | #endif | ||
diff --git a/include/uapi/linux/in6.h b/include/uapi/linux/in6.h index 633b93cac1ed..e9a1d2d973b6 100644 --- a/include/uapi/linux/in6.h +++ b/include/uapi/linux/in6.h | |||
| @@ -128,22 +128,13 @@ struct in6_flowlabel_req { | |||
| 128 | * IPV6 extension headers | 128 | * IPV6 extension headers |
| 129 | */ | 129 | */ |
| 130 | #if __UAPI_DEF_IPPROTO_V6 | 130 | #if __UAPI_DEF_IPPROTO_V6 |
| 131 | enum { | 131 | #define IPPROTO_HOPOPTS 0 /* IPv6 hop-by-hop options */ |
| 132 | IPPROTO_HOPOPTS = 0, /* IPv6 hop-by-hop options */ | 132 | #define IPPROTO_ROUTING 43 /* IPv6 routing header */ |
| 133 | #define IPPROTO_HOPOPTS IPPROTO_HOPOPTS | 133 | #define IPPROTO_FRAGMENT 44 /* IPv6 fragmentation header */ |
| 134 | IPPROTO_ROUTING = 43, /* IPv6 routing header */ | 134 | #define IPPROTO_ICMPV6 58 /* ICMPv6 */ |
| 135 | #define IPPROTO_ROUTING IPPROTO_ROUTING | 135 | #define IPPROTO_NONE 59 /* IPv6 no next header */ |
| 136 | IPPROTO_FRAGMENT = 44, /* IPv6 fragmentation header */ | 136 | #define IPPROTO_DSTOPTS 60 /* IPv6 destination options */ |
| 137 | #define IPPROTO_FRAGMENT IPPROTO_FRAGMENT | 137 | #define IPPROTO_MH 135 /* IPv6 mobility header */ |
| 138 | IPPROTO_ICMPV6 = 58, /* ICMPv6 */ | ||
| 139 | #define IPPROTO_ICMPV6 IPPROTO_ICMPV6 | ||
| 140 | IPPROTO_NONE = 59, /* IPv6 no next header */ | ||
| 141 | #define IPPROTO_NONE IPPROTO_NONE | ||
| 142 | IPPROTO_DSTOPTS = 60, /* IPv6 destination options */ | ||
| 143 | #define IPPROTO_DSTOPTS IPPROTO_DSTOPTS | ||
| 144 | IPPROTO_MH = 135, /* IPv6 mobility header */ | ||
| 145 | #define IPPROTO_MH IPPROTO_MH | ||
| 146 | }; | ||
| 147 | #endif /* __UAPI_DEF_IPPROTO_V6 */ | 138 | #endif /* __UAPI_DEF_IPPROTO_V6 */ |
| 148 | 139 | ||
| 149 | /* | 140 | /* |
diff --git a/mm/memory-failure.c b/mm/memory-failure.c index 4f08a2d61487..2f2f34a4e77d 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c | |||
| @@ -945,8 +945,10 @@ static int hwpoison_user_mappings(struct page *p, unsigned long pfn, | |||
| 945 | * to it. Similarly, page lock is shifted. | 945 | * to it. Similarly, page lock is shifted. |
| 946 | */ | 946 | */ |
| 947 | if (hpage != p) { | 947 | if (hpage != p) { |
| 948 | put_page(hpage); | 948 | if (!(flags & MF_COUNT_INCREASED)) { |
| 949 | get_page(p); | 949 | put_page(hpage); |
| 950 | get_page(p); | ||
| 951 | } | ||
| 950 | lock_page(p); | 952 | lock_page(p); |
| 951 | unlock_page(hpage); | 953 | unlock_page(hpage); |
| 952 | *hpagep = p; | 954 | *hpagep = p; |
| @@ -1004,21 +1004,19 @@ static inline void slab_free_hook(struct kmem_cache *s, void *x) | |||
| 1004 | static void add_full(struct kmem_cache *s, | 1004 | static void add_full(struct kmem_cache *s, |
| 1005 | struct kmem_cache_node *n, struct page *page) | 1005 | struct kmem_cache_node *n, struct page *page) |
| 1006 | { | 1006 | { |
| 1007 | lockdep_assert_held(&n->list_lock); | ||
| 1008 | |||
| 1009 | if (!(s->flags & SLAB_STORE_USER)) | 1007 | if (!(s->flags & SLAB_STORE_USER)) |
| 1010 | return; | 1008 | return; |
| 1011 | 1009 | ||
| 1010 | lockdep_assert_held(&n->list_lock); | ||
| 1012 | list_add(&page->lru, &n->full); | 1011 | list_add(&page->lru, &n->full); |
| 1013 | } | 1012 | } |
| 1014 | 1013 | ||
| 1015 | static void remove_full(struct kmem_cache *s, struct kmem_cache_node *n, struct page *page) | 1014 | static void remove_full(struct kmem_cache *s, struct kmem_cache_node *n, struct page *page) |
| 1016 | { | 1015 | { |
| 1017 | lockdep_assert_held(&n->list_lock); | ||
| 1018 | |||
| 1019 | if (!(s->flags & SLAB_STORE_USER)) | 1016 | if (!(s->flags & SLAB_STORE_USER)) |
| 1020 | return; | 1017 | return; |
| 1021 | 1018 | ||
| 1019 | lockdep_assert_held(&n->list_lock); | ||
| 1022 | list_del(&page->lru); | 1020 | list_del(&page->lru); |
| 1023 | } | 1021 | } |
| 1024 | 1022 | ||
| @@ -1520,11 +1518,9 @@ static void discard_slab(struct kmem_cache *s, struct page *page) | |||
| 1520 | /* | 1518 | /* |
| 1521 | * Management of partially allocated slabs. | 1519 | * Management of partially allocated slabs. |
| 1522 | */ | 1520 | */ |
| 1523 | static inline void add_partial(struct kmem_cache_node *n, | 1521 | static inline void |
| 1524 | struct page *page, int tail) | 1522 | __add_partial(struct kmem_cache_node *n, struct page *page, int tail) |
| 1525 | { | 1523 | { |
| 1526 | lockdep_assert_held(&n->list_lock); | ||
| 1527 | |||
| 1528 | n->nr_partial++; | 1524 | n->nr_partial++; |
| 1529 | if (tail == DEACTIVATE_TO_TAIL) | 1525 | if (tail == DEACTIVATE_TO_TAIL) |
| 1530 | list_add_tail(&page->lru, &n->partial); | 1526 | list_add_tail(&page->lru, &n->partial); |
| @@ -1532,15 +1528,27 @@ static inline void add_partial(struct kmem_cache_node *n, | |||
| 1532 | list_add(&page->lru, &n->partial); | 1528 | list_add(&page->lru, &n->partial); |
| 1533 | } | 1529 | } |
| 1534 | 1530 | ||
| 1535 | static inline void remove_partial(struct kmem_cache_node *n, | 1531 | static inline void add_partial(struct kmem_cache_node *n, |
| 1536 | struct page *page) | 1532 | struct page *page, int tail) |
| 1537 | { | 1533 | { |
| 1538 | lockdep_assert_held(&n->list_lock); | 1534 | lockdep_assert_held(&n->list_lock); |
| 1535 | __add_partial(n, page, tail); | ||
| 1536 | } | ||
| 1539 | 1537 | ||
| 1538 | static inline void | ||
| 1539 | __remove_partial(struct kmem_cache_node *n, struct page *page) | ||
| 1540 | { | ||
| 1540 | list_del(&page->lru); | 1541 | list_del(&page->lru); |
| 1541 | n->nr_partial--; | 1542 | n->nr_partial--; |
| 1542 | } | 1543 | } |
| 1543 | 1544 | ||
| 1545 | static inline void remove_partial(struct kmem_cache_node *n, | ||
| 1546 | struct page *page) | ||
| 1547 | { | ||
| 1548 | lockdep_assert_held(&n->list_lock); | ||
| 1549 | __remove_partial(n, page); | ||
| 1550 | } | ||
| 1551 | |||
| 1544 | /* | 1552 | /* |
| 1545 | * Remove slab from the partial list, freeze it and | 1553 | * Remove slab from the partial list, freeze it and |
| 1546 | * return the pointer to the freelist. | 1554 | * return the pointer to the freelist. |
| @@ -2906,12 +2914,10 @@ static void early_kmem_cache_node_alloc(int node) | |||
| 2906 | inc_slabs_node(kmem_cache_node, node, page->objects); | 2914 | inc_slabs_node(kmem_cache_node, node, page->objects); |
| 2907 | 2915 | ||
| 2908 | /* | 2916 | /* |
| 2909 | * the lock is for lockdep's sake, not for any actual | 2917 | * No locks need to be taken here as it has just been |
| 2910 | * race protection | 2918 | * initialized and there is no concurrent access. |
| 2911 | */ | 2919 | */ |
| 2912 | spin_lock(&n->list_lock); | 2920 | __add_partial(n, page, DEACTIVATE_TO_HEAD); |
| 2913 | add_partial(n, page, DEACTIVATE_TO_HEAD); | ||
| 2914 | spin_unlock(&n->list_lock); | ||
| 2915 | } | 2921 | } |
| 2916 | 2922 | ||
| 2917 | static void free_kmem_cache_nodes(struct kmem_cache *s) | 2923 | static void free_kmem_cache_nodes(struct kmem_cache *s) |
| @@ -3197,7 +3203,7 @@ static void free_partial(struct kmem_cache *s, struct kmem_cache_node *n) | |||
| 3197 | 3203 | ||
| 3198 | list_for_each_entry_safe(page, h, &n->partial, lru) { | 3204 | list_for_each_entry_safe(page, h, &n->partial, lru) { |
| 3199 | if (!page->inuse) { | 3205 | if (!page->inuse) { |
| 3200 | remove_partial(n, page); | 3206 | __remove_partial(n, page); |
| 3201 | discard_slab(s, page); | 3207 | discard_slab(s, page); |
| 3202 | } else { | 3208 | } else { |
| 3203 | list_slab_objects(s, page, | 3209 | list_slab_objects(s, page, |
diff --git a/net/9p/client.c b/net/9p/client.c index a5e4d2dcb03e..9186550d77a6 100644 --- a/net/9p/client.c +++ b/net/9p/client.c | |||
| @@ -204,7 +204,7 @@ free_and_return: | |||
| 204 | return ret; | 204 | return ret; |
| 205 | } | 205 | } |
| 206 | 206 | ||
| 207 | struct p9_fcall *p9_fcall_alloc(int alloc_msize) | 207 | static struct p9_fcall *p9_fcall_alloc(int alloc_msize) |
| 208 | { | 208 | { |
| 209 | struct p9_fcall *fc; | 209 | struct p9_fcall *fc; |
| 210 | fc = kmalloc(sizeof(struct p9_fcall) + alloc_msize, GFP_NOFS); | 210 | fc = kmalloc(sizeof(struct p9_fcall) + alloc_msize, GFP_NOFS); |
diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c index cd1e1ede73a4..ac2666c1d011 100644 --- a/net/9p/trans_virtio.c +++ b/net/9p/trans_virtio.c | |||
| @@ -340,7 +340,10 @@ static int p9_get_mapped_pages(struct virtio_chan *chan, | |||
| 340 | int count = nr_pages; | 340 | int count = nr_pages; |
| 341 | while (nr_pages) { | 341 | while (nr_pages) { |
| 342 | s = rest_of_page(data); | 342 | s = rest_of_page(data); |
| 343 | pages[index++] = kmap_to_page(data); | 343 | if (is_vmalloc_addr(data)) |
| 344 | pages[index++] = vmalloc_to_page(data); | ||
| 345 | else | ||
| 346 | pages[index++] = kmap_to_page(data); | ||
| 344 | data += s; | 347 | data += s; |
| 345 | nr_pages--; | 348 | nr_pages--; |
| 346 | } | 349 | } |
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c index e4401a531afb..63f0455c0bc3 100644 --- a/net/bridge/br_device.c +++ b/net/bridge/br_device.c | |||
| @@ -187,8 +187,7 @@ static int br_set_mac_address(struct net_device *dev, void *p) | |||
| 187 | 187 | ||
| 188 | spin_lock_bh(&br->lock); | 188 | spin_lock_bh(&br->lock); |
| 189 | if (!ether_addr_equal(dev->dev_addr, addr->sa_data)) { | 189 | if (!ether_addr_equal(dev->dev_addr, addr->sa_data)) { |
| 190 | memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); | 190 | /* Mac address will be changed in br_stp_change_bridge_id(). */ |
| 191 | br_fdb_change_mac_address(br, addr->sa_data); | ||
| 192 | br_stp_change_bridge_id(br, addr->sa_data); | 191 | br_stp_change_bridge_id(br, addr->sa_data); |
| 193 | } | 192 | } |
| 194 | spin_unlock_bh(&br->lock); | 193 | spin_unlock_bh(&br->lock); |
| @@ -226,6 +225,33 @@ static void br_netpoll_cleanup(struct net_device *dev) | |||
| 226 | br_netpoll_disable(p); | 225 | br_netpoll_disable(p); |
| 227 | } | 226 | } |
| 228 | 227 | ||
| 228 | static int __br_netpoll_enable(struct net_bridge_port *p, gfp_t gfp) | ||
| 229 | { | ||
| 230 | struct netpoll *np; | ||
| 231 | int err; | ||
| 232 | |||
| 233 | np = kzalloc(sizeof(*p->np), gfp); | ||
| 234 | if (!np) | ||
| 235 | return -ENOMEM; | ||
| 236 | |||
| 237 | err = __netpoll_setup(np, p->dev, gfp); | ||
| 238 | if (err) { | ||
| 239 | kfree(np); | ||
| 240 | return err; | ||
| 241 | } | ||
| 242 | |||
| 243 | p->np = np; | ||
| 244 | return err; | ||
| 245 | } | ||
| 246 | |||
| 247 | int br_netpoll_enable(struct net_bridge_port *p, gfp_t gfp) | ||
| 248 | { | ||
| 249 | if (!p->br->dev->npinfo) | ||
| 250 | return 0; | ||
| 251 | |||
| 252 | return __br_netpoll_enable(p, gfp); | ||
| 253 | } | ||
| 254 | |||
| 229 | static int br_netpoll_setup(struct net_device *dev, struct netpoll_info *ni, | 255 | static int br_netpoll_setup(struct net_device *dev, struct netpoll_info *ni, |
| 230 | gfp_t gfp) | 256 | gfp_t gfp) |
| 231 | { | 257 | { |
| @@ -236,7 +262,7 @@ static int br_netpoll_setup(struct net_device *dev, struct netpoll_info *ni, | |||
| 236 | list_for_each_entry(p, &br->port_list, list) { | 262 | list_for_each_entry(p, &br->port_list, list) { |
| 237 | if (!p->dev) | 263 | if (!p->dev) |
| 238 | continue; | 264 | continue; |
| 239 | err = br_netpoll_enable(p, gfp); | 265 | err = __br_netpoll_enable(p, gfp); |
| 240 | if (err) | 266 | if (err) |
| 241 | goto fail; | 267 | goto fail; |
| 242 | } | 268 | } |
| @@ -249,28 +275,6 @@ fail: | |||
| 249 | goto out; | 275 | goto out; |
| 250 | } | 276 | } |
| 251 | 277 | ||
| 252 | int br_netpoll_enable(struct net_bridge_port *p, gfp_t gfp) | ||
| 253 | { | ||
| 254 | struct netpoll *np; | ||
| 255 | int err; | ||
| 256 | |||
| 257 | if (!p->br->dev->npinfo) | ||
| 258 | return 0; | ||
| 259 | |||
| 260 | np = kzalloc(sizeof(*p->np), gfp); | ||
| 261 | if (!np) | ||
| 262 | return -ENOMEM; | ||
| 263 | |||
| 264 | err = __netpoll_setup(np, p->dev, gfp); | ||
| 265 | if (err) { | ||
| 266 | kfree(np); | ||
| 267 | return err; | ||
| 268 | } | ||
| 269 | |||
| 270 | p->np = np; | ||
| 271 | return err; | ||
| 272 | } | ||
| 273 | |||
| 274 | void br_netpoll_disable(struct net_bridge_port *p) | 278 | void br_netpoll_disable(struct net_bridge_port *p) |
| 275 | { | 279 | { |
| 276 | struct netpoll *np = p->np; | 280 | struct netpoll *np = p->np; |
diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c index c5f5a4a933f4..9203d5a1943f 100644 --- a/net/bridge/br_fdb.c +++ b/net/bridge/br_fdb.c | |||
| @@ -27,6 +27,9 @@ | |||
| 27 | #include "br_private.h" | 27 | #include "br_private.h" |
| 28 | 28 | ||
| 29 | static struct kmem_cache *br_fdb_cache __read_mostly; | 29 | static struct kmem_cache *br_fdb_cache __read_mostly; |
| 30 | static struct net_bridge_fdb_entry *fdb_find(struct hlist_head *head, | ||
| 31 | const unsigned char *addr, | ||
| 32 | __u16 vid); | ||
| 30 | static int fdb_insert(struct net_bridge *br, struct net_bridge_port *source, | 33 | static int fdb_insert(struct net_bridge *br, struct net_bridge_port *source, |
| 31 | const unsigned char *addr, u16 vid); | 34 | const unsigned char *addr, u16 vid); |
| 32 | static void fdb_notify(struct net_bridge *br, | 35 | static void fdb_notify(struct net_bridge *br, |
| @@ -89,11 +92,57 @@ static void fdb_delete(struct net_bridge *br, struct net_bridge_fdb_entry *f) | |||
| 89 | call_rcu(&f->rcu, fdb_rcu_free); | 92 | call_rcu(&f->rcu, fdb_rcu_free); |
| 90 | } | 93 | } |
| 91 | 94 | ||
| 95 | /* Delete a local entry if no other port had the same address. */ | ||
| 96 | static void fdb_delete_local(struct net_bridge *br, | ||
| 97 | const struct net_bridge_port *p, | ||
| 98 | struct net_bridge_fdb_entry *f) | ||
| 99 | { | ||
| 100 | const unsigned char *addr = f->addr.addr; | ||
| 101 | u16 vid = f->vlan_id; | ||
| 102 | struct net_bridge_port *op; | ||
| 103 | |||
| 104 | /* Maybe another port has same hw addr? */ | ||
| 105 | list_for_each_entry(op, &br->port_list, list) { | ||
| 106 | if (op != p && ether_addr_equal(op->dev->dev_addr, addr) && | ||
| 107 | (!vid || nbp_vlan_find(op, vid))) { | ||
| 108 | f->dst = op; | ||
| 109 | f->added_by_user = 0; | ||
| 110 | return; | ||
| 111 | } | ||
| 112 | } | ||
| 113 | |||
| 114 | /* Maybe bridge device has same hw addr? */ | ||
| 115 | if (p && ether_addr_equal(br->dev->dev_addr, addr) && | ||
| 116 | (!vid || br_vlan_find(br, vid))) { | ||
| 117 | f->dst = NULL; | ||
| 118 | f->added_by_user = 0; | ||
| 119 | return; | ||
| 120 | } | ||
| 121 | |||
| 122 | fdb_delete(br, f); | ||
| 123 | } | ||
| 124 | |||
| 125 | void br_fdb_find_delete_local(struct net_bridge *br, | ||
| 126 | const struct net_bridge_port *p, | ||
| 127 | const unsigned char *addr, u16 vid) | ||
| 128 | { | ||
| 129 | struct hlist_head *head = &br->hash[br_mac_hash(addr, vid)]; | ||
| 130 | struct net_bridge_fdb_entry *f; | ||
| 131 | |||
| 132 | spin_lock_bh(&br->hash_lock); | ||
| 133 | f = fdb_find(head, addr, vid); | ||
| 134 | if (f && f->is_local && !f->added_by_user && f->dst == p) | ||
| 135 | fdb_delete_local(br, p, f); | ||
| 136 | spin_unlock_bh(&br->hash_lock); | ||
| 137 | } | ||
| 138 | |||
| 92 | void br_fdb_changeaddr(struct net_bridge_port *p, const unsigned char *newaddr) | 139 | void br_fdb_changeaddr(struct net_bridge_port *p, const unsigned char *newaddr) |
| 93 | { | 140 | { |
| 94 | struct net_bridge *br = p->br; | 141 | struct net_bridge *br = p->br; |
| 95 | bool no_vlan = (nbp_get_vlan_info(p) == NULL) ? true : false; | 142 | struct net_port_vlans *pv = nbp_get_vlan_info(p); |
| 143 | bool no_vlan = !pv; | ||
| 96 | int i; | 144 | int i; |
| 145 | u16 vid; | ||
| 97 | 146 | ||
| 98 | spin_lock_bh(&br->hash_lock); | 147 | spin_lock_bh(&br->hash_lock); |
| 99 | 148 | ||
| @@ -104,38 +153,34 @@ void br_fdb_changeaddr(struct net_bridge_port *p, const unsigned char *newaddr) | |||
| 104 | struct net_bridge_fdb_entry *f; | 153 | struct net_bridge_fdb_entry *f; |
| 105 | 154 | ||
| 106 | f = hlist_entry(h, struct net_bridge_fdb_entry, hlist); | 155 | f = hlist_entry(h, struct net_bridge_fdb_entry, hlist); |
| 107 | if (f->dst == p && f->is_local) { | 156 | if (f->dst == p && f->is_local && !f->added_by_user) { |
| 108 | /* maybe another port has same hw addr? */ | ||
| 109 | struct net_bridge_port *op; | ||
| 110 | u16 vid = f->vlan_id; | ||
| 111 | list_for_each_entry(op, &br->port_list, list) { | ||
| 112 | if (op != p && | ||
| 113 | ether_addr_equal(op->dev->dev_addr, | ||
| 114 | f->addr.addr) && | ||
| 115 | nbp_vlan_find(op, vid)) { | ||
| 116 | f->dst = op; | ||
| 117 | goto insert; | ||
| 118 | } | ||
| 119 | } | ||
| 120 | |||
| 121 | /* delete old one */ | 157 | /* delete old one */ |
| 122 | fdb_delete(br, f); | 158 | fdb_delete_local(br, p, f); |
| 123 | insert: | ||
| 124 | /* insert new address, may fail if invalid | ||
| 125 | * address or dup. | ||
| 126 | */ | ||
| 127 | fdb_insert(br, p, newaddr, vid); | ||
| 128 | 159 | ||
| 129 | /* if this port has no vlan information | 160 | /* if this port has no vlan information |
| 130 | * configured, we can safely be done at | 161 | * configured, we can safely be done at |
| 131 | * this point. | 162 | * this point. |
| 132 | */ | 163 | */ |
| 133 | if (no_vlan) | 164 | if (no_vlan) |
| 134 | goto done; | 165 | goto insert; |
| 135 | } | 166 | } |
| 136 | } | 167 | } |
| 137 | } | 168 | } |
| 138 | 169 | ||
| 170 | insert: | ||
| 171 | /* insert new address, may fail if invalid address or dup. */ | ||
| 172 | fdb_insert(br, p, newaddr, 0); | ||
| 173 | |||
| 174 | if (no_vlan) | ||
| 175 | goto done; | ||
| 176 | |||
| 177 | /* Now add entries for every VLAN configured on the port. | ||
| 178 | * This function runs under RTNL so the bitmap will not change | ||
| 179 | * from under us. | ||
| 180 | */ | ||
| 181 | for_each_set_bit(vid, pv->vlan_bitmap, VLAN_N_VID) | ||
| 182 | fdb_insert(br, p, newaddr, vid); | ||
| 183 | |||
| 139 | done: | 184 | done: |
| 140 | spin_unlock_bh(&br->hash_lock); | 185 | spin_unlock_bh(&br->hash_lock); |
| 141 | } | 186 | } |
| @@ -146,10 +191,12 @@ void br_fdb_change_mac_address(struct net_bridge *br, const u8 *newaddr) | |||
| 146 | struct net_port_vlans *pv; | 191 | struct net_port_vlans *pv; |
| 147 | u16 vid = 0; | 192 | u16 vid = 0; |
| 148 | 193 | ||
| 194 | spin_lock_bh(&br->hash_lock); | ||
| 195 | |||
| 149 | /* If old entry was unassociated with any port, then delete it. */ | 196 | /* If old entry was unassociated with any port, then delete it. */ |
| 150 | f = __br_fdb_get(br, br->dev->dev_addr, 0); | 197 | f = __br_fdb_get(br, br->dev->dev_addr, 0); |
| 151 | if (f && f->is_local && !f->dst) | 198 | if (f && f->is_local && !f->dst) |
| 152 | fdb_delete(br, f); | 199 | fdb_delete_local(br, NULL, f); |
| 153 | 200 | ||
| 154 | fdb_insert(br, NULL, newaddr, 0); | 201 | fdb_insert(br, NULL, newaddr, 0); |
| 155 | 202 | ||
| @@ -159,14 +206,16 @@ void br_fdb_change_mac_address(struct net_bridge *br, const u8 *newaddr) | |||
| 159 | */ | 206 | */ |
| 160 | pv = br_get_vlan_info(br); | 207 | pv = br_get_vlan_info(br); |
| 161 | if (!pv) | 208 | if (!pv) |
| 162 | return; | 209 | goto out; |
| 163 | 210 | ||
| 164 | for_each_set_bit_from(vid, pv->vlan_bitmap, VLAN_N_VID) { | 211 | for_each_set_bit_from(vid, pv->vlan_bitmap, VLAN_N_VID) { |
| 165 | f = __br_fdb_get(br, br->dev->dev_addr, vid); | 212 | f = __br_fdb_get(br, br->dev->dev_addr, vid); |
| 166 | if (f && f->is_local && !f->dst) | 213 | if (f && f->is_local && !f->dst) |
| 167 | fdb_delete(br, f); | 214 | fdb_delete_local(br, NULL, f); |
| 168 | fdb_insert(br, NULL, newaddr, vid); | 215 | fdb_insert(br, NULL, newaddr, vid); |
| 169 | } | 216 | } |
| 217 | out: | ||
| 218 | spin_unlock_bh(&br->hash_lock); | ||
| 170 | } | 219 | } |
| 171 | 220 | ||
| 172 | void br_fdb_cleanup(unsigned long _data) | 221 | void br_fdb_cleanup(unsigned long _data) |
| @@ -235,25 +284,11 @@ void br_fdb_delete_by_port(struct net_bridge *br, | |||
| 235 | 284 | ||
| 236 | if (f->is_static && !do_all) | 285 | if (f->is_static && !do_all) |
| 237 | continue; | 286 | continue; |
| 238 | /* | ||
| 239 | * if multiple ports all have the same device address | ||
| 240 | * then when one port is deleted, assign | ||
| 241 | * the local entry to other port | ||
| 242 | */ | ||
| 243 | if (f->is_local) { | ||
| 244 | struct net_bridge_port *op; | ||
| 245 | list_for_each_entry(op, &br->port_list, list) { | ||
| 246 | if (op != p && | ||
| 247 | ether_addr_equal(op->dev->dev_addr, | ||
| 248 | f->addr.addr)) { | ||
| 249 | f->dst = op; | ||
| 250 | goto skip_delete; | ||
| 251 | } | ||
| 252 | } | ||
| 253 | } | ||
| 254 | 287 | ||
| 255 | fdb_delete(br, f); | 288 | if (f->is_local) |
| 256 | skip_delete: ; | 289 | fdb_delete_local(br, p, f); |
| 290 | else | ||
| 291 | fdb_delete(br, f); | ||
| 257 | } | 292 | } |
| 258 | } | 293 | } |
| 259 | spin_unlock_bh(&br->hash_lock); | 294 | spin_unlock_bh(&br->hash_lock); |
| @@ -397,6 +432,7 @@ static struct net_bridge_fdb_entry *fdb_create(struct hlist_head *head, | |||
| 397 | fdb->vlan_id = vid; | 432 | fdb->vlan_id = vid; |
| 398 | fdb->is_local = 0; | 433 | fdb->is_local = 0; |
| 399 | fdb->is_static = 0; | 434 | fdb->is_static = 0; |
| 435 | fdb->added_by_user = 0; | ||
| 400 | fdb->updated = fdb->used = jiffies; | 436 | fdb->updated = fdb->used = jiffies; |
| 401 | hlist_add_head_rcu(&fdb->hlist, head); | 437 | hlist_add_head_rcu(&fdb->hlist, head); |
| 402 | } | 438 | } |
| @@ -447,7 +483,7 @@ int br_fdb_insert(struct net_bridge *br, struct net_bridge_port *source, | |||
| 447 | } | 483 | } |
| 448 | 484 | ||
| 449 | void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source, | 485 | void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source, |
| 450 | const unsigned char *addr, u16 vid) | 486 | const unsigned char *addr, u16 vid, bool added_by_user) |
| 451 | { | 487 | { |
| 452 | struct hlist_head *head = &br->hash[br_mac_hash(addr, vid)]; | 488 | struct hlist_head *head = &br->hash[br_mac_hash(addr, vid)]; |
| 453 | struct net_bridge_fdb_entry *fdb; | 489 | struct net_bridge_fdb_entry *fdb; |
| @@ -473,13 +509,18 @@ void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source, | |||
| 473 | /* fastpath: update of existing entry */ | 509 | /* fastpath: update of existing entry */ |
| 474 | fdb->dst = source; | 510 | fdb->dst = source; |
| 475 | fdb->updated = jiffies; | 511 | fdb->updated = jiffies; |
| 512 | if (unlikely(added_by_user)) | ||
| 513 | fdb->added_by_user = 1; | ||
| 476 | } | 514 | } |
| 477 | } else { | 515 | } else { |
| 478 | spin_lock(&br->hash_lock); | 516 | spin_lock(&br->hash_lock); |
| 479 | if (likely(!fdb_find(head, addr, vid))) { | 517 | if (likely(!fdb_find(head, addr, vid))) { |
| 480 | fdb = fdb_create(head, source, addr, vid); | 518 | fdb = fdb_create(head, source, addr, vid); |
| 481 | if (fdb) | 519 | if (fdb) { |
| 520 | if (unlikely(added_by_user)) | ||
| 521 | fdb->added_by_user = 1; | ||
| 482 | fdb_notify(br, fdb, RTM_NEWNEIGH); | 522 | fdb_notify(br, fdb, RTM_NEWNEIGH); |
| 523 | } | ||
| 483 | } | 524 | } |
| 484 | /* else we lose race and someone else inserts | 525 | /* else we lose race and someone else inserts |
| 485 | * it first, don't bother updating | 526 | * it first, don't bother updating |
| @@ -647,6 +688,7 @@ static int fdb_add_entry(struct net_bridge_port *source, const __u8 *addr, | |||
| 647 | 688 | ||
| 648 | modified = true; | 689 | modified = true; |
| 649 | } | 690 | } |
| 691 | fdb->added_by_user = 1; | ||
| 650 | 692 | ||
| 651 | fdb->used = jiffies; | 693 | fdb->used = jiffies; |
| 652 | if (modified) { | 694 | if (modified) { |
| @@ -664,7 +706,7 @@ static int __br_fdb_add(struct ndmsg *ndm, struct net_bridge_port *p, | |||
| 664 | 706 | ||
| 665 | if (ndm->ndm_flags & NTF_USE) { | 707 | if (ndm->ndm_flags & NTF_USE) { |
| 666 | rcu_read_lock(); | 708 | rcu_read_lock(); |
| 667 | br_fdb_update(p->br, p, addr, vid); | 709 | br_fdb_update(p->br, p, addr, vid, true); |
| 668 | rcu_read_unlock(); | 710 | rcu_read_unlock(); |
| 669 | } else { | 711 | } else { |
| 670 | spin_lock_bh(&p->br->hash_lock); | 712 | spin_lock_bh(&p->br->hash_lock); |
| @@ -749,8 +791,7 @@ out: | |||
| 749 | return err; | 791 | return err; |
| 750 | } | 792 | } |
| 751 | 793 | ||
| 752 | int fdb_delete_by_addr(struct net_bridge *br, const u8 *addr, | 794 | static int fdb_delete_by_addr(struct net_bridge *br, const u8 *addr, u16 vlan) |
| 753 | u16 vlan) | ||
| 754 | { | 795 | { |
| 755 | struct hlist_head *head = &br->hash[br_mac_hash(addr, vlan)]; | 796 | struct hlist_head *head = &br->hash[br_mac_hash(addr, vlan)]; |
| 756 | struct net_bridge_fdb_entry *fdb; | 797 | struct net_bridge_fdb_entry *fdb; |
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index cffe1d666ba1..54d207d3a31c 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c | |||
| @@ -389,6 +389,9 @@ int br_add_if(struct net_bridge *br, struct net_device *dev) | |||
| 389 | if (br->dev->needed_headroom < dev->needed_headroom) | 389 | if (br->dev->needed_headroom < dev->needed_headroom) |
| 390 | br->dev->needed_headroom = dev->needed_headroom; | 390 | br->dev->needed_headroom = dev->needed_headroom; |
| 391 | 391 | ||
| 392 | if (br_fdb_insert(br, p, dev->dev_addr, 0)) | ||
| 393 | netdev_err(dev, "failed insert local address bridge forwarding table\n"); | ||
| 394 | |||
| 392 | spin_lock_bh(&br->lock); | 395 | spin_lock_bh(&br->lock); |
| 393 | changed_addr = br_stp_recalculate_bridge_id(br); | 396 | changed_addr = br_stp_recalculate_bridge_id(br); |
| 394 | 397 | ||
| @@ -404,9 +407,6 @@ int br_add_if(struct net_bridge *br, struct net_device *dev) | |||
| 404 | 407 | ||
| 405 | dev_set_mtu(br->dev, br_min_mtu(br)); | 408 | dev_set_mtu(br->dev, br_min_mtu(br)); |
| 406 | 409 | ||
| 407 | if (br_fdb_insert(br, p, dev->dev_addr, 0)) | ||
| 408 | netdev_err(dev, "failed insert local address bridge forwarding table\n"); | ||
| 409 | |||
| 410 | kobject_uevent(&p->kobj, KOBJ_ADD); | 410 | kobject_uevent(&p->kobj, KOBJ_ADD); |
| 411 | 411 | ||
| 412 | return 0; | 412 | return 0; |
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index bf8dc7d308d6..28d544627422 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c | |||
| @@ -77,7 +77,7 @@ int br_handle_frame_finish(struct sk_buff *skb) | |||
| 77 | /* insert into forwarding database after filtering to avoid spoofing */ | 77 | /* insert into forwarding database after filtering to avoid spoofing */ |
| 78 | br = p->br; | 78 | br = p->br; |
| 79 | if (p->flags & BR_LEARNING) | 79 | if (p->flags & BR_LEARNING) |
| 80 | br_fdb_update(br, p, eth_hdr(skb)->h_source, vid); | 80 | br_fdb_update(br, p, eth_hdr(skb)->h_source, vid, false); |
| 81 | 81 | ||
| 82 | if (!is_broadcast_ether_addr(dest) && is_multicast_ether_addr(dest) && | 82 | if (!is_broadcast_ether_addr(dest) && is_multicast_ether_addr(dest) && |
| 83 | br_multicast_rcv(br, p, skb, vid)) | 83 | br_multicast_rcv(br, p, skb, vid)) |
| @@ -148,7 +148,7 @@ static int br_handle_local_finish(struct sk_buff *skb) | |||
| 148 | 148 | ||
| 149 | br_vlan_get_tag(skb, &vid); | 149 | br_vlan_get_tag(skb, &vid); |
| 150 | if (p->flags & BR_LEARNING) | 150 | if (p->flags & BR_LEARNING) |
| 151 | br_fdb_update(p->br, p, eth_hdr(skb)->h_source, vid); | 151 | br_fdb_update(p->br, p, eth_hdr(skb)->h_source, vid, false); |
| 152 | return 0; /* process further */ | 152 | return 0; /* process further */ |
| 153 | } | 153 | } |
| 154 | 154 | ||
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index fcd12333c59b..3ba11bc99b65 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h | |||
| @@ -104,6 +104,7 @@ struct net_bridge_fdb_entry | |||
| 104 | mac_addr addr; | 104 | mac_addr addr; |
| 105 | unsigned char is_local; | 105 | unsigned char is_local; |
| 106 | unsigned char is_static; | 106 | unsigned char is_static; |
| 107 | unsigned char added_by_user; | ||
| 107 | __u16 vlan_id; | 108 | __u16 vlan_id; |
| 108 | }; | 109 | }; |
| 109 | 110 | ||
| @@ -370,6 +371,9 @@ static inline void br_netpoll_disable(struct net_bridge_port *p) | |||
| 370 | int br_fdb_init(void); | 371 | int br_fdb_init(void); |
| 371 | void br_fdb_fini(void); | 372 | void br_fdb_fini(void); |
| 372 | void br_fdb_flush(struct net_bridge *br); | 373 | void br_fdb_flush(struct net_bridge *br); |
| 374 | void br_fdb_find_delete_local(struct net_bridge *br, | ||
| 375 | const struct net_bridge_port *p, | ||
| 376 | const unsigned char *addr, u16 vid); | ||
| 373 | void br_fdb_changeaddr(struct net_bridge_port *p, const unsigned char *newaddr); | 377 | void br_fdb_changeaddr(struct net_bridge_port *p, const unsigned char *newaddr); |
| 374 | void br_fdb_change_mac_address(struct net_bridge *br, const u8 *newaddr); | 378 | void br_fdb_change_mac_address(struct net_bridge *br, const u8 *newaddr); |
| 375 | void br_fdb_cleanup(unsigned long arg); | 379 | void br_fdb_cleanup(unsigned long arg); |
| @@ -383,8 +387,7 @@ int br_fdb_fillbuf(struct net_bridge *br, void *buf, unsigned long count, | |||
| 383 | int br_fdb_insert(struct net_bridge *br, struct net_bridge_port *source, | 387 | int br_fdb_insert(struct net_bridge *br, struct net_bridge_port *source, |
| 384 | const unsigned char *addr, u16 vid); | 388 | const unsigned char *addr, u16 vid); |
| 385 | void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source, | 389 | void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source, |
| 386 | const unsigned char *addr, u16 vid); | 390 | const unsigned char *addr, u16 vid, bool added_by_user); |
| 387 | int fdb_delete_by_addr(struct net_bridge *br, const u8 *addr, u16 vid); | ||
| 388 | 391 | ||
| 389 | int br_fdb_delete(struct ndmsg *ndm, struct nlattr *tb[], | 392 | int br_fdb_delete(struct ndmsg *ndm, struct nlattr *tb[], |
| 390 | struct net_device *dev, const unsigned char *addr); | 393 | struct net_device *dev, const unsigned char *addr); |
| @@ -584,6 +587,7 @@ struct sk_buff *br_handle_vlan(struct net_bridge *br, | |||
| 584 | int br_vlan_add(struct net_bridge *br, u16 vid, u16 flags); | 587 | int br_vlan_add(struct net_bridge *br, u16 vid, u16 flags); |
| 585 | int br_vlan_delete(struct net_bridge *br, u16 vid); | 588 | int br_vlan_delete(struct net_bridge *br, u16 vid); |
| 586 | void br_vlan_flush(struct net_bridge *br); | 589 | void br_vlan_flush(struct net_bridge *br); |
| 590 | bool br_vlan_find(struct net_bridge *br, u16 vid); | ||
| 587 | int br_vlan_filter_toggle(struct net_bridge *br, unsigned long val); | 591 | int br_vlan_filter_toggle(struct net_bridge *br, unsigned long val); |
| 588 | int nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags); | 592 | int nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags); |
| 589 | int nbp_vlan_delete(struct net_bridge_port *port, u16 vid); | 593 | int nbp_vlan_delete(struct net_bridge_port *port, u16 vid); |
| @@ -665,6 +669,11 @@ static inline void br_vlan_flush(struct net_bridge *br) | |||
| 665 | { | 669 | { |
| 666 | } | 670 | } |
| 667 | 671 | ||
| 672 | static inline bool br_vlan_find(struct net_bridge *br, u16 vid) | ||
| 673 | { | ||
| 674 | return false; | ||
| 675 | } | ||
| 676 | |||
| 668 | static inline int nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags) | 677 | static inline int nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags) |
| 669 | { | 678 | { |
| 670 | return -EOPNOTSUPP; | 679 | return -EOPNOTSUPP; |
diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c index 656a6f3e40de..189ba1e7d851 100644 --- a/net/bridge/br_stp_if.c +++ b/net/bridge/br_stp_if.c | |||
| @@ -194,6 +194,8 @@ void br_stp_change_bridge_id(struct net_bridge *br, const unsigned char *addr) | |||
| 194 | 194 | ||
| 195 | wasroot = br_is_root_bridge(br); | 195 | wasroot = br_is_root_bridge(br); |
| 196 | 196 | ||
| 197 | br_fdb_change_mac_address(br, addr); | ||
| 198 | |||
| 197 | memcpy(oldaddr, br->bridge_id.addr, ETH_ALEN); | 199 | memcpy(oldaddr, br->bridge_id.addr, ETH_ALEN); |
| 198 | memcpy(br->bridge_id.addr, addr, ETH_ALEN); | 200 | memcpy(br->bridge_id.addr, addr, ETH_ALEN); |
| 199 | memcpy(br->dev->dev_addr, addr, ETH_ALEN); | 201 | memcpy(br->dev->dev_addr, addr, ETH_ALEN); |
diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c index 4ca4d0a0151c..8249ca764c79 100644 --- a/net/bridge/br_vlan.c +++ b/net/bridge/br_vlan.c | |||
| @@ -275,9 +275,7 @@ int br_vlan_delete(struct net_bridge *br, u16 vid) | |||
| 275 | if (!pv) | 275 | if (!pv) |
| 276 | return -EINVAL; | 276 | return -EINVAL; |
| 277 | 277 | ||
| 278 | spin_lock_bh(&br->hash_lock); | 278 | br_fdb_find_delete_local(br, NULL, br->dev->dev_addr, vid); |
| 279 | fdb_delete_by_addr(br, br->dev->dev_addr, vid); | ||
| 280 | spin_unlock_bh(&br->hash_lock); | ||
| 281 | 279 | ||
| 282 | __vlan_del(pv, vid); | 280 | __vlan_del(pv, vid); |
| 283 | return 0; | 281 | return 0; |
| @@ -295,6 +293,25 @@ void br_vlan_flush(struct net_bridge *br) | |||
| 295 | __vlan_flush(pv); | 293 | __vlan_flush(pv); |
| 296 | } | 294 | } |
| 297 | 295 | ||
| 296 | bool br_vlan_find(struct net_bridge *br, u16 vid) | ||
| 297 | { | ||
| 298 | struct net_port_vlans *pv; | ||
| 299 | bool found = false; | ||
| 300 | |||
| 301 | rcu_read_lock(); | ||
| 302 | pv = rcu_dereference(br->vlan_info); | ||
| 303 | |||
| 304 | if (!pv) | ||
| 305 | goto out; | ||
| 306 | |||
| 307 | if (test_bit(vid, pv->vlan_bitmap)) | ||
| 308 | found = true; | ||
| 309 | |||
| 310 | out: | ||
| 311 | rcu_read_unlock(); | ||
| 312 | return found; | ||
| 313 | } | ||
| 314 | |||
| 298 | int br_vlan_filter_toggle(struct net_bridge *br, unsigned long val) | 315 | int br_vlan_filter_toggle(struct net_bridge *br, unsigned long val) |
| 299 | { | 316 | { |
| 300 | if (!rtnl_trylock()) | 317 | if (!rtnl_trylock()) |
| @@ -359,9 +376,7 @@ int nbp_vlan_delete(struct net_bridge_port *port, u16 vid) | |||
| 359 | if (!pv) | 376 | if (!pv) |
| 360 | return -EINVAL; | 377 | return -EINVAL; |
| 361 | 378 | ||
| 362 | spin_lock_bh(&port->br->hash_lock); | 379 | br_fdb_find_delete_local(port->br, port, port->dev->dev_addr, vid); |
| 363 | fdb_delete_by_addr(port->br, port->dev->dev_addr, vid); | ||
| 364 | spin_unlock_bh(&port->br->hash_lock); | ||
| 365 | 380 | ||
| 366 | return __vlan_del(pv, vid); | 381 | return __vlan_del(pv, vid); |
| 367 | } | 382 | } |
diff --git a/net/caif/caif_dev.c b/net/caif/caif_dev.c index 4dca159435cf..edbca468fa73 100644 --- a/net/caif/caif_dev.c +++ b/net/caif/caif_dev.c | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | #include <net/pkt_sched.h> | 22 | #include <net/pkt_sched.h> |
| 23 | #include <net/caif/caif_device.h> | 23 | #include <net/caif/caif_device.h> |
| 24 | #include <net/caif/caif_layer.h> | 24 | #include <net/caif/caif_layer.h> |
| 25 | #include <net/caif/caif_dev.h> | ||
| 25 | #include <net/caif/cfpkt.h> | 26 | #include <net/caif/cfpkt.h> |
| 26 | #include <net/caif/cfcnfg.h> | 27 | #include <net/caif/cfcnfg.h> |
| 27 | #include <net/caif/cfserl.h> | 28 | #include <net/caif/cfserl.h> |
diff --git a/net/caif/cfsrvl.c b/net/caif/cfsrvl.c index 353f793d1b3b..a6e115463052 100644 --- a/net/caif/cfsrvl.c +++ b/net/caif/cfsrvl.c | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include <net/caif/caif_layer.h> | 15 | #include <net/caif/caif_layer.h> |
| 16 | #include <net/caif/cfsrvl.h> | 16 | #include <net/caif/cfsrvl.h> |
| 17 | #include <net/caif/cfpkt.h> | 17 | #include <net/caif/cfpkt.h> |
| 18 | #include <net/caif/caif_dev.h> | ||
| 18 | 19 | ||
| 19 | #define SRVL_CTRL_PKT_SIZE 1 | 20 | #define SRVL_CTRL_PKT_SIZE 1 |
| 20 | #define SRVL_FLOW_OFF 0x81 | 21 | #define SRVL_FLOW_OFF 0x81 |
diff --git a/net/can/af_can.c b/net/can/af_can.c index d249874a366d..a27f8aad9e99 100644 --- a/net/can/af_can.c +++ b/net/can/af_can.c | |||
| @@ -57,6 +57,7 @@ | |||
| 57 | #include <linux/skbuff.h> | 57 | #include <linux/skbuff.h> |
| 58 | #include <linux/can.h> | 58 | #include <linux/can.h> |
| 59 | #include <linux/can/core.h> | 59 | #include <linux/can/core.h> |
| 60 | #include <linux/can/skb.h> | ||
| 60 | #include <linux/ratelimit.h> | 61 | #include <linux/ratelimit.h> |
| 61 | #include <net/net_namespace.h> | 62 | #include <net/net_namespace.h> |
| 62 | #include <net/sock.h> | 63 | #include <net/sock.h> |
| @@ -290,7 +291,7 @@ int can_send(struct sk_buff *skb, int loop) | |||
| 290 | return -ENOMEM; | 291 | return -ENOMEM; |
| 291 | } | 292 | } |
| 292 | 293 | ||
| 293 | newskb->sk = skb->sk; | 294 | can_skb_set_owner(newskb, skb->sk); |
| 294 | newskb->ip_summed = CHECKSUM_UNNECESSARY; | 295 | newskb->ip_summed = CHECKSUM_UNNECESSARY; |
| 295 | newskb->pkt_type = PACKET_BROADCAST; | 296 | newskb->pkt_type = PACKET_BROADCAST; |
| 296 | } | 297 | } |
diff --git a/net/can/bcm.c b/net/can/bcm.c index 3fc737b214c7..dcb75c0e66c1 100644 --- a/net/can/bcm.c +++ b/net/can/bcm.c | |||
| @@ -268,7 +268,7 @@ static void bcm_can_tx(struct bcm_op *op) | |||
| 268 | 268 | ||
| 269 | /* send with loopback */ | 269 | /* send with loopback */ |
| 270 | skb->dev = dev; | 270 | skb->dev = dev; |
| 271 | skb->sk = op->sk; | 271 | can_skb_set_owner(skb, op->sk); |
| 272 | can_send(skb, 1); | 272 | can_send(skb, 1); |
| 273 | 273 | ||
| 274 | /* update statistics */ | 274 | /* update statistics */ |
| @@ -1223,7 +1223,7 @@ static int bcm_tx_send(struct msghdr *msg, int ifindex, struct sock *sk) | |||
| 1223 | 1223 | ||
| 1224 | can_skb_prv(skb)->ifindex = dev->ifindex; | 1224 | can_skb_prv(skb)->ifindex = dev->ifindex; |
| 1225 | skb->dev = dev; | 1225 | skb->dev = dev; |
| 1226 | skb->sk = sk; | 1226 | can_skb_set_owner(skb, sk); |
| 1227 | err = can_send(skb, 1); /* send with loopback */ | 1227 | err = can_send(skb, 1); /* send with loopback */ |
| 1228 | dev_put(dev); | 1228 | dev_put(dev); |
| 1229 | 1229 | ||
diff --git a/net/can/raw.c b/net/can/raw.c index 07d72d852324..8be757cca2ec 100644 --- a/net/can/raw.c +++ b/net/can/raw.c | |||
| @@ -715,6 +715,7 @@ static int raw_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
| 715 | 715 | ||
| 716 | skb->dev = dev; | 716 | skb->dev = dev; |
| 717 | skb->sk = sk; | 717 | skb->sk = sk; |
| 718 | skb->priority = sk->sk_priority; | ||
| 718 | 719 | ||
| 719 | err = can_send(skb, ro->loopback); | 720 | err = can_send(skb, ro->loopback); |
| 720 | 721 | ||
diff --git a/net/core/dev.c b/net/core/dev.c index 3721db716350..4ad1b78c9c77 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
| @@ -2803,7 +2803,7 @@ EXPORT_SYMBOL(dev_loopback_xmit); | |||
| 2803 | * the BH enable code must have IRQs enabled so that it will not deadlock. | 2803 | * the BH enable code must have IRQs enabled so that it will not deadlock. |
| 2804 | * --BLG | 2804 | * --BLG |
| 2805 | */ | 2805 | */ |
| 2806 | int __dev_queue_xmit(struct sk_buff *skb, void *accel_priv) | 2806 | static int __dev_queue_xmit(struct sk_buff *skb, void *accel_priv) |
| 2807 | { | 2807 | { |
| 2808 | struct net_device *dev = skb->dev; | 2808 | struct net_device *dev = skb->dev; |
| 2809 | struct netdev_queue *txq; | 2809 | struct netdev_queue *txq; |
| @@ -4637,7 +4637,7 @@ struct net_device *netdev_master_upper_dev_get_rcu(struct net_device *dev) | |||
| 4637 | } | 4637 | } |
| 4638 | EXPORT_SYMBOL(netdev_master_upper_dev_get_rcu); | 4638 | EXPORT_SYMBOL(netdev_master_upper_dev_get_rcu); |
| 4639 | 4639 | ||
| 4640 | int netdev_adjacent_sysfs_add(struct net_device *dev, | 4640 | static int netdev_adjacent_sysfs_add(struct net_device *dev, |
| 4641 | struct net_device *adj_dev, | 4641 | struct net_device *adj_dev, |
| 4642 | struct list_head *dev_list) | 4642 | struct list_head *dev_list) |
| 4643 | { | 4643 | { |
| @@ -4647,7 +4647,7 @@ int netdev_adjacent_sysfs_add(struct net_device *dev, | |||
| 4647 | return sysfs_create_link(&(dev->dev.kobj), &(adj_dev->dev.kobj), | 4647 | return sysfs_create_link(&(dev->dev.kobj), &(adj_dev->dev.kobj), |
| 4648 | linkname); | 4648 | linkname); |
| 4649 | } | 4649 | } |
| 4650 | void netdev_adjacent_sysfs_del(struct net_device *dev, | 4650 | static void netdev_adjacent_sysfs_del(struct net_device *dev, |
| 4651 | char *name, | 4651 | char *name, |
| 4652 | struct list_head *dev_list) | 4652 | struct list_head *dev_list) |
| 4653 | { | 4653 | { |
diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c index f409e0bd35c0..185c341fafbd 100644 --- a/net/core/fib_rules.c +++ b/net/core/fib_rules.c | |||
| @@ -745,6 +745,13 @@ static int fib_rules_event(struct notifier_block *this, unsigned long event, | |||
| 745 | attach_rules(&ops->rules_list, dev); | 745 | attach_rules(&ops->rules_list, dev); |
| 746 | break; | 746 | break; |
| 747 | 747 | ||
| 748 | case NETDEV_CHANGENAME: | ||
| 749 | list_for_each_entry(ops, &net->rules_ops, list) { | ||
| 750 | detach_rules(&ops->rules_list, dev); | ||
| 751 | attach_rules(&ops->rules_list, dev); | ||
| 752 | } | ||
| 753 | break; | ||
| 754 | |||
| 748 | case NETDEV_UNREGISTER: | 755 | case NETDEV_UNREGISTER: |
| 749 | list_for_each_entry(ops, &net->rules_ops, list) | 756 | list_for_each_entry(ops, &net->rules_ops, list) |
| 750 | detach_rules(&ops->rules_list, dev); | 757 | detach_rules(&ops->rules_list, dev); |
diff --git a/net/core/netpoll.c b/net/core/netpoll.c index c03f3dec4763..a664f7829a6d 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c | |||
| @@ -948,6 +948,7 @@ int netpoll_parse_options(struct netpoll *np, char *opt) | |||
| 948 | { | 948 | { |
| 949 | char *cur=opt, *delim; | 949 | char *cur=opt, *delim; |
| 950 | int ipv6; | 950 | int ipv6; |
| 951 | bool ipversion_set = false; | ||
| 951 | 952 | ||
| 952 | if (*cur != '@') { | 953 | if (*cur != '@') { |
| 953 | if ((delim = strchr(cur, '@')) == NULL) | 954 | if ((delim = strchr(cur, '@')) == NULL) |
| @@ -960,6 +961,7 @@ int netpoll_parse_options(struct netpoll *np, char *opt) | |||
| 960 | cur++; | 961 | cur++; |
| 961 | 962 | ||
| 962 | if (*cur != '/') { | 963 | if (*cur != '/') { |
| 964 | ipversion_set = true; | ||
| 963 | if ((delim = strchr(cur, '/')) == NULL) | 965 | if ((delim = strchr(cur, '/')) == NULL) |
| 964 | goto parse_failed; | 966 | goto parse_failed; |
| 965 | *delim = 0; | 967 | *delim = 0; |
| @@ -1002,7 +1004,7 @@ int netpoll_parse_options(struct netpoll *np, char *opt) | |||
| 1002 | ipv6 = netpoll_parse_ip_addr(cur, &np->remote_ip); | 1004 | ipv6 = netpoll_parse_ip_addr(cur, &np->remote_ip); |
| 1003 | if (ipv6 < 0) | 1005 | if (ipv6 < 0) |
| 1004 | goto parse_failed; | 1006 | goto parse_failed; |
| 1005 | else if (np->ipv6 != (bool)ipv6) | 1007 | else if (ipversion_set && np->ipv6 != (bool)ipv6) |
| 1006 | goto parse_failed; | 1008 | goto parse_failed; |
| 1007 | else | 1009 | else |
| 1008 | np->ipv6 = (bool)ipv6; | 1010 | np->ipv6 = (bool)ipv6; |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 393b1bc9a618..048dc8d183aa 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
| @@ -374,7 +374,7 @@ static size_t rtnl_link_get_slave_info_data_size(const struct net_device *dev) | |||
| 374 | if (!master_dev) | 374 | if (!master_dev) |
| 375 | return 0; | 375 | return 0; |
| 376 | ops = master_dev->rtnl_link_ops; | 376 | ops = master_dev->rtnl_link_ops; |
| 377 | if (!ops->get_slave_size) | 377 | if (!ops || !ops->get_slave_size) |
| 378 | return 0; | 378 | return 0; |
| 379 | /* IFLA_INFO_SLAVE_DATA + nested data */ | 379 | /* IFLA_INFO_SLAVE_DATA + nested data */ |
| 380 | return nla_total_size(sizeof(struct nlattr)) + | 380 | return nla_total_size(sizeof(struct nlattr)) + |
diff --git a/net/core/sock.c b/net/core/sock.c index 0c127dcdf6a8..5b6a9431b017 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
| @@ -1775,7 +1775,9 @@ struct sk_buff *sock_alloc_send_pskb(struct sock *sk, unsigned long header_len, | |||
| 1775 | while (order) { | 1775 | while (order) { |
| 1776 | if (npages >= 1 << order) { | 1776 | if (npages >= 1 << order) { |
| 1777 | page = alloc_pages(sk->sk_allocation | | 1777 | page = alloc_pages(sk->sk_allocation | |
| 1778 | __GFP_COMP | __GFP_NOWARN, | 1778 | __GFP_COMP | |
| 1779 | __GFP_NOWARN | | ||
| 1780 | __GFP_NORETRY, | ||
| 1779 | order); | 1781 | order); |
| 1780 | if (page) | 1782 | if (page) |
| 1781 | goto fill_page; | 1783 | goto fill_page; |
| @@ -1845,7 +1847,7 @@ bool skb_page_frag_refill(unsigned int sz, struct page_frag *pfrag, gfp_t prio) | |||
| 1845 | gfp_t gfp = prio; | 1847 | gfp_t gfp = prio; |
| 1846 | 1848 | ||
| 1847 | if (order) | 1849 | if (order) |
| 1848 | gfp |= __GFP_COMP | __GFP_NOWARN; | 1850 | gfp |= __GFP_COMP | __GFP_NOWARN | __GFP_NORETRY; |
| 1849 | pfrag->page = alloc_pages(gfp, order); | 1851 | pfrag->page = alloc_pages(gfp, order); |
| 1850 | if (likely(pfrag->page)) { | 1852 | if (likely(pfrag->page)) { |
| 1851 | pfrag->offset = 0; | 1853 | pfrag->offset = 0; |
diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c index 2954dcbca832..4c04848953bd 100644 --- a/net/decnet/af_decnet.c +++ b/net/decnet/af_decnet.c | |||
| @@ -2104,8 +2104,6 @@ static struct notifier_block dn_dev_notifier = { | |||
| 2104 | .notifier_call = dn_device_event, | 2104 | .notifier_call = dn_device_event, |
| 2105 | }; | 2105 | }; |
| 2106 | 2106 | ||
| 2107 | extern int dn_route_rcv(struct sk_buff *, struct net_device *, struct packet_type *, struct net_device *); | ||
| 2108 | |||
| 2109 | static struct packet_type dn_dix_packet_type __read_mostly = { | 2107 | static struct packet_type dn_dix_packet_type __read_mostly = { |
| 2110 | .type = cpu_to_be16(ETH_P_DNA_RT), | 2108 | .type = cpu_to_be16(ETH_P_DNA_RT), |
| 2111 | .func = dn_route_rcv, | 2109 | .func = dn_route_rcv, |
| @@ -2353,9 +2351,6 @@ static const struct proto_ops dn_proto_ops = { | |||
| 2353 | .sendpage = sock_no_sendpage, | 2351 | .sendpage = sock_no_sendpage, |
| 2354 | }; | 2352 | }; |
| 2355 | 2353 | ||
| 2356 | void dn_register_sysctl(void); | ||
| 2357 | void dn_unregister_sysctl(void); | ||
| 2358 | |||
| 2359 | MODULE_DESCRIPTION("The Linux DECnet Network Protocol"); | 2354 | MODULE_DESCRIPTION("The Linux DECnet Network Protocol"); |
| 2360 | MODULE_AUTHOR("Linux DECnet Project Team"); | 2355 | MODULE_AUTHOR("Linux DECnet Project Team"); |
| 2361 | MODULE_LICENSE("GPL"); | 2356 | MODULE_LICENSE("GPL"); |
diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c index 48b25c0af4d0..8edfea5da572 100644 --- a/net/ieee802154/6lowpan.c +++ b/net/ieee802154/6lowpan.c | |||
| @@ -106,7 +106,6 @@ static int lowpan_header_create(struct sk_buff *skb, | |||
| 106 | unsigned short type, const void *_daddr, | 106 | unsigned short type, const void *_daddr, |
| 107 | const void *_saddr, unsigned int len) | 107 | const void *_saddr, unsigned int len) |
| 108 | { | 108 | { |
| 109 | struct ipv6hdr *hdr; | ||
| 110 | const u8 *saddr = _saddr; | 109 | const u8 *saddr = _saddr; |
| 111 | const u8 *daddr = _daddr; | 110 | const u8 *daddr = _daddr; |
| 112 | struct ieee802154_addr sa, da; | 111 | struct ieee802154_addr sa, da; |
| @@ -117,8 +116,6 @@ static int lowpan_header_create(struct sk_buff *skb, | |||
| 117 | if (type != ETH_P_IPV6) | 116 | if (type != ETH_P_IPV6) |
| 118 | return 0; | 117 | return 0; |
| 119 | 118 | ||
| 120 | hdr = ipv6_hdr(skb); | ||
| 121 | |||
| 122 | if (!saddr) | 119 | if (!saddr) |
| 123 | saddr = dev->dev_addr; | 120 | saddr = dev->dev_addr; |
| 124 | 121 | ||
| @@ -533,7 +530,27 @@ static struct header_ops lowpan_header_ops = { | |||
| 533 | .create = lowpan_header_create, | 530 | .create = lowpan_header_create, |
| 534 | }; | 531 | }; |
| 535 | 532 | ||
| 533 | static struct lock_class_key lowpan_tx_busylock; | ||
| 534 | static struct lock_class_key lowpan_netdev_xmit_lock_key; | ||
| 535 | |||
| 536 | static void lowpan_set_lockdep_class_one(struct net_device *dev, | ||
| 537 | struct netdev_queue *txq, | ||
| 538 | void *_unused) | ||
| 539 | { | ||
| 540 | lockdep_set_class(&txq->_xmit_lock, | ||
| 541 | &lowpan_netdev_xmit_lock_key); | ||
| 542 | } | ||
| 543 | |||
| 544 | |||
| 545 | static int lowpan_dev_init(struct net_device *dev) | ||
| 546 | { | ||
| 547 | netdev_for_each_tx_queue(dev, lowpan_set_lockdep_class_one, NULL); | ||
| 548 | dev->qdisc_tx_busylock = &lowpan_tx_busylock; | ||
| 549 | return 0; | ||
| 550 | } | ||
| 551 | |||
| 536 | static const struct net_device_ops lowpan_netdev_ops = { | 552 | static const struct net_device_ops lowpan_netdev_ops = { |
| 553 | .ndo_init = lowpan_dev_init, | ||
| 537 | .ndo_start_xmit = lowpan_xmit, | 554 | .ndo_start_xmit = lowpan_xmit, |
| 538 | .ndo_set_mac_address = lowpan_set_address, | 555 | .ndo_set_mac_address = lowpan_set_address, |
| 539 | }; | 556 | }; |
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index ac2dff3c2c1c..bdbf68bb2e2d 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c | |||
| @@ -1443,7 +1443,8 @@ static size_t inet_nlmsg_size(void) | |||
| 1443 | + nla_total_size(4) /* IFA_LOCAL */ | 1443 | + nla_total_size(4) /* IFA_LOCAL */ |
| 1444 | + nla_total_size(4) /* IFA_BROADCAST */ | 1444 | + nla_total_size(4) /* IFA_BROADCAST */ |
| 1445 | + nla_total_size(IFNAMSIZ) /* IFA_LABEL */ | 1445 | + nla_total_size(IFNAMSIZ) /* IFA_LABEL */ |
| 1446 | + nla_total_size(4); /* IFA_FLAGS */ | 1446 | + nla_total_size(4) /* IFA_FLAGS */ |
| 1447 | + nla_total_size(sizeof(struct ifa_cacheinfo)); /* IFA_CACHEINFO */ | ||
| 1447 | } | 1448 | } |
| 1448 | 1449 | ||
| 1449 | static inline u32 cstamp_delta(unsigned long cstamp) | 1450 | static inline u32 cstamp_delta(unsigned long cstamp) |
diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c index bd28f386bd02..50228be5c17b 100644 --- a/net/ipv4/ip_tunnel.c +++ b/net/ipv4/ip_tunnel.c | |||
| @@ -101,28 +101,22 @@ static void tunnel_dst_reset_all(struct ip_tunnel *t) | |||
| 101 | __tunnel_dst_set(per_cpu_ptr(t->dst_cache, i), NULL); | 101 | __tunnel_dst_set(per_cpu_ptr(t->dst_cache, i), NULL); |
| 102 | } | 102 | } |
| 103 | 103 | ||
| 104 | static struct dst_entry *tunnel_dst_get(struct ip_tunnel *t) | 104 | static struct rtable *tunnel_rtable_get(struct ip_tunnel *t, u32 cookie) |
| 105 | { | 105 | { |
| 106 | struct dst_entry *dst; | 106 | struct dst_entry *dst; |
| 107 | 107 | ||
| 108 | rcu_read_lock(); | 108 | rcu_read_lock(); |
| 109 | dst = rcu_dereference(this_cpu_ptr(t->dst_cache)->dst); | 109 | dst = rcu_dereference(this_cpu_ptr(t->dst_cache)->dst); |
| 110 | if (dst) | 110 | if (dst) { |
| 111 | if (dst->obsolete && dst->ops->check(dst, cookie) == NULL) { | ||
| 112 | rcu_read_unlock(); | ||
| 113 | tunnel_dst_reset(t); | ||
| 114 | return NULL; | ||
| 115 | } | ||
| 111 | dst_hold(dst); | 116 | dst_hold(dst); |
| 112 | rcu_read_unlock(); | ||
| 113 | return dst; | ||
| 114 | } | ||
| 115 | |||
| 116 | static struct dst_entry *tunnel_dst_check(struct ip_tunnel *t, u32 cookie) | ||
| 117 | { | ||
| 118 | struct dst_entry *dst = tunnel_dst_get(t); | ||
| 119 | |||
| 120 | if (dst && dst->obsolete && dst->ops->check(dst, cookie) == NULL) { | ||
| 121 | tunnel_dst_reset(t); | ||
| 122 | return NULL; | ||
| 123 | } | 117 | } |
| 124 | 118 | rcu_read_unlock(); | |
| 125 | return dst; | 119 | return (struct rtable *)dst; |
| 126 | } | 120 | } |
| 127 | 121 | ||
| 128 | /* Often modified stats are per cpu, other are shared (netdev->stats) */ | 122 | /* Often modified stats are per cpu, other are shared (netdev->stats) */ |
| @@ -584,7 +578,7 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev, | |||
| 584 | struct flowi4 fl4; | 578 | struct flowi4 fl4; |
| 585 | u8 tos, ttl; | 579 | u8 tos, ttl; |
| 586 | __be16 df; | 580 | __be16 df; |
| 587 | struct rtable *rt = NULL; /* Route to the other host */ | 581 | struct rtable *rt; /* Route to the other host */ |
| 588 | unsigned int max_headroom; /* The extra header space needed */ | 582 | unsigned int max_headroom; /* The extra header space needed */ |
| 589 | __be32 dst; | 583 | __be32 dst; |
| 590 | int err; | 584 | int err; |
| @@ -657,8 +651,7 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev, | |||
| 657 | init_tunnel_flow(&fl4, protocol, dst, tnl_params->saddr, | 651 | init_tunnel_flow(&fl4, protocol, dst, tnl_params->saddr, |
| 658 | tunnel->parms.o_key, RT_TOS(tos), tunnel->parms.link); | 652 | tunnel->parms.o_key, RT_TOS(tos), tunnel->parms.link); |
| 659 | 653 | ||
| 660 | if (connected) | 654 | rt = connected ? tunnel_rtable_get(tunnel, 0) : NULL; |
| 661 | rt = (struct rtable *)tunnel_dst_check(tunnel, 0); | ||
| 662 | 655 | ||
| 663 | if (!rt) { | 656 | if (!rt) { |
| 664 | rt = ip_route_output_key(tunnel->net, &fl4); | 657 | rt = ip_route_output_key(tunnel->net, &fl4); |
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig index 81c6910cfa92..a26ce035e3fa 100644 --- a/net/ipv4/netfilter/Kconfig +++ b/net/ipv4/netfilter/Kconfig | |||
| @@ -61,6 +61,11 @@ config NFT_CHAIN_NAT_IPV4 | |||
| 61 | packet transformations such as the source, destination address and | 61 | packet transformations such as the source, destination address and |
| 62 | source and destination ports. | 62 | source and destination ports. |
| 63 | 63 | ||
| 64 | config NFT_REJECT_IPV4 | ||
| 65 | depends on NF_TABLES_IPV4 | ||
| 66 | default NFT_REJECT | ||
| 67 | tristate | ||
| 68 | |||
| 64 | config NF_TABLES_ARP | 69 | config NF_TABLES_ARP |
| 65 | depends on NF_TABLES | 70 | depends on NF_TABLES |
| 66 | tristate "ARP nf_tables support" | 71 | tristate "ARP nf_tables support" |
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile index c16be9d58420..90b82405331e 100644 --- a/net/ipv4/netfilter/Makefile +++ b/net/ipv4/netfilter/Makefile | |||
| @@ -30,6 +30,7 @@ obj-$(CONFIG_NF_NAT_PROTO_GRE) += nf_nat_proto_gre.o | |||
| 30 | obj-$(CONFIG_NF_TABLES_IPV4) += nf_tables_ipv4.o | 30 | obj-$(CONFIG_NF_TABLES_IPV4) += nf_tables_ipv4.o |
| 31 | obj-$(CONFIG_NFT_CHAIN_ROUTE_IPV4) += nft_chain_route_ipv4.o | 31 | obj-$(CONFIG_NFT_CHAIN_ROUTE_IPV4) += nft_chain_route_ipv4.o |
| 32 | obj-$(CONFIG_NFT_CHAIN_NAT_IPV4) += nft_chain_nat_ipv4.o | 32 | obj-$(CONFIG_NFT_CHAIN_NAT_IPV4) += nft_chain_nat_ipv4.o |
| 33 | obj-$(CONFIG_NFT_REJECT_IPV4) += nft_reject_ipv4.o | ||
| 33 | obj-$(CONFIG_NF_TABLES_ARP) += nf_tables_arp.o | 34 | obj-$(CONFIG_NF_TABLES_ARP) += nf_tables_arp.o |
| 34 | 35 | ||
| 35 | # generic IP tables | 36 | # generic IP tables |
diff --git a/net/ipv4/netfilter/nf_nat_h323.c b/net/ipv4/netfilter/nf_nat_h323.c index 9eea059dd621..574f7ebba0b6 100644 --- a/net/ipv4/netfilter/nf_nat_h323.c +++ b/net/ipv4/netfilter/nf_nat_h323.c | |||
| @@ -229,7 +229,10 @@ static int nat_rtp_rtcp(struct sk_buff *skb, struct nf_conn *ct, | |||
| 229 | ret = nf_ct_expect_related(rtcp_exp); | 229 | ret = nf_ct_expect_related(rtcp_exp); |
| 230 | if (ret == 0) | 230 | if (ret == 0) |
| 231 | break; | 231 | break; |
| 232 | else if (ret != -EBUSY) { | 232 | else if (ret == -EBUSY) { |
| 233 | nf_ct_unexpect_related(rtp_exp); | ||
| 234 | continue; | ||
| 235 | } else if (ret < 0) { | ||
| 233 | nf_ct_unexpect_related(rtp_exp); | 236 | nf_ct_unexpect_related(rtp_exp); |
| 234 | nated_port = 0; | 237 | nated_port = 0; |
| 235 | break; | 238 | break; |
diff --git a/net/ipv4/netfilter/nft_reject_ipv4.c b/net/ipv4/netfilter/nft_reject_ipv4.c new file mode 100644 index 000000000000..e79718a382f2 --- /dev/null +++ b/net/ipv4/netfilter/nft_reject_ipv4.c | |||
| @@ -0,0 +1,75 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2008-2009 Patrick McHardy <kaber@trash.net> | ||
| 3 | * Copyright (c) 2013 Eric Leblond <eric@regit.org> | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License version 2 as | ||
| 7 | * published by the Free Software Foundation. | ||
| 8 | * | ||
| 9 | * Development of this code funded by Astaro AG (http://www.astaro.com/) | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include <linux/kernel.h> | ||
| 13 | #include <linux/init.h> | ||
| 14 | #include <linux/module.h> | ||
| 15 | #include <linux/netlink.h> | ||
| 16 | #include <linux/netfilter.h> | ||
| 17 | #include <linux/netfilter/nf_tables.h> | ||
| 18 | #include <net/netfilter/nf_tables.h> | ||
| 19 | #include <net/icmp.h> | ||
| 20 | #include <net/netfilter/ipv4/nf_reject.h> | ||
| 21 | #include <net/netfilter/nft_reject.h> | ||
| 22 | |||
| 23 | void nft_reject_ipv4_eval(const struct nft_expr *expr, | ||
| 24 | struct nft_data data[NFT_REG_MAX + 1], | ||
| 25 | const struct nft_pktinfo *pkt) | ||
| 26 | { | ||
| 27 | struct nft_reject *priv = nft_expr_priv(expr); | ||
| 28 | |||
| 29 | switch (priv->type) { | ||
| 30 | case NFT_REJECT_ICMP_UNREACH: | ||
| 31 | nf_send_unreach(pkt->skb, priv->icmp_code); | ||
| 32 | break; | ||
| 33 | case NFT_REJECT_TCP_RST: | ||
| 34 | nf_send_reset(pkt->skb, pkt->ops->hooknum); | ||
| 35 | break; | ||
| 36 | } | ||
| 37 | |||
| 38 | data[NFT_REG_VERDICT].verdict = NF_DROP; | ||
| 39 | } | ||
| 40 | EXPORT_SYMBOL_GPL(nft_reject_ipv4_eval); | ||
| 41 | |||
| 42 | static struct nft_expr_type nft_reject_ipv4_type; | ||
| 43 | static const struct nft_expr_ops nft_reject_ipv4_ops = { | ||
| 44 | .type = &nft_reject_ipv4_type, | ||
| 45 | .size = NFT_EXPR_SIZE(sizeof(struct nft_reject)), | ||
| 46 | .eval = nft_reject_ipv4_eval, | ||
| 47 | .init = nft_reject_init, | ||
| 48 | .dump = nft_reject_dump, | ||
| 49 | }; | ||
| 50 | |||
| 51 | static struct nft_expr_type nft_reject_ipv4_type __read_mostly = { | ||
| 52 | .family = NFPROTO_IPV4, | ||
| 53 | .name = "reject", | ||
| 54 | .ops = &nft_reject_ipv4_ops, | ||
| 55 | .policy = nft_reject_policy, | ||
| 56 | .maxattr = NFTA_REJECT_MAX, | ||
| 57 | .owner = THIS_MODULE, | ||
| 58 | }; | ||
| 59 | |||
| 60 | static int __init nft_reject_ipv4_module_init(void) | ||
| 61 | { | ||
| 62 | return nft_register_expr(&nft_reject_ipv4_type); | ||
| 63 | } | ||
| 64 | |||
| 65 | static void __exit nft_reject_ipv4_module_exit(void) | ||
| 66 | { | ||
| 67 | nft_unregister_expr(&nft_reject_ipv4_type); | ||
| 68 | } | ||
| 69 | |||
| 70 | module_init(nft_reject_ipv4_module_init); | ||
| 71 | module_exit(nft_reject_ipv4_module_exit); | ||
| 72 | |||
| 73 | MODULE_LICENSE("GPL"); | ||
| 74 | MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); | ||
| 75 | MODULE_ALIAS_NFT_AF_EXPR(AF_INET, "reject"); | ||
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 4475b3bb494d..9f3a2db9109e 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
| @@ -2229,7 +2229,7 @@ adjudge_to_death: | |||
| 2229 | /* This is a (useful) BSD violating of the RFC. There is a | 2229 | /* This is a (useful) BSD violating of the RFC. There is a |
| 2230 | * problem with TCP as specified in that the other end could | 2230 | * problem with TCP as specified in that the other end could |
| 2231 | * keep a socket open forever with no application left this end. | 2231 | * keep a socket open forever with no application left this end. |
| 2232 | * We use a 3 minute timeout (about the same as BSD) then kill | 2232 | * We use a 1 minute timeout (about the same as BSD) then kill |
| 2233 | * our end. If they send after that then tough - BUT: long enough | 2233 | * our end. If they send after that then tough - BUT: long enough |
| 2234 | * that we won't make the old 4*rto = almost no time - whoops | 2234 | * that we won't make the old 4*rto = almost no time - whoops |
| 2235 | * reset mistake. | 2235 | * reset mistake. |
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 65cf90e063d5..227cba79fa6b 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
| @@ -671,6 +671,7 @@ static void tcp_rtt_estimator(struct sock *sk, const __u32 mrtt) | |||
| 671 | { | 671 | { |
| 672 | struct tcp_sock *tp = tcp_sk(sk); | 672 | struct tcp_sock *tp = tcp_sk(sk); |
| 673 | long m = mrtt; /* RTT */ | 673 | long m = mrtt; /* RTT */ |
| 674 | u32 srtt = tp->srtt; | ||
| 674 | 675 | ||
| 675 | /* The following amusing code comes from Jacobson's | 676 | /* The following amusing code comes from Jacobson's |
| 676 | * article in SIGCOMM '88. Note that rtt and mdev | 677 | * article in SIGCOMM '88. Note that rtt and mdev |
| @@ -688,11 +689,9 @@ static void tcp_rtt_estimator(struct sock *sk, const __u32 mrtt) | |||
| 688 | * does not matter how to _calculate_ it. Seems, it was trap | 689 | * does not matter how to _calculate_ it. Seems, it was trap |
| 689 | * that VJ failed to avoid. 8) | 690 | * that VJ failed to avoid. 8) |
| 690 | */ | 691 | */ |
| 691 | if (m == 0) | 692 | if (srtt != 0) { |
| 692 | m = 1; | 693 | m -= (srtt >> 3); /* m is now error in rtt est */ |
| 693 | if (tp->srtt != 0) { | 694 | srtt += m; /* rtt = 7/8 rtt + 1/8 new */ |
| 694 | m -= (tp->srtt >> 3); /* m is now error in rtt est */ | ||
| 695 | tp->srtt += m; /* rtt = 7/8 rtt + 1/8 new */ | ||
| 696 | if (m < 0) { | 695 | if (m < 0) { |
| 697 | m = -m; /* m is now abs(error) */ | 696 | m = -m; /* m is now abs(error) */ |
| 698 | m -= (tp->mdev >> 2); /* similar update on mdev */ | 697 | m -= (tp->mdev >> 2); /* similar update on mdev */ |
| @@ -723,11 +722,12 @@ static void tcp_rtt_estimator(struct sock *sk, const __u32 mrtt) | |||
| 723 | } | 722 | } |
| 724 | } else { | 723 | } else { |
| 725 | /* no previous measure. */ | 724 | /* no previous measure. */ |
| 726 | tp->srtt = m << 3; /* take the measured time to be rtt */ | 725 | srtt = m << 3; /* take the measured time to be rtt */ |
| 727 | tp->mdev = m << 1; /* make sure rto = 3*rtt */ | 726 | tp->mdev = m << 1; /* make sure rto = 3*rtt */ |
| 728 | tp->mdev_max = tp->rttvar = max(tp->mdev, tcp_rto_min(sk)); | 727 | tp->mdev_max = tp->rttvar = max(tp->mdev, tcp_rto_min(sk)); |
| 729 | tp->rtt_seq = tp->snd_nxt; | 728 | tp->rtt_seq = tp->snd_nxt; |
| 730 | } | 729 | } |
| 730 | tp->srtt = max(1U, srtt); | ||
| 731 | } | 731 | } |
| 732 | 732 | ||
| 733 | /* Set the sk_pacing_rate to allow proper sizing of TSO packets. | 733 | /* Set the sk_pacing_rate to allow proper sizing of TSO packets. |
| @@ -746,8 +746,10 @@ static void tcp_update_pacing_rate(struct sock *sk) | |||
| 746 | 746 | ||
| 747 | rate *= max(tp->snd_cwnd, tp->packets_out); | 747 | rate *= max(tp->snd_cwnd, tp->packets_out); |
| 748 | 748 | ||
| 749 | /* Correction for small srtt : minimum srtt being 8 (1 jiffy << 3), | 749 | /* Correction for small srtt and scheduling constraints. |
| 750 | * be conservative and assume srtt = 1 (125 us instead of 1.25 ms) | 750 | * For small rtt, consider noise is too high, and use |
| 751 | * the minimal value (srtt = 1 -> 125 us for HZ=1000) | ||
| 752 | * | ||
| 751 | * We probably need usec resolution in the future. | 753 | * We probably need usec resolution in the future. |
| 752 | * Note: This also takes care of possible srtt=0 case, | 754 | * Note: This also takes care of possible srtt=0 case, |
| 753 | * when tcp_rtt_estimator() was not yet called. | 755 | * when tcp_rtt_estimator() was not yet called. |
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 03d26b85eab8..3be16727f058 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
| @@ -698,7 +698,8 @@ static void tcp_tsq_handler(struct sock *sk) | |||
| 698 | if ((1 << sk->sk_state) & | 698 | if ((1 << sk->sk_state) & |
| 699 | (TCPF_ESTABLISHED | TCPF_FIN_WAIT1 | TCPF_CLOSING | | 699 | (TCPF_ESTABLISHED | TCPF_FIN_WAIT1 | TCPF_CLOSING | |
| 700 | TCPF_CLOSE_WAIT | TCPF_LAST_ACK)) | 700 | TCPF_CLOSE_WAIT | TCPF_LAST_ACK)) |
| 701 | tcp_write_xmit(sk, tcp_current_mss(sk), 0, 0, GFP_ATOMIC); | 701 | tcp_write_xmit(sk, tcp_current_mss(sk), tcp_sk(sk)->nonagle, |
| 702 | 0, GFP_ATOMIC); | ||
| 702 | } | 703 | } |
| 703 | /* | 704 | /* |
| 704 | * One tasklet per cpu tries to send more skbs. | 705 | * One tasklet per cpu tries to send more skbs. |
| @@ -1904,7 +1905,15 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, | |||
| 1904 | 1905 | ||
| 1905 | if (atomic_read(&sk->sk_wmem_alloc) > limit) { | 1906 | if (atomic_read(&sk->sk_wmem_alloc) > limit) { |
| 1906 | set_bit(TSQ_THROTTLED, &tp->tsq_flags); | 1907 | set_bit(TSQ_THROTTLED, &tp->tsq_flags); |
| 1907 | break; | 1908 | /* It is possible TX completion already happened |
| 1909 | * before we set TSQ_THROTTLED, so we must | ||
| 1910 | * test again the condition. | ||
| 1911 | * We abuse smp_mb__after_clear_bit() because | ||
| 1912 | * there is no smp_mb__after_set_bit() yet | ||
| 1913 | */ | ||
| 1914 | smp_mb__after_clear_bit(); | ||
| 1915 | if (atomic_read(&sk->sk_wmem_alloc) > limit) | ||
| 1916 | break; | ||
| 1908 | } | 1917 | } |
| 1909 | 1918 | ||
| 1910 | limit = mss_now; | 1919 | limit = mss_now; |
| @@ -1977,7 +1986,7 @@ bool tcp_schedule_loss_probe(struct sock *sk) | |||
| 1977 | /* Schedule a loss probe in 2*RTT for SACK capable connections | 1986 | /* Schedule a loss probe in 2*RTT for SACK capable connections |
| 1978 | * in Open state, that are either limited by cwnd or application. | 1987 | * in Open state, that are either limited by cwnd or application. |
| 1979 | */ | 1988 | */ |
| 1980 | if (sysctl_tcp_early_retrans < 3 || !rtt || !tp->packets_out || | 1989 | if (sysctl_tcp_early_retrans < 3 || !tp->srtt || !tp->packets_out || |
| 1981 | !tcp_is_sack(tp) || inet_csk(sk)->icsk_ca_state != TCP_CA_Open) | 1990 | !tcp_is_sack(tp) || inet_csk(sk)->icsk_ca_state != TCP_CA_Open) |
| 1982 | return false; | 1991 | return false; |
| 1983 | 1992 | ||
diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c index 25f5cee3a08a..88b4023ecfcf 100644 --- a/net/ipv4/udp_offload.c +++ b/net/ipv4/udp_offload.c | |||
| @@ -17,6 +17,8 @@ | |||
| 17 | static DEFINE_SPINLOCK(udp_offload_lock); | 17 | static DEFINE_SPINLOCK(udp_offload_lock); |
| 18 | static struct udp_offload_priv __rcu *udp_offload_base __read_mostly; | 18 | static struct udp_offload_priv __rcu *udp_offload_base __read_mostly; |
| 19 | 19 | ||
| 20 | #define udp_deref_protected(X) rcu_dereference_protected(X, lockdep_is_held(&udp_offload_lock)) | ||
| 21 | |||
| 20 | struct udp_offload_priv { | 22 | struct udp_offload_priv { |
| 21 | struct udp_offload *offload; | 23 | struct udp_offload *offload; |
| 22 | struct rcu_head rcu; | 24 | struct rcu_head rcu; |
| @@ -100,8 +102,7 @@ out: | |||
| 100 | 102 | ||
| 101 | int udp_add_offload(struct udp_offload *uo) | 103 | int udp_add_offload(struct udp_offload *uo) |
| 102 | { | 104 | { |
| 103 | struct udp_offload_priv __rcu **head = &udp_offload_base; | 105 | struct udp_offload_priv *new_offload = kzalloc(sizeof(*new_offload), GFP_ATOMIC); |
| 104 | struct udp_offload_priv *new_offload = kzalloc(sizeof(*new_offload), GFP_KERNEL); | ||
| 105 | 106 | ||
| 106 | if (!new_offload) | 107 | if (!new_offload) |
| 107 | return -ENOMEM; | 108 | return -ENOMEM; |
| @@ -109,8 +110,8 @@ int udp_add_offload(struct udp_offload *uo) | |||
| 109 | new_offload->offload = uo; | 110 | new_offload->offload = uo; |
| 110 | 111 | ||
| 111 | spin_lock(&udp_offload_lock); | 112 | spin_lock(&udp_offload_lock); |
| 112 | rcu_assign_pointer(new_offload->next, rcu_dereference(*head)); | 113 | new_offload->next = udp_offload_base; |
| 113 | rcu_assign_pointer(*head, new_offload); | 114 | rcu_assign_pointer(udp_offload_base, new_offload); |
| 114 | spin_unlock(&udp_offload_lock); | 115 | spin_unlock(&udp_offload_lock); |
| 115 | 116 | ||
| 116 | return 0; | 117 | return 0; |
| @@ -130,12 +131,12 @@ void udp_del_offload(struct udp_offload *uo) | |||
| 130 | 131 | ||
| 131 | spin_lock(&udp_offload_lock); | 132 | spin_lock(&udp_offload_lock); |
| 132 | 133 | ||
| 133 | uo_priv = rcu_dereference(*head); | 134 | uo_priv = udp_deref_protected(*head); |
| 134 | for (; uo_priv != NULL; | 135 | for (; uo_priv != NULL; |
| 135 | uo_priv = rcu_dereference(*head)) { | 136 | uo_priv = udp_deref_protected(*head)) { |
| 136 | |||
| 137 | if (uo_priv->offload == uo) { | 137 | if (uo_priv->offload == uo) { |
| 138 | rcu_assign_pointer(*head, rcu_dereference(uo_priv->next)); | 138 | rcu_assign_pointer(*head, |
| 139 | udp_deref_protected(uo_priv->next)); | ||
| 139 | goto unlock; | 140 | goto unlock; |
| 140 | } | 141 | } |
| 141 | head = &uo_priv->next; | 142 | head = &uo_priv->next; |
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index f81f59686f21..f2610e157660 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c | |||
| @@ -414,7 +414,7 @@ static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info) | |||
| 414 | addr_type = ipv6_addr_type(&hdr->daddr); | 414 | addr_type = ipv6_addr_type(&hdr->daddr); |
| 415 | 415 | ||
| 416 | if (ipv6_chk_addr(net, &hdr->daddr, skb->dev, 0) || | 416 | if (ipv6_chk_addr(net, &hdr->daddr, skb->dev, 0) || |
| 417 | ipv6_anycast_destination(skb)) | 417 | ipv6_chk_acast_addr_src(net, skb->dev, &hdr->daddr)) |
| 418 | saddr = &hdr->daddr; | 418 | saddr = &hdr->daddr; |
| 419 | 419 | ||
| 420 | /* | 420 | /* |
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig index 35750df744dc..4bff1f297e39 100644 --- a/net/ipv6/netfilter/Kconfig +++ b/net/ipv6/netfilter/Kconfig | |||
| @@ -50,6 +50,11 @@ config NFT_CHAIN_NAT_IPV6 | |||
| 50 | packet transformations such as the source, destination address and | 50 | packet transformations such as the source, destination address and |
| 51 | source and destination ports. | 51 | source and destination ports. |
| 52 | 52 | ||
| 53 | config NFT_REJECT_IPV6 | ||
| 54 | depends on NF_TABLES_IPV6 | ||
| 55 | default NFT_REJECT | ||
| 56 | tristate | ||
| 57 | |||
| 53 | config IP6_NF_IPTABLES | 58 | config IP6_NF_IPTABLES |
| 54 | tristate "IP6 tables support (required for filtering)" | 59 | tristate "IP6 tables support (required for filtering)" |
| 55 | depends on INET && IPV6 | 60 | depends on INET && IPV6 |
diff --git a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile index d1b4928f34f7..70d3dd66f2cd 100644 --- a/net/ipv6/netfilter/Makefile +++ b/net/ipv6/netfilter/Makefile | |||
| @@ -27,6 +27,7 @@ obj-$(CONFIG_NF_DEFRAG_IPV6) += nf_defrag_ipv6.o | |||
| 27 | obj-$(CONFIG_NF_TABLES_IPV6) += nf_tables_ipv6.o | 27 | obj-$(CONFIG_NF_TABLES_IPV6) += nf_tables_ipv6.o |
| 28 | obj-$(CONFIG_NFT_CHAIN_ROUTE_IPV6) += nft_chain_route_ipv6.o | 28 | obj-$(CONFIG_NFT_CHAIN_ROUTE_IPV6) += nft_chain_route_ipv6.o |
| 29 | obj-$(CONFIG_NFT_CHAIN_NAT_IPV6) += nft_chain_nat_ipv6.o | 29 | obj-$(CONFIG_NFT_CHAIN_NAT_IPV6) += nft_chain_nat_ipv6.o |
| 30 | obj-$(CONFIG_NFT_REJECT_IPV6) += nft_reject_ipv6.o | ||
| 30 | 31 | ||
| 31 | # matches | 32 | # matches |
| 32 | obj-$(CONFIG_IP6_NF_MATCH_AH) += ip6t_ah.o | 33 | obj-$(CONFIG_IP6_NF_MATCH_AH) += ip6t_ah.o |
diff --git a/net/ipv6/netfilter/nft_reject_ipv6.c b/net/ipv6/netfilter/nft_reject_ipv6.c new file mode 100644 index 000000000000..0bc19fa87821 --- /dev/null +++ b/net/ipv6/netfilter/nft_reject_ipv6.c | |||
| @@ -0,0 +1,76 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2008-2009 Patrick McHardy <kaber@trash.net> | ||
| 3 | * Copyright (c) 2013 Eric Leblond <eric@regit.org> | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License version 2 as | ||
| 7 | * published by the Free Software Foundation. | ||
| 8 | * | ||
| 9 | * Development of this code funded by Astaro AG (http://www.astaro.com/) | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include <linux/kernel.h> | ||
| 13 | #include <linux/init.h> | ||
| 14 | #include <linux/module.h> | ||
| 15 | #include <linux/netlink.h> | ||
| 16 | #include <linux/netfilter.h> | ||
| 17 | #include <linux/netfilter/nf_tables.h> | ||
| 18 | #include <net/netfilter/nf_tables.h> | ||
| 19 | #include <net/netfilter/nft_reject.h> | ||
| 20 | #include <net/netfilter/ipv6/nf_reject.h> | ||
| 21 | |||
| 22 | void nft_reject_ipv6_eval(const struct nft_expr *expr, | ||
| 23 | struct nft_data data[NFT_REG_MAX + 1], | ||
| 24 | const struct nft_pktinfo *pkt) | ||
| 25 | { | ||
| 26 | struct nft_reject *priv = nft_expr_priv(expr); | ||
| 27 | struct net *net = dev_net((pkt->in != NULL) ? pkt->in : pkt->out); | ||
| 28 | |||
| 29 | switch (priv->type) { | ||
| 30 | case NFT_REJECT_ICMP_UNREACH: | ||
| 31 | nf_send_unreach6(net, pkt->skb, priv->icmp_code, | ||
| 32 | pkt->ops->hooknum); | ||
| 33 | break; | ||
| 34 | case NFT_REJECT_TCP_RST: | ||
| 35 | nf_send_reset6(net, pkt->skb, pkt->ops->hooknum); | ||
| 36 | break; | ||
| 37 | } | ||
| 38 | |||
| 39 | data[NFT_REG_VERDICT].verdict = NF_DROP; | ||
| 40 | } | ||
| 41 | EXPORT_SYMBOL_GPL(nft_reject_ipv6_eval); | ||
| 42 | |||
| 43 | static struct nft_expr_type nft_reject_ipv6_type; | ||
| 44 | static const struct nft_expr_ops nft_reject_ipv6_ops = { | ||
| 45 | .type = &nft_reject_ipv6_type, | ||
| 46 | .size = NFT_EXPR_SIZE(sizeof(struct nft_reject)), | ||
| 47 | .eval = nft_reject_ipv6_eval, | ||
| 48 | .init = nft_reject_init, | ||
| 49 | .dump = nft_reject_dump, | ||
| 50 | }; | ||
| 51 | |||
| 52 | static struct nft_expr_type nft_reject_ipv6_type __read_mostly = { | ||
| 53 | .family = NFPROTO_IPV6, | ||
| 54 | .name = "reject", | ||
| 55 | .ops = &nft_reject_ipv6_ops, | ||
| 56 | .policy = nft_reject_policy, | ||
| 57 | .maxattr = NFTA_REJECT_MAX, | ||
| 58 | .owner = THIS_MODULE, | ||
| 59 | }; | ||
| 60 | |||
| 61 | static int __init nft_reject_ipv6_module_init(void) | ||
| 62 | { | ||
| 63 | return nft_register_expr(&nft_reject_ipv6_type); | ||
| 64 | } | ||
| 65 | |||
| 66 | static void __exit nft_reject_ipv6_module_exit(void) | ||
| 67 | { | ||
| 68 | nft_unregister_expr(&nft_reject_ipv6_type); | ||
| 69 | } | ||
| 70 | |||
| 71 | module_init(nft_reject_ipv6_module_init); | ||
| 72 | module_exit(nft_reject_ipv6_module_exit); | ||
| 73 | |||
| 74 | MODULE_LICENSE("GPL"); | ||
| 75 | MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); | ||
| 76 | MODULE_ALIAS_NFT_AF_EXPR(AF_INET6, "reject"); | ||
diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c index 994e28bfb32e..00b2a6d1c009 100644 --- a/net/ipx/af_ipx.c +++ b/net/ipx/af_ipx.c | |||
| @@ -52,18 +52,12 @@ | |||
| 52 | #include <net/p8022.h> | 52 | #include <net/p8022.h> |
| 53 | #include <net/psnap.h> | 53 | #include <net/psnap.h> |
| 54 | #include <net/sock.h> | 54 | #include <net/sock.h> |
| 55 | #include <net/datalink.h> | ||
| 55 | #include <net/tcp_states.h> | 56 | #include <net/tcp_states.h> |
| 57 | #include <net/net_namespace.h> | ||
| 56 | 58 | ||
| 57 | #include <asm/uaccess.h> | 59 | #include <asm/uaccess.h> |
| 58 | 60 | ||
| 59 | #ifdef CONFIG_SYSCTL | ||
| 60 | extern void ipx_register_sysctl(void); | ||
| 61 | extern void ipx_unregister_sysctl(void); | ||
| 62 | #else | ||
| 63 | #define ipx_register_sysctl() | ||
| 64 | #define ipx_unregister_sysctl() | ||
| 65 | #endif | ||
| 66 | |||
| 67 | /* Configuration Variables */ | 61 | /* Configuration Variables */ |
| 68 | static unsigned char ipxcfg_max_hops = 16; | 62 | static unsigned char ipxcfg_max_hops = 16; |
| 69 | static char ipxcfg_auto_select_primary; | 63 | static char ipxcfg_auto_select_primary; |
| @@ -84,15 +78,6 @@ DEFINE_SPINLOCK(ipx_interfaces_lock); | |||
| 84 | struct ipx_interface *ipx_primary_net; | 78 | struct ipx_interface *ipx_primary_net; |
| 85 | struct ipx_interface *ipx_internal_net; | 79 | struct ipx_interface *ipx_internal_net; |
| 86 | 80 | ||
| 87 | extern int ipxrtr_add_route(__be32 network, struct ipx_interface *intrfc, | ||
| 88 | unsigned char *node); | ||
| 89 | extern void ipxrtr_del_routes(struct ipx_interface *intrfc); | ||
| 90 | extern int ipxrtr_route_packet(struct sock *sk, struct sockaddr_ipx *usipx, | ||
| 91 | struct iovec *iov, size_t len, int noblock); | ||
| 92 | extern int ipxrtr_route_skb(struct sk_buff *skb); | ||
| 93 | extern struct ipx_route *ipxrtr_lookup(__be32 net); | ||
| 94 | extern int ipxrtr_ioctl(unsigned int cmd, void __user *arg); | ||
| 95 | |||
| 96 | struct ipx_interface *ipx_interfaces_head(void) | 81 | struct ipx_interface *ipx_interfaces_head(void) |
| 97 | { | 82 | { |
| 98 | struct ipx_interface *rc = NULL; | 83 | struct ipx_interface *rc = NULL; |
| @@ -1986,9 +1971,6 @@ static struct notifier_block ipx_dev_notifier = { | |||
| 1986 | .notifier_call = ipxitf_device_event, | 1971 | .notifier_call = ipxitf_device_event, |
| 1987 | }; | 1972 | }; |
| 1988 | 1973 | ||
| 1989 | extern struct datalink_proto *make_EII_client(void); | ||
| 1990 | extern void destroy_EII_client(struct datalink_proto *); | ||
| 1991 | |||
| 1992 | static const unsigned char ipx_8022_type = 0xE0; | 1974 | static const unsigned char ipx_8022_type = 0xE0; |
| 1993 | static const unsigned char ipx_snap_id[5] = { 0x0, 0x0, 0x0, 0x81, 0x37 }; | 1975 | static const unsigned char ipx_snap_id[5] = { 0x0, 0x0, 0x0, 0x81, 0x37 }; |
| 1994 | static const char ipx_EII_err_msg[] __initconst = | 1976 | static const char ipx_EII_err_msg[] __initconst = |
diff --git a/net/ipx/ipx_route.c b/net/ipx/ipx_route.c index 30f4519b092f..c1f03185c5e1 100644 --- a/net/ipx/ipx_route.c +++ b/net/ipx/ipx_route.c | |||
| @@ -20,15 +20,11 @@ DEFINE_RWLOCK(ipx_routes_lock); | |||
| 20 | 20 | ||
| 21 | extern struct ipx_interface *ipx_internal_net; | 21 | extern struct ipx_interface *ipx_internal_net; |
| 22 | 22 | ||
| 23 | extern __be16 ipx_cksum(struct ipxhdr *packet, int length); | ||
| 24 | extern struct ipx_interface *ipxitf_find_using_net(__be32 net); | 23 | extern struct ipx_interface *ipxitf_find_using_net(__be32 net); |
| 25 | extern int ipxitf_demux_socket(struct ipx_interface *intrfc, | 24 | extern int ipxitf_demux_socket(struct ipx_interface *intrfc, |
| 26 | struct sk_buff *skb, int copy); | 25 | struct sk_buff *skb, int copy); |
| 27 | extern int ipxitf_demux_socket(struct ipx_interface *intrfc, | 26 | extern int ipxitf_demux_socket(struct ipx_interface *intrfc, |
| 28 | struct sk_buff *skb, int copy); | 27 | struct sk_buff *skb, int copy); |
| 29 | extern int ipxitf_send(struct ipx_interface *intrfc, struct sk_buff *skb, | ||
| 30 | char *node); | ||
| 31 | extern struct ipx_interface *ipxitf_find_using_net(__be32 net); | ||
| 32 | 28 | ||
| 33 | struct ipx_route *ipxrtr_lookup(__be32 net) | 29 | struct ipx_route *ipxrtr_lookup(__be32 net) |
| 34 | { | 30 | { |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index f9ae9b85d4c1..453e974287d1 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
| @@ -1021,8 +1021,10 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev, | |||
| 1021 | IEEE80211_P2P_OPPPS_ENABLE_BIT; | 1021 | IEEE80211_P2P_OPPPS_ENABLE_BIT; |
| 1022 | 1022 | ||
| 1023 | err = ieee80211_assign_beacon(sdata, ¶ms->beacon); | 1023 | err = ieee80211_assign_beacon(sdata, ¶ms->beacon); |
| 1024 | if (err < 0) | 1024 | if (err < 0) { |
| 1025 | ieee80211_vif_release_channel(sdata); | ||
| 1025 | return err; | 1026 | return err; |
| 1027 | } | ||
| 1026 | changed |= err; | 1028 | changed |= err; |
| 1027 | 1029 | ||
| 1028 | err = drv_start_ap(sdata->local, sdata); | 1030 | err = drv_start_ap(sdata->local, sdata); |
| @@ -1032,6 +1034,7 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev, | |||
| 1032 | if (old) | 1034 | if (old) |
| 1033 | kfree_rcu(old, rcu_head); | 1035 | kfree_rcu(old, rcu_head); |
| 1034 | RCU_INIT_POINTER(sdata->u.ap.beacon, NULL); | 1036 | RCU_INIT_POINTER(sdata->u.ap.beacon, NULL); |
| 1037 | ieee80211_vif_release_channel(sdata); | ||
| 1035 | return err; | 1038 | return err; |
| 1036 | } | 1039 | } |
| 1037 | 1040 | ||
| @@ -1090,8 +1093,6 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev) | |||
| 1090 | kfree(sdata->u.ap.next_beacon); | 1093 | kfree(sdata->u.ap.next_beacon); |
| 1091 | sdata->u.ap.next_beacon = NULL; | 1094 | sdata->u.ap.next_beacon = NULL; |
| 1092 | 1095 | ||
| 1093 | cancel_work_sync(&sdata->u.ap.request_smps_work); | ||
| 1094 | |||
| 1095 | /* turn off carrier for this interface and dependent VLANs */ | 1096 | /* turn off carrier for this interface and dependent VLANs */ |
| 1096 | list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) | 1097 | list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) |
| 1097 | netif_carrier_off(vlan->dev); | 1098 | netif_carrier_off(vlan->dev); |
| @@ -1103,6 +1104,7 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev) | |||
| 1103 | kfree_rcu(old_beacon, rcu_head); | 1104 | kfree_rcu(old_beacon, rcu_head); |
| 1104 | if (old_probe_resp) | 1105 | if (old_probe_resp) |
| 1105 | kfree_rcu(old_probe_resp, rcu_head); | 1106 | kfree_rcu(old_probe_resp, rcu_head); |
| 1107 | sdata->u.ap.driver_smps_mode = IEEE80211_SMPS_OFF; | ||
| 1106 | 1108 | ||
| 1107 | __sta_info_flush(sdata, true); | 1109 | __sta_info_flush(sdata, true); |
| 1108 | ieee80211_free_keys(sdata, true); | 1110 | ieee80211_free_keys(sdata, true); |
| @@ -2638,6 +2640,24 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local, | |||
| 2638 | INIT_DELAYED_WORK(&roc->work, ieee80211_sw_roc_work); | 2640 | INIT_DELAYED_WORK(&roc->work, ieee80211_sw_roc_work); |
| 2639 | INIT_LIST_HEAD(&roc->dependents); | 2641 | INIT_LIST_HEAD(&roc->dependents); |
| 2640 | 2642 | ||
| 2643 | /* | ||
| 2644 | * cookie is either the roc cookie (for normal roc) | ||
| 2645 | * or the SKB (for mgmt TX) | ||
| 2646 | */ | ||
| 2647 | if (!txskb) { | ||
| 2648 | /* local->mtx protects this */ | ||
| 2649 | local->roc_cookie_counter++; | ||
| 2650 | roc->cookie = local->roc_cookie_counter; | ||
| 2651 | /* wow, you wrapped 64 bits ... more likely a bug */ | ||
| 2652 | if (WARN_ON(roc->cookie == 0)) { | ||
| 2653 | roc->cookie = 1; | ||
| 2654 | local->roc_cookie_counter++; | ||
| 2655 | } | ||
| 2656 | *cookie = roc->cookie; | ||
| 2657 | } else { | ||
| 2658 | *cookie = (unsigned long)txskb; | ||
| 2659 | } | ||
| 2660 | |||
| 2641 | /* if there's one pending or we're scanning, queue this one */ | 2661 | /* if there's one pending or we're scanning, queue this one */ |
| 2642 | if (!list_empty(&local->roc_list) || | 2662 | if (!list_empty(&local->roc_list) || |
| 2643 | local->scanning || local->radar_detect_enabled) | 2663 | local->scanning || local->radar_detect_enabled) |
| @@ -2772,24 +2792,6 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local, | |||
| 2772 | if (!queued) | 2792 | if (!queued) |
| 2773 | list_add_tail(&roc->list, &local->roc_list); | 2793 | list_add_tail(&roc->list, &local->roc_list); |
| 2774 | 2794 | ||
| 2775 | /* | ||
| 2776 | * cookie is either the roc cookie (for normal roc) | ||
| 2777 | * or the SKB (for mgmt TX) | ||
| 2778 | */ | ||
| 2779 | if (!txskb) { | ||
| 2780 | /* local->mtx protects this */ | ||
| 2781 | local->roc_cookie_counter++; | ||
| 2782 | roc->cookie = local->roc_cookie_counter; | ||
| 2783 | /* wow, you wrapped 64 bits ... more likely a bug */ | ||
| 2784 | if (WARN_ON(roc->cookie == 0)) { | ||
| 2785 | roc->cookie = 1; | ||
| 2786 | local->roc_cookie_counter++; | ||
| 2787 | } | ||
| 2788 | *cookie = roc->cookie; | ||
| 2789 | } else { | ||
| 2790 | *cookie = (unsigned long)txskb; | ||
| 2791 | } | ||
| 2792 | |||
| 2793 | return 0; | 2795 | return 0; |
| 2794 | } | 2796 | } |
| 2795 | 2797 | ||
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c index fab7b91923e0..70dd013de836 100644 --- a/net/mac80211/ht.c +++ b/net/mac80211/ht.c | |||
| @@ -466,7 +466,9 @@ void ieee80211_request_smps_ap_work(struct work_struct *work) | |||
| 466 | u.ap.request_smps_work); | 466 | u.ap.request_smps_work); |
| 467 | 467 | ||
| 468 | sdata_lock(sdata); | 468 | sdata_lock(sdata); |
| 469 | __ieee80211_request_smps_ap(sdata, sdata->u.ap.driver_smps_mode); | 469 | if (sdata_dereference(sdata->u.ap.beacon, sdata)) |
| 470 | __ieee80211_request_smps_ap(sdata, | ||
| 471 | sdata->u.ap.driver_smps_mode); | ||
| 470 | sdata_unlock(sdata); | 472 | sdata_unlock(sdata); |
| 471 | } | 473 | } |
| 472 | 474 | ||
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 771080ec7212..2796a198728f 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
| @@ -695,12 +695,9 @@ static void ieee80211_ibss_disconnect(struct ieee80211_sub_if_data *sdata) | |||
| 695 | struct cfg80211_bss *cbss; | 695 | struct cfg80211_bss *cbss; |
| 696 | struct beacon_data *presp; | 696 | struct beacon_data *presp; |
| 697 | struct sta_info *sta; | 697 | struct sta_info *sta; |
| 698 | int active_ibss; | ||
| 699 | u16 capability; | 698 | u16 capability; |
| 700 | 699 | ||
| 701 | active_ibss = ieee80211_sta_active_ibss(sdata); | 700 | if (!is_zero_ether_addr(ifibss->bssid)) { |
| 702 | |||
| 703 | if (!active_ibss && !is_zero_ether_addr(ifibss->bssid)) { | ||
| 704 | capability = WLAN_CAPABILITY_IBSS; | 701 | capability = WLAN_CAPABILITY_IBSS; |
| 705 | 702 | ||
| 706 | if (ifibss->privacy) | 703 | if (ifibss->privacy) |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 3dfd20a453ab..d6d1f1df9119 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
| @@ -418,20 +418,24 @@ int ieee80211_add_virtual_monitor(struct ieee80211_local *local) | |||
| 418 | return ret; | 418 | return ret; |
| 419 | } | 419 | } |
| 420 | 420 | ||
| 421 | mutex_lock(&local->iflist_mtx); | ||
| 422 | rcu_assign_pointer(local->monitor_sdata, sdata); | ||
| 423 | mutex_unlock(&local->iflist_mtx); | ||
| 424 | |||
| 421 | mutex_lock(&local->mtx); | 425 | mutex_lock(&local->mtx); |
| 422 | ret = ieee80211_vif_use_channel(sdata, &local->monitor_chandef, | 426 | ret = ieee80211_vif_use_channel(sdata, &local->monitor_chandef, |
| 423 | IEEE80211_CHANCTX_EXCLUSIVE); | 427 | IEEE80211_CHANCTX_EXCLUSIVE); |
| 424 | mutex_unlock(&local->mtx); | 428 | mutex_unlock(&local->mtx); |
| 425 | if (ret) { | 429 | if (ret) { |
| 430 | mutex_lock(&local->iflist_mtx); | ||
| 431 | rcu_assign_pointer(local->monitor_sdata, NULL); | ||
| 432 | mutex_unlock(&local->iflist_mtx); | ||
| 433 | synchronize_net(); | ||
| 426 | drv_remove_interface(local, sdata); | 434 | drv_remove_interface(local, sdata); |
| 427 | kfree(sdata); | 435 | kfree(sdata); |
| 428 | return ret; | 436 | return ret; |
| 429 | } | 437 | } |
| 430 | 438 | ||
| 431 | mutex_lock(&local->iflist_mtx); | ||
| 432 | rcu_assign_pointer(local->monitor_sdata, sdata); | ||
| 433 | mutex_unlock(&local->iflist_mtx); | ||
| 434 | |||
| 435 | return 0; | 439 | return 0; |
| 436 | } | 440 | } |
| 437 | 441 | ||
| @@ -770,12 +774,19 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, | |||
| 770 | 774 | ||
| 771 | ieee80211_roc_purge(local, sdata); | 775 | ieee80211_roc_purge(local, sdata); |
| 772 | 776 | ||
| 773 | if (sdata->vif.type == NL80211_IFTYPE_STATION) | 777 | switch (sdata->vif.type) { |
| 778 | case NL80211_IFTYPE_STATION: | ||
| 774 | ieee80211_mgd_stop(sdata); | 779 | ieee80211_mgd_stop(sdata); |
| 775 | 780 | break; | |
| 776 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC) | 781 | case NL80211_IFTYPE_ADHOC: |
| 777 | ieee80211_ibss_stop(sdata); | 782 | ieee80211_ibss_stop(sdata); |
| 778 | 783 | break; | |
| 784 | case NL80211_IFTYPE_AP: | ||
| 785 | cancel_work_sync(&sdata->u.ap.request_smps_work); | ||
| 786 | break; | ||
| 787 | default: | ||
| 788 | break; | ||
| 789 | } | ||
| 779 | 790 | ||
| 780 | /* | 791 | /* |
| 781 | * Remove all stations associated with this interface. | 792 | * Remove all stations associated with this interface. |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 27c990bf2320..97a02d3f7d87 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
| @@ -878,7 +878,7 @@ static int ieee80211_fragment(struct ieee80211_tx_data *tx, | |||
| 878 | } | 878 | } |
| 879 | 879 | ||
| 880 | /* adjust first fragment's length */ | 880 | /* adjust first fragment's length */ |
| 881 | skb->len = hdrlen + per_fragm; | 881 | skb_trim(skb, hdrlen + per_fragm); |
| 882 | return 0; | 882 | return 0; |
| 883 | } | 883 | } |
| 884 | 884 | ||
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig index c37467562fd0..e9410d17619d 100644 --- a/net/netfilter/Kconfig +++ b/net/netfilter/Kconfig | |||
| @@ -513,7 +513,6 @@ config NFT_QUEUE | |||
| 513 | 513 | ||
| 514 | config NFT_REJECT | 514 | config NFT_REJECT |
| 515 | depends on NF_TABLES | 515 | depends on NF_TABLES |
| 516 | depends on NF_TABLES_IPV6 || !NF_TABLES_IPV6 | ||
| 517 | default m if NETFILTER_ADVANCED=n | 516 | default m if NETFILTER_ADVANCED=n |
| 518 | tristate "Netfilter nf_tables reject support" | 517 | tristate "Netfilter nf_tables reject support" |
| 519 | help | 518 | help |
| @@ -521,6 +520,11 @@ config NFT_REJECT | |||
| 521 | explicitly deny and notify via TCP reset/ICMP informational errors | 520 | explicitly deny and notify via TCP reset/ICMP informational errors |
| 522 | unallowed traffic. | 521 | unallowed traffic. |
| 523 | 522 | ||
| 523 | config NFT_REJECT_INET | ||
| 524 | depends on NF_TABLES_INET | ||
| 525 | default NFT_REJECT | ||
| 526 | tristate | ||
| 527 | |||
| 524 | config NFT_COMPAT | 528 | config NFT_COMPAT |
| 525 | depends on NF_TABLES | 529 | depends on NF_TABLES |
| 526 | depends on NETFILTER_XTABLES | 530 | depends on NETFILTER_XTABLES |
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile index ee9c4de5f8ed..bffdad774da7 100644 --- a/net/netfilter/Makefile +++ b/net/netfilter/Makefile | |||
| @@ -79,6 +79,7 @@ obj-$(CONFIG_NFT_LIMIT) += nft_limit.o | |||
| 79 | obj-$(CONFIG_NFT_NAT) += nft_nat.o | 79 | obj-$(CONFIG_NFT_NAT) += nft_nat.o |
| 80 | obj-$(CONFIG_NFT_QUEUE) += nft_queue.o | 80 | obj-$(CONFIG_NFT_QUEUE) += nft_queue.o |
| 81 | obj-$(CONFIG_NFT_REJECT) += nft_reject.o | 81 | obj-$(CONFIG_NFT_REJECT) += nft_reject.o |
| 82 | obj-$(CONFIG_NFT_REJECT_INET) += nft_reject_inet.o | ||
| 82 | obj-$(CONFIG_NFT_RBTREE) += nft_rbtree.o | 83 | obj-$(CONFIG_NFT_RBTREE) += nft_rbtree.o |
| 83 | obj-$(CONFIG_NFT_HASH) += nft_hash.o | 84 | obj-$(CONFIG_NFT_HASH) += nft_hash.o |
| 84 | obj-$(CONFIG_NFT_COUNTER) += nft_counter.o | 85 | obj-$(CONFIG_NFT_COUNTER) += nft_counter.o |
diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c index 59a1a85bcb3e..a8eb0a89326a 100644 --- a/net/netfilter/ipvs/ip_vs_conn.c +++ b/net/netfilter/ipvs/ip_vs_conn.c | |||
| @@ -871,11 +871,11 @@ ip_vs_conn_new(const struct ip_vs_conn_param *p, | |||
| 871 | cp->protocol = p->protocol; | 871 | cp->protocol = p->protocol; |
| 872 | ip_vs_addr_set(p->af, &cp->caddr, p->caddr); | 872 | ip_vs_addr_set(p->af, &cp->caddr, p->caddr); |
| 873 | cp->cport = p->cport; | 873 | cp->cport = p->cport; |
| 874 | ip_vs_addr_set(p->af, &cp->vaddr, p->vaddr); | 874 | /* proto should only be IPPROTO_IP if p->vaddr is a fwmark */ |
| 875 | cp->vport = p->vport; | ||
| 876 | /* proto should only be IPPROTO_IP if d_addr is a fwmark */ | ||
| 877 | ip_vs_addr_set(p->protocol == IPPROTO_IP ? AF_UNSPEC : p->af, | 875 | ip_vs_addr_set(p->protocol == IPPROTO_IP ? AF_UNSPEC : p->af, |
| 878 | &cp->daddr, daddr); | 876 | &cp->vaddr, p->vaddr); |
| 877 | cp->vport = p->vport; | ||
| 878 | ip_vs_addr_set(p->af, &cp->daddr, daddr); | ||
| 879 | cp->dport = dport; | 879 | cp->dport = dport; |
| 880 | cp->flags = flags; | 880 | cp->flags = flags; |
| 881 | cp->fwmark = fwmark; | 881 | cp->fwmark = fwmark; |
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 8824ed0ccc9c..356bef519fe5 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c | |||
| @@ -312,6 +312,21 @@ static void death_by_timeout(unsigned long ul_conntrack) | |||
| 312 | nf_ct_delete((struct nf_conn *)ul_conntrack, 0, 0); | 312 | nf_ct_delete((struct nf_conn *)ul_conntrack, 0, 0); |
| 313 | } | 313 | } |
| 314 | 314 | ||
| 315 | static inline bool | ||
| 316 | nf_ct_key_equal(struct nf_conntrack_tuple_hash *h, | ||
| 317 | const struct nf_conntrack_tuple *tuple, | ||
| 318 | u16 zone) | ||
| 319 | { | ||
| 320 | struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(h); | ||
| 321 | |||
| 322 | /* A conntrack can be recreated with the equal tuple, | ||
| 323 | * so we need to check that the conntrack is confirmed | ||
| 324 | */ | ||
| 325 | return nf_ct_tuple_equal(tuple, &h->tuple) && | ||
| 326 | nf_ct_zone(ct) == zone && | ||
| 327 | nf_ct_is_confirmed(ct); | ||
| 328 | } | ||
| 329 | |||
| 315 | /* | 330 | /* |
| 316 | * Warning : | 331 | * Warning : |
| 317 | * - Caller must take a reference on returned object | 332 | * - Caller must take a reference on returned object |
| @@ -333,8 +348,7 @@ ____nf_conntrack_find(struct net *net, u16 zone, | |||
| 333 | local_bh_disable(); | 348 | local_bh_disable(); |
| 334 | begin: | 349 | begin: |
| 335 | hlist_nulls_for_each_entry_rcu(h, n, &net->ct.hash[bucket], hnnode) { | 350 | hlist_nulls_for_each_entry_rcu(h, n, &net->ct.hash[bucket], hnnode) { |
| 336 | if (nf_ct_tuple_equal(tuple, &h->tuple) && | 351 | if (nf_ct_key_equal(h, tuple, zone)) { |
| 337 | nf_ct_zone(nf_ct_tuplehash_to_ctrack(h)) == zone) { | ||
| 338 | NF_CT_STAT_INC(net, found); | 352 | NF_CT_STAT_INC(net, found); |
| 339 | local_bh_enable(); | 353 | local_bh_enable(); |
| 340 | return h; | 354 | return h; |
| @@ -372,8 +386,7 @@ begin: | |||
| 372 | !atomic_inc_not_zero(&ct->ct_general.use))) | 386 | !atomic_inc_not_zero(&ct->ct_general.use))) |
| 373 | h = NULL; | 387 | h = NULL; |
| 374 | else { | 388 | else { |
| 375 | if (unlikely(!nf_ct_tuple_equal(tuple, &h->tuple) || | 389 | if (unlikely(!nf_ct_key_equal(h, tuple, zone))) { |
| 376 | nf_ct_zone(ct) != zone)) { | ||
| 377 | nf_ct_put(ct); | 390 | nf_ct_put(ct); |
| 378 | goto begin; | 391 | goto begin; |
| 379 | } | 392 | } |
| @@ -435,7 +448,9 @@ nf_conntrack_hash_check_insert(struct nf_conn *ct) | |||
| 435 | goto out; | 448 | goto out; |
| 436 | 449 | ||
| 437 | add_timer(&ct->timeout); | 450 | add_timer(&ct->timeout); |
| 438 | nf_conntrack_get(&ct->ct_general); | 451 | smp_wmb(); |
| 452 | /* The caller holds a reference to this object */ | ||
| 453 | atomic_set(&ct->ct_general.use, 2); | ||
| 439 | __nf_conntrack_hash_insert(ct, hash, repl_hash); | 454 | __nf_conntrack_hash_insert(ct, hash, repl_hash); |
| 440 | NF_CT_STAT_INC(net, insert); | 455 | NF_CT_STAT_INC(net, insert); |
| 441 | spin_unlock_bh(&nf_conntrack_lock); | 456 | spin_unlock_bh(&nf_conntrack_lock); |
| @@ -449,6 +464,21 @@ out: | |||
| 449 | } | 464 | } |
| 450 | EXPORT_SYMBOL_GPL(nf_conntrack_hash_check_insert); | 465 | EXPORT_SYMBOL_GPL(nf_conntrack_hash_check_insert); |
| 451 | 466 | ||
| 467 | /* deletion from this larval template list happens via nf_ct_put() */ | ||
| 468 | void nf_conntrack_tmpl_insert(struct net *net, struct nf_conn *tmpl) | ||
| 469 | { | ||
| 470 | __set_bit(IPS_TEMPLATE_BIT, &tmpl->status); | ||
| 471 | __set_bit(IPS_CONFIRMED_BIT, &tmpl->status); | ||
| 472 | nf_conntrack_get(&tmpl->ct_general); | ||
| 473 | |||
| 474 | spin_lock_bh(&nf_conntrack_lock); | ||
| 475 | /* Overload tuple linked list to put us in template list. */ | ||
| 476 | hlist_nulls_add_head_rcu(&tmpl->tuplehash[IP_CT_DIR_ORIGINAL].hnnode, | ||
| 477 | &net->ct.tmpl); | ||
| 478 | spin_unlock_bh(&nf_conntrack_lock); | ||
| 479 | } | ||
| 480 | EXPORT_SYMBOL_GPL(nf_conntrack_tmpl_insert); | ||
| 481 | |||
| 452 | /* Confirm a connection given skb; places it in hash table */ | 482 | /* Confirm a connection given skb; places it in hash table */ |
| 453 | int | 483 | int |
| 454 | __nf_conntrack_confirm(struct sk_buff *skb) | 484 | __nf_conntrack_confirm(struct sk_buff *skb) |
| @@ -720,11 +750,10 @@ __nf_conntrack_alloc(struct net *net, u16 zone, | |||
| 720 | nf_ct_zone->id = zone; | 750 | nf_ct_zone->id = zone; |
| 721 | } | 751 | } |
| 722 | #endif | 752 | #endif |
| 723 | /* | 753 | /* Because we use RCU lookups, we set ct_general.use to zero before |
| 724 | * changes to lookup keys must be done before setting refcnt to 1 | 754 | * this is inserted in any list. |
| 725 | */ | 755 | */ |
| 726 | smp_wmb(); | 756 | atomic_set(&ct->ct_general.use, 0); |
| 727 | atomic_set(&ct->ct_general.use, 1); | ||
| 728 | return ct; | 757 | return ct; |
| 729 | 758 | ||
| 730 | #ifdef CONFIG_NF_CONNTRACK_ZONES | 759 | #ifdef CONFIG_NF_CONNTRACK_ZONES |
| @@ -748,6 +777,11 @@ void nf_conntrack_free(struct nf_conn *ct) | |||
| 748 | { | 777 | { |
| 749 | struct net *net = nf_ct_net(ct); | 778 | struct net *net = nf_ct_net(ct); |
| 750 | 779 | ||
| 780 | /* A freed object has refcnt == 0, that's | ||
| 781 | * the golden rule for SLAB_DESTROY_BY_RCU | ||
| 782 | */ | ||
| 783 | NF_CT_ASSERT(atomic_read(&ct->ct_general.use) == 0); | ||
| 784 | |||
| 751 | nf_ct_ext_destroy(ct); | 785 | nf_ct_ext_destroy(ct); |
| 752 | nf_ct_ext_free(ct); | 786 | nf_ct_ext_free(ct); |
| 753 | kmem_cache_free(net->ct.nf_conntrack_cachep, ct); | 787 | kmem_cache_free(net->ct.nf_conntrack_cachep, ct); |
| @@ -843,6 +877,9 @@ init_conntrack(struct net *net, struct nf_conn *tmpl, | |||
| 843 | NF_CT_STAT_INC(net, new); | 877 | NF_CT_STAT_INC(net, new); |
| 844 | } | 878 | } |
| 845 | 879 | ||
| 880 | /* Now it is inserted into the unconfirmed list, bump refcount */ | ||
| 881 | nf_conntrack_get(&ct->ct_general); | ||
| 882 | |||
| 846 | /* Overload tuple linked list to put us in unconfirmed list. */ | 883 | /* Overload tuple linked list to put us in unconfirmed list. */ |
| 847 | hlist_nulls_add_head_rcu(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode, | 884 | hlist_nulls_add_head_rcu(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode, |
| 848 | &net->ct.unconfirmed); | 885 | &net->ct.unconfirmed); |
diff --git a/net/netfilter/nf_synproxy_core.c b/net/netfilter/nf_synproxy_core.c index 9858e3e51a3a..52e20c9a46a5 100644 --- a/net/netfilter/nf_synproxy_core.c +++ b/net/netfilter/nf_synproxy_core.c | |||
| @@ -363,9 +363,8 @@ static int __net_init synproxy_net_init(struct net *net) | |||
| 363 | goto err2; | 363 | goto err2; |
| 364 | if (!nfct_synproxy_ext_add(ct)) | 364 | if (!nfct_synproxy_ext_add(ct)) |
| 365 | goto err2; | 365 | goto err2; |
| 366 | __set_bit(IPS_TEMPLATE_BIT, &ct->status); | ||
| 367 | __set_bit(IPS_CONFIRMED_BIT, &ct->status); | ||
| 368 | 366 | ||
| 367 | nf_conntrack_tmpl_insert(net, ct); | ||
| 369 | snet->tmpl = ct; | 368 | snet->tmpl = ct; |
| 370 | 369 | ||
| 371 | snet->stats = alloc_percpu(struct synproxy_stats); | 370 | snet->stats = alloc_percpu(struct synproxy_stats); |
| @@ -390,7 +389,7 @@ static void __net_exit synproxy_net_exit(struct net *net) | |||
| 390 | { | 389 | { |
| 391 | struct synproxy_net *snet = synproxy_pernet(net); | 390 | struct synproxy_net *snet = synproxy_pernet(net); |
| 392 | 391 | ||
| 393 | nf_conntrack_free(snet->tmpl); | 392 | nf_ct_put(snet->tmpl); |
| 394 | synproxy_proc_exit(net); | 393 | synproxy_proc_exit(net); |
| 395 | free_percpu(snet->stats); | 394 | free_percpu(snet->stats); |
| 396 | } | 395 | } |
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 117bbaaddde6..adce01e8bb57 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c | |||
| @@ -1008,10 +1008,8 @@ notify: | |||
| 1008 | return 0; | 1008 | return 0; |
| 1009 | } | 1009 | } |
| 1010 | 1010 | ||
| 1011 | static void nf_tables_rcu_chain_destroy(struct rcu_head *head) | 1011 | static void nf_tables_chain_destroy(struct nft_chain *chain) |
| 1012 | { | 1012 | { |
| 1013 | struct nft_chain *chain = container_of(head, struct nft_chain, rcu_head); | ||
| 1014 | |||
| 1015 | BUG_ON(chain->use > 0); | 1013 | BUG_ON(chain->use > 0); |
| 1016 | 1014 | ||
| 1017 | if (chain->flags & NFT_BASE_CHAIN) { | 1015 | if (chain->flags & NFT_BASE_CHAIN) { |
| @@ -1045,7 +1043,7 @@ static int nf_tables_delchain(struct sock *nlsk, struct sk_buff *skb, | |||
| 1045 | if (IS_ERR(chain)) | 1043 | if (IS_ERR(chain)) |
| 1046 | return PTR_ERR(chain); | 1044 | return PTR_ERR(chain); |
| 1047 | 1045 | ||
| 1048 | if (!list_empty(&chain->rules)) | 1046 | if (!list_empty(&chain->rules) || chain->use > 0) |
| 1049 | return -EBUSY; | 1047 | return -EBUSY; |
| 1050 | 1048 | ||
| 1051 | list_del(&chain->list); | 1049 | list_del(&chain->list); |
| @@ -1059,7 +1057,9 @@ static int nf_tables_delchain(struct sock *nlsk, struct sk_buff *skb, | |||
| 1059 | family); | 1057 | family); |
| 1060 | 1058 | ||
| 1061 | /* Make sure all rule references are gone before this is released */ | 1059 | /* Make sure all rule references are gone before this is released */ |
| 1062 | call_rcu(&chain->rcu_head, nf_tables_rcu_chain_destroy); | 1060 | synchronize_rcu(); |
| 1061 | |||
| 1062 | nf_tables_chain_destroy(chain); | ||
| 1063 | return 0; | 1063 | return 0; |
| 1064 | } | 1064 | } |
| 1065 | 1065 | ||
| @@ -1114,35 +1114,45 @@ void nft_unregister_expr(struct nft_expr_type *type) | |||
| 1114 | } | 1114 | } |
| 1115 | EXPORT_SYMBOL_GPL(nft_unregister_expr); | 1115 | EXPORT_SYMBOL_GPL(nft_unregister_expr); |
| 1116 | 1116 | ||
| 1117 | static const struct nft_expr_type *__nft_expr_type_get(struct nlattr *nla) | 1117 | static const struct nft_expr_type *__nft_expr_type_get(u8 family, |
| 1118 | struct nlattr *nla) | ||
| 1118 | { | 1119 | { |
| 1119 | const struct nft_expr_type *type; | 1120 | const struct nft_expr_type *type; |
| 1120 | 1121 | ||
| 1121 | list_for_each_entry(type, &nf_tables_expressions, list) { | 1122 | list_for_each_entry(type, &nf_tables_expressions, list) { |
| 1122 | if (!nla_strcmp(nla, type->name)) | 1123 | if (!nla_strcmp(nla, type->name) && |
| 1124 | (!type->family || type->family == family)) | ||
| 1123 | return type; | 1125 | return type; |
| 1124 | } | 1126 | } |
| 1125 | return NULL; | 1127 | return NULL; |
| 1126 | } | 1128 | } |
| 1127 | 1129 | ||
| 1128 | static const struct nft_expr_type *nft_expr_type_get(struct nlattr *nla) | 1130 | static const struct nft_expr_type *nft_expr_type_get(u8 family, |
| 1131 | struct nlattr *nla) | ||
| 1129 | { | 1132 | { |
| 1130 | const struct nft_expr_type *type; | 1133 | const struct nft_expr_type *type; |
| 1131 | 1134 | ||
| 1132 | if (nla == NULL) | 1135 | if (nla == NULL) |
| 1133 | return ERR_PTR(-EINVAL); | 1136 | return ERR_PTR(-EINVAL); |
| 1134 | 1137 | ||
| 1135 | type = __nft_expr_type_get(nla); | 1138 | type = __nft_expr_type_get(family, nla); |
| 1136 | if (type != NULL && try_module_get(type->owner)) | 1139 | if (type != NULL && try_module_get(type->owner)) |
| 1137 | return type; | 1140 | return type; |
| 1138 | 1141 | ||
| 1139 | #ifdef CONFIG_MODULES | 1142 | #ifdef CONFIG_MODULES |
| 1140 | if (type == NULL) { | 1143 | if (type == NULL) { |
| 1141 | nfnl_unlock(NFNL_SUBSYS_NFTABLES); | 1144 | nfnl_unlock(NFNL_SUBSYS_NFTABLES); |
| 1145 | request_module("nft-expr-%u-%.*s", family, | ||
| 1146 | nla_len(nla), (char *)nla_data(nla)); | ||
| 1147 | nfnl_lock(NFNL_SUBSYS_NFTABLES); | ||
| 1148 | if (__nft_expr_type_get(family, nla)) | ||
| 1149 | return ERR_PTR(-EAGAIN); | ||
| 1150 | |||
| 1151 | nfnl_unlock(NFNL_SUBSYS_NFTABLES); | ||
| 1142 | request_module("nft-expr-%.*s", | 1152 | request_module("nft-expr-%.*s", |
| 1143 | nla_len(nla), (char *)nla_data(nla)); | 1153 | nla_len(nla), (char *)nla_data(nla)); |
| 1144 | nfnl_lock(NFNL_SUBSYS_NFTABLES); | 1154 | nfnl_lock(NFNL_SUBSYS_NFTABLES); |
| 1145 | if (__nft_expr_type_get(nla)) | 1155 | if (__nft_expr_type_get(family, nla)) |
| 1146 | return ERR_PTR(-EAGAIN); | 1156 | return ERR_PTR(-EAGAIN); |
| 1147 | } | 1157 | } |
| 1148 | #endif | 1158 | #endif |
| @@ -1193,7 +1203,7 @@ static int nf_tables_expr_parse(const struct nft_ctx *ctx, | |||
| 1193 | if (err < 0) | 1203 | if (err < 0) |
| 1194 | return err; | 1204 | return err; |
| 1195 | 1205 | ||
| 1196 | type = nft_expr_type_get(tb[NFTA_EXPR_NAME]); | 1206 | type = nft_expr_type_get(ctx->afi->family, tb[NFTA_EXPR_NAME]); |
| 1197 | if (IS_ERR(type)) | 1207 | if (IS_ERR(type)) |
| 1198 | return PTR_ERR(type); | 1208 | return PTR_ERR(type); |
| 1199 | 1209 | ||
| @@ -1521,9 +1531,8 @@ err: | |||
| 1521 | return err; | 1531 | return err; |
| 1522 | } | 1532 | } |
| 1523 | 1533 | ||
| 1524 | static void nf_tables_rcu_rule_destroy(struct rcu_head *head) | 1534 | static void nf_tables_rule_destroy(struct nft_rule *rule) |
| 1525 | { | 1535 | { |
| 1526 | struct nft_rule *rule = container_of(head, struct nft_rule, rcu_head); | ||
| 1527 | struct nft_expr *expr; | 1536 | struct nft_expr *expr; |
| 1528 | 1537 | ||
| 1529 | /* | 1538 | /* |
| @@ -1538,11 +1547,6 @@ static void nf_tables_rcu_rule_destroy(struct rcu_head *head) | |||
| 1538 | kfree(rule); | 1547 | kfree(rule); |
| 1539 | } | 1548 | } |
| 1540 | 1549 | ||
| 1541 | static void nf_tables_rule_destroy(struct nft_rule *rule) | ||
| 1542 | { | ||
| 1543 | call_rcu(&rule->rcu_head, nf_tables_rcu_rule_destroy); | ||
| 1544 | } | ||
| 1545 | |||
| 1546 | #define NFT_RULE_MAXEXPRS 128 | 1550 | #define NFT_RULE_MAXEXPRS 128 |
| 1547 | 1551 | ||
| 1548 | static struct nft_expr_info *info; | 1552 | static struct nft_expr_info *info; |
| @@ -1809,9 +1813,6 @@ static int nf_tables_commit(struct sk_buff *skb) | |||
| 1809 | synchronize_rcu(); | 1813 | synchronize_rcu(); |
| 1810 | 1814 | ||
| 1811 | list_for_each_entry_safe(rupd, tmp, &net->nft.commit_list, list) { | 1815 | list_for_each_entry_safe(rupd, tmp, &net->nft.commit_list, list) { |
| 1812 | /* Delete this rule from the dirty list */ | ||
| 1813 | list_del(&rupd->list); | ||
| 1814 | |||
| 1815 | /* This rule was inactive in the past and just became active. | 1816 | /* This rule was inactive in the past and just became active. |
| 1816 | * Clear the next bit of the genmask since its meaning has | 1817 | * Clear the next bit of the genmask since its meaning has |
| 1817 | * changed, now it is the future. | 1818 | * changed, now it is the future. |
| @@ -1822,6 +1823,7 @@ static int nf_tables_commit(struct sk_buff *skb) | |||
| 1822 | rupd->chain, rupd->rule, | 1823 | rupd->chain, rupd->rule, |
| 1823 | NFT_MSG_NEWRULE, 0, | 1824 | NFT_MSG_NEWRULE, 0, |
| 1824 | rupd->family); | 1825 | rupd->family); |
| 1826 | list_del(&rupd->list); | ||
| 1825 | kfree(rupd); | 1827 | kfree(rupd); |
| 1826 | continue; | 1828 | continue; |
| 1827 | } | 1829 | } |
| @@ -1831,7 +1833,15 @@ static int nf_tables_commit(struct sk_buff *skb) | |||
| 1831 | nf_tables_rule_notify(skb, rupd->nlh, rupd->table, rupd->chain, | 1833 | nf_tables_rule_notify(skb, rupd->nlh, rupd->table, rupd->chain, |
| 1832 | rupd->rule, NFT_MSG_DELRULE, 0, | 1834 | rupd->rule, NFT_MSG_DELRULE, 0, |
| 1833 | rupd->family); | 1835 | rupd->family); |
| 1836 | } | ||
| 1837 | |||
| 1838 | /* Make sure we don't see any packet traversing old rules */ | ||
| 1839 | synchronize_rcu(); | ||
| 1840 | |||
| 1841 | /* Now we can safely release unused old rules */ | ||
| 1842 | list_for_each_entry_safe(rupd, tmp, &net->nft.commit_list, list) { | ||
| 1834 | nf_tables_rule_destroy(rupd->rule); | 1843 | nf_tables_rule_destroy(rupd->rule); |
| 1844 | list_del(&rupd->list); | ||
| 1835 | kfree(rupd); | 1845 | kfree(rupd); |
| 1836 | } | 1846 | } |
| 1837 | 1847 | ||
| @@ -1844,20 +1854,26 @@ static int nf_tables_abort(struct sk_buff *skb) | |||
| 1844 | struct nft_rule_trans *rupd, *tmp; | 1854 | struct nft_rule_trans *rupd, *tmp; |
| 1845 | 1855 | ||
| 1846 | list_for_each_entry_safe(rupd, tmp, &net->nft.commit_list, list) { | 1856 | list_for_each_entry_safe(rupd, tmp, &net->nft.commit_list, list) { |
| 1847 | /* Delete all rules from the dirty list */ | ||
| 1848 | list_del(&rupd->list); | ||
| 1849 | |||
| 1850 | if (!nft_rule_is_active_next(net, rupd->rule)) { | 1857 | if (!nft_rule_is_active_next(net, rupd->rule)) { |
| 1851 | nft_rule_clear(net, rupd->rule); | 1858 | nft_rule_clear(net, rupd->rule); |
| 1859 | list_del(&rupd->list); | ||
| 1852 | kfree(rupd); | 1860 | kfree(rupd); |
| 1853 | continue; | 1861 | continue; |
| 1854 | } | 1862 | } |
| 1855 | 1863 | ||
| 1856 | /* This rule is inactive, get rid of it */ | 1864 | /* This rule is inactive, get rid of it */ |
| 1857 | list_del_rcu(&rupd->rule->list); | 1865 | list_del_rcu(&rupd->rule->list); |
| 1866 | } | ||
| 1867 | |||
| 1868 | /* Make sure we don't see any packet accessing aborted rules */ | ||
| 1869 | synchronize_rcu(); | ||
| 1870 | |||
| 1871 | list_for_each_entry_safe(rupd, tmp, &net->nft.commit_list, list) { | ||
| 1858 | nf_tables_rule_destroy(rupd->rule); | 1872 | nf_tables_rule_destroy(rupd->rule); |
| 1873 | list_del(&rupd->list); | ||
| 1859 | kfree(rupd); | 1874 | kfree(rupd); |
| 1860 | } | 1875 | } |
| 1876 | |||
| 1861 | return 0; | 1877 | return 0; |
| 1862 | } | 1878 | } |
| 1863 | 1879 | ||
| @@ -1943,6 +1959,9 @@ static int nft_ctx_init_from_setattr(struct nft_ctx *ctx, | |||
| 1943 | } | 1959 | } |
| 1944 | 1960 | ||
| 1945 | if (nla[NFTA_SET_TABLE] != NULL) { | 1961 | if (nla[NFTA_SET_TABLE] != NULL) { |
| 1962 | if (afi == NULL) | ||
| 1963 | return -EAFNOSUPPORT; | ||
| 1964 | |||
| 1946 | table = nf_tables_table_lookup(afi, nla[NFTA_SET_TABLE]); | 1965 | table = nf_tables_table_lookup(afi, nla[NFTA_SET_TABLE]); |
| 1947 | if (IS_ERR(table)) | 1966 | if (IS_ERR(table)) |
| 1948 | return PTR_ERR(table); | 1967 | return PTR_ERR(table); |
| @@ -1989,13 +2008,13 @@ static int nf_tables_set_alloc_name(struct nft_ctx *ctx, struct nft_set *set, | |||
| 1989 | 2008 | ||
| 1990 | if (!sscanf(i->name, name, &tmp)) | 2009 | if (!sscanf(i->name, name, &tmp)) |
| 1991 | continue; | 2010 | continue; |
| 1992 | if (tmp < 0 || tmp > BITS_PER_LONG * PAGE_SIZE) | 2011 | if (tmp < 0 || tmp >= BITS_PER_BYTE * PAGE_SIZE) |
| 1993 | continue; | 2012 | continue; |
| 1994 | 2013 | ||
| 1995 | set_bit(tmp, inuse); | 2014 | set_bit(tmp, inuse); |
| 1996 | } | 2015 | } |
| 1997 | 2016 | ||
| 1998 | n = find_first_zero_bit(inuse, BITS_PER_LONG * PAGE_SIZE); | 2017 | n = find_first_zero_bit(inuse, BITS_PER_BYTE * PAGE_SIZE); |
| 1999 | free_page((unsigned long)inuse); | 2018 | free_page((unsigned long)inuse); |
| 2000 | } | 2019 | } |
| 2001 | 2020 | ||
| @@ -2428,6 +2447,8 @@ static int nf_tables_delset(struct sock *nlsk, struct sk_buff *skb, | |||
| 2428 | struct nft_ctx ctx; | 2447 | struct nft_ctx ctx; |
| 2429 | int err; | 2448 | int err; |
| 2430 | 2449 | ||
| 2450 | if (nfmsg->nfgen_family == NFPROTO_UNSPEC) | ||
| 2451 | return -EAFNOSUPPORT; | ||
| 2431 | if (nla[NFTA_SET_TABLE] == NULL) | 2452 | if (nla[NFTA_SET_TABLE] == NULL) |
| 2432 | return -EINVAL; | 2453 | return -EINVAL; |
| 2433 | 2454 | ||
| @@ -2435,9 +2456,6 @@ static int nf_tables_delset(struct sock *nlsk, struct sk_buff *skb, | |||
| 2435 | if (err < 0) | 2456 | if (err < 0) |
| 2436 | return err; | 2457 | return err; |
| 2437 | 2458 | ||
| 2438 | if (nfmsg->nfgen_family == NFPROTO_UNSPEC) | ||
| 2439 | return -EAFNOSUPPORT; | ||
| 2440 | |||
| 2441 | set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_NAME]); | 2459 | set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_NAME]); |
| 2442 | if (IS_ERR(set)) | 2460 | if (IS_ERR(set)) |
| 2443 | return PTR_ERR(set); | 2461 | return PTR_ERR(set); |
| @@ -2723,6 +2741,9 @@ static int nft_add_set_elem(const struct nft_ctx *ctx, struct nft_set *set, | |||
| 2723 | if (nla[NFTA_SET_ELEM_DATA] == NULL && | 2741 | if (nla[NFTA_SET_ELEM_DATA] == NULL && |
| 2724 | !(elem.flags & NFT_SET_ELEM_INTERVAL_END)) | 2742 | !(elem.flags & NFT_SET_ELEM_INTERVAL_END)) |
| 2725 | return -EINVAL; | 2743 | return -EINVAL; |
| 2744 | if (nla[NFTA_SET_ELEM_DATA] != NULL && | ||
| 2745 | elem.flags & NFT_SET_ELEM_INTERVAL_END) | ||
| 2746 | return -EINVAL; | ||
| 2726 | } else { | 2747 | } else { |
| 2727 | if (nla[NFTA_SET_ELEM_DATA] != NULL) | 2748 | if (nla[NFTA_SET_ELEM_DATA] != NULL) |
| 2728 | return -EINVAL; | 2749 | return -EINVAL; |
| @@ -2977,6 +2998,9 @@ static int nf_tables_loop_check_setelem(const struct nft_ctx *ctx, | |||
| 2977 | const struct nft_set_iter *iter, | 2998 | const struct nft_set_iter *iter, |
| 2978 | const struct nft_set_elem *elem) | 2999 | const struct nft_set_elem *elem) |
| 2979 | { | 3000 | { |
| 3001 | if (elem->flags & NFT_SET_ELEM_INTERVAL_END) | ||
| 3002 | return 0; | ||
| 3003 | |||
| 2980 | switch (elem->data.verdict) { | 3004 | switch (elem->data.verdict) { |
| 2981 | case NFT_JUMP: | 3005 | case NFT_JUMP: |
| 2982 | case NFT_GOTO: | 3006 | case NFT_GOTO: |
diff --git a/net/netfilter/nf_tables_core.c b/net/netfilter/nf_tables_core.c index 0d879fcb8763..90998a6ff8b9 100644 --- a/net/netfilter/nf_tables_core.c +++ b/net/netfilter/nf_tables_core.c | |||
| @@ -103,9 +103,9 @@ static struct nf_loginfo trace_loginfo = { | |||
| 103 | }, | 103 | }, |
| 104 | }; | 104 | }; |
| 105 | 105 | ||
| 106 | static inline void nft_trace_packet(const struct nft_pktinfo *pkt, | 106 | static void nft_trace_packet(const struct nft_pktinfo *pkt, |
| 107 | const struct nft_chain *chain, | 107 | const struct nft_chain *chain, |
| 108 | int rulenum, enum nft_trace type) | 108 | int rulenum, enum nft_trace type) |
| 109 | { | 109 | { |
| 110 | struct net *net = dev_net(pkt->in ? pkt->in : pkt->out); | 110 | struct net *net = dev_net(pkt->in ? pkt->in : pkt->out); |
| 111 | 111 | ||
diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c index 917052e20602..46e275403838 100644 --- a/net/netfilter/nft_ct.c +++ b/net/netfilter/nft_ct.c | |||
| @@ -226,6 +226,7 @@ static int nft_ct_init_validate_get(const struct nft_expr *expr, | |||
| 226 | if (tb[NFTA_CT_DIRECTION] != NULL) | 226 | if (tb[NFTA_CT_DIRECTION] != NULL) |
| 227 | return -EINVAL; | 227 | return -EINVAL; |
| 228 | break; | 228 | break; |
| 229 | case NFT_CT_L3PROTOCOL: | ||
| 229 | case NFT_CT_PROTOCOL: | 230 | case NFT_CT_PROTOCOL: |
| 230 | case NFT_CT_SRC: | 231 | case NFT_CT_SRC: |
| 231 | case NFT_CT_DST: | 232 | case NFT_CT_DST: |
| @@ -311,8 +312,19 @@ static int nft_ct_get_dump(struct sk_buff *skb, const struct nft_expr *expr) | |||
| 311 | goto nla_put_failure; | 312 | goto nla_put_failure; |
| 312 | if (nla_put_be32(skb, NFTA_CT_KEY, htonl(priv->key))) | 313 | if (nla_put_be32(skb, NFTA_CT_KEY, htonl(priv->key))) |
| 313 | goto nla_put_failure; | 314 | goto nla_put_failure; |
| 314 | if (nla_put_u8(skb, NFTA_CT_DIRECTION, priv->dir)) | 315 | |
| 315 | goto nla_put_failure; | 316 | switch (priv->key) { |
| 317 | case NFT_CT_PROTOCOL: | ||
| 318 | case NFT_CT_SRC: | ||
| 319 | case NFT_CT_DST: | ||
| 320 | case NFT_CT_PROTO_SRC: | ||
| 321 | case NFT_CT_PROTO_DST: | ||
| 322 | if (nla_put_u8(skb, NFTA_CT_DIRECTION, priv->dir)) | ||
| 323 | goto nla_put_failure; | ||
| 324 | default: | ||
| 325 | break; | ||
| 326 | } | ||
| 327 | |||
| 316 | return 0; | 328 | return 0; |
| 317 | 329 | ||
| 318 | nla_put_failure: | 330 | nla_put_failure: |
diff --git a/net/netfilter/nft_log.c b/net/netfilter/nft_log.c index 5af790123ad8..26c5154e05f3 100644 --- a/net/netfilter/nft_log.c +++ b/net/netfilter/nft_log.c | |||
| @@ -23,7 +23,6 @@ static const char *nft_log_null_prefix = ""; | |||
| 23 | struct nft_log { | 23 | struct nft_log { |
| 24 | struct nf_loginfo loginfo; | 24 | struct nf_loginfo loginfo; |
| 25 | char *prefix; | 25 | char *prefix; |
| 26 | int family; | ||
| 27 | }; | 26 | }; |
| 28 | 27 | ||
| 29 | static void nft_log_eval(const struct nft_expr *expr, | 28 | static void nft_log_eval(const struct nft_expr *expr, |
| @@ -33,7 +32,7 @@ static void nft_log_eval(const struct nft_expr *expr, | |||
| 33 | const struct nft_log *priv = nft_expr_priv(expr); | 32 | const struct nft_log *priv = nft_expr_priv(expr); |
| 34 | struct net *net = dev_net(pkt->in ? pkt->in : pkt->out); | 33 | struct net *net = dev_net(pkt->in ? pkt->in : pkt->out); |
| 35 | 34 | ||
| 36 | nf_log_packet(net, priv->family, pkt->ops->hooknum, pkt->skb, pkt->in, | 35 | nf_log_packet(net, pkt->ops->pf, pkt->ops->hooknum, pkt->skb, pkt->in, |
| 37 | pkt->out, &priv->loginfo, "%s", priv->prefix); | 36 | pkt->out, &priv->loginfo, "%s", priv->prefix); |
| 38 | } | 37 | } |
| 39 | 38 | ||
| @@ -52,8 +51,6 @@ static int nft_log_init(const struct nft_ctx *ctx, | |||
| 52 | struct nf_loginfo *li = &priv->loginfo; | 51 | struct nf_loginfo *li = &priv->loginfo; |
| 53 | const struct nlattr *nla; | 52 | const struct nlattr *nla; |
| 54 | 53 | ||
| 55 | priv->family = ctx->afi->family; | ||
| 56 | |||
| 57 | nla = tb[NFTA_LOG_PREFIX]; | 54 | nla = tb[NFTA_LOG_PREFIX]; |
| 58 | if (nla != NULL) { | 55 | if (nla != NULL) { |
| 59 | priv->prefix = kmalloc(nla_len(nla) + 1, GFP_KERNEL); | 56 | priv->prefix = kmalloc(nla_len(nla) + 1, GFP_KERNEL); |
diff --git a/net/netfilter/nft_lookup.c b/net/netfilter/nft_lookup.c index 8a6116b75b5a..bb4ef4cccb6e 100644 --- a/net/netfilter/nft_lookup.c +++ b/net/netfilter/nft_lookup.c | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | #include <linux/netfilter.h> | 16 | #include <linux/netfilter.h> |
| 17 | #include <linux/netfilter/nf_tables.h> | 17 | #include <linux/netfilter/nf_tables.h> |
| 18 | #include <net/netfilter/nf_tables.h> | 18 | #include <net/netfilter/nf_tables.h> |
| 19 | #include <net/netfilter/nf_tables_core.h> | ||
| 19 | 20 | ||
| 20 | struct nft_lookup { | 21 | struct nft_lookup { |
| 21 | struct nft_set *set; | 22 | struct nft_set *set; |
diff --git a/net/netfilter/nft_queue.c b/net/netfilter/nft_queue.c index cbea473d69e9..e8ae2f6bf232 100644 --- a/net/netfilter/nft_queue.c +++ b/net/netfilter/nft_queue.c | |||
| @@ -25,7 +25,6 @@ struct nft_queue { | |||
| 25 | u16 queuenum; | 25 | u16 queuenum; |
| 26 | u16 queues_total; | 26 | u16 queues_total; |
| 27 | u16 flags; | 27 | u16 flags; |
| 28 | u8 family; | ||
| 29 | }; | 28 | }; |
| 30 | 29 | ||
| 31 | static void nft_queue_eval(const struct nft_expr *expr, | 30 | static void nft_queue_eval(const struct nft_expr *expr, |
| @@ -43,7 +42,7 @@ static void nft_queue_eval(const struct nft_expr *expr, | |||
| 43 | queue = priv->queuenum + cpu % priv->queues_total; | 42 | queue = priv->queuenum + cpu % priv->queues_total; |
| 44 | } else { | 43 | } else { |
| 45 | queue = nfqueue_hash(pkt->skb, queue, | 44 | queue = nfqueue_hash(pkt->skb, queue, |
| 46 | priv->queues_total, priv->family, | 45 | priv->queues_total, pkt->ops->pf, |
| 47 | jhash_initval); | 46 | jhash_initval); |
| 48 | } | 47 | } |
| 49 | } | 48 | } |
| @@ -71,7 +70,6 @@ static int nft_queue_init(const struct nft_ctx *ctx, | |||
| 71 | return -EINVAL; | 70 | return -EINVAL; |
| 72 | 71 | ||
| 73 | init_hashrandom(&jhash_initval); | 72 | init_hashrandom(&jhash_initval); |
| 74 | priv->family = ctx->afi->family; | ||
| 75 | priv->queuenum = ntohs(nla_get_be16(tb[NFTA_QUEUE_NUM])); | 73 | priv->queuenum = ntohs(nla_get_be16(tb[NFTA_QUEUE_NUM])); |
| 76 | 74 | ||
| 77 | if (tb[NFTA_QUEUE_TOTAL] != NULL) | 75 | if (tb[NFTA_QUEUE_TOTAL] != NULL) |
diff --git a/net/netfilter/nft_rbtree.c b/net/netfilter/nft_rbtree.c index ca0c1b231bfe..e21d69d13506 100644 --- a/net/netfilter/nft_rbtree.c +++ b/net/netfilter/nft_rbtree.c | |||
| @@ -69,8 +69,10 @@ static void nft_rbtree_elem_destroy(const struct nft_set *set, | |||
| 69 | struct nft_rbtree_elem *rbe) | 69 | struct nft_rbtree_elem *rbe) |
| 70 | { | 70 | { |
| 71 | nft_data_uninit(&rbe->key, NFT_DATA_VALUE); | 71 | nft_data_uninit(&rbe->key, NFT_DATA_VALUE); |
| 72 | if (set->flags & NFT_SET_MAP) | 72 | if (set->flags & NFT_SET_MAP && |
| 73 | !(rbe->flags & NFT_SET_ELEM_INTERVAL_END)) | ||
| 73 | nft_data_uninit(rbe->data, set->dtype); | 74 | nft_data_uninit(rbe->data, set->dtype); |
| 75 | |||
| 74 | kfree(rbe); | 76 | kfree(rbe); |
| 75 | } | 77 | } |
| 76 | 78 | ||
| @@ -108,7 +110,8 @@ static int nft_rbtree_insert(const struct nft_set *set, | |||
| 108 | int err; | 110 | int err; |
| 109 | 111 | ||
| 110 | size = sizeof(*rbe); | 112 | size = sizeof(*rbe); |
| 111 | if (set->flags & NFT_SET_MAP) | 113 | if (set->flags & NFT_SET_MAP && |
| 114 | !(elem->flags & NFT_SET_ELEM_INTERVAL_END)) | ||
| 112 | size += sizeof(rbe->data[0]); | 115 | size += sizeof(rbe->data[0]); |
| 113 | 116 | ||
| 114 | rbe = kzalloc(size, GFP_KERNEL); | 117 | rbe = kzalloc(size, GFP_KERNEL); |
| @@ -117,7 +120,8 @@ static int nft_rbtree_insert(const struct nft_set *set, | |||
| 117 | 120 | ||
| 118 | rbe->flags = elem->flags; | 121 | rbe->flags = elem->flags; |
| 119 | nft_data_copy(&rbe->key, &elem->key); | 122 | nft_data_copy(&rbe->key, &elem->key); |
| 120 | if (set->flags & NFT_SET_MAP) | 123 | if (set->flags & NFT_SET_MAP && |
| 124 | !(rbe->flags & NFT_SET_ELEM_INTERVAL_END)) | ||
| 121 | nft_data_copy(rbe->data, &elem->data); | 125 | nft_data_copy(rbe->data, &elem->data); |
| 122 | 126 | ||
| 123 | err = __nft_rbtree_insert(set, rbe); | 127 | err = __nft_rbtree_insert(set, rbe); |
| @@ -153,7 +157,8 @@ static int nft_rbtree_get(const struct nft_set *set, struct nft_set_elem *elem) | |||
| 153 | parent = parent->rb_right; | 157 | parent = parent->rb_right; |
| 154 | else { | 158 | else { |
| 155 | elem->cookie = rbe; | 159 | elem->cookie = rbe; |
| 156 | if (set->flags & NFT_SET_MAP) | 160 | if (set->flags & NFT_SET_MAP && |
| 161 | !(rbe->flags & NFT_SET_ELEM_INTERVAL_END)) | ||
| 157 | nft_data_copy(&elem->data, rbe->data); | 162 | nft_data_copy(&elem->data, rbe->data); |
| 158 | elem->flags = rbe->flags; | 163 | elem->flags = rbe->flags; |
| 159 | return 0; | 164 | return 0; |
| @@ -177,7 +182,8 @@ static void nft_rbtree_walk(const struct nft_ctx *ctx, | |||
| 177 | 182 | ||
| 178 | rbe = rb_entry(node, struct nft_rbtree_elem, node); | 183 | rbe = rb_entry(node, struct nft_rbtree_elem, node); |
| 179 | nft_data_copy(&elem.key, &rbe->key); | 184 | nft_data_copy(&elem.key, &rbe->key); |
| 180 | if (set->flags & NFT_SET_MAP) | 185 | if (set->flags & NFT_SET_MAP && |
| 186 | !(rbe->flags & NFT_SET_ELEM_INTERVAL_END)) | ||
| 181 | nft_data_copy(&elem.data, rbe->data); | 187 | nft_data_copy(&elem.data, rbe->data); |
| 182 | elem.flags = rbe->flags; | 188 | elem.flags = rbe->flags; |
| 183 | 189 | ||
diff --git a/net/netfilter/nft_reject.c b/net/netfilter/nft_reject.c index 5e204711d704..f3448c296446 100644 --- a/net/netfilter/nft_reject.c +++ b/net/netfilter/nft_reject.c | |||
| @@ -16,65 +16,23 @@ | |||
| 16 | #include <linux/netfilter.h> | 16 | #include <linux/netfilter.h> |
| 17 | #include <linux/netfilter/nf_tables.h> | 17 | #include <linux/netfilter/nf_tables.h> |
| 18 | #include <net/netfilter/nf_tables.h> | 18 | #include <net/netfilter/nf_tables.h> |
| 19 | #include <net/icmp.h> | 19 | #include <net/netfilter/nft_reject.h> |
| 20 | #include <net/netfilter/ipv4/nf_reject.h> | ||
| 21 | 20 | ||
| 22 | #if IS_ENABLED(CONFIG_NF_TABLES_IPV6) | 21 | const struct nla_policy nft_reject_policy[NFTA_REJECT_MAX + 1] = { |
| 23 | #include <net/netfilter/ipv6/nf_reject.h> | ||
| 24 | #endif | ||
| 25 | |||
| 26 | struct nft_reject { | ||
| 27 | enum nft_reject_types type:8; | ||
| 28 | u8 icmp_code; | ||
| 29 | u8 family; | ||
| 30 | }; | ||
| 31 | |||
| 32 | static void nft_reject_eval(const struct nft_expr *expr, | ||
| 33 | struct nft_data data[NFT_REG_MAX + 1], | ||
| 34 | const struct nft_pktinfo *pkt) | ||
| 35 | { | ||
| 36 | struct nft_reject *priv = nft_expr_priv(expr); | ||
| 37 | #if IS_ENABLED(CONFIG_NF_TABLES_IPV6) | ||
| 38 | struct net *net = dev_net((pkt->in != NULL) ? pkt->in : pkt->out); | ||
| 39 | #endif | ||
| 40 | switch (priv->type) { | ||
| 41 | case NFT_REJECT_ICMP_UNREACH: | ||
| 42 | if (priv->family == NFPROTO_IPV4) | ||
| 43 | nf_send_unreach(pkt->skb, priv->icmp_code); | ||
| 44 | #if IS_ENABLED(CONFIG_NF_TABLES_IPV6) | ||
| 45 | else if (priv->family == NFPROTO_IPV6) | ||
| 46 | nf_send_unreach6(net, pkt->skb, priv->icmp_code, | ||
| 47 | pkt->ops->hooknum); | ||
| 48 | #endif | ||
| 49 | break; | ||
| 50 | case NFT_REJECT_TCP_RST: | ||
| 51 | if (priv->family == NFPROTO_IPV4) | ||
| 52 | nf_send_reset(pkt->skb, pkt->ops->hooknum); | ||
| 53 | #if IS_ENABLED(CONFIG_NF_TABLES_IPV6) | ||
| 54 | else if (priv->family == NFPROTO_IPV6) | ||
| 55 | nf_send_reset6(net, pkt->skb, pkt->ops->hooknum); | ||
| 56 | #endif | ||
| 57 | break; | ||
| 58 | } | ||
| 59 | |||
| 60 | data[NFT_REG_VERDICT].verdict = NF_DROP; | ||
| 61 | } | ||
| 62 | |||
| 63 | static const struct nla_policy nft_reject_policy[NFTA_REJECT_MAX + 1] = { | ||
| 64 | [NFTA_REJECT_TYPE] = { .type = NLA_U32 }, | 22 | [NFTA_REJECT_TYPE] = { .type = NLA_U32 }, |
| 65 | [NFTA_REJECT_ICMP_CODE] = { .type = NLA_U8 }, | 23 | [NFTA_REJECT_ICMP_CODE] = { .type = NLA_U8 }, |
| 66 | }; | 24 | }; |
| 25 | EXPORT_SYMBOL_GPL(nft_reject_policy); | ||
| 67 | 26 | ||
| 68 | static int nft_reject_init(const struct nft_ctx *ctx, | 27 | int nft_reject_init(const struct nft_ctx *ctx, |
| 69 | const struct nft_expr *expr, | 28 | const struct nft_expr *expr, |
| 70 | const struct nlattr * const tb[]) | 29 | const struct nlattr * const tb[]) |
| 71 | { | 30 | { |
| 72 | struct nft_reject *priv = nft_expr_priv(expr); | 31 | struct nft_reject *priv = nft_expr_priv(expr); |
| 73 | 32 | ||
| 74 | if (tb[NFTA_REJECT_TYPE] == NULL) | 33 | if (tb[NFTA_REJECT_TYPE] == NULL) |
| 75 | return -EINVAL; | 34 | return -EINVAL; |
| 76 | 35 | ||
| 77 | priv->family = ctx->afi->family; | ||
| 78 | priv->type = ntohl(nla_get_be32(tb[NFTA_REJECT_TYPE])); | 36 | priv->type = ntohl(nla_get_be32(tb[NFTA_REJECT_TYPE])); |
| 79 | switch (priv->type) { | 37 | switch (priv->type) { |
| 80 | case NFT_REJECT_ICMP_UNREACH: | 38 | case NFT_REJECT_ICMP_UNREACH: |
| @@ -89,8 +47,9 @@ static int nft_reject_init(const struct nft_ctx *ctx, | |||
| 89 | 47 | ||
| 90 | return 0; | 48 | return 0; |
| 91 | } | 49 | } |
| 50 | EXPORT_SYMBOL_GPL(nft_reject_init); | ||
| 92 | 51 | ||
| 93 | static int nft_reject_dump(struct sk_buff *skb, const struct nft_expr *expr) | 52 | int nft_reject_dump(struct sk_buff *skb, const struct nft_expr *expr) |
| 94 | { | 53 | { |
| 95 | const struct nft_reject *priv = nft_expr_priv(expr); | 54 | const struct nft_reject *priv = nft_expr_priv(expr); |
| 96 | 55 | ||
| @@ -109,37 +68,7 @@ static int nft_reject_dump(struct sk_buff *skb, const struct nft_expr *expr) | |||
| 109 | nla_put_failure: | 68 | nla_put_failure: |
| 110 | return -1; | 69 | return -1; |
| 111 | } | 70 | } |
| 112 | 71 | EXPORT_SYMBOL_GPL(nft_reject_dump); | |
| 113 | static struct nft_expr_type nft_reject_type; | ||
| 114 | static const struct nft_expr_ops nft_reject_ops = { | ||
| 115 | .type = &nft_reject_type, | ||
| 116 | .size = NFT_EXPR_SIZE(sizeof(struct nft_reject)), | ||
| 117 | .eval = nft_reject_eval, | ||
| 118 | .init = nft_reject_init, | ||
| 119 | .dump = nft_reject_dump, | ||
| 120 | }; | ||
| 121 | |||
| 122 | static struct nft_expr_type nft_reject_type __read_mostly = { | ||
| 123 | .name = "reject", | ||
| 124 | .ops = &nft_reject_ops, | ||
| 125 | .policy = nft_reject_policy, | ||
| 126 | .maxattr = NFTA_REJECT_MAX, | ||
| 127 | .owner = THIS_MODULE, | ||
| 128 | }; | ||
| 129 | |||
| 130 | static int __init nft_reject_module_init(void) | ||
| 131 | { | ||
| 132 | return nft_register_expr(&nft_reject_type); | ||
| 133 | } | ||
| 134 | |||
| 135 | static void __exit nft_reject_module_exit(void) | ||
| 136 | { | ||
| 137 | nft_unregister_expr(&nft_reject_type); | ||
| 138 | } | ||
| 139 | |||
| 140 | module_init(nft_reject_module_init); | ||
| 141 | module_exit(nft_reject_module_exit); | ||
| 142 | 72 | ||
| 143 | MODULE_LICENSE("GPL"); | 73 | MODULE_LICENSE("GPL"); |
| 144 | MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); | 74 | MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); |
| 145 | MODULE_ALIAS_NFT_EXPR("reject"); | ||
diff --git a/net/netfilter/nft_reject_inet.c b/net/netfilter/nft_reject_inet.c new file mode 100644 index 000000000000..8a310f239c93 --- /dev/null +++ b/net/netfilter/nft_reject_inet.c | |||
| @@ -0,0 +1,63 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2014 Patrick McHardy <kaber@trash.net> | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License version 2 as | ||
| 6 | * published by the Free Software Foundation. | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <linux/kernel.h> | ||
| 10 | #include <linux/init.h> | ||
| 11 | #include <linux/module.h> | ||
| 12 | #include <linux/netlink.h> | ||
| 13 | #include <linux/netfilter.h> | ||
| 14 | #include <linux/netfilter/nf_tables.h> | ||
| 15 | #include <net/netfilter/nf_tables.h> | ||
| 16 | #include <net/netfilter/nft_reject.h> | ||
| 17 | |||
| 18 | static void nft_reject_inet_eval(const struct nft_expr *expr, | ||
| 19 | struct nft_data data[NFT_REG_MAX + 1], | ||
| 20 | const struct nft_pktinfo *pkt) | ||
| 21 | { | ||
| 22 | switch (pkt->ops->pf) { | ||
| 23 | case NFPROTO_IPV4: | ||
| 24 | nft_reject_ipv4_eval(expr, data, pkt); | ||
| 25 | case NFPROTO_IPV6: | ||
| 26 | nft_reject_ipv6_eval(expr, data, pkt); | ||
| 27 | } | ||
| 28 | } | ||
| 29 | |||
| 30 | static struct nft_expr_type nft_reject_inet_type; | ||
| 31 | static const struct nft_expr_ops nft_reject_inet_ops = { | ||
| 32 | .type = &nft_reject_inet_type, | ||
| 33 | .size = NFT_EXPR_SIZE(sizeof(struct nft_reject)), | ||
| 34 | .eval = nft_reject_inet_eval, | ||
| 35 | .init = nft_reject_init, | ||
| 36 | .dump = nft_reject_dump, | ||
| 37 | }; | ||
| 38 | |||
| 39 | static struct nft_expr_type nft_reject_inet_type __read_mostly = { | ||
| 40 | .family = NFPROTO_INET, | ||
| 41 | .name = "reject", | ||
| 42 | .ops = &nft_reject_inet_ops, | ||
| 43 | .policy = nft_reject_policy, | ||
| 44 | .maxattr = NFTA_REJECT_MAX, | ||
| 45 | .owner = THIS_MODULE, | ||
| 46 | }; | ||
| 47 | |||
| 48 | static int __init nft_reject_inet_module_init(void) | ||
| 49 | { | ||
| 50 | return nft_register_expr(&nft_reject_inet_type); | ||
| 51 | } | ||
| 52 | |||
| 53 | static void __exit nft_reject_inet_module_exit(void) | ||
| 54 | { | ||
| 55 | nft_unregister_expr(&nft_reject_inet_type); | ||
| 56 | } | ||
| 57 | |||
| 58 | module_init(nft_reject_inet_module_init); | ||
| 59 | module_exit(nft_reject_inet_module_exit); | ||
| 60 | |||
| 61 | MODULE_LICENSE("GPL"); | ||
| 62 | MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); | ||
| 63 | MODULE_ALIAS_NFT_AF_EXPR(1, "reject"); | ||
diff --git a/net/netfilter/xt_CT.c b/net/netfilter/xt_CT.c index 5929be622c5c..75747aecdebe 100644 --- a/net/netfilter/xt_CT.c +++ b/net/netfilter/xt_CT.c | |||
| @@ -228,12 +228,7 @@ static int xt_ct_tg_check(const struct xt_tgchk_param *par, | |||
| 228 | goto err3; | 228 | goto err3; |
| 229 | } | 229 | } |
| 230 | 230 | ||
| 231 | __set_bit(IPS_TEMPLATE_BIT, &ct->status); | 231 | nf_conntrack_tmpl_insert(par->net, ct); |
| 232 | __set_bit(IPS_CONFIRMED_BIT, &ct->status); | ||
| 233 | |||
| 234 | /* Overload tuple linked list to put us in template list. */ | ||
| 235 | hlist_nulls_add_head_rcu(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode, | ||
| 236 | &par->net->ct.tmpl); | ||
| 237 | out: | 232 | out: |
| 238 | info->ct = ct; | 233 | info->ct = ct; |
| 239 | return 0; | 234 | return 0; |
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index df4692826ead..e9a48baf8551 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c | |||
| @@ -55,6 +55,7 @@ | |||
| 55 | 55 | ||
| 56 | #include "datapath.h" | 56 | #include "datapath.h" |
| 57 | #include "flow.h" | 57 | #include "flow.h" |
| 58 | #include "flow_table.h" | ||
| 58 | #include "flow_netlink.h" | 59 | #include "flow_netlink.h" |
| 59 | #include "vport-internal_dev.h" | 60 | #include "vport-internal_dev.h" |
| 60 | #include "vport-netdev.h" | 61 | #include "vport-netdev.h" |
| @@ -160,7 +161,6 @@ static void destroy_dp_rcu(struct rcu_head *rcu) | |||
| 160 | { | 161 | { |
| 161 | struct datapath *dp = container_of(rcu, struct datapath, rcu); | 162 | struct datapath *dp = container_of(rcu, struct datapath, rcu); |
| 162 | 163 | ||
| 163 | ovs_flow_tbl_destroy(&dp->table); | ||
| 164 | free_percpu(dp->stats_percpu); | 164 | free_percpu(dp->stats_percpu); |
| 165 | release_net(ovs_dp_get_net(dp)); | 165 | release_net(ovs_dp_get_net(dp)); |
| 166 | kfree(dp->ports); | 166 | kfree(dp->ports); |
| @@ -466,6 +466,14 @@ static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb, | |||
| 466 | 466 | ||
| 467 | skb_zerocopy(user_skb, skb, skb->len, hlen); | 467 | skb_zerocopy(user_skb, skb, skb->len, hlen); |
| 468 | 468 | ||
| 469 | /* Pad OVS_PACKET_ATTR_PACKET if linear copy was performed */ | ||
| 470 | if (!(dp->user_features & OVS_DP_F_UNALIGNED)) { | ||
| 471 | size_t plen = NLA_ALIGN(user_skb->len) - user_skb->len; | ||
| 472 | |||
| 473 | if (plen > 0) | ||
| 474 | memset(skb_put(user_skb, plen), 0, plen); | ||
| 475 | } | ||
| 476 | |||
| 469 | ((struct nlmsghdr *) user_skb->data)->nlmsg_len = user_skb->len; | 477 | ((struct nlmsghdr *) user_skb->data)->nlmsg_len = user_skb->len; |
| 470 | 478 | ||
| 471 | err = genlmsg_unicast(ovs_dp_get_net(dp), user_skb, upcall_info->portid); | 479 | err = genlmsg_unicast(ovs_dp_get_net(dp), user_skb, upcall_info->portid); |
| @@ -852,11 +860,8 @@ static int ovs_flow_cmd_new_or_set(struct sk_buff *skb, struct genl_info *info) | |||
| 852 | goto err_unlock_ovs; | 860 | goto err_unlock_ovs; |
| 853 | 861 | ||
| 854 | /* The unmasked key has to be the same for flow updates. */ | 862 | /* The unmasked key has to be the same for flow updates. */ |
| 855 | error = -EINVAL; | 863 | if (!ovs_flow_cmp_unmasked_key(flow, &match)) |
| 856 | if (!ovs_flow_cmp_unmasked_key(flow, &match)) { | ||
| 857 | OVS_NLERR("Flow modification message rejected, unmasked key does not match.\n"); | ||
| 858 | goto err_unlock_ovs; | 864 | goto err_unlock_ovs; |
| 859 | } | ||
| 860 | 865 | ||
| 861 | /* Update actions. */ | 866 | /* Update actions. */ |
| 862 | old_acts = ovsl_dereference(flow->sf_acts); | 867 | old_acts = ovsl_dereference(flow->sf_acts); |
| @@ -1079,6 +1084,7 @@ static size_t ovs_dp_cmd_msg_size(void) | |||
| 1079 | msgsize += nla_total_size(IFNAMSIZ); | 1084 | msgsize += nla_total_size(IFNAMSIZ); |
| 1080 | msgsize += nla_total_size(sizeof(struct ovs_dp_stats)); | 1085 | msgsize += nla_total_size(sizeof(struct ovs_dp_stats)); |
| 1081 | msgsize += nla_total_size(sizeof(struct ovs_dp_megaflow_stats)); | 1086 | msgsize += nla_total_size(sizeof(struct ovs_dp_megaflow_stats)); |
| 1087 | msgsize += nla_total_size(sizeof(u32)); /* OVS_DP_ATTR_USER_FEATURES */ | ||
| 1082 | 1088 | ||
| 1083 | return msgsize; | 1089 | return msgsize; |
| 1084 | } | 1090 | } |
| @@ -1279,7 +1285,7 @@ err_destroy_ports_array: | |||
| 1279 | err_destroy_percpu: | 1285 | err_destroy_percpu: |
| 1280 | free_percpu(dp->stats_percpu); | 1286 | free_percpu(dp->stats_percpu); |
| 1281 | err_destroy_table: | 1287 | err_destroy_table: |
| 1282 | ovs_flow_tbl_destroy(&dp->table); | 1288 | ovs_flow_tbl_destroy(&dp->table, false); |
| 1283 | err_free_dp: | 1289 | err_free_dp: |
| 1284 | release_net(ovs_dp_get_net(dp)); | 1290 | release_net(ovs_dp_get_net(dp)); |
| 1285 | kfree(dp); | 1291 | kfree(dp); |
| @@ -1306,10 +1312,13 @@ static void __dp_destroy(struct datapath *dp) | |||
| 1306 | list_del_rcu(&dp->list_node); | 1312 | list_del_rcu(&dp->list_node); |
| 1307 | 1313 | ||
| 1308 | /* OVSP_LOCAL is datapath internal port. We need to make sure that | 1314 | /* OVSP_LOCAL is datapath internal port. We need to make sure that |
| 1309 | * all port in datapath are destroyed first before freeing datapath. | 1315 | * all ports in datapath are destroyed first before freeing datapath. |
| 1310 | */ | 1316 | */ |
| 1311 | ovs_dp_detach_port(ovs_vport_ovsl(dp, OVSP_LOCAL)); | 1317 | ovs_dp_detach_port(ovs_vport_ovsl(dp, OVSP_LOCAL)); |
| 1312 | 1318 | ||
| 1319 | /* RCU destroy the flow table */ | ||
| 1320 | ovs_flow_tbl_destroy(&dp->table, true); | ||
| 1321 | |||
| 1313 | call_rcu(&dp->rcu, destroy_dp_rcu); | 1322 | call_rcu(&dp->rcu, destroy_dp_rcu); |
| 1314 | } | 1323 | } |
| 1315 | 1324 | ||
diff --git a/net/openvswitch/flow_table.c b/net/openvswitch/flow_table.c index c58a0fe3c889..3c268b3d71c3 100644 --- a/net/openvswitch/flow_table.c +++ b/net/openvswitch/flow_table.c | |||
| @@ -153,29 +153,29 @@ static void rcu_free_flow_callback(struct rcu_head *rcu) | |||
| 153 | flow_free(flow); | 153 | flow_free(flow); |
| 154 | } | 154 | } |
| 155 | 155 | ||
| 156 | static void flow_mask_del_ref(struct sw_flow_mask *mask, bool deferred) | ||
| 157 | { | ||
| 158 | if (!mask) | ||
| 159 | return; | ||
| 160 | |||
| 161 | BUG_ON(!mask->ref_count); | ||
| 162 | mask->ref_count--; | ||
| 163 | |||
| 164 | if (!mask->ref_count) { | ||
| 165 | list_del_rcu(&mask->list); | ||
| 166 | if (deferred) | ||
| 167 | kfree_rcu(mask, rcu); | ||
| 168 | else | ||
| 169 | kfree(mask); | ||
| 170 | } | ||
| 171 | } | ||
| 172 | |||
| 173 | void ovs_flow_free(struct sw_flow *flow, bool deferred) | 156 | void ovs_flow_free(struct sw_flow *flow, bool deferred) |
| 174 | { | 157 | { |
| 175 | if (!flow) | 158 | if (!flow) |
| 176 | return; | 159 | return; |
| 177 | 160 | ||
| 178 | flow_mask_del_ref(flow->mask, deferred); | 161 | if (flow->mask) { |
| 162 | struct sw_flow_mask *mask = flow->mask; | ||
| 163 | |||
| 164 | /* ovs-lock is required to protect mask-refcount and | ||
| 165 | * mask list. | ||
| 166 | */ | ||
| 167 | ASSERT_OVSL(); | ||
| 168 | BUG_ON(!mask->ref_count); | ||
| 169 | mask->ref_count--; | ||
| 170 | |||
| 171 | if (!mask->ref_count) { | ||
| 172 | list_del_rcu(&mask->list); | ||
| 173 | if (deferred) | ||
| 174 | kfree_rcu(mask, rcu); | ||
| 175 | else | ||
| 176 | kfree(mask); | ||
| 177 | } | ||
| 178 | } | ||
| 179 | 179 | ||
| 180 | if (deferred) | 180 | if (deferred) |
| 181 | call_rcu(&flow->rcu, rcu_free_flow_callback); | 181 | call_rcu(&flow->rcu, rcu_free_flow_callback); |
| @@ -188,26 +188,9 @@ static void free_buckets(struct flex_array *buckets) | |||
| 188 | flex_array_free(buckets); | 188 | flex_array_free(buckets); |
| 189 | } | 189 | } |
| 190 | 190 | ||
| 191 | |||
| 191 | static void __table_instance_destroy(struct table_instance *ti) | 192 | static void __table_instance_destroy(struct table_instance *ti) |
| 192 | { | 193 | { |
| 193 | int i; | ||
| 194 | |||
| 195 | if (ti->keep_flows) | ||
| 196 | goto skip_flows; | ||
| 197 | |||
| 198 | for (i = 0; i < ti->n_buckets; i++) { | ||
| 199 | struct sw_flow *flow; | ||
| 200 | struct hlist_head *head = flex_array_get(ti->buckets, i); | ||
| 201 | struct hlist_node *n; | ||
| 202 | int ver = ti->node_ver; | ||
| 203 | |||
| 204 | hlist_for_each_entry_safe(flow, n, head, hash_node[ver]) { | ||
| 205 | hlist_del(&flow->hash_node[ver]); | ||
| 206 | ovs_flow_free(flow, false); | ||
| 207 | } | ||
| 208 | } | ||
| 209 | |||
| 210 | skip_flows: | ||
| 211 | free_buckets(ti->buckets); | 194 | free_buckets(ti->buckets); |
| 212 | kfree(ti); | 195 | kfree(ti); |
| 213 | } | 196 | } |
| @@ -258,20 +241,38 @@ static void flow_tbl_destroy_rcu_cb(struct rcu_head *rcu) | |||
| 258 | 241 | ||
| 259 | static void table_instance_destroy(struct table_instance *ti, bool deferred) | 242 | static void table_instance_destroy(struct table_instance *ti, bool deferred) |
| 260 | { | 243 | { |
| 244 | int i; | ||
| 245 | |||
| 261 | if (!ti) | 246 | if (!ti) |
| 262 | return; | 247 | return; |
| 263 | 248 | ||
| 249 | if (ti->keep_flows) | ||
| 250 | goto skip_flows; | ||
| 251 | |||
| 252 | for (i = 0; i < ti->n_buckets; i++) { | ||
| 253 | struct sw_flow *flow; | ||
| 254 | struct hlist_head *head = flex_array_get(ti->buckets, i); | ||
| 255 | struct hlist_node *n; | ||
| 256 | int ver = ti->node_ver; | ||
| 257 | |||
| 258 | hlist_for_each_entry_safe(flow, n, head, hash_node[ver]) { | ||
| 259 | hlist_del_rcu(&flow->hash_node[ver]); | ||
| 260 | ovs_flow_free(flow, deferred); | ||
| 261 | } | ||
| 262 | } | ||
| 263 | |||
| 264 | skip_flows: | ||
| 264 | if (deferred) | 265 | if (deferred) |
| 265 | call_rcu(&ti->rcu, flow_tbl_destroy_rcu_cb); | 266 | call_rcu(&ti->rcu, flow_tbl_destroy_rcu_cb); |
| 266 | else | 267 | else |
| 267 | __table_instance_destroy(ti); | 268 | __table_instance_destroy(ti); |
| 268 | } | 269 | } |
| 269 | 270 | ||
| 270 | void ovs_flow_tbl_destroy(struct flow_table *table) | 271 | void ovs_flow_tbl_destroy(struct flow_table *table, bool deferred) |
| 271 | { | 272 | { |
| 272 | struct table_instance *ti = ovsl_dereference(table->ti); | 273 | struct table_instance *ti = ovsl_dereference(table->ti); |
| 273 | 274 | ||
| 274 | table_instance_destroy(ti, false); | 275 | table_instance_destroy(ti, deferred); |
| 275 | } | 276 | } |
| 276 | 277 | ||
| 277 | struct sw_flow *ovs_flow_tbl_dump_next(struct table_instance *ti, | 278 | struct sw_flow *ovs_flow_tbl_dump_next(struct table_instance *ti, |
| @@ -504,16 +505,11 @@ static struct sw_flow_mask *mask_alloc(void) | |||
| 504 | 505 | ||
| 505 | mask = kmalloc(sizeof(*mask), GFP_KERNEL); | 506 | mask = kmalloc(sizeof(*mask), GFP_KERNEL); |
| 506 | if (mask) | 507 | if (mask) |
| 507 | mask->ref_count = 0; | 508 | mask->ref_count = 1; |
| 508 | 509 | ||
| 509 | return mask; | 510 | return mask; |
| 510 | } | 511 | } |
| 511 | 512 | ||
| 512 | static void mask_add_ref(struct sw_flow_mask *mask) | ||
| 513 | { | ||
| 514 | mask->ref_count++; | ||
| 515 | } | ||
| 516 | |||
| 517 | static bool mask_equal(const struct sw_flow_mask *a, | 513 | static bool mask_equal(const struct sw_flow_mask *a, |
| 518 | const struct sw_flow_mask *b) | 514 | const struct sw_flow_mask *b) |
| 519 | { | 515 | { |
| @@ -554,9 +550,11 @@ static int flow_mask_insert(struct flow_table *tbl, struct sw_flow *flow, | |||
| 554 | mask->key = new->key; | 550 | mask->key = new->key; |
| 555 | mask->range = new->range; | 551 | mask->range = new->range; |
| 556 | list_add_rcu(&mask->list, &tbl->mask_list); | 552 | list_add_rcu(&mask->list, &tbl->mask_list); |
| 553 | } else { | ||
| 554 | BUG_ON(!mask->ref_count); | ||
| 555 | mask->ref_count++; | ||
| 557 | } | 556 | } |
| 558 | 557 | ||
| 559 | mask_add_ref(mask); | ||
| 560 | flow->mask = mask; | 558 | flow->mask = mask; |
| 561 | return 0; | 559 | return 0; |
| 562 | } | 560 | } |
diff --git a/net/openvswitch/flow_table.h b/net/openvswitch/flow_table.h index 1996e34c0fd8..baaeb101924d 100644 --- a/net/openvswitch/flow_table.h +++ b/net/openvswitch/flow_table.h | |||
| @@ -60,7 +60,7 @@ void ovs_flow_free(struct sw_flow *, bool deferred); | |||
| 60 | 60 | ||
| 61 | int ovs_flow_tbl_init(struct flow_table *); | 61 | int ovs_flow_tbl_init(struct flow_table *); |
| 62 | int ovs_flow_tbl_count(struct flow_table *table); | 62 | int ovs_flow_tbl_count(struct flow_table *table); |
| 63 | void ovs_flow_tbl_destroy(struct flow_table *table); | 63 | void ovs_flow_tbl_destroy(struct flow_table *table, bool deferred); |
| 64 | int ovs_flow_tbl_flush(struct flow_table *flow_table); | 64 | int ovs_flow_tbl_flush(struct flow_table *flow_table); |
| 65 | 65 | ||
| 66 | int ovs_flow_tbl_insert(struct flow_table *table, struct sw_flow *flow, | 66 | int ovs_flow_tbl_insert(struct flow_table *table, struct sw_flow *flow, |
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index 0f6259a6a932..2b1738ef9394 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c | |||
| @@ -662,6 +662,8 @@ static struct sock *sctp_v6_create_accept_sk(struct sock *sk, | |||
| 662 | */ | 662 | */ |
| 663 | sctp_v6_to_sk_daddr(&asoc->peer.primary_addr, newsk); | 663 | sctp_v6_to_sk_daddr(&asoc->peer.primary_addr, newsk); |
| 664 | 664 | ||
| 665 | newsk->sk_v6_rcv_saddr = sk->sk_v6_rcv_saddr; | ||
| 666 | |||
| 665 | sk_refcnt_debug_inc(newsk); | 667 | sk_refcnt_debug_inc(newsk); |
| 666 | 668 | ||
| 667 | if (newsk->sk_prot->init(newsk)) { | 669 | if (newsk->sk_prot->init(newsk)) { |
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index 80a6640f329b..06c6ff0cb911 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c | |||
| @@ -571,7 +571,7 @@ static void svc_check_conn_limits(struct svc_serv *serv) | |||
| 571 | } | 571 | } |
| 572 | } | 572 | } |
| 573 | 573 | ||
| 574 | int svc_alloc_arg(struct svc_rqst *rqstp) | 574 | static int svc_alloc_arg(struct svc_rqst *rqstp) |
| 575 | { | 575 | { |
| 576 | struct svc_serv *serv = rqstp->rq_server; | 576 | struct svc_serv *serv = rqstp->rq_server; |
| 577 | struct xdr_buf *arg; | 577 | struct xdr_buf *arg; |
| @@ -612,7 +612,7 @@ int svc_alloc_arg(struct svc_rqst *rqstp) | |||
| 612 | return 0; | 612 | return 0; |
| 613 | } | 613 | } |
| 614 | 614 | ||
| 615 | struct svc_xprt *svc_get_next_xprt(struct svc_rqst *rqstp, long timeout) | 615 | static struct svc_xprt *svc_get_next_xprt(struct svc_rqst *rqstp, long timeout) |
| 616 | { | 616 | { |
| 617 | struct svc_xprt *xprt; | 617 | struct svc_xprt *xprt; |
| 618 | struct svc_pool *pool = rqstp->rq_pool; | 618 | struct svc_pool *pool = rqstp->rq_pool; |
| @@ -691,7 +691,7 @@ struct svc_xprt *svc_get_next_xprt(struct svc_rqst *rqstp, long timeout) | |||
| 691 | return xprt; | 691 | return xprt; |
| 692 | } | 692 | } |
| 693 | 693 | ||
| 694 | void svc_add_new_temp_xprt(struct svc_serv *serv, struct svc_xprt *newxpt) | 694 | static void svc_add_new_temp_xprt(struct svc_serv *serv, struct svc_xprt *newxpt) |
| 695 | { | 695 | { |
| 696 | spin_lock_bh(&serv->sv_lock); | 696 | spin_lock_bh(&serv->sv_lock); |
| 697 | set_bit(XPT_TEMP, &newxpt->xpt_flags); | 697 | set_bit(XPT_TEMP, &newxpt->xpt_flags); |
diff --git a/net/wireless/core.c b/net/wireless/core.c index d89dee2259b5..010892b81a06 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
| @@ -203,8 +203,11 @@ void cfg80211_stop_p2p_device(struct cfg80211_registered_device *rdev, | |||
| 203 | 203 | ||
| 204 | rdev->opencount--; | 204 | rdev->opencount--; |
| 205 | 205 | ||
| 206 | WARN_ON(rdev->scan_req && rdev->scan_req->wdev == wdev && | 206 | if (rdev->scan_req && rdev->scan_req->wdev == wdev) { |
| 207 | !rdev->scan_req->notified); | 207 | if (WARN_ON(!rdev->scan_req->notified)) |
| 208 | rdev->scan_req->aborted = true; | ||
| 209 | ___cfg80211_scan_done(rdev, false); | ||
| 210 | } | ||
| 208 | } | 211 | } |
| 209 | 212 | ||
| 210 | static int cfg80211_rfkill_set_block(void *data, bool blocked) | 213 | static int cfg80211_rfkill_set_block(void *data, bool blocked) |
| @@ -440,9 +443,6 @@ int wiphy_register(struct wiphy *wiphy) | |||
| 440 | int i; | 443 | int i; |
| 441 | u16 ifmodes = wiphy->interface_modes; | 444 | u16 ifmodes = wiphy->interface_modes; |
| 442 | 445 | ||
| 443 | /* support for 5/10 MHz is broken due to nl80211 API mess - disable */ | ||
| 444 | wiphy->flags &= ~WIPHY_FLAG_SUPPORTS_5_10_MHZ; | ||
| 445 | |||
| 446 | /* | 446 | /* |
| 447 | * There are major locking problems in nl80211/mac80211 for CSA, | 447 | * There are major locking problems in nl80211/mac80211 for CSA, |
| 448 | * disable for all drivers until this has been reworked. | 448 | * disable for all drivers until this has been reworked. |
| @@ -859,8 +859,11 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb, | |||
| 859 | break; | 859 | break; |
| 860 | case NETDEV_DOWN: | 860 | case NETDEV_DOWN: |
| 861 | cfg80211_update_iface_num(rdev, wdev->iftype, -1); | 861 | cfg80211_update_iface_num(rdev, wdev->iftype, -1); |
| 862 | WARN_ON(rdev->scan_req && rdev->scan_req->wdev == wdev && | 862 | if (rdev->scan_req && rdev->scan_req->wdev == wdev) { |
| 863 | !rdev->scan_req->notified); | 863 | if (WARN_ON(!rdev->scan_req->notified)) |
| 864 | rdev->scan_req->aborted = true; | ||
| 865 | ___cfg80211_scan_done(rdev, false); | ||
| 866 | } | ||
| 864 | 867 | ||
| 865 | if (WARN_ON(rdev->sched_scan_req && | 868 | if (WARN_ON(rdev->sched_scan_req && |
| 866 | rdev->sched_scan_req->dev == wdev->netdev)) { | 869 | rdev->sched_scan_req->dev == wdev->netdev)) { |
diff --git a/net/wireless/core.h b/net/wireless/core.h index 37ec16d7bb1a..f1d193b557b6 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h | |||
| @@ -62,6 +62,7 @@ struct cfg80211_registered_device { | |||
| 62 | struct rb_root bss_tree; | 62 | struct rb_root bss_tree; |
| 63 | u32 bss_generation; | 63 | u32 bss_generation; |
| 64 | struct cfg80211_scan_request *scan_req; /* protected by RTNL */ | 64 | struct cfg80211_scan_request *scan_req; /* protected by RTNL */ |
| 65 | struct sk_buff *scan_msg; | ||
| 65 | struct cfg80211_sched_scan_request *sched_scan_req; | 66 | struct cfg80211_sched_scan_request *sched_scan_req; |
| 66 | unsigned long suspend_at; | 67 | unsigned long suspend_at; |
| 67 | struct work_struct scan_done_wk; | 68 | struct work_struct scan_done_wk; |
| @@ -361,7 +362,8 @@ int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev, | |||
| 361 | struct key_params *params, int key_idx, | 362 | struct key_params *params, int key_idx, |
| 362 | bool pairwise, const u8 *mac_addr); | 363 | bool pairwise, const u8 *mac_addr); |
| 363 | void __cfg80211_scan_done(struct work_struct *wk); | 364 | void __cfg80211_scan_done(struct work_struct *wk); |
| 364 | void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev); | 365 | void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, |
| 366 | bool send_message); | ||
| 365 | void __cfg80211_sched_scan_results(struct work_struct *wk); | 367 | void __cfg80211_sched_scan_results(struct work_struct *wk); |
| 366 | int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev, | 368 | int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev, |
| 367 | bool driver_initiated); | 369 | bool driver_initiated); |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 7a742594916e..4fe2e6e2bc76 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
| @@ -1719,9 +1719,10 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb) | |||
| 1719 | * We can then retry with the larger buffer. | 1719 | * We can then retry with the larger buffer. |
| 1720 | */ | 1720 | */ |
| 1721 | if ((ret == -ENOBUFS || ret == -EMSGSIZE) && | 1721 | if ((ret == -ENOBUFS || ret == -EMSGSIZE) && |
| 1722 | !skb->len && | 1722 | !skb->len && !state->split && |
| 1723 | cb->min_dump_alloc < 4096) { | 1723 | cb->min_dump_alloc < 4096) { |
| 1724 | cb->min_dump_alloc = 4096; | 1724 | cb->min_dump_alloc = 4096; |
| 1725 | state->split_start = 0; | ||
| 1725 | rtnl_unlock(); | 1726 | rtnl_unlock(); |
| 1726 | return 1; | 1727 | return 1; |
| 1727 | } | 1728 | } |
| @@ -5244,7 +5245,7 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) | |||
| 5244 | if (!rdev->ops->scan) | 5245 | if (!rdev->ops->scan) |
| 5245 | return -EOPNOTSUPP; | 5246 | return -EOPNOTSUPP; |
| 5246 | 5247 | ||
| 5247 | if (rdev->scan_req) { | 5248 | if (rdev->scan_req || rdev->scan_msg) { |
| 5248 | err = -EBUSY; | 5249 | err = -EBUSY; |
| 5249 | goto unlock; | 5250 | goto unlock; |
| 5250 | } | 5251 | } |
| @@ -10011,40 +10012,31 @@ void nl80211_send_scan_start(struct cfg80211_registered_device *rdev, | |||
| 10011 | NL80211_MCGRP_SCAN, GFP_KERNEL); | 10012 | NL80211_MCGRP_SCAN, GFP_KERNEL); |
| 10012 | } | 10013 | } |
| 10013 | 10014 | ||
| 10014 | void nl80211_send_scan_done(struct cfg80211_registered_device *rdev, | 10015 | struct sk_buff *nl80211_build_scan_msg(struct cfg80211_registered_device *rdev, |
| 10015 | struct wireless_dev *wdev) | 10016 | struct wireless_dev *wdev, bool aborted) |
| 10016 | { | 10017 | { |
| 10017 | struct sk_buff *msg; | 10018 | struct sk_buff *msg; |
| 10018 | 10019 | ||
| 10019 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | 10020 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); |
| 10020 | if (!msg) | 10021 | if (!msg) |
| 10021 | return; | 10022 | return NULL; |
| 10022 | 10023 | ||
| 10023 | if (nl80211_send_scan_msg(msg, rdev, wdev, 0, 0, 0, | 10024 | if (nl80211_send_scan_msg(msg, rdev, wdev, 0, 0, 0, |
| 10024 | NL80211_CMD_NEW_SCAN_RESULTS) < 0) { | 10025 | aborted ? NL80211_CMD_SCAN_ABORTED : |
| 10026 | NL80211_CMD_NEW_SCAN_RESULTS) < 0) { | ||
| 10025 | nlmsg_free(msg); | 10027 | nlmsg_free(msg); |
| 10026 | return; | 10028 | return NULL; |
| 10027 | } | 10029 | } |
| 10028 | 10030 | ||
| 10029 | genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, | 10031 | return msg; |
| 10030 | NL80211_MCGRP_SCAN, GFP_KERNEL); | ||
| 10031 | } | 10032 | } |
| 10032 | 10033 | ||
| 10033 | void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev, | 10034 | void nl80211_send_scan_result(struct cfg80211_registered_device *rdev, |
| 10034 | struct wireless_dev *wdev) | 10035 | struct sk_buff *msg) |
| 10035 | { | 10036 | { |
| 10036 | struct sk_buff *msg; | ||
| 10037 | |||
| 10038 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | ||
| 10039 | if (!msg) | 10037 | if (!msg) |
| 10040 | return; | 10038 | return; |
| 10041 | 10039 | ||
| 10042 | if (nl80211_send_scan_msg(msg, rdev, wdev, 0, 0, 0, | ||
| 10043 | NL80211_CMD_SCAN_ABORTED) < 0) { | ||
| 10044 | nlmsg_free(msg); | ||
| 10045 | return; | ||
| 10046 | } | ||
| 10047 | |||
| 10048 | genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, | 10040 | genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, |
| 10049 | NL80211_MCGRP_SCAN, GFP_KERNEL); | 10041 | NL80211_MCGRP_SCAN, GFP_KERNEL); |
| 10050 | } | 10042 | } |
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h index b1b231324e10..75799746d845 100644 --- a/net/wireless/nl80211.h +++ b/net/wireless/nl80211.h | |||
| @@ -8,10 +8,10 @@ void nl80211_exit(void); | |||
| 8 | void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev); | 8 | void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev); |
| 9 | void nl80211_send_scan_start(struct cfg80211_registered_device *rdev, | 9 | void nl80211_send_scan_start(struct cfg80211_registered_device *rdev, |
| 10 | struct wireless_dev *wdev); | 10 | struct wireless_dev *wdev); |
| 11 | void nl80211_send_scan_done(struct cfg80211_registered_device *rdev, | 11 | struct sk_buff *nl80211_build_scan_msg(struct cfg80211_registered_device *rdev, |
| 12 | struct wireless_dev *wdev); | 12 | struct wireless_dev *wdev, bool aborted); |
| 13 | void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev, | 13 | void nl80211_send_scan_result(struct cfg80211_registered_device *rdev, |
| 14 | struct wireless_dev *wdev); | 14 | struct sk_buff *msg); |
| 15 | void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev, | 15 | void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev, |
| 16 | struct net_device *netdev, u32 cmd); | 16 | struct net_device *netdev, u32 cmd); |
| 17 | void nl80211_send_sched_scan_results(struct cfg80211_registered_device *rdev, | 17 | void nl80211_send_sched_scan_results(struct cfg80211_registered_device *rdev, |
diff --git a/net/wireless/scan.c b/net/wireless/scan.c index b528e31da2cf..d1ed4aebbbb7 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c | |||
| @@ -161,18 +161,25 @@ static void __cfg80211_bss_expire(struct cfg80211_registered_device *dev, | |||
| 161 | dev->bss_generation++; | 161 | dev->bss_generation++; |
| 162 | } | 162 | } |
| 163 | 163 | ||
| 164 | void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev) | 164 | void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, |
| 165 | bool send_message) | ||
| 165 | { | 166 | { |
| 166 | struct cfg80211_scan_request *request; | 167 | struct cfg80211_scan_request *request; |
| 167 | struct wireless_dev *wdev; | 168 | struct wireless_dev *wdev; |
| 169 | struct sk_buff *msg; | ||
| 168 | #ifdef CONFIG_CFG80211_WEXT | 170 | #ifdef CONFIG_CFG80211_WEXT |
| 169 | union iwreq_data wrqu; | 171 | union iwreq_data wrqu; |
| 170 | #endif | 172 | #endif |
| 171 | 173 | ||
| 172 | ASSERT_RTNL(); | 174 | ASSERT_RTNL(); |
| 173 | 175 | ||
| 174 | request = rdev->scan_req; | 176 | if (rdev->scan_msg) { |
| 177 | nl80211_send_scan_result(rdev, rdev->scan_msg); | ||
| 178 | rdev->scan_msg = NULL; | ||
| 179 | return; | ||
| 180 | } | ||
| 175 | 181 | ||
| 182 | request = rdev->scan_req; | ||
| 176 | if (!request) | 183 | if (!request) |
| 177 | return; | 184 | return; |
| 178 | 185 | ||
| @@ -186,18 +193,16 @@ void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev) | |||
| 186 | if (wdev->netdev) | 193 | if (wdev->netdev) |
| 187 | cfg80211_sme_scan_done(wdev->netdev); | 194 | cfg80211_sme_scan_done(wdev->netdev); |
| 188 | 195 | ||
| 189 | if (request->aborted) { | 196 | if (!request->aborted && |
| 190 | nl80211_send_scan_aborted(rdev, wdev); | 197 | request->flags & NL80211_SCAN_FLAG_FLUSH) { |
| 191 | } else { | 198 | /* flush entries from previous scans */ |
| 192 | if (request->flags & NL80211_SCAN_FLAG_FLUSH) { | 199 | spin_lock_bh(&rdev->bss_lock); |
| 193 | /* flush entries from previous scans */ | 200 | __cfg80211_bss_expire(rdev, request->scan_start); |
| 194 | spin_lock_bh(&rdev->bss_lock); | 201 | spin_unlock_bh(&rdev->bss_lock); |
| 195 | __cfg80211_bss_expire(rdev, request->scan_start); | ||
| 196 | spin_unlock_bh(&rdev->bss_lock); | ||
| 197 | } | ||
| 198 | nl80211_send_scan_done(rdev, wdev); | ||
| 199 | } | 202 | } |
| 200 | 203 | ||
| 204 | msg = nl80211_build_scan_msg(rdev, wdev, request->aborted); | ||
| 205 | |||
| 201 | #ifdef CONFIG_CFG80211_WEXT | 206 | #ifdef CONFIG_CFG80211_WEXT |
| 202 | if (wdev->netdev && !request->aborted) { | 207 | if (wdev->netdev && !request->aborted) { |
| 203 | memset(&wrqu, 0, sizeof(wrqu)); | 208 | memset(&wrqu, 0, sizeof(wrqu)); |
| @@ -211,6 +216,11 @@ void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev) | |||
| 211 | 216 | ||
| 212 | rdev->scan_req = NULL; | 217 | rdev->scan_req = NULL; |
| 213 | kfree(request); | 218 | kfree(request); |
| 219 | |||
| 220 | if (!send_message) | ||
| 221 | rdev->scan_msg = msg; | ||
| 222 | else | ||
| 223 | nl80211_send_scan_result(rdev, msg); | ||
| 214 | } | 224 | } |
| 215 | 225 | ||
| 216 | void __cfg80211_scan_done(struct work_struct *wk) | 226 | void __cfg80211_scan_done(struct work_struct *wk) |
| @@ -221,7 +231,7 @@ void __cfg80211_scan_done(struct work_struct *wk) | |||
| 221 | scan_done_wk); | 231 | scan_done_wk); |
| 222 | 232 | ||
| 223 | rtnl_lock(); | 233 | rtnl_lock(); |
| 224 | ___cfg80211_scan_done(rdev); | 234 | ___cfg80211_scan_done(rdev, true); |
| 225 | rtnl_unlock(); | 235 | rtnl_unlock(); |
| 226 | } | 236 | } |
| 227 | 237 | ||
| @@ -1079,7 +1089,7 @@ int cfg80211_wext_siwscan(struct net_device *dev, | |||
| 1079 | if (IS_ERR(rdev)) | 1089 | if (IS_ERR(rdev)) |
| 1080 | return PTR_ERR(rdev); | 1090 | return PTR_ERR(rdev); |
| 1081 | 1091 | ||
| 1082 | if (rdev->scan_req) { | 1092 | if (rdev->scan_req || rdev->scan_msg) { |
| 1083 | err = -EBUSY; | 1093 | err = -EBUSY; |
| 1084 | goto out; | 1094 | goto out; |
| 1085 | } | 1095 | } |
| @@ -1481,7 +1491,7 @@ int cfg80211_wext_giwscan(struct net_device *dev, | |||
| 1481 | if (IS_ERR(rdev)) | 1491 | if (IS_ERR(rdev)) |
| 1482 | return PTR_ERR(rdev); | 1492 | return PTR_ERR(rdev); |
| 1483 | 1493 | ||
| 1484 | if (rdev->scan_req) | 1494 | if (rdev->scan_req || rdev->scan_msg) |
| 1485 | return -EAGAIN; | 1495 | return -EAGAIN; |
| 1486 | 1496 | ||
| 1487 | res = ieee80211_scan_results(rdev, info, extra, data->length); | 1497 | res = ieee80211_scan_results(rdev, info, extra, data->length); |
diff --git a/net/wireless/sme.c b/net/wireless/sme.c index a63509118508..f04d4c32e96e 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c | |||
| @@ -67,7 +67,7 @@ static int cfg80211_conn_scan(struct wireless_dev *wdev) | |||
| 67 | ASSERT_RDEV_LOCK(rdev); | 67 | ASSERT_RDEV_LOCK(rdev); |
| 68 | ASSERT_WDEV_LOCK(wdev); | 68 | ASSERT_WDEV_LOCK(wdev); |
| 69 | 69 | ||
| 70 | if (rdev->scan_req) | 70 | if (rdev->scan_req || rdev->scan_msg) |
| 71 | return -EBUSY; | 71 | return -EBUSY; |
| 72 | 72 | ||
| 73 | if (wdev->conn->params.channel) | 73 | if (wdev->conn->params.channel) |
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 0ea2a1e24ade..464dcef79b35 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl | |||
| @@ -471,7 +471,7 @@ sub seed_camelcase_includes { | |||
| 471 | 471 | ||
| 472 | $camelcase_seeded = 1; | 472 | $camelcase_seeded = 1; |
| 473 | 473 | ||
| 474 | if (-d ".git") { | 474 | if (-e ".git") { |
| 475 | my $git_last_include_commit = `git log --no-merges --pretty=format:"%h%n" -1 -- include`; | 475 | my $git_last_include_commit = `git log --no-merges --pretty=format:"%h%n" -1 -- include`; |
| 476 | chomp $git_last_include_commit; | 476 | chomp $git_last_include_commit; |
| 477 | $camelcase_cache = ".checkpatch-camelcase.git.$git_last_include_commit"; | 477 | $camelcase_cache = ".checkpatch-camelcase.git.$git_last_include_commit"; |
| @@ -499,7 +499,7 @@ sub seed_camelcase_includes { | |||
| 499 | return; | 499 | return; |
| 500 | } | 500 | } |
| 501 | 501 | ||
| 502 | if (-d ".git") { | 502 | if (-e ".git") { |
| 503 | $files = `git ls-files "include/*.h"`; | 503 | $files = `git ls-files "include/*.h"`; |
| 504 | @include_files = split('\n', $files); | 504 | @include_files = split('\n', $files); |
| 505 | } | 505 | } |
diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl index 9c3986f4140c..41987885bd31 100755 --- a/scripts/get_maintainer.pl +++ b/scripts/get_maintainer.pl | |||
| @@ -95,7 +95,7 @@ my %VCS_cmds; | |||
| 95 | 95 | ||
| 96 | my %VCS_cmds_git = ( | 96 | my %VCS_cmds_git = ( |
| 97 | "execute_cmd" => \&git_execute_cmd, | 97 | "execute_cmd" => \&git_execute_cmd, |
| 98 | "available" => '(which("git") ne "") && (-d ".git")', | 98 | "available" => '(which("git") ne "") && (-e ".git")', |
| 99 | "find_signers_cmd" => | 99 | "find_signers_cmd" => |
| 100 | "git log --no-color --follow --since=\$email_git_since " . | 100 | "git log --no-color --follow --since=\$email_git_since " . |
| 101 | '--numstat --no-merges ' . | 101 | '--numstat --no-merges ' . |
